mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-04 12:42:43 +01:00
(stable) Promote 2019 Week 34
This commit is contained in:
commit
3e02f3c89c
167 changed files with 7176 additions and 3543 deletions
|
@ -1 +0,0 @@
|
|||
../scripts/user/account_admin.php
|
|
@ -1 +0,0 @@
|
|||
../scripts/people/manage_people.php
|
1
bin/user
Symbolic link
1
bin/user
Symbolic link
|
@ -0,0 +1 @@
|
|||
../scripts/setup/manage_user.php
|
|
@ -92,7 +92,7 @@ return array(
|
|||
'rsrc/css/application/pholio/pholio.css' => '88ef5ef1',
|
||||
'rsrc/css/application/phortune/phortune-credit-card-form.css' => '3b9868a8',
|
||||
'rsrc/css/application/phortune/phortune-invoice.css' => '4436b241',
|
||||
'rsrc/css/application/phortune/phortune.css' => '12e8251a',
|
||||
'rsrc/css/application/phortune/phortune.css' => '508a1a5e',
|
||||
'rsrc/css/application/phrequent/phrequent.css' => 'bd79cc67',
|
||||
'rsrc/css/application/phriction/phriction-document-css.css' => '03380da0',
|
||||
'rsrc/css/application/policy/policy-edit.css' => '8794e2ed',
|
||||
|
@ -810,7 +810,7 @@ return array(
|
|||
'pholio-inline-comments-css' => '722b48c2',
|
||||
'phortune-credit-card-form' => 'd12d214f',
|
||||
'phortune-credit-card-form-css' => '3b9868a8',
|
||||
'phortune-css' => '12e8251a',
|
||||
'phortune-css' => '508a1a5e',
|
||||
'phortune-invoice-css' => '4436b241',
|
||||
'phrequent-css' => 'bd79cc67',
|
||||
'phriction-document-css' => '03380da0',
|
||||
|
|
12
resources/sql/autopatches/20190802.email.01.storage.sql
Normal file
12
resources/sql/autopatches/20190802.email.01.storage.sql
Normal file
|
@ -0,0 +1,12 @@
|
|||
CREATE TABLE {$NAMESPACE}_phortune.phortune_accountemail (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
accountPHID VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
address VARCHAR(128) NOT NULL COLLATE {$COLLATE_SORT},
|
||||
status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
addressKey VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
accessKey VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
19
resources/sql/autopatches/20190802.email.02.xaction.sql
Normal file
19
resources/sql/autopatches/20190802.email.02.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_phortune.phortune_accountemailtransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGTEXT NOT NULL,
|
||||
newValue LONGTEXT NOT NULL,
|
||||
contentSource LONGTEXT NOT NULL,
|
||||
metadata LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
10
resources/sql/autopatches/20190815.account.01.carts.php
Normal file
10
resources/sql/autopatches/20190815.account.01.carts.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
$edge_type = PhortuneAccountHasMerchantEdgeType::EDGECONST;
|
||||
|
||||
$table = new PhortuneCart();
|
||||
foreach (new LiskMigrationIterator($table) as $cart) {
|
||||
id(new PhabricatorEdgeEditor())
|
||||
->addEdge($cart->getAccountPHID(), $edge_type, $cart->getMerchantPHID())
|
||||
->save();
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
$edge_type = PhortuneAccountHasMerchantEdgeType::EDGECONST;
|
||||
|
||||
$table = new PhortuneSubscription();
|
||||
foreach (new LiskMigrationIterator($table) as $sub) {
|
||||
id(new PhabricatorEdgeEditor())
|
||||
->addEdge($sub->getAccountPHID(), $edge_type, $sub->getMerchantPHID())
|
||||
->save();
|
||||
}
|
19
resources/sql/autopatches/20190816.payment.01.xaction.sql
Normal file
19
resources/sql/autopatches/20190816.payment.01.xaction.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_phortune.phortune_paymentmethodtransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGTEXT NOT NULL,
|
||||
newValue LONGTEXT NOT NULL,
|
||||
contentSource LONGTEXT NOT NULL,
|
||||
metadata LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE {$NAMESPACE}_phortune.phortune_subscriptiontransaction (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
authorPHID VARBINARY(64) NOT NULL,
|
||||
objectPHID VARBINARY(64) NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL,
|
||||
oldValue LONGTEXT NOT NULL,
|
||||
newValue LONGTEXT NOT NULL,
|
||||
contentSource LONGTEXT NOT NULL,
|
||||
metadata LONGTEXT NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (`phid`),
|
||||
KEY `key_object` (`objectPHID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
2
resources/sql/autopatches/20190822.merchant.01.view.sql
Normal file
2
resources/sql/autopatches/20190822.merchant.01.view.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_phortune.phortune_merchant
|
||||
DROP viewPolicy;
|
|
@ -6,8 +6,8 @@ require_once $root.'/scripts/__init_script__.php';
|
|||
|
||||
$args = new PhutilArgumentParser($argv);
|
||||
$args->setSynopsis(<<<EOSYNOPSIS
|
||||
**people** __command__ [__options__]
|
||||
Manage user profiles and accounts.
|
||||
**user** __command__ [__options__]
|
||||
Modify user accounts to regain access to an install.
|
||||
|
||||
EOSYNOPSIS
|
||||
);
|
|
@ -1,228 +0,0 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
$table = new PhabricatorUser();
|
||||
$any_user = queryfx_one(
|
||||
$table->establishConnection('r'),
|
||||
'SELECT * FROM %T LIMIT 1',
|
||||
$table->getTableName());
|
||||
$is_first_user = (!$any_user);
|
||||
|
||||
if ($is_first_user) {
|
||||
echo pht(
|
||||
"WARNING\n\n".
|
||||
"You're about to create the first account on this install. Normally, ".
|
||||
"you should use the web interface to create the first account, not ".
|
||||
"this script.\n\n".
|
||||
"If you use the web interface, it will drop you into a nice UI workflow ".
|
||||
"which gives you more help setting up your install. If you create an ".
|
||||
"account with this script instead, you will skip the setup help and you ".
|
||||
"will not be able to access it later.");
|
||||
if (!phutil_console_confirm(pht('Skip easy setup and create account?'))) {
|
||||
echo pht('Cancelled.')."\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
echo pht(
|
||||
'Enter a username to create a new account or edit an existing account.');
|
||||
|
||||
$username = phutil_console_prompt(pht('Enter a username:'));
|
||||
if (!strlen($username)) {
|
||||
echo pht('Cancelled.')."\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!PhabricatorUser::validateUsername($username)) {
|
||||
$valid = PhabricatorUser::describeValidUsername();
|
||||
echo pht("The username '%s' is invalid. %s", $username, $valid)."\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
$user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$username);
|
||||
|
||||
if (!$user) {
|
||||
$original = new PhabricatorUser();
|
||||
|
||||
echo pht("There is no existing user account '%s'.", $username)."\n";
|
||||
$ok = phutil_console_confirm(
|
||||
pht("Do you want to create a new '%s' account?", $username),
|
||||
$default_no = false);
|
||||
if (!$ok) {
|
||||
echo pht('Cancelled.')."\n";
|
||||
exit(1);
|
||||
}
|
||||
$user = new PhabricatorUser();
|
||||
$user->setUsername($username);
|
||||
|
||||
$is_new = true;
|
||||
} else {
|
||||
$original = clone $user;
|
||||
|
||||
echo pht("There is an existing user account '%s'.", $username)."\n";
|
||||
$ok = phutil_console_confirm(
|
||||
pht("Do you want to edit the existing '%s' account?", $username),
|
||||
$default_no = false);
|
||||
if (!$ok) {
|
||||
echo pht('Cancelled.')."\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$is_new = false;
|
||||
}
|
||||
|
||||
$user_realname = $user->getRealName();
|
||||
if (strlen($user_realname)) {
|
||||
$realname_prompt = ' ['.$user_realname.']:';
|
||||
} else {
|
||||
$realname_prompt = ':';
|
||||
}
|
||||
$realname = nonempty(
|
||||
phutil_console_prompt(pht('Enter user real name').$realname_prompt),
|
||||
$user_realname);
|
||||
$user->setRealName($realname);
|
||||
|
||||
// When creating a new user we prompt for an email address; when editing an
|
||||
// existing user we just skip this because it would be quite involved to provide
|
||||
// a reasonable CLI interface for editing multiple addresses and managing email
|
||||
// verification and primary addresses.
|
||||
|
||||
$create_email = null;
|
||||
if ($is_new) {
|
||||
do {
|
||||
$email = phutil_console_prompt(pht('Enter user email address:'));
|
||||
$duplicate = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
$email);
|
||||
if ($duplicate) {
|
||||
echo pht(
|
||||
"ERROR: There is already a user with that email address. ".
|
||||
"Each user must have a unique email address.\n");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
$create_email = $email;
|
||||
}
|
||||
|
||||
$is_system_agent = $user->getIsSystemAgent();
|
||||
$set_system_agent = phutil_console_confirm(
|
||||
pht('Is this user a bot?'),
|
||||
$default_no = !$is_system_agent);
|
||||
|
||||
$verify_email = null;
|
||||
$set_verified = false;
|
||||
// Allow administrators to verify primary email addresses at this time in edit
|
||||
// scenarios. (Create will work just fine from here as we auto-verify email
|
||||
// on create.)
|
||||
if (!$is_new) {
|
||||
$verify_email = $user->loadPrimaryEmail();
|
||||
if (!$verify_email->getIsVerified()) {
|
||||
$set_verified = phutil_console_confirm(
|
||||
pht('Should the primary email address be verified?'),
|
||||
$default_no = true);
|
||||
} else {
|
||||
// Already verified so let's not make a fuss.
|
||||
$verify_email = null;
|
||||
}
|
||||
}
|
||||
|
||||
$is_admin = $user->getIsAdmin();
|
||||
$set_admin = phutil_console_confirm(
|
||||
pht('Should this user be an administrator?'),
|
||||
$default_no = !$is_admin);
|
||||
|
||||
echo "\n\n".pht('ACCOUNT SUMMARY')."\n\n";
|
||||
$tpl = "%12s %-30s %-30s\n";
|
||||
printf($tpl, null, pht('OLD VALUE'), pht('NEW VALUE'));
|
||||
printf($tpl, pht('Username'), $original->getUsername(), $user->getUsername());
|
||||
printf($tpl, pht('Real Name'), $original->getRealName(), $user->getRealName());
|
||||
if ($is_new) {
|
||||
printf($tpl, pht('Email'), '', $create_email);
|
||||
}
|
||||
|
||||
printf(
|
||||
$tpl,
|
||||
pht('Bot'),
|
||||
$original->getIsSystemAgent() ? 'Y' : 'N',
|
||||
$set_system_agent ? 'Y' : 'N');
|
||||
|
||||
if ($verify_email) {
|
||||
printf(
|
||||
$tpl,
|
||||
pht('Verify Email'),
|
||||
$verify_email->getIsVerified() ? 'Y' : 'N',
|
||||
$set_verified ? 'Y' : 'N');
|
||||
}
|
||||
|
||||
printf(
|
||||
$tpl,
|
||||
pht('Admin'),
|
||||
$original->getIsAdmin() ? 'Y' : 'N',
|
||||
$set_admin ? 'Y' : 'N');
|
||||
|
||||
echo "\n";
|
||||
|
||||
if (!phutil_console_confirm(pht('Save these changes?'), $default_no = false)) {
|
||||
echo pht('Cancelled.')."\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$user->openTransaction();
|
||||
|
||||
$editor = new PhabricatorUserEditor();
|
||||
|
||||
// TODO: This is wrong, but we have a chicken-and-egg problem when you use
|
||||
// this script to create the first user.
|
||||
$editor->setActor($user);
|
||||
|
||||
if ($is_new) {
|
||||
$email = id(new PhabricatorUserEmail())
|
||||
->setAddress($create_email)
|
||||
->setIsVerified(1);
|
||||
|
||||
// Unconditionally approve new accounts created from the CLI.
|
||||
$user->setIsApproved(1);
|
||||
|
||||
$editor->createNewUser($user, $email);
|
||||
} else {
|
||||
if ($verify_email) {
|
||||
$user->setIsEmailVerified(1);
|
||||
$verify_email->setIsVerified($set_verified ? 1 : 0);
|
||||
}
|
||||
$editor->updateUser($user, $verify_email);
|
||||
}
|
||||
|
||||
$editor->makeSystemAgentUser($user, $set_system_agent);
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(
|
||||
PhabricatorUserEmpowerTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($set_admin);
|
||||
|
||||
$actor = PhabricatorUser::getOmnipotentUser();
|
||||
$content_source = PhabricatorContentSource::newForSource(
|
||||
PhabricatorConsoleContentSource::SOURCECONST);
|
||||
|
||||
$people_application_phid = id(new PhabricatorPeopleApplication())->getPHID();
|
||||
|
||||
$transaction_editor = id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setActingAsPHID($people_application_phid)
|
||||
->setContentSource($content_source)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$transaction_editor->applyTransactions($user, $xactions);
|
||||
|
||||
$user->saveTransaction();
|
||||
|
||||
echo pht('Saved changes.')."\n";
|
|
@ -1,73 +0,0 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
if ($argc !== 5) {
|
||||
echo pht(
|
||||
"Usage: %s\n",
|
||||
'add_user.php <username> <email> <realname> <admin_user>');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$username = $argv[1];
|
||||
$email = $argv[2];
|
||||
$realname = $argv[3];
|
||||
$admin = $argv[4];
|
||||
|
||||
$admin = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$argv[4]);
|
||||
if (!$admin) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Admin user must be the username of a valid Phabricator account, used '.
|
||||
'to send the new user a welcome email.'));
|
||||
}
|
||||
|
||||
$existing_user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$username);
|
||||
if ($existing_user) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"There is already a user with the username '%s'!",
|
||||
$username));
|
||||
}
|
||||
|
||||
$existing_email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
$email);
|
||||
if ($existing_email) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
"There is already a user with the email '%s'!",
|
||||
$email));
|
||||
}
|
||||
|
||||
$user = new PhabricatorUser();
|
||||
$user->setUsername($username);
|
||||
$user->setRealname($realname);
|
||||
$user->setIsApproved(1);
|
||||
|
||||
$email_object = id(new PhabricatorUserEmail())
|
||||
->setAddress($email)
|
||||
->setIsVerified(1);
|
||||
|
||||
id(new PhabricatorUserEditor())
|
||||
->setActor($admin)
|
||||
->createNewUser($user, $email_object);
|
||||
|
||||
$welcome_engine = id(new PhabricatorPeopleWelcomeMailEngine())
|
||||
->setSender($admin)
|
||||
->setRecipient($user);
|
||||
if ($welcome_engine->canSendMail()) {
|
||||
$welcome_engine->sendMail();
|
||||
}
|
||||
|
||||
echo pht(
|
||||
"Created user '%s' (realname='%s', email='%s').\n",
|
||||
$username,
|
||||
$realname,
|
||||
$email);
|
|
@ -1222,6 +1222,7 @@ phutil_register_library_map(array(
|
|||
'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php',
|
||||
'DrydockResourceReclaimLogType' => 'applications/drydock/logtype/DrydockResourceReclaimLogType.php',
|
||||
'DrydockResourceReleaseController' => 'applications/drydock/controller/DrydockResourceReleaseController.php',
|
||||
'DrydockResourceSearchConduitAPIMethod' => 'applications/drydock/conduit/DrydockResourceSearchConduitAPIMethod.php',
|
||||
'DrydockResourceSearchEngine' => 'applications/drydock/query/DrydockResourceSearchEngine.php',
|
||||
'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php',
|
||||
'DrydockResourceUpdateWorker' => 'applications/drydock/worker/DrydockResourceUpdateWorker.php',
|
||||
|
@ -4050,6 +4051,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleMailEngine' => 'applications/people/mail/PhabricatorPeopleMailEngine.php',
|
||||
'PhabricatorPeopleMailEngineException' => 'applications/people/mail/PhabricatorPeopleMailEngineException.php',
|
||||
'PhabricatorPeopleManageProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleManageProfileMenuItem.php',
|
||||
'PhabricatorPeopleManagementEmpowerWorkflow' => 'applications/people/management/PhabricatorPeopleManagementEmpowerWorkflow.php',
|
||||
'PhabricatorPeopleManagementEnableWorkflow' => 'applications/people/management/PhabricatorPeopleManagementEnableWorkflow.php',
|
||||
'PhabricatorPeopleManagementWorkflow' => 'applications/people/management/PhabricatorPeopleManagementWorkflow.php',
|
||||
'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
|
||||
'PhabricatorPeopleNoOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleNoOwnerDatasource.php',
|
||||
|
@ -4059,7 +4062,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileCommitsController' => 'applications/people/controller/PhabricatorPeopleProfileCommitsController.php',
|
||||
'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
|
||||
'PhabricatorPeopleProfileEditController' => 'applications/people/controller/PhabricatorPeopleProfileEditController.php',
|
||||
'PhabricatorPeopleProfileImageWorkflow' => 'applications/people/management/PhabricatorPeopleProfileImageWorkflow.php',
|
||||
'PhabricatorPeopleProfileManageController' => 'applications/people/controller/PhabricatorPeopleProfileManageController.php',
|
||||
'PhabricatorPeopleProfileMenuEngine' => 'applications/people/engine/PhabricatorPeopleProfileMenuEngine.php',
|
||||
'PhabricatorPeopleProfilePictureController' => 'applications/people/controller/PhabricatorPeopleProfilePictureController.php',
|
||||
|
@ -5219,25 +5221,50 @@ phutil_register_library_map(array(
|
|||
'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
|
||||
'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php',
|
||||
'PhortuneAccountBillingAddressTransaction' => 'applications/phortune/xaction/PhortuneAccountBillingAddressTransaction.php',
|
||||
'PhortuneAccountBillingController' => 'applications/phortune/controller/account/PhortuneAccountBillingController.php',
|
||||
'PhortuneAccountBillingNameTransaction' => 'applications/phortune/xaction/PhortuneAccountBillingNameTransaction.php',
|
||||
'PhortuneAccountChargeListController' => 'applications/phortune/controller/account/PhortuneAccountChargeListController.php',
|
||||
'PhortuneAccountChargesController' => 'applications/phortune/controller/account/PhortuneAccountChargesController.php',
|
||||
'PhortuneAccountController' => 'applications/phortune/controller/account/PhortuneAccountController.php',
|
||||
'PhortuneAccountDetailsController' => 'applications/phortune/controller/account/PhortuneAccountDetailsController.php',
|
||||
'PhortuneAccountEditController' => 'applications/phortune/controller/account/PhortuneAccountEditController.php',
|
||||
'PhortuneAccountEditEngine' => 'applications/phortune/editor/PhortuneAccountEditEngine.php',
|
||||
'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php',
|
||||
'PhortuneAccountEmail' => 'applications/phortune/storage/PhortuneAccountEmail.php',
|
||||
'PhortuneAccountEmailAddressTransaction' => 'applications/phortune/xaction/PhortuneAccountEmailAddressTransaction.php',
|
||||
'PhortuneAccountEmailAddressesController' => 'applications/phortune/controller/account/PhortuneAccountEmailAddressesController.php',
|
||||
'PhortuneAccountEmailEditController' => 'applications/phortune/controller/account/PhortuneAccountEmailEditController.php',
|
||||
'PhortuneAccountEmailEditEngine' => 'applications/phortune/editor/PhortuneAccountEmailEditEngine.php',
|
||||
'PhortuneAccountEmailEditor' => 'applications/phortune/editor/PhortuneAccountEmailEditor.php',
|
||||
'PhortuneAccountEmailPHIDType' => 'applications/phortune/phid/PhortuneAccountEmailPHIDType.php',
|
||||
'PhortuneAccountEmailQuery' => 'applications/phortune/query/PhortuneAccountEmailQuery.php',
|
||||
'PhortuneAccountEmailRotateController' => 'applications/phortune/controller/account/PhortuneAccountEmailRotateController.php',
|
||||
'PhortuneAccountEmailRotateTransaction' => 'applications/phortune/xaction/PhortuneAccountEmailRotateTransaction.php',
|
||||
'PhortuneAccountEmailStatus' => 'applications/phortune/constants/PhortuneAccountEmailStatus.php',
|
||||
'PhortuneAccountEmailStatusController' => 'applications/phortune/controller/account/PhortuneAccountEmailStatusController.php',
|
||||
'PhortuneAccountEmailStatusTransaction' => 'applications/phortune/xaction/PhortuneAccountEmailStatusTransaction.php',
|
||||
'PhortuneAccountEmailTransaction' => 'applications/phortune/storage/PhortuneAccountEmailTransaction.php',
|
||||
'PhortuneAccountEmailTransactionQuery' => 'applications/phortune/query/PhortuneAccountEmailTransactionQuery.php',
|
||||
'PhortuneAccountEmailTransactionType' => 'applications/phortune/xaction/PhortuneAccountEmailTransactionType.php',
|
||||
'PhortuneAccountEmailViewController' => 'applications/phortune/controller/account/PhortuneAccountEmailViewController.php',
|
||||
'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php',
|
||||
'PhortuneAccountHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMerchantEdgeType.php',
|
||||
'PhortuneAccountListController' => 'applications/phortune/controller/account/PhortuneAccountListController.php',
|
||||
'PhortuneAccountManagerController' => 'applications/phortune/controller/account/PhortuneAccountManagerController.php',
|
||||
'PhortuneAccountManagersController' => 'applications/phortune/controller/account/PhortuneAccountManagersController.php',
|
||||
'PhortuneAccountNameTransaction' => 'applications/phortune/xaction/PhortuneAccountNameTransaction.php',
|
||||
'PhortuneAccountOrderListController' => 'applications/phortune/controller/account/PhortuneAccountOrderListController.php',
|
||||
'PhortuneAccountOrdersController' => 'applications/phortune/controller/account/PhortuneAccountOrdersController.php',
|
||||
'PhortuneAccountOverviewController' => 'applications/phortune/controller/account/PhortuneAccountOverviewController.php',
|
||||
'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php',
|
||||
'PhortuneAccountPaymentMethodController' => 'applications/phortune/controller/account/PhortuneAccountPaymentMethodController.php',
|
||||
'PhortuneAccountPaymentMethodViewController' => 'applications/phortune/controller/account/PhortuneAccountPaymentMethodViewController.php',
|
||||
'PhortuneAccountProfileController' => 'applications/phortune/controller/account/PhortuneAccountProfileController.php',
|
||||
'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php',
|
||||
'PhortuneAccountSubscriptionAutopayController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionAutopayController.php',
|
||||
'PhortuneAccountSubscriptionController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionController.php',
|
||||
'PhortuneAccountSubscriptionViewController' => 'applications/phortune/controller/account/PhortuneAccountSubscriptionViewController.php',
|
||||
'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
|
||||
'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
|
||||
'PhortuneAccountTransactionType' => 'applications/phortune/xaction/PhortuneAccountTransactionType.php',
|
||||
'PhortuneAccountViewController' => 'applications/phortune/controller/account/PhortuneAccountViewController.php',
|
||||
'PhortuneAdHocCart' => 'applications/phortune/cart/PhortuneAdHocCart.php',
|
||||
'PhortuneAdHocProduct' => 'applications/phortune/product/PhortuneAdHocProduct.php',
|
||||
'PhortuneAddPaymentMethodAction' => 'applications/phortune/action/PhortuneAddPaymentMethodAction.php',
|
||||
|
@ -5248,7 +5275,6 @@ phutil_register_library_map(array(
|
|||
'PhortuneCartController' => 'applications/phortune/controller/cart/PhortuneCartController.php',
|
||||
'PhortuneCartEditor' => 'applications/phortune/editor/PhortuneCartEditor.php',
|
||||
'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
|
||||
'PhortuneCartListController' => 'applications/phortune/controller/cart/PhortuneCartListController.php',
|
||||
'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php',
|
||||
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
||||
'PhortuneCartReplyHandler' => 'applications/phortune/mail/PhortuneCartReplyHandler.php',
|
||||
|
@ -5257,6 +5283,7 @@ phutil_register_library_map(array(
|
|||
'PhortuneCartTransactionQuery' => 'applications/phortune/query/PhortuneCartTransactionQuery.php',
|
||||
'PhortuneCartUpdateController' => 'applications/phortune/controller/cart/PhortuneCartUpdateController.php',
|
||||
'PhortuneCartViewController' => 'applications/phortune/controller/cart/PhortuneCartViewController.php',
|
||||
'PhortuneCartVoidController' => 'applications/phortune/controller/cart/PhortuneCartVoidController.php',
|
||||
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
||||
'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
|
||||
'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php',
|
||||
|
@ -5271,7 +5298,10 @@ phutil_register_library_map(array(
|
|||
'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php',
|
||||
'PhortuneDisplayException' => 'applications/phortune/exception/PhortuneDisplayException.php',
|
||||
'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php',
|
||||
'PhortuneInvoiceView' => 'applications/phortune/view/PhortuneInvoiceView.php',
|
||||
'PhortuneExternalController' => 'applications/phortune/controller/external/PhortuneExternalController.php',
|
||||
'PhortuneExternalOrderController' => 'applications/phortune/controller/external/PhortuneExternalOrderController.php',
|
||||
'PhortuneExternalOverviewController' => 'applications/phortune/controller/external/PhortuneExternalOverviewController.php',
|
||||
'PhortuneExternalUnsubscribeController' => 'applications/phortune/controller/external/PhortuneExternalUnsubscribeController.php',
|
||||
'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php',
|
||||
'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php',
|
||||
'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php',
|
||||
|
@ -5281,35 +5311,56 @@ phutil_register_library_map(array(
|
|||
'PhortuneMerchantContactInfoTransaction' => 'applications/phortune/xaction/PhortuneMerchantContactInfoTransaction.php',
|
||||
'PhortuneMerchantController' => 'applications/phortune/controller/merchant/PhortuneMerchantController.php',
|
||||
'PhortuneMerchantDescriptionTransaction' => 'applications/phortune/xaction/PhortuneMerchantDescriptionTransaction.php',
|
||||
'PhortuneMerchantDetailsController' => 'applications/phortune/controller/merchant/PhortuneMerchantDetailsController.php',
|
||||
'PhortuneMerchantEditController' => 'applications/phortune/controller/merchant/PhortuneMerchantEditController.php',
|
||||
'PhortuneMerchantEditEngine' => 'applications/phortune/editor/PhortuneMerchantEditEngine.php',
|
||||
'PhortuneMerchantEditor' => 'applications/phortune/editor/PhortuneMerchantEditor.php',
|
||||
'PhortuneMerchantHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasAccountEdgeType.php',
|
||||
'PhortuneMerchantHasMemberEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php',
|
||||
'PhortuneMerchantInvoiceCreateController' => 'applications/phortune/controller/merchant/PhortuneMerchantInvoiceCreateController.php',
|
||||
'PhortuneMerchantInvoiceEmailTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceEmailTransaction.php',
|
||||
'PhortuneMerchantInvoiceFooterTransaction' => 'applications/phortune/xaction/PhortuneMerchantInvoiceFooterTransaction.php',
|
||||
'PhortuneMerchantListController' => 'applications/phortune/controller/merchant/PhortuneMerchantListController.php',
|
||||
'PhortuneMerchantManagerController' => 'applications/phortune/controller/merchant/PhortuneMerchantManagerController.php',
|
||||
'PhortuneMerchantManagersController' => 'applications/phortune/controller/merchant/PhortuneMerchantManagersController.php',
|
||||
'PhortuneMerchantNameTransaction' => 'applications/phortune/xaction/PhortuneMerchantNameTransaction.php',
|
||||
'PhortuneMerchantOrderListController' => 'applications/phortune/controller/merchant/PhortuneMerchantOrderListController.php',
|
||||
'PhortuneMerchantOrdersController' => 'applications/phortune/controller/merchant/PhortuneMerchantOrdersController.php',
|
||||
'PhortuneMerchantOverviewController' => 'applications/phortune/controller/merchant/PhortuneMerchantOverviewController.php',
|
||||
'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
|
||||
'PhortuneMerchantPictureController' => 'applications/phortune/controller/merchant/PhortuneMerchantPictureController.php',
|
||||
'PhortuneMerchantPictureTransaction' => 'applications/phortune/xaction/PhortuneMerchantPictureTransaction.php',
|
||||
'PhortuneMerchantProfileController' => 'applications/phortune/controller/merchant/PhortuneMerchantProfileController.php',
|
||||
'PhortuneMerchantProviderDisableController' => 'applications/phortune/controller/merchant/PhortuneMerchantProviderDisableController.php',
|
||||
'PhortuneMerchantProviderEditController' => 'applications/phortune/controller/merchant/PhortuneMerchantProviderEditController.php',
|
||||
'PhortuneMerchantProviderViewController' => 'applications/phortune/controller/merchant/PhortuneMerchantProviderViewController.php',
|
||||
'PhortuneMerchantProvidersController' => 'applications/phortune/controller/merchant/PhortuneMerchantProvidersController.php',
|
||||
'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
|
||||
'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php',
|
||||
'PhortuneMerchantSubscriptionListController' => 'applications/phortune/controller/merchant/PhortuneMerchantSubscriptionListController.php',
|
||||
'PhortuneMerchantSubscriptionsController' => 'applications/phortune/controller/merchant/PhortuneMerchantSubscriptionsController.php',
|
||||
'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php',
|
||||
'PhortuneMerchantTransactionQuery' => 'applications/phortune/query/PhortuneMerchantTransactionQuery.php',
|
||||
'PhortuneMerchantTransactionType' => 'applications/phortune/xaction/PhortuneMerchantTransactionType.php',
|
||||
'PhortuneMerchantViewController' => 'applications/phortune/controller/merchant/PhortuneMerchantViewController.php',
|
||||
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
|
||||
'PhortuneOrderDescriptionView' => 'applications/phortune/view/PhortuneOrderDescriptionView.php',
|
||||
'PhortuneOrderItemsView' => 'applications/phortune/view/PhortuneOrderItemsView.php',
|
||||
'PhortuneOrderSummaryView' => 'applications/phortune/view/PhortuneOrderSummaryView.php',
|
||||
'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
|
||||
'PhortuneOrderView' => 'applications/phortune/view/PhortuneOrderView.php',
|
||||
'PhortunePayPalPaymentProvider' => 'applications/phortune/provider/PhortunePayPalPaymentProvider.php',
|
||||
'PhortunePaymentMethod' => 'applications/phortune/storage/PhortunePaymentMethod.php',
|
||||
'PhortunePaymentMethodCreateController' => 'applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php',
|
||||
'PhortunePaymentMethodDisableController' => 'applications/phortune/controller/payment/PhortunePaymentMethodDisableController.php',
|
||||
'PhortunePaymentMethodEditController' => 'applications/phortune/controller/payment/PhortunePaymentMethodEditController.php',
|
||||
'PhortunePaymentMethodCreateController' => 'applications/phortune/controller/paymentmethod/PhortunePaymentMethodCreateController.php',
|
||||
'PhortunePaymentMethodDisableController' => 'applications/phortune/controller/paymentmethod/PhortunePaymentMethodDisableController.php',
|
||||
'PhortunePaymentMethodEditController' => 'applications/phortune/controller/paymentmethod/PhortunePaymentMethodEditController.php',
|
||||
'PhortunePaymentMethodEditor' => 'applications/phortune/editor/PhortunePaymentMethodEditor.php',
|
||||
'PhortunePaymentMethodNameTransaction' => 'applications/phortune/xaction/paymentmethod/PhortunePaymentMethodNameTransaction.php',
|
||||
'PhortunePaymentMethodPHIDType' => 'applications/phortune/phid/PhortunePaymentMethodPHIDType.php',
|
||||
'PhortunePaymentMethodPolicyCodex' => 'applications/phortune/codex/PhortunePaymentMethodPolicyCodex.php',
|
||||
'PhortunePaymentMethodQuery' => 'applications/phortune/query/PhortunePaymentMethodQuery.php',
|
||||
'PhortunePaymentMethodStatusTransaction' => 'applications/phortune/xaction/paymentmethod/PhortunePaymentMethodStatusTransaction.php',
|
||||
'PhortunePaymentMethodTransaction' => 'applications/phortune/storage/PhortunePaymentMethodTransaction.php',
|
||||
'PhortunePaymentMethodTransactionQuery' => 'applications/phortune/query/PhortunePaymentMethodTransactionQuery.php',
|
||||
'PhortunePaymentMethodTransactionType' => 'applications/phortune/xaction/paymentmethod/PhortunePaymentMethodTransactionType.php',
|
||||
'PhortunePaymentProvider' => 'applications/phortune/provider/PhortunePaymentProvider.php',
|
||||
'PhortunePaymentProviderConfig' => 'applications/phortune/storage/PhortunePaymentProviderConfig.php',
|
||||
'PhortunePaymentProviderConfigEditor' => 'applications/phortune/editor/PhortunePaymentProviderConfigEditor.php',
|
||||
|
@ -5325,24 +5376,25 @@ phutil_register_library_map(array(
|
|||
'PhortuneProductQuery' => 'applications/phortune/query/PhortuneProductQuery.php',
|
||||
'PhortuneProductViewController' => 'applications/phortune/controller/product/PhortuneProductViewController.php',
|
||||
'PhortuneProviderActionController' => 'applications/phortune/controller/provider/PhortuneProviderActionController.php',
|
||||
'PhortuneProviderDisableController' => 'applications/phortune/controller/provider/PhortuneProviderDisableController.php',
|
||||
'PhortuneProviderEditController' => 'applications/phortune/controller/provider/PhortuneProviderEditController.php',
|
||||
'PhortunePurchase' => 'applications/phortune/storage/PhortunePurchase.php',
|
||||
'PhortunePurchasePHIDType' => 'applications/phortune/phid/PhortunePurchasePHIDType.php',
|
||||
'PhortunePurchaseQuery' => 'applications/phortune/query/PhortunePurchaseQuery.php',
|
||||
'PhortuneSchemaSpec' => 'applications/phortune/storage/PhortuneSchemaSpec.php',
|
||||
'PhortuneStripePaymentProvider' => 'applications/phortune/provider/PhortuneStripePaymentProvider.php',
|
||||
'PhortuneSubscription' => 'applications/phortune/storage/PhortuneSubscription.php',
|
||||
'PhortuneSubscriptionAutopayTransaction' => 'applications/phortune/xaction/subscription/PhortuneSubscriptionAutopayTransaction.php',
|
||||
'PhortuneSubscriptionCart' => 'applications/phortune/cart/PhortuneSubscriptionCart.php',
|
||||
'PhortuneSubscriptionEditController' => 'applications/phortune/controller/subscription/PhortuneSubscriptionEditController.php',
|
||||
'PhortuneSubscriptionEditor' => 'applications/phortune/editor/PhortuneSubscriptionEditor.php',
|
||||
'PhortuneSubscriptionImplementation' => 'applications/phortune/subscription/PhortuneSubscriptionImplementation.php',
|
||||
'PhortuneSubscriptionListController' => 'applications/phortune/controller/subscription/PhortuneSubscriptionListController.php',
|
||||
'PhortuneSubscriptionPHIDType' => 'applications/phortune/phid/PhortuneSubscriptionPHIDType.php',
|
||||
'PhortuneSubscriptionPolicyCodex' => 'applications/phortune/codex/PhortuneSubscriptionPolicyCodex.php',
|
||||
'PhortuneSubscriptionProduct' => 'applications/phortune/product/PhortuneSubscriptionProduct.php',
|
||||
'PhortuneSubscriptionQuery' => 'applications/phortune/query/PhortuneSubscriptionQuery.php',
|
||||
'PhortuneSubscriptionSearchEngine' => 'applications/phortune/query/PhortuneSubscriptionSearchEngine.php',
|
||||
'PhortuneSubscriptionTableView' => 'applications/phortune/view/PhortuneSubscriptionTableView.php',
|
||||
'PhortuneSubscriptionViewController' => 'applications/phortune/controller/subscription/PhortuneSubscriptionViewController.php',
|
||||
'PhortuneSubscriptionTransaction' => 'applications/phortune/storage/PhortuneSubscriptionTransaction.php',
|
||||
'PhortuneSubscriptionTransactionQuery' => 'applications/phortune/query/PhortuneSubscriptionTransactionQuery.php',
|
||||
'PhortuneSubscriptionTransactionType' => 'applications/phortune/xaction/subscription/PhortuneSubscriptionTransactionType.php',
|
||||
'PhortuneSubscriptionWorker' => 'applications/phortune/worker/PhortuneSubscriptionWorker.php',
|
||||
'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
|
||||
'PhragmentBrowseController' => 'applications/phragment/controller/PhragmentBrowseController.php',
|
||||
|
@ -7021,6 +7073,7 @@ phutil_register_library_map(array(
|
|||
'DrydockResource' => array(
|
||||
'DrydockDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
),
|
||||
'DrydockResourceActivationFailureLogType' => 'DrydockLogType',
|
||||
'DrydockResourceActivationYieldLogType' => 'DrydockLogType',
|
||||
|
@ -7034,6 +7087,7 @@ phutil_register_library_map(array(
|
|||
'DrydockResourceQuery' => 'DrydockQuery',
|
||||
'DrydockResourceReclaimLogType' => 'DrydockLogType',
|
||||
'DrydockResourceReleaseController' => 'DrydockResourceController',
|
||||
'DrydockResourceSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'DrydockResourceSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'DrydockResourceStatus' => 'PhabricatorObjectStatus',
|
||||
'DrydockResourceUpdateWorker' => 'DrydockWorker',
|
||||
|
@ -10329,6 +10383,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleMailEngine' => 'Phobject',
|
||||
'PhabricatorPeopleMailEngineException' => 'Exception',
|
||||
'PhabricatorPeopleManageProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleManagementEmpowerWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||
'PhabricatorPeopleManagementEnableWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||
'PhabricatorPeopleManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
|
@ -10338,7 +10394,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPeopleProfileCommitsController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileImageWorkflow' => 'PhabricatorPeopleManagementWorkflow',
|
||||
'PhabricatorPeopleProfileManageController' => 'PhabricatorPeopleProfileController',
|
||||
'PhabricatorPeopleProfileMenuEngine' => 'PhabricatorProfileMenuEngine',
|
||||
'PhabricatorPeopleProfilePictureController' => 'PhabricatorPeopleProfileController',
|
||||
|
@ -11746,27 +11801,57 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
),
|
||||
'PhortuneAccountAddManagerController' => 'PhortuneController',
|
||||
'PhortuneAccountAddManagerController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountBillingAddressTransaction' => 'PhortuneAccountTransactionType',
|
||||
'PhortuneAccountBillingController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountBillingNameTransaction' => 'PhortuneAccountTransactionType',
|
||||
'PhortuneAccountChargeListController' => 'PhortuneController',
|
||||
'PhortuneAccountChargeListController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountChargesController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountController' => 'PhortuneController',
|
||||
'PhortuneAccountDetailsController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountEditController' => 'PhortuneController',
|
||||
'PhortuneAccountEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortuneAccountEmail' => array(
|
||||
'PhortuneDAO',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
),
|
||||
'PhortuneAccountEmailAddressTransaction' => 'PhortuneAccountEmailTransactionType',
|
||||
'PhortuneAccountEmailAddressesController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountEmailEditController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountEmailEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhortuneAccountEmailEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortuneAccountEmailPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneAccountEmailQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneAccountEmailRotateController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountEmailRotateTransaction' => 'PhortuneAccountEmailTransactionType',
|
||||
'PhortuneAccountEmailStatus' => 'Phobject',
|
||||
'PhortuneAccountEmailStatusController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountEmailStatusTransaction' => 'PhortuneAccountEmailTransactionType',
|
||||
'PhortuneAccountEmailTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortuneAccountEmailTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneAccountEmailTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortuneAccountEmailViewController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhortuneAccountHasMerchantEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhortuneAccountListController' => 'PhortuneController',
|
||||
'PhortuneAccountManagerController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountManagersController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountNameTransaction' => 'PhortuneAccountTransactionType',
|
||||
'PhortuneAccountOrderListController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountOrdersController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountOverviewController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneAccountPaymentMethodController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountPaymentMethodViewController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountProfileController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneAccountSubscriptionAutopayController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountSubscriptionController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAccountSubscriptionViewController' => 'PhortuneAccountController',
|
||||
'PhortuneAccountTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneAccountTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortuneAccountViewController' => 'PhortuneAccountProfileController',
|
||||
'PhortuneAdHocCart' => 'PhortuneCartImplementation',
|
||||
'PhortuneAdHocProduct' => 'PhortuneProductImplementation',
|
||||
'PhortuneAddPaymentMethodAction' => 'PhabricatorSystemAction',
|
||||
|
@ -11774,6 +11859,7 @@ phutil_register_library_map(array(
|
|||
'PhortuneDAO',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
),
|
||||
'PhortuneCartAcceptController' => 'PhortuneCartController',
|
||||
'PhortuneCartCancelController' => 'PhortuneCartController',
|
||||
|
@ -11781,7 +11867,6 @@ phutil_register_library_map(array(
|
|||
'PhortuneCartController' => 'PhortuneController',
|
||||
'PhortuneCartEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortuneCartImplementation' => 'Phobject',
|
||||
'PhortuneCartListController' => 'PhortuneController',
|
||||
'PhortuneCartPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneCartReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
|
@ -11790,9 +11875,11 @@ phutil_register_library_map(array(
|
|||
'PhortuneCartTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneCartUpdateController' => 'PhortuneCartController',
|
||||
'PhortuneCartViewController' => 'PhortuneCartController',
|
||||
'PhortuneCartVoidController' => 'PhortuneCartController',
|
||||
'PhortuneCharge' => array(
|
||||
'PhortuneDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
),
|
||||
'PhortuneChargePHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
|
@ -11807,7 +11894,10 @@ phutil_register_library_map(array(
|
|||
'PhortuneDAO' => 'PhabricatorLiskDAO',
|
||||
'PhortuneDisplayException' => 'Exception',
|
||||
'PhortuneErrCode' => 'PhortuneConstants',
|
||||
'PhortuneInvoiceView' => 'AphrontTagView',
|
||||
'PhortuneExternalController' => 'PhortuneController',
|
||||
'PhortuneExternalOrderController' => 'PhortuneExternalController',
|
||||
'PhortuneExternalOverviewController' => 'PhortuneExternalController',
|
||||
'PhortuneExternalUnsubscribeController' => 'PhortuneExternalController',
|
||||
'PhortuneLandingController' => 'PhortuneController',
|
||||
'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhortuneMemberHasMerchantEdgeType' => 'PhabricatorEdgeType',
|
||||
|
@ -11816,43 +11906,67 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorPolicyInterface',
|
||||
),
|
||||
'PhortuneMerchantAddManagerController' => 'PhortuneController',
|
||||
'PhortuneMerchantAddManagerController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantCapability' => 'PhabricatorPolicyCapability',
|
||||
'PhortuneMerchantContactInfoTransaction' => 'PhortuneMerchantTransactionType',
|
||||
'PhortuneMerchantController' => 'PhortuneController',
|
||||
'PhortuneMerchantDescriptionTransaction' => 'PhortuneMerchantTransactionType',
|
||||
'PhortuneMerchantEditController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantDetailsController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantEditController' => 'PhortuneController',
|
||||
'PhortuneMerchantEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortuneMerchantHasAccountEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantInvoiceCreateController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantInvoiceEmailTransaction' => 'PhortuneMerchantTransactionType',
|
||||
'PhortuneMerchantInvoiceFooterTransaction' => 'PhortuneMerchantTransactionType',
|
||||
'PhortuneMerchantListController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantManagerController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantListController' => 'PhortuneController',
|
||||
'PhortuneMerchantManagersController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantNameTransaction' => 'PhortuneMerchantTransactionType',
|
||||
'PhortuneMerchantOrderListController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantOrdersController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantOverviewController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneMerchantPictureController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantPictureController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantPictureTransaction' => 'PhortuneMerchantTransactionType',
|
||||
'PhortuneMerchantProfileController' => 'PhortuneController',
|
||||
'PhortuneMerchantProfileController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantProviderDisableController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantProviderEditController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantProviderViewController' => 'PhortuneMerchantController',
|
||||
'PhortuneMerchantProvidersController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhortuneMerchantSubscriptionListController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantSubscriptionsController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMerchantTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneMerchantTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortuneMerchantViewController' => 'PhortuneMerchantProfileController',
|
||||
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
|
||||
'PhortuneOrderDescriptionView' => 'AphrontView',
|
||||
'PhortuneOrderItemsView' => 'PhortuneOrderView',
|
||||
'PhortuneOrderSummaryView' => 'PhortuneOrderView',
|
||||
'PhortuneOrderTableView' => 'AphrontView',
|
||||
'PhortuneOrderView' => 'AphrontView',
|
||||
'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
|
||||
'PhortunePaymentMethod' => array(
|
||||
'PhortuneDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
'PhabricatorPolicyCodexInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'PhortunePaymentMethodCreateController' => 'PhortuneController',
|
||||
'PhortunePaymentMethodDisableController' => 'PhortuneController',
|
||||
'PhortunePaymentMethodEditController' => 'PhortuneController',
|
||||
'PhortunePaymentMethodEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortunePaymentMethodNameTransaction' => 'PhortunePaymentMethodTransactionType',
|
||||
'PhortunePaymentMethodPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortunePaymentMethodPolicyCodex' => 'PhabricatorPolicyCodex',
|
||||
'PhortunePaymentMethodQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortunePaymentMethodStatusTransaction' => 'PhortunePaymentMethodTransactionType',
|
||||
'PhortunePaymentMethodTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortunePaymentMethodTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortunePaymentMethodTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortunePaymentProvider' => 'Phobject',
|
||||
'PhortunePaymentProviderConfig' => array(
|
||||
'PhortuneDAO',
|
||||
|
@ -11875,8 +11989,6 @@ phutil_register_library_map(array(
|
|||
'PhortuneProductQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneProductViewController' => 'PhortuneController',
|
||||
'PhortuneProviderActionController' => 'PhortuneController',
|
||||
'PhortuneProviderDisableController' => 'PhortuneMerchantController',
|
||||
'PhortuneProviderEditController' => 'PhortuneMerchantController',
|
||||
'PhortunePurchase' => array(
|
||||
'PhortuneDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
|
@ -11888,17 +12000,23 @@ phutil_register_library_map(array(
|
|||
'PhortuneSubscription' => array(
|
||||
'PhortuneDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorExtendedPolicyInterface',
|
||||
'PhabricatorPolicyCodexInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
),
|
||||
'PhortuneSubscriptionAutopayTransaction' => 'PhortuneSubscriptionTransactionType',
|
||||
'PhortuneSubscriptionCart' => 'PhortuneCartImplementation',
|
||||
'PhortuneSubscriptionEditController' => 'PhortuneController',
|
||||
'PhortuneSubscriptionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhortuneSubscriptionImplementation' => 'Phobject',
|
||||
'PhortuneSubscriptionListController' => 'PhortuneController',
|
||||
'PhortuneSubscriptionPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhortuneSubscriptionPolicyCodex' => 'PhabricatorPolicyCodex',
|
||||
'PhortuneSubscriptionProduct' => 'PhortuneProductImplementation',
|
||||
'PhortuneSubscriptionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhortuneSubscriptionSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhortuneSubscriptionTableView' => 'AphrontView',
|
||||
'PhortuneSubscriptionViewController' => 'PhortuneController',
|
||||
'PhortuneSubscriptionTransaction' => 'PhabricatorModularTransaction',
|
||||
'PhortuneSubscriptionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhortuneSubscriptionTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'PhortuneSubscriptionWorker' => 'PhabricatorWorker',
|
||||
'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
|
||||
'PhragmentBrowseController' => 'PhragmentController',
|
||||
|
|
|
@ -312,11 +312,17 @@ final class AphrontApplicationConfiguration
|
|||
if ($response_exception) {
|
||||
// If we encountered an exception while building a normal response, then
|
||||
// encountered another exception while building a response for the first
|
||||
// exception, just throw the original exception. It is more likely to be
|
||||
// useful and point at a root cause than the second exception we ran into
|
||||
// while telling the user about it.
|
||||
// exception, throw an aggregate exception that will be unpacked by the
|
||||
// higher-level handler. This is above our pay grade.
|
||||
if ($original_exception) {
|
||||
throw $original_exception;
|
||||
throw new PhutilAggregateException(
|
||||
pht(
|
||||
'Encountered a processing exception, then another exception when '.
|
||||
'trying to build a response for the first exception.'),
|
||||
array(
|
||||
$response_exception,
|
||||
$original_exception,
|
||||
));
|
||||
}
|
||||
|
||||
// If we built a response successfully and then ran into an exception
|
||||
|
|
|
@ -8,16 +8,19 @@ final class Aphront404Response extends AphrontHTMLResponse {
|
|||
|
||||
public function buildResponseString() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setViewer($viewer)
|
||||
->setTitle(pht('404 Not Found'))
|
||||
->addCancelButton('/', pht('Focus'))
|
||||
->addCancelButton('/', pht('Return to Charted Waters'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Do not dwell in the past, do not dream of the future, '.
|
||||
'concentrate the mind on the present moment.'));
|
||||
'You arrive at your destination, but there is nothing here.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Perhaps the real treasure was the friends you made '.
|
||||
'along the way.'));
|
||||
|
||||
$view = id(new PhabricatorStandardPageView())
|
||||
->setTitle(pht('404 Not Found'))
|
||||
|
|
|
@ -61,9 +61,39 @@ final class AphrontUnhandledExceptionResponse
|
|||
return 'unhandled-exception';
|
||||
}
|
||||
|
||||
protected function getResponseBody() {
|
||||
$ex = $this->exception;
|
||||
private function getExceptionList() {
|
||||
return $this->expandException($this->exception);
|
||||
}
|
||||
|
||||
private function expandException($root) {
|
||||
if ($root instanceof PhutilAggregateException) {
|
||||
$list = array();
|
||||
|
||||
$list[] = $root;
|
||||
|
||||
foreach ($root->getExceptions() as $ex) {
|
||||
foreach ($this->expandException($ex) as $child) {
|
||||
$list[] = $child;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
return array($root);
|
||||
}
|
||||
|
||||
protected function getResponseBody() {
|
||||
$body = array();
|
||||
|
||||
foreach ($this->getExceptionList() as $ex) {
|
||||
$body[] = $this->newHTMLMessage($ex);
|
||||
}
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
private function newHTMLMessage($ex) {
|
||||
if ($ex instanceof AphrontMalformedRequestException) {
|
||||
$title = $ex->getTitle();
|
||||
} else {
|
||||
|
@ -122,12 +152,20 @@ final class AphrontUnhandledExceptionResponse
|
|||
}
|
||||
|
||||
protected function buildPlainTextResponseString() {
|
||||
$ex = $this->exception;
|
||||
$messages = array();
|
||||
|
||||
foreach ($this->getExceptionList() as $exception) {
|
||||
$messages[] = $this->newPlainTextMessage($exception);
|
||||
}
|
||||
|
||||
return implode("\n\n", $messages);
|
||||
}
|
||||
|
||||
private function newPlainTextMessage($exception) {
|
||||
return pht(
|
||||
'%s: %s',
|
||||
get_class($ex),
|
||||
$ex->getMessage());
|
||||
get_class($exception),
|
||||
$exception->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -481,7 +481,7 @@ abstract class PhabricatorController extends AphrontController {
|
|||
|
||||
protected function buildTransactionTimeline(
|
||||
PhabricatorApplicationTransactionInterface $object,
|
||||
PhabricatorApplicationTransactionQuery $query,
|
||||
PhabricatorApplicationTransactionQuery $query = null,
|
||||
PhabricatorMarkupEngine $engine = null,
|
||||
$view_data = array()) {
|
||||
|
||||
|
@ -489,6 +489,17 @@ abstract class PhabricatorController extends AphrontController {
|
|||
$viewer = $this->getViewer();
|
||||
$xaction = $object->getApplicationTransactionTemplate();
|
||||
|
||||
if (!$query) {
|
||||
$query = PhabricatorApplicationTransactionQuery::newQueryForObject(
|
||||
$object);
|
||||
if (!$query) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unable to find transaction query for object of class "%s".',
|
||||
get_class($object)));
|
||||
}
|
||||
}
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request)
|
||||
->setURI(new PhutilURI(
|
||||
|
|
|
@ -119,8 +119,11 @@ final class DifferentialCreateDiffConduitAPIMethod
|
|||
break;
|
||||
}
|
||||
|
||||
$source_path = $request->getValue('sourcePath');
|
||||
$source_path = $this->normalizeSourcePath($source_path);
|
||||
|
||||
$diff_data_dict = array(
|
||||
'sourcePath' => $request->getValue('sourcePath'),
|
||||
'sourcePath' => $source_path,
|
||||
'sourceMachine' => $request->getValue('sourceMachine'),
|
||||
'branch' => $request->getValue('branch'),
|
||||
'creationMethod' => $request->getValue('creationMethod'),
|
||||
|
@ -158,4 +161,18 @@ final class DifferentialCreateDiffConduitAPIMethod
|
|||
);
|
||||
}
|
||||
|
||||
private function normalizeSourcePath($source_path) {
|
||||
// See T13385. This property is probably headed for deletion. Until we get
|
||||
// there, stop errors arising from running "arc diff" in a working copy
|
||||
// with too many characters.
|
||||
|
||||
$max_size = id(new DifferentialDiff())
|
||||
->getColumnMaximumByteLength('sourcePath');
|
||||
|
||||
return id(new PhutilUTF8StringTruncator())
|
||||
->setMaximumBytes($max_size)
|
||||
->setTerminator('')
|
||||
->truncateString($source_path);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,6 +51,12 @@ final class DifferentialRevisionSearchEngine
|
|||
$map['createdEnd']);
|
||||
}
|
||||
|
||||
if ($map['modifiedStart'] || $map['modifiedEnd']) {
|
||||
$query->withUpdatedEpochBetween(
|
||||
$map['modifiedStart'],
|
||||
$map['modifiedEnd']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -100,6 +106,18 @@ final class DifferentialRevisionSearchEngine
|
|||
->setKey('createdEnd')
|
||||
->setDescription(
|
||||
pht('Find revisions created at or before a particular time.')),
|
||||
id(new PhabricatorSearchDateField())
|
||||
->setLabel(pht('Modified After'))
|
||||
->setKey('modifiedStart')
|
||||
->setIsHidden(true)
|
||||
->setDescription(
|
||||
pht('Find revisions modified at or after a particular time.')),
|
||||
id(new PhabricatorSearchDateField())
|
||||
->setLabel(pht('Modified Before'))
|
||||
->setKey('modifiedEnd')
|
||||
->setIsHidden(true)
|
||||
->setDescription(
|
||||
pht('Find revisions modified at or before a particular time.')),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,11 +112,6 @@ final class DifferentialRevision extends DifferentialDAO
|
|||
'repositoryPHID' => 'phid?',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_phid' => null,
|
||||
'phid' => array(
|
||||
'columns' => array('phid'),
|
||||
'unique' => true,
|
||||
),
|
||||
'authorPHID' => array(
|
||||
'columns' => array('authorPHID', 'status'),
|
||||
),
|
||||
|
@ -131,6 +126,9 @@ final class DifferentialRevision extends DifferentialDAO
|
|||
'key_status' => array(
|
||||
'columns' => array('status', 'phid'),
|
||||
),
|
||||
'key_modified' => array(
|
||||
'columns' => array('dateModified'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
final class DrydockResourceSearchConduitAPIMethod
|
||||
extends PhabricatorSearchEngineAPIMethod {
|
||||
|
||||
public function getAPIMethodName() {
|
||||
return 'drydock.resource.search';
|
||||
}
|
||||
|
||||
public function newSearchEngine() {
|
||||
return new DrydockResourceSearchEngine();
|
||||
}
|
||||
|
||||
public function getMethodSummary() {
|
||||
return pht('Retrieve information about Drydock resources.');
|
||||
}
|
||||
|
||||
}
|
|
@ -44,6 +44,10 @@ final class DrydockLeaseSearchEngine
|
|||
$query->withOwnerPHIDs($map['ownerPHIDs']);
|
||||
}
|
||||
|
||||
if ($map['resourcePHIDs']) {
|
||||
$query->withResourcePHIDs($map['resourcePHIDs']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -58,6 +62,11 @@ final class DrydockLeaseSearchEngine
|
|||
->setKey('ownerPHIDs')
|
||||
->setAliases(array('owner', 'owners', 'ownerPHID'))
|
||||
->setDescription(pht('Search leases by owner.')),
|
||||
id(new PhabricatorPHIDsSearchField())
|
||||
->setLabel(pht('Resources'))
|
||||
->setKey('resourcePHIDs')
|
||||
->setAliases(array('resorucePHID', 'resource', 'resources'))
|
||||
->setDescription(pht('Search leases by resource.')),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,46 +100,50 @@ final class DrydockResourceQuery extends DrydockQuery {
|
|||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
'resource.id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'phid IN (%Ls)',
|
||||
'resource.phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->types !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'type IN (%Ls)',
|
||||
'resource.type IN (%Ls)',
|
||||
$this->types);
|
||||
}
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'status IN (%Ls)',
|
||||
'resource.status IN (%Ls)',
|
||||
$this->statuses);
|
||||
}
|
||||
|
||||
if ($this->blueprintPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'blueprintPHID IN (%Ls)',
|
||||
'resource.blueprintPHID IN (%Ls)',
|
||||
$this->blueprintPHIDs);
|
||||
}
|
||||
|
||||
if ($this->datasourceQuery !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'name LIKE %>',
|
||||
'resource.name LIKE %>',
|
||||
$this->datasourceQuery);
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
protected function getPrimaryTableAlias() {
|
||||
return 'resource';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ final class DrydockResourceSearchEngine
|
|||
$query->withStatuses($map['statuses']);
|
||||
}
|
||||
|
||||
if ($map['blueprintPHIDs']) {
|
||||
$query->withBlueprintPHIDs($map['blueprintPHIDs']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -49,6 +53,12 @@ final class DrydockResourceSearchEngine
|
|||
->setLabel(pht('Statuses'))
|
||||
->setKey('statuses')
|
||||
->setOptions(DrydockResourceStatus::getStatusMap()),
|
||||
id(new PhabricatorPHIDsSearchField())
|
||||
->setLabel(pht('Blueprints'))
|
||||
->setKey('blueprintPHIDs')
|
||||
->setAliases(array('blueprintPHID', 'blueprints', 'blueprint'))
|
||||
->setDescription(
|
||||
pht('Search for resources generated by particular blueprints.')),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<?php
|
||||
|
||||
final class DrydockResource extends DrydockDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorConduitResultInterface {
|
||||
|
||||
protected $id;
|
||||
protected $phid;
|
||||
|
@ -340,4 +342,38 @@ final class DrydockResource extends DrydockDAO
|
|||
public function describeAutomaticCapability($capability) {
|
||||
return pht('Resources inherit the policies of their blueprints.');
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorConduitResultInterface )---------------------------------- */
|
||||
|
||||
|
||||
public function getFieldSpecificationsForConduit() {
|
||||
return array(
|
||||
id(new PhabricatorConduitSearchFieldSpecification())
|
||||
->setKey('blueprintPHID')
|
||||
->setType('phid')
|
||||
->setDescription(pht('The blueprint which generated this resource.')),
|
||||
id(new PhabricatorConduitSearchFieldSpecification())
|
||||
->setKey('status')
|
||||
->setType('map<string, wild>')
|
||||
->setDescription(pht('Information about resource status.')),
|
||||
);
|
||||
}
|
||||
|
||||
public function getFieldValuesForConduit() {
|
||||
$status = $this->getStatus();
|
||||
|
||||
return array(
|
||||
'blueprintPHID' => $this->getBlueprintPHID(),
|
||||
'status' => array(
|
||||
'value' => $status,
|
||||
'name' => DrydockResourceStatus::getNameForStatus($status),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function getConduitSearchAttachments() {
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -261,6 +261,7 @@ EODOCS
|
|||
|
||||
$parent_type = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
|
||||
$subtask_type = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
|
||||
$commit_type = ManiphestTaskHasCommitEdgeType::EDGECONST;
|
||||
|
||||
$src_phid = $object->getPHID();
|
||||
if ($src_phid) {
|
||||
|
@ -270,6 +271,7 @@ EODOCS
|
|||
array(
|
||||
$parent_type,
|
||||
$subtask_type,
|
||||
$commit_type,
|
||||
));
|
||||
$edge_query->execute();
|
||||
|
||||
|
@ -280,9 +282,14 @@ EODOCS
|
|||
$subtask_phids = $edge_query->getDestinationPHIDs(
|
||||
array($src_phid),
|
||||
array($subtask_type));
|
||||
|
||||
$commit_phids = $edge_query->getDestinationPHIDs(
|
||||
array($src_phid),
|
||||
array($commit_type));
|
||||
} else {
|
||||
$parent_phids = array();
|
||||
$subtask_phids = array();
|
||||
$commit_phids = array();
|
||||
}
|
||||
|
||||
$fields[] = id(new PhabricatorHandlesEditField())
|
||||
|
@ -307,7 +314,19 @@ EODOCS
|
|||
->setIsFormField(false)
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $subtask_type)
|
||||
->setValue($parent_phids);
|
||||
->setValue($subtask_phids);
|
||||
|
||||
$fields[] = id(new PhabricatorHandlesEditField())
|
||||
->setKey('commits')
|
||||
->setLabel(pht('Commits'))
|
||||
->setDescription(pht('Related commits.'))
|
||||
->setConduitDescription(pht('Change the related commits for this task.'))
|
||||
->setConduitTypeDescription(pht('List of related commit PHIDs.'))
|
||||
->setUseEdgeTransactions(true)
|
||||
->setIsFormField(false)
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $commit_type)
|
||||
->setValue($commit_phids);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,8 @@ final class PhabricatorPeopleEmpowerController
|
|||
|
||||
$done_uri = $this->getApplicationURI("manage/{$id}/");
|
||||
|
||||
id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
|
||||
$viewer,
|
||||
$request,
|
||||
$done_uri);
|
||||
|
||||
$validation_exception = null;
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
if ($request->isFormOrHisecPost()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(
|
||||
|
@ -34,7 +28,8 @@ final class PhabricatorPeopleEmpowerController
|
|||
$editor = id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true);
|
||||
->setContinueOnMissingFields(true)
|
||||
->setCancelURI($done_uri);
|
||||
|
||||
try {
|
||||
$editor->applyTransactions($user, $xactions);
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorPeopleManagementEmpowerWorkflow
|
||||
extends PhabricatorPeopleManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$arguments = array_merge(
|
||||
$this->getUserSelectionArguments(),
|
||||
array());
|
||||
|
||||
$this
|
||||
->setName('empower')
|
||||
->setExamples('**empower** --user __username__')
|
||||
->setSynopsis(pht('Turn a user account into an administrator account.'))
|
||||
->setArguments($arguments);
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$user = $this->selectUser($args);
|
||||
$display_name = $user->getUsername();
|
||||
|
||||
if ($user->getIsAdmin()) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'User account "%s" is already an administrator. You can only '.
|
||||
'empower accounts that are not yet administrators.',
|
||||
$display_name));
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = $user->getApplicationTransactionTemplate()
|
||||
->setTransactionType(PhabricatorUserEmpowerTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(true);
|
||||
|
||||
$this->applyTransactions($user, $xactions);
|
||||
|
||||
$this->logOkay(
|
||||
pht('DONE'),
|
||||
pht('Empowered user account "%s".', $display_name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorPeopleManagementEnableWorkflow
|
||||
extends PhabricatorPeopleManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$arguments = array_merge(
|
||||
$this->getUserSelectionArguments(),
|
||||
array());
|
||||
|
||||
$this
|
||||
->setName('enable')
|
||||
->setExamples('**enable** --user __username__')
|
||||
->setSynopsis(pht('Enable a disabled user account.'))
|
||||
->setArguments($arguments);
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$user = $this->selectUser($args);
|
||||
$display_name = $user->getUsername();
|
||||
|
||||
if (!$user->getIsDisabled()) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'User account "%s" is not disabled. You can only enable accounts '.
|
||||
'that are disabled.',
|
||||
$display_name));
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = $user->getApplicationTransactionTemplate()
|
||||
->setTransactionType(PhabricatorUserDisableTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(false);
|
||||
|
||||
$this->applyTransactions($user, $xactions);
|
||||
|
||||
$this->logOkay(
|
||||
pht('DONE'),
|
||||
pht('Enabled user account "%s".', $display_name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,45 +3,55 @@
|
|||
abstract class PhabricatorPeopleManagementWorkflow
|
||||
extends PhabricatorManagementWorkflow {
|
||||
|
||||
protected function buildIterator(PhutilArgumentParser $args) {
|
||||
$usernames = $args->getArg('users');
|
||||
|
||||
if ($args->getArg('all')) {
|
||||
if ($usernames) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Specify either a list of users or `%s`, but not both.',
|
||||
'--all'));
|
||||
}
|
||||
return new LiskMigrationIterator(new PhabricatorUser());
|
||||
}
|
||||
|
||||
if ($usernames) {
|
||||
return $this->loadUsersWithUsernames($usernames);
|
||||
}
|
||||
|
||||
return null;
|
||||
final protected function getUserSelectionArguments() {
|
||||
return array(
|
||||
array(
|
||||
'name' => 'user',
|
||||
'param' => 'username',
|
||||
'help' => pht('User account to act on.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadUsersWithUsernames(array $usernames) {
|
||||
$users = array();
|
||||
foreach($usernames as $username) {
|
||||
$query = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withUsernames(array($username))
|
||||
->executeOne();
|
||||
final protected function selectUser(PhutilArgumentParser $argv) {
|
||||
$username = $argv->getArg('user');
|
||||
|
||||
if (!$query) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'"%s" is not a valid username.',
|
||||
$username));
|
||||
}
|
||||
$users[] = $query;
|
||||
if (!strlen($username)) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Select a user account to act on with "--user <username>".'));
|
||||
}
|
||||
|
||||
return $users;
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withUsernames(array($username))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'No user with username "%s" exists.',
|
||||
$username));
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
final protected function applyTransactions(
|
||||
PhabricatorUser $user,
|
||||
array $xactions) {
|
||||
assert_instances_of($xactions, 'PhabricatorUserTransaction');
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$application = id(new PhabricatorPeopleApplication())->getPHID();
|
||||
$content_source = $this->newContentSource();
|
||||
|
||||
$editor = $user->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setActingAsPHID($application)
|
||||
->setContentSource($content_source)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
return $editor->applyTransactions($user, $xactions);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorPeopleProfileImageWorkflow
|
||||
extends PhabricatorPeopleManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('profileimage')
|
||||
->setExamples('**profileimage** --users __username__')
|
||||
->setSynopsis(pht('Generate default profile images.'))
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'all',
|
||||
'help' => pht(
|
||||
'Generate default profile images for all users.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'force',
|
||||
'short' => 'f',
|
||||
'help' => pht(
|
||||
'Force a default profile image to be replaced.'),
|
||||
),
|
||||
array(
|
||||
'name' => 'users',
|
||||
'wildcard' => true,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
|
||||
$is_force = $args->getArg('force');
|
||||
$is_all = $args->getArg('all');
|
||||
|
||||
$gd = function_exists('imagecreatefromstring');
|
||||
if (!$gd) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'GD is not installed for php-cli. Aborting.'));
|
||||
}
|
||||
|
||||
$iterator = $this->buildIterator($args);
|
||||
if (!$iterator) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'Either specify a list of users to update, or use `%s` '.
|
||||
'to update all users.',
|
||||
'--all'));
|
||||
}
|
||||
|
||||
$version = PhabricatorFilesComposeAvatarBuiltinFile::VERSION;
|
||||
$generator = new PhabricatorFilesComposeAvatarBuiltinFile();
|
||||
|
||||
foreach ($iterator as $user) {
|
||||
$username = $user->getUsername();
|
||||
$default_phid = $user->getDefaultProfileImagePHID();
|
||||
$gen_version = $user->getDefaultProfileImageVersion();
|
||||
|
||||
$generate = false;
|
||||
if ($gen_version != $version) {
|
||||
$generate = true;
|
||||
}
|
||||
|
||||
if ($default_phid == null || $is_force || $generate) {
|
||||
$console->writeOut(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Generating profile image for "%s".',
|
||||
$username));
|
||||
|
||||
$generator->updateUser($user);
|
||||
} else {
|
||||
$console->writeOut(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Default profile image "%s" already set for "%s".',
|
||||
$version,
|
||||
$username));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -86,4 +86,11 @@ final class PhabricatorUserEmpowerTransaction
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function shouldTryMFA(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,26 +34,6 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
return array(
|
||||
'/phortune/' => array(
|
||||
'' => 'PhortuneLandingController',
|
||||
'(?P<accountID>\d+)/' => array(
|
||||
'' => 'PhortuneAccountViewController',
|
||||
'card/' => array(
|
||||
'new/' => 'PhortunePaymentMethodCreateController',
|
||||
),
|
||||
'order/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneCartListController',
|
||||
'subscription/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneSubscriptionListController',
|
||||
'view/(?P<id>\d+)/'
|
||||
=> 'PhortuneSubscriptionViewController',
|
||||
'edit/(?P<id>\d+)/'
|
||||
=> 'PhortuneSubscriptionEditController',
|
||||
'order/(?P<subscriptionID>\d+)/'
|
||||
=> 'PhortuneCartListController',
|
||||
),
|
||||
'charge/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneAccountChargeListController',
|
||||
),
|
||||
'card/(?P<id>\d+)/' => array(
|
||||
'edit/' => 'PhortunePaymentMethodEditController',
|
||||
'disable/' => 'PhortunePaymentMethodDisableController',
|
||||
|
@ -63,21 +43,59 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'checkout/' => 'PhortuneCartCheckoutController',
|
||||
'(?P<action>print)/' => 'PhortuneCartViewController',
|
||||
'(?P<action>cancel|refund)/' => 'PhortuneCartCancelController',
|
||||
'accept/' => 'PhortuneCartAcceptController',
|
||||
'void/' => 'PhortuneCartVoidController',
|
||||
'update/' => 'PhortuneCartUpdateController',
|
||||
),
|
||||
'account/' => array(
|
||||
'' => 'PhortuneAccountListController',
|
||||
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'PhortuneAccountEditController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneAccountEditController',
|
||||
'add/manager/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhortuneAccountAddManagerController',
|
||||
'billing/(?:(?P<id>\d+)/)?' => 'PhortuneAccountBillingController',
|
||||
'subscription/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhortuneAccountSubscriptionController',
|
||||
'manager/' => array(
|
||||
'(?:(?P<id>\d+)/)?' => 'PhortuneAccountManagerController',
|
||||
'add/(?:(?P<id>\d+)/)?' => 'PhortuneAccountAddManagerController',
|
||||
|
||||
'(?P<accountID>\d+)/' => array(
|
||||
'' => 'PhortuneAccountOverviewController',
|
||||
'details/' => 'PhortuneAccountDetailsController',
|
||||
'methods/' => array(
|
||||
'' => 'PhortuneAccountPaymentMethodController',
|
||||
'(?P<id>\d+)/' => 'PhortuneAccountPaymentMethodViewController',
|
||||
'new/' => 'PhortunePaymentMethodCreateController',
|
||||
),
|
||||
'orders/' => array(
|
||||
'' => 'PhortuneAccountOrdersController',
|
||||
$this->getQueryRoutePattern('list/')
|
||||
=> 'PhortuneAccountOrderListController',
|
||||
),
|
||||
'charges/' => array(
|
||||
'' => 'PhortuneAccountChargesController',
|
||||
$this->getQueryRoutePattern('list/')
|
||||
=> 'PhortuneAccountChargeListController',
|
||||
),
|
||||
'subscriptions/' => array(
|
||||
'' => 'PhortuneAccountSubscriptionController',
|
||||
'(?P<subscriptionID>\d+)/' => array(
|
||||
'' => 'PhortuneAccountSubscriptionViewController',
|
||||
'autopay/(?P<methodID>\d+)/'
|
||||
=> 'PhortuneAccountSubscriptionAutopayController',
|
||||
$this->getQueryRoutePattern('orders/')
|
||||
=> 'PhortuneAccountOrderListController',
|
||||
),
|
||||
),
|
||||
'managers/' => array(
|
||||
'' => 'PhortuneAccountManagersController',
|
||||
'add/' => 'PhortuneAccountAddManagerController',
|
||||
),
|
||||
'addresses/' => array(
|
||||
'' => 'PhortuneAccountEmailAddressesController',
|
||||
'(?P<addressID>\d+)/' => array(
|
||||
'' => 'PhortuneAccountEmailViewController',
|
||||
'rotate/' => 'PhortuneAccountEmailRotateController',
|
||||
'(?P<action>disable|enable)/'
|
||||
=> 'PhortuneAccountEmailStatusController',
|
||||
),
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'PhortuneAccountEmailEditController',
|
||||
),
|
||||
),
|
||||
),
|
||||
'product/' => array(
|
||||
|
@ -91,37 +109,51 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
'(?P<id>\d+)/(?P<action>[^/]+)/'
|
||||
=> 'PhortuneProviderActionController',
|
||||
),
|
||||
'external/(?P<addressKey>[^/]+)/(?P<accessKey>[^/]+)/' => array(
|
||||
'' => 'PhortuneExternalOverviewController',
|
||||
'unsubscribe/' => 'PhortuneExternalUnsubscribeController',
|
||||
'order/' => array(
|
||||
'(?P<orderID>[^/]+)/' => array(
|
||||
'' => 'PhortuneExternalOrderController',
|
||||
'(?P<action>print)/' => 'PhortuneExternalOrderController',
|
||||
),
|
||||
),
|
||||
),
|
||||
'merchant/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhortuneMerchantListController',
|
||||
'picture/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantPictureController',
|
||||
$this->getQueryRoutePattern()
|
||||
=> 'PhortuneMerchantListController',
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'PhortuneMerchantEditController',
|
||||
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneCartListController',
|
||||
'manager/' => array(
|
||||
'(?:(?P<id>\d+)/)?' => 'PhortuneMerchantManagerController',
|
||||
'add/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantAddManagerController',
|
||||
),
|
||||
'(?P<merchantID>\d+)/' => array(
|
||||
'cart/(?P<id>\d+)/' => array(
|
||||
'' => 'PhortuneCartViewController',
|
||||
'(?P<action>cancel|refund)/' => 'PhortuneCartCancelController',
|
||||
'update/' => 'PhortuneCartUpdateController',
|
||||
'accept/' => 'PhortuneCartAcceptController',
|
||||
'' => 'PhortuneMerchantOverviewController',
|
||||
'details/' => 'PhortuneMerchantDetailsController',
|
||||
'providers/' => array(
|
||||
'' => 'PhortuneMerchantProvidersController',
|
||||
'(?P<providerID>\d+)/' => array(
|
||||
'' => 'PhortuneMerchantProviderViewController',
|
||||
'disable/' => 'PhortuneMerchantProviderDisableController',
|
||||
),
|
||||
$this->getEditRoutePattern('edit/')
|
||||
=> 'PhortuneMerchantProviderEditController',
|
||||
),
|
||||
'subscription/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhortuneSubscriptionListController',
|
||||
'view/(?P<id>\d+)/'
|
||||
=> 'PhortuneSubscriptionViewController',
|
||||
'order/(?P<subscriptionID>\d+)/'
|
||||
=> 'PhortuneCartListController',
|
||||
'orders/' => array(
|
||||
'' => 'PhortuneMerchantOrdersController',
|
||||
$this->getQueryRoutePattern('list/')
|
||||
=> 'PhortuneMerchantOrderListController',
|
||||
),
|
||||
'invoice/' => array(
|
||||
'new/' => 'PhortuneMerchantInvoiceCreateController',
|
||||
'picture/' => array(
|
||||
'edit/' => 'PhortuneMerchantPictureController',
|
||||
),
|
||||
'subscriptions/' => array(
|
||||
'' => 'PhortuneMerchantSubscriptionsController',
|
||||
$this->getQueryRoutePattern('list/')
|
||||
=> 'PhortuneMerchantSubscriptionListController',
|
||||
),
|
||||
'managers/' => array(
|
||||
'' => 'PhortuneMerchantManagersController',
|
||||
'new/' => 'PhortuneMerchantAddManagerController',
|
||||
),
|
||||
),
|
||||
'(?P<id>\d+)/' => 'PhortuneMerchantViewController',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
final class PhortunePaymentMethodPolicyCodex
|
||||
extends PhabricatorPolicyCodex {
|
||||
|
||||
public function getPolicySpecialRuleDescriptions() {
|
||||
$object = $this->getObject();
|
||||
|
||||
$rules = array();
|
||||
|
||||
$rules[] = $this->newRule()
|
||||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Account members may view and edit payment methods.'));
|
||||
|
||||
$rules[] = $this->newRule()
|
||||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Merchants you have a relationship with may view associated '.
|
||||
'payment methods.'));
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionPolicyCodex
|
||||
extends PhabricatorPolicyCodex {
|
||||
|
||||
public function getPolicySpecialRuleDescriptions() {
|
||||
$object = $this->getObject();
|
||||
|
||||
$rules = array();
|
||||
|
||||
$rules[] = $this->newRule()
|
||||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Account members may view and edit subscriptions.'));
|
||||
|
||||
$rules[] = $this->newRule()
|
||||
->setCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
))
|
||||
->setIsActive(true)
|
||||
->setDescription(
|
||||
pht(
|
||||
'Merchants you have a relationship with may view associated '.
|
||||
'subscriptions.'));
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountEmailStatus
|
||||
extends Phobject {
|
||||
|
||||
const STATUS_ACTIVE = 'active';
|
||||
const STATUS_DISABLED = 'disabled';
|
||||
const STATUS_UNSUBSCRIBED = 'unsubscribed';
|
||||
|
||||
public static function getDefaultStatusConstant() {
|
||||
return self::STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
private static function getMap() {
|
||||
return array(
|
||||
self::STATUS_ACTIVE => array(
|
||||
'name' => pht('Active'),
|
||||
'closed' => false,
|
||||
),
|
||||
self::STATUS_DISABLED => array(
|
||||
'name' => pht('Disabled'),
|
||||
'closed' => true,
|
||||
),
|
||||
self::STATUS_UNSUBSCRIBED => array(
|
||||
'name' => pht('Unsubscribed'),
|
||||
'closed' => true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,42 +2,6 @@
|
|||
|
||||
abstract class PhortuneController extends PhabricatorController {
|
||||
|
||||
protected function addAccountCrumb(
|
||||
$crumbs,
|
||||
PhortuneAccount $account,
|
||||
$link = true) {
|
||||
|
||||
$name = $account->getName();
|
||||
$href = null;
|
||||
|
||||
if ($link) {
|
||||
$href = $this->getApplicationURI($account->getID().'/');
|
||||
$crumbs->addTextCrumb($name, $href);
|
||||
} else {
|
||||
$crumbs->addTextCrumb($name);
|
||||
}
|
||||
}
|
||||
|
||||
protected function addMerchantCrumb(
|
||||
$crumbs,
|
||||
PhortuneMerchant $merchant,
|
||||
$link = true) {
|
||||
|
||||
$name = $merchant->getName();
|
||||
$href = null;
|
||||
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Merchants'),
|
||||
$this->getApplicationURI('merchant/'));
|
||||
|
||||
if ($link) {
|
||||
$href = $this->getApplicationURI('merchant/'.$merchant->getID().'/');
|
||||
$crumbs->addTextCrumb($name, $href);
|
||||
} else {
|
||||
$crumbs->addTextCrumb($name);
|
||||
}
|
||||
}
|
||||
|
||||
private function loadEnabledProvidersForMerchant(PhortuneMerchant $merchant) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
|
@ -84,30 +48,4 @@ abstract class PhortuneController extends PhabricatorController {
|
|||
return $providers;
|
||||
}
|
||||
|
||||
protected function loadMerchantAuthority() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$is_merchant = (bool)$request->getURIData('merchantID');
|
||||
if (!$is_merchant) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('merchantID')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$viewer->grantAuthority($merchant);
|
||||
return $merchant;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ final class PhortuneLandingController extends PhortuneController {
|
|||
|
||||
if (count($accounts) == 1) {
|
||||
$account = head($accounts);
|
||||
$next_uri = $this->getApplicationURI($account->getID().'/');
|
||||
$next_uri = $account->getURI();
|
||||
} else {
|
||||
$next_uri = $this->getApplicationURI('account/');
|
||||
}
|
||||
|
|
|
@ -1,27 +1,21 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountAddManagerController extends PhortuneController {
|
||||
final class PhortuneAccountAddManagerController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$account = $this->getAccount();
|
||||
|
||||
$account = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$id = $account->getID();
|
||||
|
||||
$v_managers = array();
|
||||
$e_managers = null;
|
||||
$account_uri = $this->getApplicationURI("/account/manager/{$id}/");
|
||||
$account_uri = $this->getApplicationURI("/account/{$id}/managers/");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
@ -53,23 +47,34 @@ final class PhortuneAccountAddManagerController extends PhortuneController {
|
|||
}
|
||||
}
|
||||
|
||||
$account_phid = $account->getPHID();
|
||||
$handles = $viewer->loadHandles(array($account_phid));
|
||||
$handle = $handles[$account_phid];
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->setViewer($viewer)
|
||||
->appendInstructions(
|
||||
pht(
|
||||
'Choose one or more users to add as account managers. Managers '.
|
||||
'have full control of the account.'))
|
||||
->appendControl(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel(pht('Payment Account'))
|
||||
->setValue($handle->renderLink()))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new PhabricatorPeopleDatasource())
|
||||
->setLabel(pht('Managers'))
|
||||
->setLabel(pht('Add Managers'))
|
||||
->setName('managerPHIDs')
|
||||
->setValue($v_managers)
|
||||
->setError($e_managers));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Manager'))
|
||||
->setTitle(pht('Add New Managers'))
|
||||
->appendForm($form)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->addCancelButton($account_uri)
|
||||
->addSubmitButton(pht('Add Manager'));
|
||||
|
||||
->addSubmitButton(pht('Add Managers'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountBillingController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->loadAccount();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Billing'));
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$methods = $this->buildPaymentMethodsSection($account);
|
||||
$charge_history = $this->buildChargeHistorySection($account);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$methods,
|
||||
$charge_history,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('billing');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildPaymentMethodsSection(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$id = $account->getID();
|
||||
|
||||
// TODO: Allow adding a card here directly
|
||||
$add = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('New Payment Method'))
|
||||
->setIcon('fa-plus')
|
||||
->setHref($this->getApplicationURI("{$id}/card/new/"));
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Payment Methods'));
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer)
|
||||
->setFlush(true)
|
||||
->setNoDataString(
|
||||
pht('No payment methods associated with this account.'));
|
||||
|
||||
$methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
foreach ($methods as $method) {
|
||||
$id = $method->getID();
|
||||
|
||||
$item = new PHUIObjectItemView();
|
||||
$item->setHeader($method->getFullDisplayName());
|
||||
|
||||
switch ($method->getStatus()) {
|
||||
case PhortunePaymentMethod::STATUS_ACTIVE:
|
||||
$item->setStatusIcon('fa-check green');
|
||||
|
||||
$disable_uri = $this->getApplicationURI('card/'.$id.'/disable/');
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-times')
|
||||
->setHref($disable_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
break;
|
||||
case PhortunePaymentMethod::STATUS_DISABLED:
|
||||
$item->setStatusIcon('fa-ban lightbluetext');
|
||||
$item->setDisabled(true);
|
||||
break;
|
||||
}
|
||||
|
||||
$provider = $method->buildPaymentProvider();
|
||||
$item->addAttribute($provider->getPaymentMethodProviderDescription());
|
||||
|
||||
$edit_uri = $this->getApplicationURI('card/'.$id.'/edit/');
|
||||
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
}
|
||||
|
||||
private function buildChargeHistorySection(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needCarts(true)
|
||||
->setLimit(10)
|
||||
->execute();
|
||||
|
||||
$phids = array();
|
||||
foreach ($charges as $charge) {
|
||||
$phids[] = $charge->getProviderPHID();
|
||||
$phids[] = $charge->getCartPHID();
|
||||
$phids[] = $charge->getMerchantPHID();
|
||||
$phids[] = $charge->getPaymentMethodPHID();
|
||||
}
|
||||
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$charges_uri = $this->getApplicationURI($account->getID().'/charge/');
|
||||
|
||||
$table = id(new PhortuneChargeTableView())
|
||||
->setUser($viewer)
|
||||
->setCharges($charges)
|
||||
->setHandles($handles);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Charge History'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($charges_uri)
|
||||
->setText(pht('View All Charges')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,71 +1,32 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountChargeListController
|
||||
extends PhortuneController {
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
private $account;
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$querykey = $request->getURIData('queryKey');
|
||||
$account_id = $request->getURIData('accountID');
|
||||
|
||||
$engine = new PhortuneChargeSearchEngine();
|
||||
|
||||
if ($account_id) {
|
||||
$account = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($account_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->account = $account;
|
||||
$engine->setAccount($account);
|
||||
} else {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$controller = id(new PhabricatorApplicationSearchController())
|
||||
->setQueryKey($querykey)
|
||||
->setSearchEngine($engine)
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
return $this->delegateToController($controller);
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function buildSideNavView() {
|
||||
$viewer = $this->getViewer();
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
id(new PhortuneChargeSearchEngine())
|
||||
->setViewer($viewer)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
return id(new PhortuneChargeSearchEngine())
|
||||
->setAccount($account)
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$account = $this->account;
|
||||
if ($account) {
|
||||
if ($this->hasAccount()) {
|
||||
$account = $this->getAccount();
|
||||
$id = $account->getID();
|
||||
$crumbs->addTextCrumb(
|
||||
$account->getName(),
|
||||
$this->getApplicationURI("{$id}/"));
|
||||
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Charges'),
|
||||
$this->getApplicationURI("{$id}/charge/"));
|
||||
$account->getChargesURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountChargesController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Orders'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
$charge_history = $this->buildChargeHistorySection($account);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$charge_history,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('charges');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildChargeHistorySection(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needCarts(true)
|
||||
->setLimit(100)
|
||||
->execute();
|
||||
|
||||
$charges_uri = $account->getChargeListURI();
|
||||
|
||||
$table = id(new PhortuneChargeTableView())
|
||||
->setUser($viewer)
|
||||
->setCharges($charges);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Recent Charges'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($charges_uri)
|
||||
->setText(pht('View All Charges')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,61 +4,159 @@ abstract class PhortuneAccountController
|
|||
extends PhortuneController {
|
||||
|
||||
private $account;
|
||||
private $merchants;
|
||||
|
||||
final public function handleRequest(AphrontRequest $request) {
|
||||
if ($this->shouldRequireAccountEditCapability()) {
|
||||
$response = $this->loadAccountForEdit();
|
||||
} else {
|
||||
$response = $this->loadAccountForView();
|
||||
}
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $this->handleAccountRequest($request);
|
||||
}
|
||||
|
||||
abstract protected function shouldRequireAccountEditCapability();
|
||||
abstract protected function handleAccountRequest(AphrontRequest $request);
|
||||
|
||||
final protected function hasAccount() {
|
||||
return (bool)$this->account;
|
||||
}
|
||||
|
||||
final protected function getAccount() {
|
||||
if ($this->account === null) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unable to "getAccount()" before loading or setting account '.
|
||||
'context.'));
|
||||
}
|
||||
|
||||
protected function getAccount() {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$account = $this->getAccount();
|
||||
if ($account) {
|
||||
// If we hit a policy exception, we can make it here without finding
|
||||
// an account.
|
||||
if ($this->hasAccount()) {
|
||||
$account = $this->getAccount();
|
||||
$crumbs->addTextCrumb($account->getName(), $account->getURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
protected function loadAccount() {
|
||||
// TODO: Currently, you must be able to edit an account to view the detail
|
||||
// page, because the account must be broadly visible so merchants can
|
||||
// process orders but merchants should not be able to see all the details
|
||||
// of an account. Ideally the profile pages should be visible to merchants,
|
||||
// too, just with less information.
|
||||
return $this->loadAccountForEdit();
|
||||
private function loadAccountForEdit() {
|
||||
return $this->loadAccountWithCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
));
|
||||
}
|
||||
|
||||
private function loadAccountForView() {
|
||||
return $this->loadAccountWithCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
));
|
||||
}
|
||||
|
||||
protected function loadAccountForEdit() {
|
||||
private function loadAccountWithCapabilities(array $capabilities) {
|
||||
$viewer = $this->getViewer();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$account_id = $request->getURIData('accountID');
|
||||
if (!$account_id) {
|
||||
$account_id = $request->getURIData('id');
|
||||
}
|
||||
|
||||
if (!$account_id) {
|
||||
return new Aphront404Response();
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Controller ("%s") extends controller "%s", but is reachable '.
|
||||
'with no "accountID" in URI.',
|
||||
get_class($this),
|
||||
__CLASS__));
|
||||
}
|
||||
|
||||
$account = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($account_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->requireCapabilities($capabilities)
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->account = $account;
|
||||
$this->setAccount($account);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function setAccount(PhortuneAccount $account) {
|
||||
$this->account = $account;
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
if (!$account->isUserAccountMember($viewer)) {
|
||||
$merchant_phids = $account->getMerchantPHIDs();
|
||||
$merchants = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($merchant_phids)
|
||||
->withMemberPHIDs(array($viewer->getPHID()))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->execute();
|
||||
|
||||
$this->merchants = $merchants;
|
||||
} else {
|
||||
$this->merchants = array();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
final protected function getMerchants() {
|
||||
if ($this->merchants === null) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Unable to "getMerchants()" before loading or setting account '.
|
||||
'context.'));
|
||||
}
|
||||
|
||||
return $this->merchants;
|
||||
}
|
||||
|
||||
final protected function newAccountAuthorityView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$merchants = $this->getMerchants();
|
||||
if (!$merchants) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$merchant_phids = mpull($merchants, 'getPHID');
|
||||
$merchant_handles = $viewer->loadHandles($merchant_phids);
|
||||
$merchant_handles = iterator_to_array($merchant_handles);
|
||||
|
||||
$merchant_list = mpull($merchant_handles, 'renderLink');
|
||||
$merchant_list = phutil_implode_html(', ', $merchant_list);
|
||||
|
||||
$merchant_message = pht(
|
||||
'You can view this account because you control %d merchant(s) it '.
|
||||
'has a relationship with: %s.',
|
||||
phutil_count($merchants),
|
||||
$merchant_list);
|
||||
|
||||
return id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->setErrors(
|
||||
array(
|
||||
$merchant_message,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountDetailsController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
$details = $this->newDetailsView($account);
|
||||
|
||||
$curtain = $this->buildCurtainView($account);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$account,
|
||||
new PhortuneAccountTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$authority,
|
||||
$details,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('details');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getApplicationURI('account/edit/'.$account->getID().'/');
|
||||
|
||||
$curtain = $this->newCurtainView($account);
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Account'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$member_phids = $account->getMemberPHIDs();
|
||||
$handles = $viewer->loadHandles($member_phids);
|
||||
|
||||
$member_list = id(new PHUIObjectItemListView())
|
||||
->setSimple(true);
|
||||
|
||||
foreach ($member_phids as $member_phid) {
|
||||
$image_uri = $handles[$member_phid]->getImageURI();
|
||||
$image_href = $handles[$member_phid]->getURI();
|
||||
$person = $handles[$member_phid];
|
||||
|
||||
$member = id(new PHUIObjectItemView())
|
||||
->setImageURI($image_uri)
|
||||
->setHref($image_href)
|
||||
->setHeader($person->getFullName());
|
||||
|
||||
$member_list->addItem($member);
|
||||
}
|
||||
|
||||
$curtain->newPanel()
|
||||
->setHeaderText(pht('Managers'))
|
||||
->appendChild($member_list);
|
||||
|
||||
$merchant_list = id(new PHUIObjectItemListView())
|
||||
->setSimple(true)
|
||||
->setNoDataString(pht('No purchase history.'));
|
||||
|
||||
$merchant_phids = $account->getMerchantPHIDs();
|
||||
$handles = $viewer->loadHandles($merchant_phids);
|
||||
|
||||
foreach ($merchant_phids as $merchant_phid) {
|
||||
$handle = $handles[$merchant_phid];
|
||||
|
||||
$merchant = id(new PHUIObjectItemView())
|
||||
->setImageURI($handle->getImageURI())
|
||||
->setHref($handle->getURI())
|
||||
->setHeader($handle->getFullName());
|
||||
|
||||
$merchant_list->addItem($merchant);
|
||||
}
|
||||
|
||||
$curtain->newPanel()
|
||||
->setHeaderText(pht('Merchants'))
|
||||
->appendChild($merchant_list);
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function newDetailsView(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$view->addProperty(pht('Account Name'), $account->getName());
|
||||
|
||||
$display_name = $account->getBillingName();
|
||||
if (!strlen($display_name)) {
|
||||
$display_name = phutil_tag('em', array(), pht('None'));
|
||||
}
|
||||
|
||||
$display_address = $account->getBillingAddress();
|
||||
if (!strlen($display_address)) {
|
||||
$display_address = phutil_tag('em', array(), pht('None'));
|
||||
} else {
|
||||
$display_address = phutil_escape_html_newlines($display_address);
|
||||
}
|
||||
|
||||
$view->addProperty(pht('Billing Name'), $display_name);
|
||||
$view->addProperty(pht('Billing Address'), $display_address);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Account Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountEmailAddressesController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Email Addresses'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
$addresses = $this->buildAddressesSection($account);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$addresses,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('addresses');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildAddressesSection(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$id = $account->getID();
|
||||
|
||||
$add = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Add Address'))
|
||||
->setIcon('fa-plus')
|
||||
->setWorkflow(!$can_edit)
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref("/phortune/account/{$id}/addresses/edit/");
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Billing Email Addresses'))
|
||||
->addActionLink($add);
|
||||
|
||||
$addresses = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->execute();
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer)
|
||||
->setNoDataString(
|
||||
pht(
|
||||
'There are no billing email addresses associated '.
|
||||
'with this account.'));
|
||||
|
||||
$addresses = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->execute();
|
||||
foreach ($addresses as $address) {
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName($address->getObjectName())
|
||||
->setHeader($address->getAddress())
|
||||
->setHref($address->getURI());
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountEmailEditController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
|
||||
$engine = id(new PhortuneAccountEmailEditEngine())
|
||||
->setController($this);
|
||||
|
||||
if (!$request->getURIData('id')) {
|
||||
$engine->setAccount($account);
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountEmailRotateController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$address = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($request->getURIData('addressID')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$address) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$address_uri = $address->getURI();
|
||||
|
||||
if ($request->isFormOrHisecPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $address->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortuneAccountEmailRotateTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(true);
|
||||
|
||||
$address->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setCancelURI($address_uri)
|
||||
->applyTransactions($address, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($address_uri);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Rotate Access Key'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Rotate the access key for email address %s?',
|
||||
phutil_tag('strong', array(), $address->getAddress())))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Existing access links which have been sent to this email address '.
|
||||
'will stop working.'))
|
||||
->addSubmitButton(pht('Rotate Access Key'))
|
||||
->addCancelButton($address_uri);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountEmailStatusController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$address = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($request->getURIData('addressID')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$address) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$address_uri = $address->getURI();
|
||||
|
||||
$is_enable = false;
|
||||
$is_disable = false;
|
||||
|
||||
$old_status = $address->getStatus();
|
||||
switch ($request->getURIData('action')) {
|
||||
case 'enable':
|
||||
if ($old_status === PhortuneAccountEmailStatus::STATUS_ACTIVE) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Already Enabled'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You can not enable this address because it is already '.
|
||||
'active.'))
|
||||
->addCancelButton($address_uri);
|
||||
}
|
||||
|
||||
if ($old_status === PhortuneAccountEmailStatus::STATUS_UNSUBSCRIBED) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Permanently Unsubscribed'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You can not enable this address because it has been '.
|
||||
'permanently unsubscribed.'))
|
||||
->addCancelButton($address_uri);
|
||||
}
|
||||
|
||||
$new_status = PhortuneAccountEmailStatus::STATUS_ACTIVE;
|
||||
$is_enable = true;
|
||||
break;
|
||||
case 'disable':
|
||||
if ($old_status === PhortuneAccountEmailStatus::STATUS_DISABLED) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Already Disabled'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You can not disabled this address because it is already '.
|
||||
'disabled.'))
|
||||
->addCancelButton($address_uri);
|
||||
}
|
||||
|
||||
if ($old_status === PhortuneAccountEmailStatus::STATUS_UNSUBSCRIBED) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Permanently Unsubscribed'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You can not disable this address because it has been '.
|
||||
'permanently unsubscribed.'))
|
||||
->addCancelButton($address_uri);
|
||||
}
|
||||
|
||||
$new_status = PhortuneAccountEmailStatus::STATUS_DISABLED;
|
||||
$is_disable = true;
|
||||
break;
|
||||
default:
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if ($request->isFormOrHisecPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $address->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortuneAccountEmailStatusTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_status);
|
||||
|
||||
$address->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setCancelURI($address_uri)
|
||||
->applyTransactions($address, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($address_uri);
|
||||
}
|
||||
|
||||
$dialog = $this->newDialog();
|
||||
|
||||
$body = array();
|
||||
|
||||
if ($is_disable) {
|
||||
$title = pht('Disable Address');
|
||||
|
||||
$body[] = pht(
|
||||
'This address will no longer receive email, and access links will '.
|
||||
'no longer function.');
|
||||
|
||||
$submit = pht('Disable Address');
|
||||
} else {
|
||||
$title = pht('Enable Address');
|
||||
|
||||
$body[] = pht(
|
||||
'This address will receive email again, and existing links '.
|
||||
'to access order history will work again.');
|
||||
|
||||
$submit = pht('Enable Address');
|
||||
}
|
||||
|
||||
foreach ($body as $graph) {
|
||||
$dialog->appendParagraph($graph);
|
||||
}
|
||||
|
||||
return $dialog
|
||||
->setTitle($title)
|
||||
->addCancelButton($address_uri)
|
||||
->addSubmitButton($submit);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountEmailViewController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$address = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($request->getURIData('addressID')))
|
||||
->executeOne();
|
||||
if (!$address) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Email Addresses'), $account->getEmailAddressesURI())
|
||||
->addTextCrumb($address->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Account Email: %s', $address->getAddress()));
|
||||
|
||||
$details = $this->newDetailsView($address);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$address,
|
||||
new PhortuneAccountEmailTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$curtain = $this->buildCurtainView($address);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$details,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($address->getObjectName())
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortuneAccountEmail $address) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $address->getAccount();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$address,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'account/%d/addresses/edit/%d/',
|
||||
$account->getID(),
|
||||
$address->getID()));
|
||||
|
||||
if ($can_edit) {
|
||||
$external_uri = $address->getExternalURI();
|
||||
} else {
|
||||
$external_uri = null;
|
||||
}
|
||||
|
||||
$curtain = $this->newCurtainView($account);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Address'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
switch ($address->getStatus()) {
|
||||
case PhortuneAccountEmailStatus::STATUS_ACTIVE:
|
||||
$disable_name = pht('Disable Address');
|
||||
$disable_icon = 'fa-times';
|
||||
$can_disable = true;
|
||||
$disable_action = 'disable';
|
||||
break;
|
||||
case PhortuneAccountEmailStatus::STATUS_DISABLED:
|
||||
$disable_name = pht('Enable Address');
|
||||
$disable_icon = 'fa-check';
|
||||
$can_disable = true;
|
||||
$disable_action = 'enable';
|
||||
break;
|
||||
case PhortuneAccountEmailStatus::STATUS_UNSUBSCRIBED:
|
||||
$disable_name = pht('Disable Address');
|
||||
$disable_icon = 'fa-times';
|
||||
$can_disable = false;
|
||||
$disable_action = 'disable';
|
||||
break;
|
||||
}
|
||||
|
||||
$disable_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'account/%d/addresses/%d/%s/',
|
||||
$account->getID(),
|
||||
$address->getID(),
|
||||
$disable_action));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName($disable_name)
|
||||
->setIcon($disable_icon)
|
||||
->setHref($disable_uri)
|
||||
->setDisabled(!$can_disable)
|
||||
->setWorkflow(true));
|
||||
|
||||
$rotate_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'account/%d/addresses/%d/rotate/',
|
||||
$account->getID(),
|
||||
$address->getID()));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Rotate Access Key'))
|
||||
->setIcon('fa-refresh')
|
||||
->setHref($rotate_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Show External View'))
|
||||
->setIcon('fa-eye')
|
||||
->setHref($external_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setOpenInNewWindow(true));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function newDetailsView(PhortuneAccountEmail $address) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$access_key = $address->getAccessKey();
|
||||
|
||||
// This is not a meaningful security barrier: the full plaintext of the
|
||||
// access key is visible on the page in the link target of the "Show
|
||||
// External View" action. It's just here to make it clear "Rotate Access
|
||||
// Key" actually does something.
|
||||
|
||||
$prefix_length = 4;
|
||||
$visible_part = substr($access_key, 0, $prefix_length);
|
||||
$masked_part = str_repeat(
|
||||
"\xE2\x80\xA2",
|
||||
strlen($access_key) - $prefix_length);
|
||||
$access_display = $visible_part.$masked_part;
|
||||
$access_display = phutil_tag('tt', array(), $access_display);
|
||||
|
||||
$view->addProperty(pht('Email Address'), $address->getAddress());
|
||||
$view->addProperty(pht('Access Key'), $access_display);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Email Address Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($view);
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ final class PhortuneAccountListController extends PhortuneController {
|
|||
$item = id(new PHUIObjectItemView())
|
||||
->setSubhead(pht('Account %d', $account->getID()))
|
||||
->setHeader($account->getName())
|
||||
->setHref($this->getApplicationURI($account->getID().'/'))
|
||||
->setHref($account->getURI())
|
||||
->setObject($account)
|
||||
->setImageIcon('fa-user-circle');
|
||||
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountManagerController
|
||||
final class PhortuneAccountManagersController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->loadAccount();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Managers'));
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Managers'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
$members = $this->buildMembersSection($account);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$members,
|
||||
));
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$members,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('managers');
|
||||
|
||||
|
@ -46,11 +49,11 @@ final class PhortuneAccountManagerController
|
|||
|
||||
$add = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('New Manager'))
|
||||
->setText(pht('Add Managers'))
|
||||
->setIcon('fa-plus')
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref("/phortune/account/manager/add/{$id}/");
|
||||
->setHref("/phortune/account/{$id}/managers/add/");
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Account Managers'))
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountOrderListController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
private $subscription;
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$engine = id(new PhortuneCartSearchEngine())
|
||||
->setController($this)
|
||||
->setAccount($account);
|
||||
|
||||
$subscription_id = $request->getURIData('subscriptionID');
|
||||
if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($subscription_id))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$engine->setSubscription($subscription);
|
||||
$this->subscription = $subscription;
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$subscription = $this->subscription;
|
||||
if ($subscription) {
|
||||
$crumbs->addTextCrumb(
|
||||
$subscription->getObjectName(),
|
||||
$subscription->getURI());
|
||||
} else if ($this->hasAccount()) {
|
||||
$account = $this->getAccount();
|
||||
|
||||
$crumbs->addTextCrumb(pht('Orders'), $account->getOrdersURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountOrdersController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Orders'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
|
||||
$order_history = $this->newRecentOrdersView($account, 100);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$order_history,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('orders');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountOverviewController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
$status = $this->buildStatusView($account, $invoices);
|
||||
$invoices = $this->buildInvoicesSection($account, $invoices);
|
||||
$purchase_history = $this->newRecentOrdersView($account, 10);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$status,
|
||||
$invoices,
|
||||
$purchase_history,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('overview');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildStatusView(PhortuneAccount $account, $invoices) {
|
||||
$status_items = $this->getStatusItemsForAccount($account, $invoices);
|
||||
$view = array();
|
||||
foreach ($status_items as $item) {
|
||||
$view[] = id(new PHUIInfoView())
|
||||
->setSeverity(idx($item, 'severity'))
|
||||
->appendChild(idx($item, 'note'));
|
||||
}
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildInvoicesSection(
|
||||
PhortuneAccount $account,
|
||||
array $carts) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$table = id(new PhortuneOrderTableView())
|
||||
->setNoDataString(pht('You have no unpaid invoices.'))
|
||||
->setIsInvoices(true)
|
||||
->setUser($viewer)
|
||||
->setCarts($carts);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices Due'));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-exchange')
|
||||
->setHref($this->getApplicationURI('account/'))
|
||||
->setName(pht('Switch Accounts')));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
private function getStatusItemsForAccount(
|
||||
PhortuneAccount $account,
|
||||
array $invoices) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
assert_instances_of($invoices, 'PhortuneCart');
|
||||
$items = array();
|
||||
|
||||
$methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
if ($invoices) {
|
||||
$items[] = array(
|
||||
'severity' => PHUIInfoView::SEVERITY_ERROR,
|
||||
'note' => pht('You have %d unpaid invoice(s).', count($invoices)),
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: If a payment method has expired or is expiring soon, we should
|
||||
// add a status check for it.
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountPaymentMethodController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Payment Methods'))
|
||||
->setBorder(true);
|
||||
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
$header = $this->buildHeaderView();
|
||||
$methods = $this->buildPaymentMethodsSection($account);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$methods,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('methods');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildPaymentMethodsSection(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$id = $account->getID();
|
||||
|
||||
$add = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Add Payment Method'))
|
||||
->setIcon('fa-plus')
|
||||
->setHref($this->getApplicationURI("account/{$id}/methods/new/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Payment Methods'))
|
||||
->addActionLink($add);
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer)
|
||||
->setFlush(true)
|
||||
->setNoDataString(
|
||||
pht('There are no payment methods associated with this account.'));
|
||||
|
||||
$methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
foreach ($methods as $method) {
|
||||
$id = $method->getID();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName($method->getObjectName())
|
||||
->setHeader($method->getFullDisplayName())
|
||||
->setHref($method->getURI());
|
||||
|
||||
$provider = $method->buildPaymentProvider();
|
||||
$item->addAttribute($provider->getPaymentMethodProviderDescription());
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountPaymentMethodViewController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$method = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$method) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Payment Methods'), $account->getPaymentMethodsURI())
|
||||
->addTextCrumb($method->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($method->getFullDisplayName());
|
||||
|
||||
$details = $this->newDetailsView($method);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$method,
|
||||
new PhortunePaymentMethodTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$autopay = $this->newAutopayView($method);
|
||||
|
||||
$curtain = $this->buildCurtainView($method);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$details,
|
||||
$autopay,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($method->getObjectName())
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortunePaymentMethod $method) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$method,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'card/%d/edit/',
|
||||
$method->getID()));
|
||||
|
||||
$remove_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'card/%d/disable/',
|
||||
$method->getID()));
|
||||
|
||||
$curtain = $this->newCurtainView($method);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Payment Method'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Remove Payment Method'))
|
||||
->setIcon('fa-times')
|
||||
->setHref($remove_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function newDetailsView(PhortunePaymentMethod $method) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$merchant_phid = $method->getMerchantPHID();
|
||||
$handles = $viewer->loadHandles(
|
||||
array(
|
||||
$merchant_phid,
|
||||
));
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
if (strlen($method->getName())) {
|
||||
$view->addProperty(pht('Name'), $method->getDisplayName());
|
||||
}
|
||||
|
||||
$view->addProperty(pht('Summary'), $method->getSummary());
|
||||
$view->addProperty(pht('Expires'), $method->getDisplayExpires());
|
||||
|
||||
$view->addProperty(
|
||||
pht('Merchant'),
|
||||
$handles[$merchant_phid]->renderLink());
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Payment Method Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($view);
|
||||
}
|
||||
|
||||
private function newAutopayView(PhortunePaymentMethod $method) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$subscriptions = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withPaymentMethodPHIDs(array($method->getPHID()))
|
||||
->execute();
|
||||
|
||||
$table = id(new PhortuneSubscriptionTableView())
|
||||
->setViewer($viewer)
|
||||
->setSubscriptions($subscriptions)
|
||||
->newTableView();
|
||||
|
||||
$table->setNoDataString(
|
||||
pht(
|
||||
'This payment method is not the default payment method for '.
|
||||
'any subscriptions.'));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Autopay Subscriptions'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,10 +3,6 @@
|
|||
abstract class PhortuneAccountProfileController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
protected function buildHeaderView() {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
@ -17,13 +13,16 @@ abstract class PhortuneAccountProfileController
|
|||
->setHeader($title)
|
||||
->setHeaderIcon('fa-user-circle');
|
||||
|
||||
return $header;
|
||||
}
|
||||
if ($this->getMerchants()) {
|
||||
$customer_tag = id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_SHADE)
|
||||
->setName(pht('Customer Account'))
|
||||
->setColor('indigo')
|
||||
->setIcon('fa-credit-card');
|
||||
$header->addTag($customer_tag);
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$crumbs->setBorder(true);
|
||||
return $crumbs;
|
||||
return $header;
|
||||
}
|
||||
|
||||
protected function buildSideNavView($filter = null) {
|
||||
|
@ -31,6 +30,8 @@ abstract class PhortuneAccountProfileController
|
|||
$account = $this->getAccount();
|
||||
$id = $account->getID();
|
||||
|
||||
$can_edit = !$this->getMerchants();
|
||||
|
||||
$nav = id(new AphrontSideNavFilterView())
|
||||
->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
|
@ -39,30 +40,103 @@ abstract class PhortuneAccountProfileController
|
|||
$nav->addFilter(
|
||||
'overview',
|
||||
pht('Overview'),
|
||||
$this->getApplicationURI("/{$id}/"),
|
||||
$account->getURI(),
|
||||
'fa-user-circle');
|
||||
|
||||
$nav->newLink('details')
|
||||
->setName(pht('Account Details'))
|
||||
->setHref($this->getApplicationURI("/account/{$id}/details/"))
|
||||
->setIcon('fa-address-card-o')
|
||||
->setWorkflow(!$can_edit)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
$nav->addLabel(pht('Payments'));
|
||||
|
||||
$nav->addFilter(
|
||||
'methods',
|
||||
pht('Payment Methods'),
|
||||
$account->getPaymentMethodsURI(),
|
||||
'fa-credit-card');
|
||||
|
||||
$nav->addFilter(
|
||||
'subscriptions',
|
||||
pht('Subscriptions'),
|
||||
$this->getApplicationURI("/account/subscription/{$id}/"),
|
||||
$account->getSubscriptionsURI(),
|
||||
'fa-retweet');
|
||||
|
||||
$nav->addFilter(
|
||||
'billing',
|
||||
pht('Billing / History'),
|
||||
$this->getApplicationURI("/account/billing/{$id}/"),
|
||||
'fa-credit-card');
|
||||
'orders',
|
||||
pht('Orders'),
|
||||
$account->getOrdersURI(),
|
||||
'fa-shopping-bag');
|
||||
|
||||
$nav->addFilter(
|
||||
'charges',
|
||||
pht('Charges'),
|
||||
$account->getChargesURI(),
|
||||
'fa-calculator');
|
||||
|
||||
$nav->addLabel(pht('Personnel'));
|
||||
|
||||
$nav->addFilter(
|
||||
'managers',
|
||||
pht('Managers'),
|
||||
$this->getApplicationURI("/account/manager/{$id}/"),
|
||||
pht('Account Managers'),
|
||||
$this->getApplicationURI("/account/{$id}/managers/"),
|
||||
'fa-group');
|
||||
|
||||
$nav->newLink('addresses')
|
||||
->setname(pht('Email Addresses'))
|
||||
->setHref($account->getEmailAddressesURI())
|
||||
->setIcon('fa-envelope-o')
|
||||
->setWorkflow(!$can_edit)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
$nav->selectFilter($filter);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
final protected function newRecentOrdersView(
|
||||
PhortuneAccount $account,
|
||||
$limit) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$carts = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_HOLD,
|
||||
PhortuneCart::STATUS_REVIEW,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
))
|
||||
->setLimit($limit)
|
||||
->execute();
|
||||
|
||||
$orders_uri = $account->getOrderListURI();
|
||||
|
||||
$table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($carts);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Recent Orders'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($orders_uri)
|
||||
->setText(pht('View All Orders')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountSubscriptionAutopayController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $this->getAccount();
|
||||
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('subscriptionID')))
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$method = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('methodID')))
|
||||
->withAccountPHIDs(array($subscription->getAccountPHID()))
|
||||
->withMerchantPHIDs(array($subscription->getMerchantPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$method) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$next_uri = $subscription->getURI();
|
||||
|
||||
$autopay_phid = $subscription->getDefaultPaymentMethodPHID();
|
||||
$is_stop = ($autopay_phid === $method->getPHID());
|
||||
|
||||
if ($request->isFormOrHisecPost()) {
|
||||
if ($is_stop) {
|
||||
$new_phid = null;
|
||||
} else {
|
||||
$new_phid = $method->getPHID();
|
||||
}
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $subscription->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortuneSubscriptionAutopayTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($new_phid);
|
||||
|
||||
$editor = $subscription->getApplicationTransactionEditor()
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setCancelURI($next_uri);
|
||||
|
||||
$editor->applyTransactions($subscription, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
}
|
||||
|
||||
$method_phid = $method->getPHID();
|
||||
$subscription_phid = $subscription->getPHID();
|
||||
|
||||
$handles = $viewer->loadHandles(
|
||||
array(
|
||||
$method_phid,
|
||||
$subscription_phid,
|
||||
));
|
||||
|
||||
$method_handle = $handles[$method_phid];
|
||||
$subscription_handle = $handles[$subscription_phid];
|
||||
|
||||
$method_display = $method_handle->renderLink();
|
||||
$method_display = phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$method_display);
|
||||
|
||||
$subscription_display = $subscription_handle->renderLink();
|
||||
$subscription_display = phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$subscription_display);
|
||||
|
||||
$body = array();
|
||||
if ($is_stop) {
|
||||
$title = pht('Stop Autopay');
|
||||
|
||||
$body[] = pht(
|
||||
'Remove %s as the automatic payment method for subscription %s?',
|
||||
$method_display,
|
||||
$subscription_display);
|
||||
|
||||
$body[] = pht(
|
||||
'This payment method will no longer be charged automatically.');
|
||||
|
||||
$submit = pht('Stop Autopay');
|
||||
} else {
|
||||
$title = pht('Start Autopay');
|
||||
|
||||
$body[] = pht(
|
||||
'Set %s as the automatic payment method for subscription %s?',
|
||||
$method_display,
|
||||
$subscription_display);
|
||||
|
||||
$body[] = pht(
|
||||
'This payment method will be used to automatically pay future '.
|
||||
'charges.');
|
||||
|
||||
$submit = pht('Start Autopay');
|
||||
}
|
||||
|
||||
$dialog = $this->newDialog()
|
||||
->setTitle($title)
|
||||
->addCancelButton($next_uri)
|
||||
->addSubmitButton($submit);
|
||||
|
||||
foreach ($body as $graph) {
|
||||
$dialog->appendParagraph($graph);
|
||||
}
|
||||
|
||||
return $dialog;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,26 +3,30 @@
|
|||
final class PhortuneAccountSubscriptionController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->loadAccount();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Subscriptions'));
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Subscriptions'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$authority = $this->newAccountAuthorityView();
|
||||
|
||||
$subscriptions = $this->buildSubscriptionsSection($account);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$subscriptions,
|
||||
));
|
||||
->setFooter(
|
||||
array(
|
||||
$authority,
|
||||
$subscriptions,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('subscriptions');
|
||||
|
||||
|
@ -43,11 +47,8 @@ final class PhortuneAccountSubscriptionController
|
|||
->setLimit(25)
|
||||
->execute();
|
||||
|
||||
$handles = $this->loadViewerHandles(mpull($subscriptions, 'getPHID'));
|
||||
|
||||
$table = id(new PhortuneSubscriptionTableView())
|
||||
->setUser($viewer)
|
||||
->setHandles($handles)
|
||||
->setSubscriptions($subscriptions);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountSubscriptionViewController
|
||||
extends PhortuneAccountController {
|
||||
|
||||
protected function shouldRequireAccountEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleAccountRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('subscriptionID')))
|
||||
->needTriggers(true)
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$subscription,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$merchant = $subscription->getMerchant();
|
||||
$account = $subscription->getAccount();
|
||||
|
||||
$account_id = $account->getID();
|
||||
$subscription_id = $subscription->getID();
|
||||
|
||||
$title = $subscription->getSubscriptionFullName();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setHeaderIcon('fa-retweet');
|
||||
|
||||
$edit_uri = $subscription->getEditURI();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($subscription->getSubscriptionCrumbName())
|
||||
->setBorder(true);
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$next_invoice = $subscription->getTrigger()->getNextEventPrediction();
|
||||
$properties->addProperty(
|
||||
pht('Next Invoice'),
|
||||
phabricator_datetime($next_invoice, $viewer));
|
||||
|
||||
$autopay = $this->newAutopayView($subscription);
|
||||
|
||||
$details = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Subscription Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($properties);
|
||||
|
||||
$due_box = $this->buildDueInvoices($subscription);
|
||||
$invoice_box = $this->buildPastInvoices($subscription);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$subscription,
|
||||
new PhortuneSubscriptionTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$details,
|
||||
$autopay,
|
||||
$due_box,
|
||||
$invoice_box,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildDueInvoices(PhortuneSubscription $subscription) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withSubscriptionPHIDs(array($subscription->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$invoice_table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($invoices)
|
||||
->setIsInvoices(true);
|
||||
|
||||
$invoice_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices Due'));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($invoice_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($invoice_table);
|
||||
}
|
||||
|
||||
private function buildPastInvoices(PhortuneSubscription $subscription) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withSubscriptionPHIDs(array($subscription->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_HOLD,
|
||||
PhortuneCart::STATUS_REVIEW,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
))
|
||||
->setLimit(50)
|
||||
->execute();
|
||||
|
||||
$invoice_table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($invoices);
|
||||
|
||||
$account = $subscription->getAccount();
|
||||
$merchant = $subscription->getMerchant();
|
||||
|
||||
$account_id = $account->getID();
|
||||
$merchant_id = $merchant->getID();
|
||||
$subscription_id = $subscription->getID();
|
||||
|
||||
$invoices_uri = $this->getApplicationURI(
|
||||
"{$account_id}/subscription/order/{$subscription_id}/");
|
||||
|
||||
$invoice_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Past Invoices'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($invoices_uri)
|
||||
->setText(pht('View All Invoices')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($invoice_header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($invoice_table);
|
||||
}
|
||||
|
||||
private function newAutopayView(PhortuneSubscription $subscription) {
|
||||
$viewer = $this->getViewer();
|
||||
$account = $subscription->getAccount();
|
||||
|
||||
$add_method_uri = urisprintf(
|
||||
'/account/%d/methods/new/?subscriptionID=%s',
|
||||
$account->getID(),
|
||||
$subscription->getID());
|
||||
$add_method_uri = $this->getApplicationURI($add_method_uri);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$subscription,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($subscription->getAccountPHID()))
|
||||
->withMerchantPHIDs(array($subscription->getMerchantPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
$methods = mpull($methods, null, 'getPHID');
|
||||
|
||||
$autopay_phid = $subscription->getDefaultPaymentMethodPHID();
|
||||
$autopay_method = idx($methods, $autopay_phid);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Autopay'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-plus')
|
||||
->setHref($add_method_uri)
|
||||
->setText(pht('Add Payment Method'))
|
||||
->setWorkflow(!$can_edit)
|
||||
->setDisabled(!$can_edit));
|
||||
|
||||
$methods = array_select_keys($methods, array($autopay_phid)) + $methods;
|
||||
|
||||
$rows = array();
|
||||
$rowc = array();
|
||||
foreach ($methods as $method) {
|
||||
$is_autopay = ($autopay_method === $method);
|
||||
|
||||
$remove_uri = urisprintf(
|
||||
'/card/%d/disable/?subscriptionID=%d',
|
||||
$method->getID(),
|
||||
$subscription->getID());
|
||||
$remove_uri = $this->getApplicationURI($remove_uri);
|
||||
|
||||
$autopay_uri = urisprintf(
|
||||
'/account/%d/subscriptions/%d/autopay/%d/',
|
||||
$account->getID(),
|
||||
$subscription->getID(),
|
||||
$method->getID());
|
||||
$autopay_uri = $this->getApplicationURI($autopay_uri);
|
||||
|
||||
$remove_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setColor('grey')
|
||||
->setIcon('fa-times')
|
||||
->setText(pht('Delete'))
|
||||
->setHref($remove_uri)
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
if ($is_autopay) {
|
||||
$autopay_button = id(new PHUIButtonView())
|
||||
->setColor('red')
|
||||
->setIcon('fa-times')
|
||||
->setText(pht('Stop Autopay'));
|
||||
} else {
|
||||
if ($autopay_method) {
|
||||
$make_color = 'grey';
|
||||
} else {
|
||||
$make_color = 'green';
|
||||
}
|
||||
|
||||
$autopay_button = id(new PHUIButtonView())
|
||||
->setColor($make_color)
|
||||
->setIcon('fa-retweet')
|
||||
->setText(pht('Start Autopay'));
|
||||
}
|
||||
|
||||
$autopay_button
|
||||
->setTag('a')
|
||||
->setHref($autopay_uri)
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit);
|
||||
|
||||
$rows[] = array(
|
||||
$method->getID(),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $method->getURI(),
|
||||
),
|
||||
$method->getFullDisplayName()),
|
||||
$method->getDisplayExpires(),
|
||||
$autopay_button,
|
||||
$remove_button,
|
||||
);
|
||||
|
||||
if ($is_autopay) {
|
||||
$rowc[] = 'highlighted';
|
||||
} else {
|
||||
$rowc[] = null;
|
||||
}
|
||||
}
|
||||
|
||||
$method_table = id(new AphrontTableView($rows))
|
||||
->setHeaders(
|
||||
array(
|
||||
pht('ID'),
|
||||
pht('Payment Method'),
|
||||
pht('Expires'),
|
||||
null,
|
||||
null,
|
||||
))
|
||||
->setRowClasses($rowc)
|
||||
->setColumnClasses(
|
||||
array(
|
||||
null,
|
||||
'pri wide',
|
||||
null,
|
||||
'right',
|
||||
null,
|
||||
));
|
||||
|
||||
if (!$autopay_method) {
|
||||
$method_table->setNotice(
|
||||
array(
|
||||
id(new PHUIIconView())->setIcon('fa-warning yellow'),
|
||||
' ',
|
||||
pht('Autopay is not currently configured for this subscription.'),
|
||||
));
|
||||
} else {
|
||||
$method_table->setNotice(
|
||||
array(
|
||||
id(new PHUIIconView())->setIcon('fa-check green'),
|
||||
' ',
|
||||
pht(
|
||||
'Autopay is configured using %s.',
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $autopay_method->getURI(),
|
||||
),
|
||||
$autopay_method->getFullDisplayName())),
|
||||
));
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($method_table);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,238 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountViewController
|
||||
extends PhortuneAccountProfileController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->loadAccount();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$account = $this->getAccount();
|
||||
$title = $account->getName();
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$curtain = $this->buildCurtainView($account);
|
||||
$status = $this->buildStatusView($account, $invoices);
|
||||
$invoices = $this->buildInvoicesSection($account, $invoices);
|
||||
$purchase_history = $this->buildPurchaseHistorySection($account);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$account,
|
||||
new PhortuneAccountTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$status,
|
||||
$invoices,
|
||||
$purchase_history,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('overview');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildStatusView(PhortuneAccount $account, $invoices) {
|
||||
$status_items = $this->getStatusItemsForAccount($account, $invoices);
|
||||
$view = array();
|
||||
foreach ($status_items as $item) {
|
||||
$view[] = id(new PHUIInfoView())
|
||||
->setSeverity(idx($item, 'severity'))
|
||||
->appendChild(idx($item, 'note'));
|
||||
}
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getApplicationURI('account/edit/'.$account->getID().'/');
|
||||
|
||||
$curtain = $this->newCurtainView($account);
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Account'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$member_phids = $account->getMemberPHIDs();
|
||||
$handles = $viewer->loadHandles($member_phids);
|
||||
|
||||
$member_list = id(new PHUIObjectItemListView())
|
||||
->setSimple(true);
|
||||
|
||||
foreach ($member_phids as $member_phid) {
|
||||
$image_uri = $handles[$member_phid]->getImageURI();
|
||||
$image_href = $handles[$member_phid]->getURI();
|
||||
$person = $handles[$member_phid];
|
||||
|
||||
$member = id(new PHUIObjectItemView())
|
||||
->setImageURI($image_uri)
|
||||
->setHref($image_href)
|
||||
->setHeader($person->getFullName());
|
||||
|
||||
$member_list->addItem($member);
|
||||
}
|
||||
|
||||
$curtain->newPanel()
|
||||
->setHeaderText(pht('Managers'))
|
||||
->appendChild($member_list);
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function buildInvoicesSection(
|
||||
PhortuneAccount $account,
|
||||
array $carts) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$phids = array();
|
||||
foreach ($carts as $cart) {
|
||||
$phids[] = $cart->getPHID();
|
||||
$phids[] = $cart->getMerchantPHID();
|
||||
foreach ($cart->getPurchases() as $purchase) {
|
||||
$phids[] = $purchase->getPHID();
|
||||
}
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$table = id(new PhortuneOrderTableView())
|
||||
->setNoDataString(pht('You have no unpaid invoices.'))
|
||||
->setIsInvoices(true)
|
||||
->setUser($viewer)
|
||||
->setCarts($carts)
|
||||
->setHandles($handles);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices Due'));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
private function buildPurchaseHistorySection(PhortuneAccount $account) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$carts = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_HOLD,
|
||||
PhortuneCart::STATUS_REVIEW,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
))
|
||||
->setLimit(10)
|
||||
->execute();
|
||||
|
||||
$phids = array();
|
||||
foreach ($carts as $cart) {
|
||||
$phids[] = $cart->getPHID();
|
||||
foreach ($cart->getPurchases() as $purchase) {
|
||||
$phids[] = $purchase->getPHID();
|
||||
}
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$orders_uri = $this->getApplicationURI($account->getID().'/order/');
|
||||
|
||||
$table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($carts)
|
||||
->setHandles($handles);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Recent Orders'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($orders_uri)
|
||||
->setText(pht('View All Orders')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-exchange')
|
||||
->setHref($this->getApplicationURI('account/'))
|
||||
->setName(pht('Switch Accounts')));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
private function getStatusItemsForAccount(
|
||||
PhortuneAccount $account,
|
||||
array $invoices) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
assert_instances_of($invoices, 'PhortuneCart');
|
||||
$items = array();
|
||||
|
||||
$methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->execute();
|
||||
|
||||
if ($invoices) {
|
||||
$items[] = array(
|
||||
'severity' => PHUIInfoView::SEVERITY_ERROR,
|
||||
'note' => pht('You have %d unpaid invoice(s).', count($invoices)),
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: If a payment method has expired or is expiring soon, we should
|
||||
// add a status check for it.
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,27 +3,19 @@
|
|||
final class PhortuneCartAcceptController
|
||||
extends PhortuneCartController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function shouldRequireMerchantAuthority() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$cart = $this->getCart();
|
||||
|
||||
// You must control the merchant to accept orders.
|
||||
$authority = $this->loadMerchantAuthority();
|
||||
if (!$authority) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cart = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->withMerchantPHIDs(array($authority->getPHID()))
|
||||
->needPurchases(true)
|
||||
->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cancel_uri = $cart->getDetailURI($authority);
|
||||
$cancel_uri = $cart->getDetailURI();
|
||||
|
||||
if ($cart->getStatus() !== PhortuneCart::STATUS_REVIEW) {
|
||||
return $this->newDialog()
|
||||
|
|
|
@ -3,26 +3,21 @@
|
|||
final class PhortuneCartCancelController
|
||||
extends PhortuneCartController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function shouldRequireMerchantAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$action = $request->getURIData('action');
|
||||
|
||||
$authority = $this->loadMerchantAuthority();
|
||||
|
||||
$cart_query = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPurchases(true);
|
||||
|
||||
if ($authority) {
|
||||
$cart_query->withMerchantPHIDs(array($authority->getPHID()));
|
||||
}
|
||||
|
||||
$cart = $cart_query->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$cart = $this->getCart();
|
||||
$authority = $this->getMerchantAuthority();
|
||||
|
||||
switch ($action) {
|
||||
case 'cancel':
|
||||
|
@ -45,7 +40,7 @@ final class PhortuneCartCancelController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cancel_uri = $cart->getDetailURI($authority);
|
||||
$cancel_uri = $cart->getDetailURI();
|
||||
$merchant = $cart->getMerchant();
|
||||
|
||||
try {
|
||||
|
@ -60,7 +55,7 @@ final class PhortuneCartCancelController
|
|||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->appendChild($ex->getMessage())
|
||||
->addCancelButton($cancel_uri);
|
||||
->addCancelButton($cancel_uri, pht('Rats'));
|
||||
}
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
|
|
|
@ -3,18 +3,17 @@
|
|||
final class PhortuneCartCheckoutController
|
||||
extends PhortuneCartController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return true;
|
||||
}
|
||||
|
||||
$cart = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPurchases(true)
|
||||
->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
protected function shouldRequireMerchantAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$cart = $this->getCart();
|
||||
|
||||
$cancel_uri = $cart->getCancelURI();
|
||||
$merchant = $cart->getMerchant();
|
||||
|
@ -139,7 +138,10 @@ final class PhortuneCartCheckoutController
|
|||
'cartID' => $cart->getID(),
|
||||
);
|
||||
|
||||
$payment_method_uri = $this->getApplicationURI("{$account_id}/card/new/");
|
||||
$payment_method_uri = urisprintf(
|
||||
'account/%d/methods/new/',
|
||||
$account->getID());
|
||||
$payment_method_uri = $this->getApplicationURI($payment_method_uri);
|
||||
$payment_method_uri = new PhutilURI($payment_method_uri, $params);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
|
@ -205,7 +207,9 @@ final class PhortuneCartCheckoutController
|
|||
->appendChild($form)
|
||||
->appendChild($provider_form);
|
||||
|
||||
$description_box = $this->renderCartDescription($cart);
|
||||
$description_view = id(new PhortuneOrderDescriptionView())
|
||||
->setViewer($viewer)
|
||||
->setOrder($cart);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Checkout'));
|
||||
|
@ -218,11 +222,12 @@ final class PhortuneCartCheckoutController
|
|||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$cart_box,
|
||||
$description_box,
|
||||
$payment_box,
|
||||
));
|
||||
->setFooter(
|
||||
array(
|
||||
$description_view,
|
||||
$cart_box,
|
||||
$payment_box,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
|
|
|
@ -3,61 +3,75 @@
|
|||
abstract class PhortuneCartController
|
||||
extends PhortuneController {
|
||||
|
||||
protected function buildCartContentTable(PhortuneCart $cart) {
|
||||
private $cart;
|
||||
private $merchantAuthority;
|
||||
|
||||
$rows = array();
|
||||
foreach ($cart->getPurchases() as $purchase) {
|
||||
$rows[] = array(
|
||||
$purchase->getFullDisplayName(),
|
||||
$purchase->getBasePriceAsCurrency()->formatForDisplay(),
|
||||
$purchase->getQuantity(),
|
||||
$purchase->getTotalPriceAsCurrency()->formatForDisplay(),
|
||||
abstract protected function shouldRequireAccountAuthority();
|
||||
abstract protected function shouldRequireMerchantAuthority();
|
||||
abstract protected function handleCartRequest(AphrontRequest $request);
|
||||
|
||||
final public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($this->shouldRequireAccountAuthority()) {
|
||||
$capabilities = array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
);
|
||||
} else {
|
||||
$capabilities = array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
);
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
phutil_tag('strong', array(), pht('Total')),
|
||||
'',
|
||||
'',
|
||||
phutil_tag('strong', array(),
|
||||
$cart->getTotalPriceAsCurrency()->formatForDisplay()),
|
||||
);
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
pht('Item'),
|
||||
pht('Price'),
|
||||
pht('Qty.'),
|
||||
pht('Total'),
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'wide',
|
||||
'right',
|
||||
'right',
|
||||
'right',
|
||||
));
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
protected function renderCartDescription(PhortuneCart $cart) {
|
||||
$description = $cart->getDescription();
|
||||
if (!strlen($description)) {
|
||||
return null;
|
||||
$cart = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->needPurchases(true)
|
||||
->requireCapabilities($capabilities)
|
||||
->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$output = new PHUIRemarkupView($this->getViewer(), $description);
|
||||
if ($this->shouldRequireMerchantAuthority()) {
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$viewer,
|
||||
$cart->getMerchant(),
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
|
||||
$box = id(new PHUIBoxView())
|
||||
->addMargin(PHUI::MARGIN_LARGE)
|
||||
->appendChild($output);
|
||||
$this->cart = $cart;
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Description'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($box);
|
||||
$can_edit = PhortuneMerchantQuery::canViewersEditMerchants(
|
||||
array($viewer->getPHID()),
|
||||
array($cart->getMerchantPHID()));
|
||||
if ($can_edit) {
|
||||
$this->merchantAuthority = $cart->getMerchant();
|
||||
} else {
|
||||
$this->merchantAuthority = null;
|
||||
}
|
||||
|
||||
return $this->handleCartRequest($request);
|
||||
}
|
||||
|
||||
final protected function getCart() {
|
||||
return $this->cart;
|
||||
}
|
||||
|
||||
final protected function getMerchantAuthority() {
|
||||
return $this->merchantAuthority;
|
||||
}
|
||||
|
||||
final protected function hasMerchantAuthority() {
|
||||
return (bool)$this->merchantAuthority;
|
||||
}
|
||||
|
||||
final protected function hasAccountAuthority() {
|
||||
return (bool)PhabricatorPolicyFilter::hasCapability(
|
||||
$this->getViewer(),
|
||||
$this->getCart(),
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneCartListController
|
||||
extends PhortuneController {
|
||||
|
||||
private $merchant;
|
||||
private $account;
|
||||
private $subscription;
|
||||
private $engine;
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$merchant_id = $request->getURIData('merchantID');
|
||||
$account_id = $request->getURIData('accountID');
|
||||
$subscription_id = $request->getURIData('subscriptionID');
|
||||
|
||||
$engine = id(new PhortuneCartSearchEngine())
|
||||
->setViewer($viewer);
|
||||
|
||||
if ($merchant_id) {
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($merchant_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->merchant = $merchant;
|
||||
$viewer->grantAuthority($merchant);
|
||||
$engine->setMerchant($merchant);
|
||||
} else if ($account_id) {
|
||||
$account = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($account_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->account = $account;
|
||||
$engine->setAccount($account);
|
||||
} else {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
// NOTE: We must process this after processing the merchant authority, so
|
||||
// it becomes visible in merchant contexts.
|
||||
if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($subscription_id))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->subscription = $subscription;
|
||||
$engine->setSubscription($subscription);
|
||||
}
|
||||
|
||||
$this->engine = $engine;
|
||||
|
||||
$controller = id(new PhabricatorApplicationSearchController())
|
||||
->setQueryKey($request->getURIData('queryKey'))
|
||||
->setSearchEngine($engine)
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
public function buildSideNavView() {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
$this->engine->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$subscription = $this->subscription;
|
||||
|
||||
$merchant = $this->merchant;
|
||||
if ($merchant) {
|
||||
$id = $merchant->getID();
|
||||
$this->addMerchantCrumb($crumbs, $merchant);
|
||||
if (!$subscription) {
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Orders'),
|
||||
$this->getApplicationURI("merchant/orders/{$id}/"));
|
||||
}
|
||||
}
|
||||
|
||||
$account = $this->account;
|
||||
if ($account) {
|
||||
$id = $account->getID();
|
||||
$this->addAccountCrumb($crumbs, $account);
|
||||
if (!$subscription) {
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Orders'),
|
||||
$this->getApplicationURI("{$id}/order/"));
|
||||
}
|
||||
}
|
||||
|
||||
if ($subscription) {
|
||||
if ($merchant) {
|
||||
$subscription_uri = $subscription->getMerchantURI();
|
||||
} else {
|
||||
$subscription_uri = $subscription->getURI();
|
||||
}
|
||||
$crumbs->addTextCrumb(
|
||||
$subscription->getSubscriptionName(),
|
||||
$subscription_uri);
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,25 +3,20 @@
|
|||
final class PhortuneCartUpdateController
|
||||
extends PhortuneCartController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function shouldRequireMerchantAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$authority = $this->loadMerchantAuthority();
|
||||
|
||||
$cart_query = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPurchases(true);
|
||||
|
||||
if ($authority) {
|
||||
$cart_query->withMerchantPHIDs(array($authority->getPHID()));
|
||||
}
|
||||
|
||||
$cart = $cart_query->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$cart = $this->getCart();
|
||||
$authority = $this->getMerchantAuthority();
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
->setViewer($viewer)
|
||||
|
@ -60,7 +55,7 @@ final class PhortuneCartUpdateController
|
|||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($cart->getDetailURI($authority));
|
||||
->setURI($cart->getDetailURI());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,312 +3,111 @@
|
|||
final class PhortuneCartViewController
|
||||
extends PhortuneCartController {
|
||||
|
||||
private $action = null;
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireMerchantAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$this->action = $request->getURIData('action');
|
||||
$order = $this->getCart();
|
||||
$authority = $this->getMerchantAuthority();
|
||||
$can_edit = $this->hasAccountAuthority();
|
||||
|
||||
$authority = $this->loadMerchantAuthority();
|
||||
require_celerity_resource('phortune-css');
|
||||
$is_printable = ($request->getURIData('action') === 'print');
|
||||
|
||||
$query = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPurchases(true);
|
||||
|
||||
if ($authority) {
|
||||
$query->withMerchantPHIDs(array($authority->getPHID()));
|
||||
}
|
||||
|
||||
$cart = $query->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cart_table = $this->buildCartContentTable($cart);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$cart,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$errors = array();
|
||||
$error_view = null;
|
||||
$resume_uri = null;
|
||||
switch ($cart->getStatus()) {
|
||||
case PhortuneCart::STATUS_READY:
|
||||
if ($authority && $cart->getIsInvoice()) {
|
||||
// We arrived here by following the ad-hoc invoice workflow, and
|
||||
// are acting with merchant authority.
|
||||
|
||||
$checkout_uri = PhabricatorEnv::getURI($cart->getCheckoutURI());
|
||||
|
||||
$invoice_message = array(
|
||||
pht(
|
||||
'Manual invoices do not automatically notify recipients yet. '.
|
||||
'Send the payer this checkout link:'),
|
||||
' ',
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $checkout_uri,
|
||||
),
|
||||
$checkout_uri),
|
||||
);
|
||||
|
||||
$error_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||
->setErrors(array($invoice_message));
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_PURCHASING:
|
||||
if ($can_edit) {
|
||||
$resume_uri = $cart->getMetadataValue('provider.checkoutURI');
|
||||
if ($resume_uri) {
|
||||
$errors[] = pht(
|
||||
'The checkout process has been started, but not yet completed. '.
|
||||
'You can continue checking out by clicking %s, or cancel the '.
|
||||
'order, or contact the merchant for assistance.',
|
||||
phutil_tag('strong', array(), pht('Continue Checkout')));
|
||||
} else {
|
||||
$errors[] = pht(
|
||||
'The checkout process has been started, but an error occurred. '.
|
||||
'You can cancel the order or contact the merchant for '.
|
||||
'assistance.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_CHARGED:
|
||||
if ($can_edit) {
|
||||
$errors[] = pht(
|
||||
'You have been charged, but processing could not be completed. '.
|
||||
'You can cancel your order, or contact the merchant for '.
|
||||
'assistance.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_HOLD:
|
||||
if ($can_edit) {
|
||||
$errors[] = pht(
|
||||
'Payment for this order is on hold. You can click %s to check '.
|
||||
'for updates, cancel the order, or contact the merchant for '.
|
||||
'assistance.',
|
||||
phutil_tag('strong', array(), pht('Update Status')));
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_REVIEW:
|
||||
if ($authority) {
|
||||
$errors[] = pht(
|
||||
'This order has been flagged for manual review. Review the order '.
|
||||
'and choose %s to accept it or %s to reject it.',
|
||||
phutil_tag('strong', array(), pht('Accept Order')),
|
||||
phutil_tag('strong', array(), pht('Refund Order')));
|
||||
} else if ($can_edit) {
|
||||
$errors[] = pht(
|
||||
'This order requires manual processing and will complete once '.
|
||||
'the merchant accepts it.');
|
||||
}
|
||||
break;
|
||||
case PhortuneCart::STATUS_PURCHASED:
|
||||
$error_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_SUCCESS)
|
||||
->appendChild(pht('This purchase has been completed.'));
|
||||
break;
|
||||
if ($order->getStatus() === PhortuneCart::STATUS_PURCHASING) {
|
||||
if ($can_edit) {
|
||||
$resume_uri = $order->getMetadataValue('provider.checkoutURI');
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
$error_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||
->appendChild($errors);
|
||||
}
|
||||
|
||||
$details = $this->buildDetailsView($cart);
|
||||
$curtain = $this->buildCurtainView(
|
||||
$cart,
|
||||
$can_edit,
|
||||
$authority,
|
||||
$resume_uri);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setHeader($cart->getName())
|
||||
->setHeaderIcon('fa-shopping-cart');
|
||||
->setHeader($order->getName())
|
||||
->setHeaderIcon('fa-shopping-bag');
|
||||
|
||||
if ($cart->getStatus() == PhortuneCart::STATUS_PURCHASED) {
|
||||
$done_uri = $cart->getDoneURI();
|
||||
if ($order->getStatus() == PhortuneCart::STATUS_PURCHASED) {
|
||||
$done_uri = $order->getDoneURI();
|
||||
if ($done_uri) {
|
||||
$header->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($done_uri)
|
||||
->setIcon('fa-check-square green')
|
||||
->setText($cart->getDoneActionName()));
|
||||
->setText($order->getDoneActionName()));
|
||||
}
|
||||
}
|
||||
|
||||
$cart_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Cart Items'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($cart_table);
|
||||
|
||||
$description = $this->renderCartDescription($cart);
|
||||
|
||||
$charges = id(new PhortuneChargeQuery())
|
||||
$order_view = id(new PhortuneOrderSummaryView())
|
||||
->setViewer($viewer)
|
||||
->withCartPHIDs(array($cart->getPHID()))
|
||||
->needCarts(true)
|
||||
->execute();
|
||||
->setOrder($order)
|
||||
->setResumeURI($resume_uri)
|
||||
->setPrintable($is_printable);
|
||||
|
||||
$phids = array();
|
||||
foreach ($charges as $charge) {
|
||||
$phids[] = $charge->getProviderPHID();
|
||||
$phids[] = $charge->getCartPHID();
|
||||
$phids[] = $charge->getMerchantPHID();
|
||||
$phids[] = $charge->getPaymentMethodPHID();
|
||||
}
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
$crumbs = null;
|
||||
$curtain = null;
|
||||
|
||||
$charges_table = id(new PhortuneChargeTableView())
|
||||
->setUser($viewer)
|
||||
->setHandles($handles)
|
||||
->setCharges($charges)
|
||||
->setShowOrder(false);
|
||||
$main = array();
|
||||
$tail = array();
|
||||
|
||||
$charges = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Charges'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($charges_table);
|
||||
require_celerity_resource('phortune-invoice-css');
|
||||
|
||||
$account = $cart->getAccount();
|
||||
if ($is_printable) {
|
||||
$body_class = 'phortune-invoice-view';
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
if ($authority) {
|
||||
$this->addMerchantCrumb($crumbs, $authority);
|
||||
$tail[] = $order_view;
|
||||
} else {
|
||||
$this->addAccountCrumb($crumbs, $cart->getAccount());
|
||||
$body_class = 'phortune-cart-page';
|
||||
|
||||
$curtain = $this->buildCurtainView(
|
||||
$order,
|
||||
$can_edit,
|
||||
$authority,
|
||||
$resume_uri);
|
||||
|
||||
$account = $order->getAccount();
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($account->getName(), $account->getURI())
|
||||
->addTextCrumb(pht('Orders'), $account->getOrdersURI())
|
||||
->addTextCrumb($order->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline($order)
|
||||
->setShouldTerminate(true);
|
||||
|
||||
$main[] = $order_view;
|
||||
$main[] = $timeline;
|
||||
}
|
||||
$crumbs->addTextCrumb(pht('Cart %d', $cart->getID()));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
if (!$this->action) {
|
||||
$class = 'phortune-cart-page';
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$cart,
|
||||
new PhortuneCartTransactionQuery());
|
||||
$timeline
|
||||
->setShouldTerminate(true);
|
||||
$column_view = id(new PHUITwoColumnView())
|
||||
->setMainColumn($main)
|
||||
->setFooter($tail);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$error_view,
|
||||
$details,
|
||||
$cart_box,
|
||||
$description,
|
||||
$charges,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
} else {
|
||||
$class = 'phortune-invoice-view';
|
||||
$crumbs = null;
|
||||
$merchant_phid = $cart->getMerchantPHID();
|
||||
$buyer_phid = $cart->getAuthorPHID();
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($merchant_phid))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
$buyer = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($buyer_phid))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
|
||||
$merchant_contact = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$merchant->getContactInfo());
|
||||
|
||||
$account_name = $account->getBillingName();
|
||||
if (!strlen($account_name)) {
|
||||
$account_name = $buyer->getRealName();
|
||||
}
|
||||
|
||||
$account_contact = $account->getBillingAddress();
|
||||
if (strlen($account_contact)) {
|
||||
$account_contact = new PHUIRemarkupView(
|
||||
$viewer,
|
||||
$account_contact);
|
||||
}
|
||||
|
||||
$view = id(new PhortuneInvoiceView())
|
||||
->setMerchantName($merchant->getName())
|
||||
->setMerchantLogo($merchant->getProfileImageURI())
|
||||
->setMerchantContact($merchant_contact)
|
||||
->setMerchantFooter($merchant->getInvoiceFooter())
|
||||
->setAccountName($account_name)
|
||||
->setAccountContact($account_contact)
|
||||
->setStatus($error_view)
|
||||
->setContent(
|
||||
array(
|
||||
$details,
|
||||
$cart_box,
|
||||
$charges,
|
||||
));
|
||||
if ($curtain) {
|
||||
$column_view->setCurtain($curtain);
|
||||
}
|
||||
|
||||
$page = $this->newPage()
|
||||
->setTitle(pht('Cart %d', $cart->getID()))
|
||||
->addClass($class)
|
||||
->appendChild($view);
|
||||
->addClass($body_class)
|
||||
->setTitle(
|
||||
array(
|
||||
$order->getObjectName(),
|
||||
$order->getName(),
|
||||
))
|
||||
->appendChild($column_view);
|
||||
|
||||
if ($crumbs) {
|
||||
$page->setCrumbs($crumbs);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
private function buildDetailsView(PhortuneCart $cart) {
|
||||
$viewer = $this->getViewer();
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($cart);
|
||||
|
||||
$handles = $this->loadViewerHandles(
|
||||
array(
|
||||
$cart->getAccountPHID(),
|
||||
$cart->getAuthorPHID(),
|
||||
$cart->getMerchantPHID(),
|
||||
));
|
||||
|
||||
if ($this->action == 'print') {
|
||||
$view->addProperty(pht('Order Name'), $cart->getName());
|
||||
}
|
||||
|
||||
$view->addProperty(
|
||||
pht('Account'),
|
||||
$handles[$cart->getAccountPHID()]->renderLink());
|
||||
$view->addProperty(
|
||||
pht('Authorized By'),
|
||||
$handles[$cart->getAuthorPHID()]->renderLink());
|
||||
$view->addProperty(
|
||||
pht('Merchant'),
|
||||
$handles[$cart->getMerchantPHID()]->renderLink());
|
||||
$view->addProperty(
|
||||
pht('Status'),
|
||||
PhortuneCart::getNameForStatus($cart->getStatus()));
|
||||
$view->addProperty(
|
||||
pht('Updated'),
|
||||
phabricator_datetime($cart->getDateModified(), $viewer));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(
|
||||
PhortuneCart $cart,
|
||||
$can_edit,
|
||||
|
@ -318,20 +117,43 @@ final class PhortuneCartViewController
|
|||
$viewer = $this->getViewer();
|
||||
$id = $cart->getID();
|
||||
$curtain = $this->newCurtainView($cart);
|
||||
$status = $cart->getStatus();
|
||||
|
||||
$is_ready = ($status === PhortuneCart::STATUS_READY);
|
||||
|
||||
$can_cancel = ($can_edit && $cart->canCancelOrder());
|
||||
$can_checkout = ($can_edit && $is_ready);
|
||||
$can_accept = ($status === PhortuneCart::STATUS_REVIEW);
|
||||
$can_refund = ($authority && $cart->canRefundOrder());
|
||||
$can_void = ($authority && $cart->canVoidOrder());
|
||||
|
||||
if ($authority) {
|
||||
$prefix = 'merchant/'.$authority->getID().'/';
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
$cancel_uri = $this->getApplicationURI("cart/{$id}/cancel/");
|
||||
$refund_uri = $this->getApplicationURI("cart/{$id}/refund/");
|
||||
$update_uri = $this->getApplicationURI("cart/{$id}/update/");
|
||||
$accept_uri = $this->getApplicationURI("cart/{$id}/accept/");
|
||||
$print_uri = $this->getApplicationURI("cart/{$id}/print/");
|
||||
$checkout_uri = $cart->getCheckoutURI();
|
||||
$void_uri = $this->getApplicationURI("cart/{$id}/void/");
|
||||
|
||||
$cancel_uri = $this->getApplicationURI("{$prefix}cart/{$id}/cancel/");
|
||||
$refund_uri = $this->getApplicationURI("{$prefix}cart/{$id}/refund/");
|
||||
$update_uri = $this->getApplicationURI("{$prefix}cart/{$id}/update/");
|
||||
$accept_uri = $this->getApplicationURI("{$prefix}cart/{$id}/accept/");
|
||||
$print_uri = $this->getApplicationURI("{$prefix}cart/{$id}/print/");
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Printable Version'))
|
||||
->setHref($print_uri)
|
||||
->setOpenInNewWindow(true)
|
||||
->setIcon('fa-print'));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Pay Now'))
|
||||
->setIcon('fa-credit-card')
|
||||
->setDisabled(!$can_checkout)
|
||||
->setWorkflow(!$can_checkout)
|
||||
->setHref($checkout_uri));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
|
@ -341,24 +163,6 @@ final class PhortuneCartViewController
|
|||
->setWorkflow(true)
|
||||
->setHref($cancel_uri));
|
||||
|
||||
if ($authority) {
|
||||
if ($cart->getStatus() == PhortuneCart::STATUS_REVIEW) {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Accept Order'))
|
||||
->setIcon('fa-check')
|
||||
->setWorkflow(true)
|
||||
->setHref($accept_uri));
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Refund Order'))
|
||||
->setIcon('fa-reply')
|
||||
->setWorkflow(true)
|
||||
->setHref($refund_uri));
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Update Status'))
|
||||
|
@ -369,16 +173,39 @@ final class PhortuneCartViewController
|
|||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Continue Checkout'))
|
||||
->setIcon('fa-shopping-cart')
|
||||
->setIcon('fa-shopping-bag')
|
||||
->setHref($resume_uri));
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Printable Version'))
|
||||
->setHref($print_uri)
|
||||
->setOpenInNewWindow(true)
|
||||
->setIcon('fa-print'));
|
||||
if ($authority) {
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Accept Order'))
|
||||
->setIcon('fa-check')
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_accept)
|
||||
->setHref($accept_uri));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Refund Order'))
|
||||
->setIcon('fa-reply')
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_refund)
|
||||
->setHref($refund_uri));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Void Invoice'))
|
||||
->setIcon('fa-times')
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_void)
|
||||
->setHref($void_uri));
|
||||
}
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneCartVoidController
|
||||
extends PhortuneCartController {
|
||||
|
||||
protected function shouldRequireAccountAuthority() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function shouldRequireMerchantAuthority() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleCartRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$cart = $this->getCart();
|
||||
|
||||
$cancel_uri = $cart->getDetailURI();
|
||||
|
||||
try {
|
||||
$title = pht('Unable to Void Invoice');
|
||||
$cart->assertCanVoidOrder();
|
||||
} catch (Exception $ex) {
|
||||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->appendChild($ex->getMessage())
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Void Invoice?'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Really void this invoice? The customer will no longer be asked '.
|
||||
'to submit payment for it.'))
|
||||
->addCancelButton($cancel_uri)
|
||||
->addSubmitButton(pht('Void Invoice'));
|
||||
}
|
||||
}
|
172
src/applications/phortune/controller/external/PhortuneExternalController.php
vendored
Normal file
172
src/applications/phortune/controller/external/PhortuneExternalController.php
vendored
Normal file
|
@ -0,0 +1,172 @@
|
|||
<?php
|
||||
|
||||
abstract class PhortuneExternalController
|
||||
extends PhortuneController {
|
||||
|
||||
private $email;
|
||||
|
||||
final public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract protected function handleExternalRequest(AphrontRequest $request);
|
||||
|
||||
final protected function hasAccountEmail() {
|
||||
return (bool)$this->email;
|
||||
}
|
||||
|
||||
final protected function getAccountEmail() {
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
final protected function getExternalViewer() {
|
||||
return PhabricatorUser::getOmnipotentUser();
|
||||
}
|
||||
|
||||
final public function handleRequest(AphrontRequest $request) {
|
||||
$address_key = $request->getURIData('addressKey');
|
||||
$access_key = $request->getURIData('accessKey');
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$xviewer = $this->getExternalViewer();
|
||||
|
||||
$email = id(new PhortuneAccountEmailQuery())
|
||||
->setViewer($xviewer)
|
||||
->withAddressKeys(array($address_key))
|
||||
->executeOne();
|
||||
if (!$email) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$account = $email->getAccount();
|
||||
|
||||
$can_see = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$account,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$email_display = phutil_tag('strong', array(), $email->getAddress());
|
||||
$user_display = phutil_tag('strong', array(), $viewer->getUsername());
|
||||
|
||||
$actual_key = $email->getAccessKey();
|
||||
if (!phutil_hashes_are_identical($access_key, $actual_key)) {
|
||||
$dialog = $this->newDialog()
|
||||
->setTitle(pht('Email Access Link Out of Date'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You are trying to access this payment account as: %s',
|
||||
$email_display))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'The access link you have followed is out of date and no longer '.
|
||||
'works.'));
|
||||
|
||||
if ($can_see) {
|
||||
$dialog->appendParagraph(
|
||||
pht(
|
||||
'You are currently logged in as a user (%s) who has '.
|
||||
'permission to manage the payment account, so you can '.
|
||||
'continue to the updated link.',
|
||||
$user_display));
|
||||
|
||||
$dialog->addCancelButton(
|
||||
$email->getExternalURI(),
|
||||
pht('Continue to Updated Link'));
|
||||
} else {
|
||||
$dialog->appendParagraph(
|
||||
pht(
|
||||
'To access information about this payment account, follow '.
|
||||
'a more recent link or ask a user with access to give you '.
|
||||
'an updated link.'));
|
||||
}
|
||||
|
||||
return $dialog;
|
||||
}
|
||||
|
||||
switch ($email->getStatus()) {
|
||||
case PhortuneAccountEmailStatus::STATUS_ACTIVE:
|
||||
break;
|
||||
case PhortuneAccountEmailStatus::STATUS_DISABLED:
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Address Disabled'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This email address (%s) has been disabled and no longer has '.
|
||||
'access to this payment account.',
|
||||
$email_display));
|
||||
case PhortuneAccountEmailStatus::STATUS_UNSUBSCRIBED:
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Permanently Unsubscribed'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This email address (%s) has been permanently unsubscribed '.
|
||||
'and no longer has access to this payment account.',
|
||||
$email_display));
|
||||
break;
|
||||
default:
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->email = $email;
|
||||
|
||||
return $this->handleExternalRequest($request);
|
||||
}
|
||||
|
||||
final protected function newExternalCrumbs() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$crumbs = new PHUICrumbsView();
|
||||
|
||||
if ($this->hasAccountEmail()) {
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$crumb_name = pht(
|
||||
'Payment Account: %s',
|
||||
$account->getName());
|
||||
|
||||
$crumb = id(new PHUICrumbView())
|
||||
->setIcon('fa-diamond')
|
||||
->setName($crumb_name)
|
||||
->setHref($email->getExternalURI());
|
||||
|
||||
$crumbs
|
||||
->addCrumb($crumb);
|
||||
} else {
|
||||
$crumb = id(new PHUICrumbView())
|
||||
->setIcon('fa-diamond')
|
||||
->setText(pht('External Account View'));
|
||||
|
||||
$crumbs->addCrumb($crumb);
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
final protected function newExternalView() {
|
||||
$email = $this->getAccountEmail();
|
||||
$xviewer = $this->getExternalViewer();
|
||||
|
||||
$origin_phid = $email->getAuthorPHID();
|
||||
|
||||
$handles = $xviewer->loadHandles(array($origin_phid));
|
||||
|
||||
|
||||
$messages = array();
|
||||
$messages[] = pht(
|
||||
'You are viewing this payment account as: %s',
|
||||
phutil_tag('strong', array(), $email->getAddress()));
|
||||
|
||||
$messages[] = pht(
|
||||
'This email address was added to this payment account by: %s',
|
||||
phutil_tag('strong', array(), $handles[$origin_phid]->getFullName()));
|
||||
|
||||
$messages[] = pht(
|
||||
'Anyone who has a link to this page can view order history for '.
|
||||
'this payment account.');
|
||||
|
||||
return id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
|
||||
->setErrors($messages);
|
||||
}
|
||||
}
|
98
src/applications/phortune/controller/external/PhortuneExternalOrderController.php
vendored
Normal file
98
src/applications/phortune/controller/external/PhortuneExternalOrderController.php
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneExternalOrderController
|
||||
extends PhortuneExternalController {
|
||||
|
||||
protected function handleExternalRequest(AphrontRequest $request) {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$order = id(new PhortuneCartQuery())
|
||||
->setViewer($xviewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($request->getURIData('orderID')))
|
||||
->executeOne();
|
||||
if (!$order) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$is_printable = ($request->getURIData('action') === 'print');
|
||||
|
||||
$order_view = id(new PhortuneOrderSummaryView())
|
||||
->setViewer($xviewer)
|
||||
->setOrder($order)
|
||||
->setPrintable($is_printable);
|
||||
|
||||
$crumbs = null;
|
||||
$curtain = null;
|
||||
|
||||
$main = array();
|
||||
$tail = array();
|
||||
|
||||
require_celerity_resource('phortune-invoice-css');
|
||||
|
||||
if ($is_printable) {
|
||||
$body_class = 'phortune-invoice-view';
|
||||
|
||||
$tail[] = $order_view;
|
||||
} else {
|
||||
$body_class = 'phortune-cart-page';
|
||||
|
||||
$curtain = $this->newCurtain($order);
|
||||
|
||||
$crumbs = $this->newExternalCrumbs()
|
||||
->addTextCrumb($order->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline($order)
|
||||
->setShouldTerminate(true);
|
||||
|
||||
$main[] = $order_view;
|
||||
$main[] = $timeline;
|
||||
}
|
||||
|
||||
$column_view = id(new PHUITwoColumnView())
|
||||
->setMainColumn($main)
|
||||
->setFooter($tail);
|
||||
|
||||
if ($curtain) {
|
||||
$column_view->setCurtain($curtain);
|
||||
}
|
||||
|
||||
$page = $this->newPage()
|
||||
->addClass($body_class)
|
||||
->setTitle(
|
||||
array(
|
||||
$order->getObjectName(),
|
||||
$order->getName(),
|
||||
))
|
||||
->appendChild($column_view);
|
||||
|
||||
if ($crumbs) {
|
||||
$page->setCrumbs($crumbs);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
|
||||
private function newCurtain(PhortuneCart $order) {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
|
||||
$curtain = $this->newCurtainView($order);
|
||||
|
||||
$print_uri = $email->getExternalOrderPrintURI($order);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Printable Version'))
|
||||
->setHref($print_uri)
|
||||
->setOpenInNewWindow(true)
|
||||
->setIcon('fa-print'));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
}
|
101
src/applications/phortune/controller/external/PhortuneExternalOverviewController.php
vendored
Normal file
101
src/applications/phortune/controller/external/PhortuneExternalOverviewController.php
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneExternalOverviewController
|
||||
extends PhortuneExternalController {
|
||||
|
||||
protected function handleExternalRequest(AphrontRequest $request) {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$crumbs = $this->newExternalCrumbs()
|
||||
->addTextCrumb(pht('Viewing As "%s"', $email->getAddress()))
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices and Receipts: %s', $account->getName()))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-times')
|
||||
->setText(pht('Unsubscribe'))
|
||||
->setHref($email->getUnsubscribeURI())
|
||||
->setWorkflow(true));
|
||||
|
||||
$external_view = $this->newExternalView();
|
||||
$invoices_view = $this->newInvoicesView();
|
||||
$receipts_view = $this->newReceiptsView();
|
||||
|
||||
$column_view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$external_view,
|
||||
$invoices_view,
|
||||
$receipts_view,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setCrumbs($crumbs)
|
||||
->setTitle(
|
||||
array(
|
||||
pht('Invoices and Receipts'),
|
||||
$account->getName(),
|
||||
))
|
||||
->appendChild($column_view);
|
||||
}
|
||||
|
||||
private function newInvoicesView() {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$invoices = id(new PhortuneCartQuery())
|
||||
->setViewer($xviewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(true)
|
||||
->execute();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Invoices'));
|
||||
|
||||
$invoices_table = id(new PhortuneOrderTableView())
|
||||
->setViewer($xviewer)
|
||||
->setAccountEmail($email)
|
||||
->setCarts($invoices)
|
||||
->setIsInvoices(true);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($invoices_table);
|
||||
}
|
||||
|
||||
private function newReceiptsView() {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$receipts = id(new PhortuneCartQuery())
|
||||
->setViewer($xviewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withInvoices(false)
|
||||
->execute();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Receipts'));
|
||||
|
||||
$receipts_table = id(new PhortuneOrderTableView())
|
||||
->setViewer($xviewer)
|
||||
->setAccountEmail($email)
|
||||
->setCarts($receipts);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($receipts_table);
|
||||
}
|
||||
|
||||
}
|
67
src/applications/phortune/controller/external/PhortuneExternalUnsubscribeController.php
vendored
Normal file
67
src/applications/phortune/controller/external/PhortuneExternalUnsubscribeController.php
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneExternalUnsubscribeController
|
||||
extends PhortuneExternalController {
|
||||
|
||||
protected function handleExternalRequest(AphrontRequest $request) {
|
||||
$xviewer = $this->getExternalViewer();
|
||||
$email = $this->getAccountEmail();
|
||||
$account = $email->getAccount();
|
||||
|
||||
$email_uri = $email->getExternalURI();
|
||||
|
||||
if ($request->isFormOrHisecPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $email->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortuneAccountEmailStatusTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(PhortuneAccountEmailStatus::STATUS_UNSUBSCRIBED);
|
||||
|
||||
$email->getApplicationTransactionEditor()
|
||||
->setActor($xviewer)
|
||||
->setActingAsPHID($email->getPHID())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setCancelURI($email_uri)
|
||||
->applyTransactions($email, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($email_uri);
|
||||
}
|
||||
|
||||
$email_display = phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$email->getAddress());
|
||||
|
||||
$account_display = phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$account->getName());
|
||||
|
||||
$submit = pht(
|
||||
'Permanently Unsubscribe (%s)',
|
||||
$email->getAddress());
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Permanently Unsubscribe'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Permanently unsubscribe this email address (%s) from this '.
|
||||
'payment account (%s)?',
|
||||
$email_display,
|
||||
$account_display))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You will no longer receive email and access links will no longer '.
|
||||
'function.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'This action is permanent and can not be undone.'))
|
||||
->addCancelButton($email_uri)
|
||||
->addSubmitButton($submit);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +1,23 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantAddManagerController extends PhortuneController {
|
||||
final class PhortuneMerchantAddManagerController
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needProfileImage(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$v_members = array();
|
||||
$e_members = null;
|
||||
$merchant_uri = $this->getApplicationURI("/merchant/manager/{$id}/");
|
||||
$merchant_uri = $merchant->getManagersURI();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
if ($request->isFormOrHiSecPost()) {
|
||||
$xactions = array();
|
||||
$v_members = $request->getArr('memberPHIDs');
|
||||
$v_members = $request->getArr('managerPHIDs');
|
||||
$type_edge = PhabricatorTransactions::TYPE_EDGE;
|
||||
|
||||
$xactions[] = id(new PhortuneMerchantTransaction())
|
||||
|
@ -59,13 +50,13 @@ final class PhortuneMerchantAddManagerController extends PhortuneController {
|
|||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new PhabricatorPeopleDatasource())
|
||||
->setLabel(pht('Members'))
|
||||
->setName('memberPHIDs')
|
||||
->setLabel(pht('New Managers'))
|
||||
->setName('managerPHIDs')
|
||||
->setValue($v_members)
|
||||
->setError($e_members));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Manager'))
|
||||
->setTitle(pht('Add New Managers'))
|
||||
->appendForm($form)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->addCancelButton($merchant_uri)
|
||||
|
|
|
@ -3,11 +3,80 @@
|
|||
abstract class PhortuneMerchantController
|
||||
extends PhortuneController {
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Merchants'),
|
||||
$this->getApplicationURI('merchant/'));
|
||||
return $crumbs;
|
||||
private $merchant;
|
||||
|
||||
final protected function setMerchant(PhortuneMerchant $merchant) {
|
||||
$this->merchant = $merchant;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final protected function getMerchant() {
|
||||
return $this->merchant;
|
||||
}
|
||||
|
||||
final protected function hasMerchant() {
|
||||
return (bool)$this->merchant;
|
||||
}
|
||||
|
||||
final public function handleRequest(AphrontRequest $request) {
|
||||
if ($this->shouldRequireMerchantEditCapability()) {
|
||||
$response = $this->loadMerchantForEdit();
|
||||
} else {
|
||||
$response = $this->loadMerchantForView();
|
||||
}
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return $this->handleMerchantRequest($request);
|
||||
}
|
||||
|
||||
abstract protected function shouldRequireMerchantEditCapability();
|
||||
abstract protected function handleMerchantRequest(AphrontRequest $request);
|
||||
|
||||
private function loadMerchantForEdit() {
|
||||
return $this->loadMerchantWithCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
));
|
||||
}
|
||||
|
||||
private function loadMerchantForView() {
|
||||
return $this->loadMerchantWithCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
));
|
||||
}
|
||||
|
||||
private function loadMerchantWithCapabilities(array $capabilities) {
|
||||
$viewer = $this->getViewer();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$merchant_id = $request->getURIData('merchantID');
|
||||
if (!$merchant_id) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Controller ("%s") extends controller "%s", but is reachable '.
|
||||
'with no "merchantID" in URI.',
|
||||
get_class($this),
|
||||
__CLASS__));
|
||||
}
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($merchant_id))
|
||||
->needProfileImage(true)
|
||||
->requireCapabilities($capabilities)
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setMerchant($merchant);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantDetailsController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Account Details'))
|
||||
->setBorder(true);
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$title = pht(
|
||||
'%s %s',
|
||||
$merchant->getObjectName(),
|
||||
$merchant->getName());
|
||||
|
||||
$details = $this->buildDetailsView($merchant);
|
||||
$curtain = $this->buildCurtainView($merchant);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$merchant,
|
||||
new PhortuneMerchantTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$navigation = $this->buildSideNavView('details');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$details,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildDetailsView(PhortuneMerchant $merchant) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($merchant);
|
||||
|
||||
$invoice_from = $merchant->getInvoiceEmail();
|
||||
if (!$invoice_from) {
|
||||
$invoice_from = pht('No email address set');
|
||||
$invoice_from = phutil_tag('em', array(), $invoice_from);
|
||||
}
|
||||
$view->addProperty(pht('Invoice From'), $invoice_from);
|
||||
|
||||
$description = $merchant->getDescription();
|
||||
if (strlen($description)) {
|
||||
$description = new PHUIRemarkupView($viewer, $description);
|
||||
$view->addSectionHeader(
|
||||
pht('Description'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($description);
|
||||
}
|
||||
|
||||
$contact_info = $merchant->getContactInfo();
|
||||
if (strlen($contact_info)) {
|
||||
$contact_info = new PHUIRemarkupView($viewer, $contact_info);
|
||||
$view->addSectionHeader(
|
||||
pht('Contact Information'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($contact_info);
|
||||
}
|
||||
|
||||
$footer_info = $merchant->getInvoiceFooter();
|
||||
if (strlen($footer_info)) {
|
||||
$footer_info = new PHUIRemarkupView($viewer, $footer_info);
|
||||
$view->addSectionHeader(
|
||||
pht('Invoice Footer'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($footer_info);
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortuneMerchant $merchant) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$id = $merchant->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$merchant,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$curtain = $this->newCurtainView($merchant);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Merchant'))
|
||||
->setIcon('fa-pencil')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setHref($this->getApplicationURI("merchant/edit/{$id}/")));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Logo'))
|
||||
->setIcon('fa-picture-o')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setHref($this->getApplicationURI("merchant/{$id}/picture/edit/")));
|
||||
|
||||
$member_phids = $merchant->getMemberPHIDs();
|
||||
$handles = $viewer->loadHandles($member_phids);
|
||||
|
||||
$member_list = id(new PHUIObjectItemListView())
|
||||
->setSimple(true);
|
||||
|
||||
foreach ($member_phids as $member_phid) {
|
||||
$image_uri = $handles[$member_phid]->getImageURI();
|
||||
$image_href = $handles[$member_phid]->getURI();
|
||||
$person = $handles[$member_phid];
|
||||
|
||||
$member = id(new PHUIObjectItemView())
|
||||
->setImageURI($image_uri)
|
||||
->setHref($image_href)
|
||||
->setHeader($person->getFullName());
|
||||
|
||||
$member_list->addItem($member);
|
||||
}
|
||||
|
||||
$curtain->newPanel()
|
||||
->setHeaderText(pht('Managers'))
|
||||
->appendChild($member_list);
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantEditController
|
||||
extends PhortuneMerchantController {
|
||||
extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
return id(new PhortuneMerchantEditEngine())
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantInvoiceCreateController
|
||||
extends PhortuneMerchantProfileController {
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
// TODO: Make this work again, or destroy it.
|
||||
return new Aphront404Response();
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$merchant = $this->loadMerchantAuthority();
|
||||
|
@ -58,9 +65,10 @@ final class PhortuneMerchantInvoiceCreateController
|
|||
}
|
||||
|
||||
if (!$target_account) {
|
||||
$accounts = PhortuneAccountQuery::loadAccountsForUser(
|
||||
$target_user,
|
||||
PhabricatorContentSource::newFromRequest($request));
|
||||
$accounts = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withMemberPHIDs(array($target_user->getPHID()))
|
||||
->execute();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
|
|
|
@ -1,37 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantListController
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$querykey = $request->getURIData('queryKey');
|
||||
|
||||
$controller = id(new PhabricatorApplicationSearchController())
|
||||
->setQueryKey($querykey)
|
||||
->setSearchEngine(new PhortuneMerchantSearchEngine())
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
public function buildSideNavView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
id(new PhortuneMerchantSearchEngine())
|
||||
->setViewer($viewer)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
return id(new PhortuneMerchantSearchEngine())
|
||||
->setController($this)
|
||||
->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
|
|
|
@ -1,35 +1,29 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantManagerController
|
||||
final class PhortuneMerchantManagersController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setMerchant($merchant);
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Managers'));
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Managers'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$members = $this->buildMembersSection($merchant);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$members,
|
||||
));
|
||||
->setFooter(
|
||||
array(
|
||||
$members,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('managers');
|
||||
|
||||
|
@ -38,7 +32,6 @@ final class PhortuneMerchantManagerController
|
|||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildMembersSection(PhortuneMerchant $merchant) {
|
||||
|
@ -51,12 +44,18 @@ final class PhortuneMerchantManagerController
|
|||
|
||||
$id = $merchant->getID();
|
||||
|
||||
$add_uri = urisprintf(
|
||||
'merchant/%d/managers/new/',
|
||||
$merchant->getID());
|
||||
$add_uri = $this->getApplicationURI($add_uri);
|
||||
|
||||
$add = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('New Manager'))
|
||||
->setIcon('fa-plus')
|
||||
->setWorkflow(true)
|
||||
->setHref("/phortune/merchant/manager/add/{$id}/");
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref($add_uri);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Merchant Account Managers'))
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantOrderListController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
private $subscription;
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$engine = id(new PhortuneCartSearchEngine())
|
||||
->setController($this)
|
||||
->setMerchant($merchant);
|
||||
|
||||
$subscription_id = $request->getURIData('subscriptionID');
|
||||
if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($subscription_id))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$engine->setSubscription($subscription);
|
||||
$this->subscription = $subscription;
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$subscription = $this->subscription;
|
||||
if ($subscription) {
|
||||
$crumbs->addTextCrumb(
|
||||
$subscription->getObjectName(),
|
||||
$subscription->getURI());
|
||||
} else if ($this->hasMerchant()) {
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$crumbs->addTextCrumb(pht('Orders'), $merchant->getOrdersURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantOrdersController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$merchant = $this->getMerchant();
|
||||
$title = $merchant->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Orders'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$order_history = $this->newRecentOrdersView($merchant, 100);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$order_history,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('orders');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function newRecentOrdersView(
|
||||
PhortuneMerchant $merchant,
|
||||
$limit) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$carts = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->needPurchases(true)
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortuneCart::STATUS_PURCHASING,
|
||||
PhortuneCart::STATUS_CHARGED,
|
||||
PhortuneCart::STATUS_HOLD,
|
||||
PhortuneCart::STATUS_REVIEW,
|
||||
PhortuneCart::STATUS_PURCHASED,
|
||||
))
|
||||
->setLimit($limit)
|
||||
->execute();
|
||||
|
||||
$orders_uri = $merchant->getOrderListURI();
|
||||
|
||||
$table = id(new PhortuneOrderTableView())
|
||||
->setUser($viewer)
|
||||
->setCarts($carts);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Recent Orders'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($orders_uri)
|
||||
->setText(pht('View All Orders')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantOverviewController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$title = pht(
|
||||
'%s %s',
|
||||
$merchant->getObjectName(),
|
||||
$merchant->getName());
|
||||
|
||||
$providers = id(new PhortunePaymentProviderConfigQuery())
|
||||
->setViewer($viewer)
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->execute();
|
||||
|
||||
$details = $this->buildDetailsView($merchant, $providers);
|
||||
$navigation = $this->buildSideNavView('overview');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$details,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildDetailsView(
|
||||
PhortuneMerchant $merchant,
|
||||
array $providers) {
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($merchant);
|
||||
|
||||
$status_view = new PHUIStatusListView();
|
||||
|
||||
$have_any = false;
|
||||
$any_test = false;
|
||||
foreach ($providers as $provider_config) {
|
||||
$provider = $provider_config->buildProvider();
|
||||
if ($provider->isEnabled()) {
|
||||
$have_any = true;
|
||||
}
|
||||
if (!$provider->isAcceptingLivePayments()) {
|
||||
$any_test = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($have_any) {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Accepts Payments'))
|
||||
->setNote(pht('This merchant can accept payments.')));
|
||||
|
||||
if ($any_test) {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow')
|
||||
->setTarget(pht('Test Mode'))
|
||||
->setNote(pht('This merchant is accepting test payments.')));
|
||||
} else {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Live Mode'))
|
||||
->setNote(pht('This merchant is accepting live payments.')));
|
||||
}
|
||||
} else if ($providers) {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_REJECT, 'red')
|
||||
->setTarget(pht('No Enabled Providers'))
|
||||
->setNote(
|
||||
pht(
|
||||
'All of the payment providers for this merchant are '.
|
||||
'disabled.')));
|
||||
} else {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow')
|
||||
->setTarget(pht('No Providers'))
|
||||
->setNote(
|
||||
pht(
|
||||
'This merchant does not have any payment providers configured '.
|
||||
'yet, so it can not accept payments. Add a provider.')));
|
||||
}
|
||||
|
||||
$view->addProperty(pht('Status'), $status_view);
|
||||
|
||||
$description = $merchant->getDescription();
|
||||
if (strlen($description)) {
|
||||
$description = new PHUIRemarkupView($viewer, $description);
|
||||
$view->addSectionHeader(
|
||||
pht('Description'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($description);
|
||||
}
|
||||
|
||||
$contact_info = $merchant->getContactInfo();
|
||||
if (strlen($contact_info)) {
|
||||
$contact_info = new PHUIRemarkupView($viewer, $contact_info);
|
||||
$view->addSectionHeader(
|
||||
pht('Contact Information'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($contact_info);
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +1,17 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantPictureController
|
||||
extends PhortuneMerchantProfileController {
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needProfileImage(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setMerchant($merchant);
|
||||
$uri = $merchant->getURI();
|
||||
$uri = $merchant->getDetailsURI();
|
||||
|
||||
$supported_formats = PhabricatorFile::getTransformableImageFormats();
|
||||
$e_file = true;
|
||||
|
@ -222,12 +211,9 @@ final class PhortuneMerchantPictureController
|
|||
$upload_box,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView();
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild(
|
||||
array(
|
||||
$view,
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
<?php
|
||||
|
||||
abstract class PhortuneMerchantProfileController
|
||||
extends PhortuneController {
|
||||
|
||||
private $merchant;
|
||||
|
||||
public function setMerchant(PhortuneMerchant $merchant) {
|
||||
$this->merchant = $merchant;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMerchant() {
|
||||
return $this->merchant;
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
protected function buildHeaderView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -26,20 +11,20 @@ abstract class PhortuneMerchantProfileController
|
|||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($merchant)
|
||||
->setImage($merchant->getProfileImageURI());
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$merchant = $this->getMerchant();
|
||||
$id = $merchant->getID();
|
||||
$merchant_uri = $this->getApplicationURI("/merchant/{$id}/");
|
||||
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($merchant->getName(), $merchant_uri);
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
if ($this->hasMerchant()) {
|
||||
$merchant = $this->getMerchant();
|
||||
$merchant_uri = $merchant->getURI();
|
||||
$crumbs->addTextCrumb($merchant->getName(), $merchant_uri);
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
|
@ -58,31 +43,47 @@ abstract class PhortuneMerchantProfileController
|
|||
|
||||
$nav->addLabel(pht('Merchant'));
|
||||
|
||||
$nav->addFilter(
|
||||
'overview',
|
||||
pht('Overview'),
|
||||
$this->getApplicationURI("/merchant/{$id}/"),
|
||||
'fa-building-o');
|
||||
$nav->newLink('overview')
|
||||
->setName(pht('Overview'))
|
||||
->setHref($merchant->getURI())
|
||||
->setIcon('fa-building-o');
|
||||
|
||||
if ($can_edit) {
|
||||
$nav->addFilter(
|
||||
'orders',
|
||||
pht('Orders'),
|
||||
$this->getApplicationURI("merchant/orders/{$id}/"),
|
||||
'fa-retweet');
|
||||
$nav->newLink('details')
|
||||
->setName(pht('Account Details'))
|
||||
->setHref($merchant->getDetailsURI())
|
||||
->setIcon('fa-address-card-o')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$nav->addFilter(
|
||||
'subscriptions',
|
||||
pht('Subscriptions'),
|
||||
$this->getApplicationURI("merchant/{$id}/subscription/"),
|
||||
'fa-shopping-cart');
|
||||
$nav->addLabel(pht('Payments'));
|
||||
|
||||
$nav->addFilter(
|
||||
'managers',
|
||||
pht('Managers'),
|
||||
$this->getApplicationURI("/merchant/manager/{$id}/"),
|
||||
'fa-group');
|
||||
}
|
||||
$nav->newLink('providers')
|
||||
->setName(pht('Payment Providers'))
|
||||
->setHref($merchant->getPaymentProvidersURI())
|
||||
->setIcon('fa-credit-card')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$nav->newLink('orders')
|
||||
->setName(pht('Orders'))
|
||||
->setHref($merchant->getOrdersURI())
|
||||
->setIcon('fa-shopping-bag')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$nav->newLink('subscriptions')
|
||||
->setName(pht('Subscriptions'))
|
||||
->setHref($merchant->getSubscriptionsURI())
|
||||
->setIcon('fa-retweet')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$nav->addLabel(pht('Personnel'));
|
||||
|
||||
$nav->newLink('managers')
|
||||
->setName(pht('Managers'))
|
||||
->setHref($merchant->getManagersURI())
|
||||
->setIcon('fa-group');
|
||||
|
||||
$nav->selectFilter($filter);
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneProviderDisableController
|
||||
final class PhortuneMerchantProviderDisableController
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$id = $request->getURIData('providerID');
|
||||
|
||||
$provider_config = id(new PhortunePaymentProviderConfigQuery())
|
||||
->setViewer($viewer)
|
||||
|
@ -20,9 +26,8 @@ final class PhortuneProviderDisableController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$merchant = $provider_config->getMerchant();
|
||||
$merchant_id = $merchant->getID();
|
||||
$cancel_uri = $this->getApplicationURI("merchant/{$merchant_id}/");
|
||||
$cancel_uri = $provider_config->getURI();
|
||||
|
||||
$provider = $provider_config->buildProvider();
|
||||
|
|
@ -1,16 +1,23 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneProviderEditController
|
||||
final class PhortuneMerchantProviderEditController
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if ($id) {
|
||||
$provider_config = id(new PhortunePaymentProviderConfigQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
|
@ -25,20 +32,8 @@ final class PhortuneProviderEditController
|
|||
|
||||
$merchant = $provider_config->getMerchant();
|
||||
$merchant_id = $merchant->getID();
|
||||
$cancel_uri = $this->getApplicationURI("merchant/{$merchant_id}/");
|
||||
$cancel_uri = $provider_config->getURI();
|
||||
} else {
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getStr('merchantID')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$merchant_id = $merchant->getID();
|
||||
|
||||
$current_providers = id(new PhortunePaymentProviderConfigQuery())
|
||||
|
@ -62,9 +57,7 @@ final class PhortuneProviderEditController
|
|||
}
|
||||
|
||||
$provider_config->setProviderClass($class);
|
||||
|
||||
$cancel_uri = $this->getApplicationURI(
|
||||
'provider/edit/?merchantID='.$merchant_id);
|
||||
$cancel_uri = $merchant->getPaymentProvidersURI();
|
||||
}
|
||||
|
||||
$provider = $provider_config->buildProvider();
|
||||
|
@ -123,10 +116,12 @@ final class PhortuneProviderEditController
|
|||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhortunePaymentProviderConfigTransaction())
|
||||
->setTransactionType(
|
||||
PhortunePaymentProviderConfigTransaction::TYPE_CREATE)
|
||||
->setNewValue(true);
|
||||
if (!$provider_config->getID()) {
|
||||
$xactions[] = id(new PhortunePaymentProviderConfigTransaction())
|
||||
->setTransactionType(
|
||||
PhortunePaymentProviderConfigTransaction::TYPE_CREATE)
|
||||
->setNewValue(true);
|
||||
}
|
||||
|
||||
foreach ($xaction_values as $key => $value) {
|
||||
$xactions[] = id(clone $template)
|
||||
|
@ -143,9 +138,9 @@ final class PhortuneProviderEditController
|
|||
|
||||
$editor->applyTransactions($provider_config, $xactions);
|
||||
|
||||
$merchant_uri = $this->getApplicationURI(
|
||||
'merchant/'.$merchant->getID().'/');
|
||||
return id(new AphrontRedirectResponse())->setURI($merchant_uri);
|
||||
$next_uri = $provider_config->getURI();
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -155,7 +150,6 @@ final class PhortuneProviderEditController
|
|||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('merchantID', $merchant->getID())
|
||||
->addHiddenInput('class', $provider_config->getProviderClass())
|
||||
->addHiddenInput('edit', true)
|
||||
->appendChild(
|
||||
|
@ -261,7 +255,6 @@ final class PhortuneProviderEditController
|
|||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('merchantID', $merchant->getID())
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose the type of payment provider to add:'))
|
||||
->appendChild($panel_classes)
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantProviderViewController
|
||||
extends PhortuneMerchantController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$provider = id(new PhortunePaymentProviderConfigQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('providerID')))
|
||||
->executeOne();
|
||||
if (!$provider) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$provider_type = $provider->buildProvider();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($merchant->getName(), $merchant->getURI())
|
||||
->addTextCrumb(
|
||||
pht('Payment Providers'),
|
||||
$merchant->getPaymentProvidersURI())
|
||||
->addTextCrumb($provider->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Payment Provider: %s', $provider_type->getName()));
|
||||
|
||||
$details = $this->newDetailsView($provider);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$provider,
|
||||
new PhortunePaymentProviderConfigTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$curtain = $this->buildCurtainView($provider);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(
|
||||
array(
|
||||
$details,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($provider->getObjectName())
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortunePaymentProviderConfig $provider) {
|
||||
$viewer = $this->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$provider,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'merchant/%d/providers/edit/%d/',
|
||||
$merchant->getID(),
|
||||
$provider->getID()));
|
||||
|
||||
$disable_uri = $this->getApplicationURI(
|
||||
urisprintf(
|
||||
'merchant/%d/providers/%d/disable/',
|
||||
$merchant->getID(),
|
||||
$provider->getID()));
|
||||
|
||||
$curtain = $this->newCurtainView($provider);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Provider'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$provider_type = $provider->buildProvider();
|
||||
|
||||
if ($provider_type->isEnabled()) {
|
||||
$disable_icon = 'fa-times';
|
||||
$disable_name = pht('Disable Provider');
|
||||
} else {
|
||||
$disable_icon = 'fa-check';
|
||||
$disable_name = pht('Enable Provider');
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName($disable_name)
|
||||
->setIcon($disable_icon)
|
||||
->setHref($disable_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function newDetailsView(PhortunePaymentProviderConfig $provider) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer);
|
||||
|
||||
$provider_type = $provider->buildProvider();
|
||||
|
||||
$view->addProperty(pht('Provider Type'), $provider_type->getName());
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Payment Provider Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addPropertyList($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantProvidersController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Payment Providers'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$title = pht(
|
||||
'%s %s',
|
||||
$merchant->getObjectName(),
|
||||
$merchant->getName());
|
||||
|
||||
$providers = id(new PhortunePaymentProviderConfigQuery())
|
||||
->setViewer($viewer)
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->execute();
|
||||
|
||||
$provider_list = $this->buildProviderList(
|
||||
$merchant,
|
||||
$providers);
|
||||
|
||||
$navigation = $this->buildSideNavView('providers');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$provider_list,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildProviderList(
|
||||
PhortuneMerchant $merchant,
|
||||
array $providers) {
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$id = $merchant->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$merchant,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$provider_list = id(new PHUIObjectItemListView())
|
||||
->setNoDataString(pht('This merchant has no payment providers.'));
|
||||
|
||||
foreach ($providers as $provider_config) {
|
||||
$provider = $provider_config->buildProvider();
|
||||
$provider_id = $provider_config->getID();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName($provider_config->getObjectName())
|
||||
->setHeader($provider->getName())
|
||||
->setHref($provider_config->getURI());
|
||||
|
||||
if ($provider->isEnabled()) {
|
||||
if ($provider->isAcceptingLivePayments()) {
|
||||
$item->setStatusIcon('fa-check green');
|
||||
} else {
|
||||
$item->setStatusIcon('fa-warning yellow');
|
||||
$item->addIcon('fa-exclamation-triangle', pht('Test Mode'));
|
||||
}
|
||||
|
||||
$item->addAttribute($provider->getConfigureProvidesDescription());
|
||||
} else {
|
||||
$item->setDisabled(true);
|
||||
$item->addAttribute(
|
||||
phutil_tag('em', array(), pht('This payment provider is disabled.')));
|
||||
}
|
||||
|
||||
$provider_list->addItem($item);
|
||||
}
|
||||
|
||||
$add_uri = urisprintf(
|
||||
'merchant/%d/providers/edit/',
|
||||
$merchant->getID());
|
||||
$add_uri = $this->getApplicationURI($add_uri);
|
||||
|
||||
$add_action = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($add_uri)
|
||||
->setText(pht('Add Payment Provider'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setIcon('fa-plus');
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Payment Providers'))
|
||||
->addActionLink($add_action);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($provider_list);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantSubscriptionListController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$engine = id(new PhortuneCartSearchEngine())
|
||||
->setController($this)
|
||||
->setMerchant($merchant);
|
||||
|
||||
$subscription_id = $request->getURIData('subscriptionID');
|
||||
if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($subscription_id))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$engine->setSubscription($subscription);
|
||||
$this->subscription = $subscription;
|
||||
}
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
if ($this->hasMerchant()) {
|
||||
$merchant = $this->getMerchant();
|
||||
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Subscriptions'),
|
||||
$merchant->getSubscriptionsURI());
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantSubscriptionsController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
protected function shouldRequireMerchantEditCapability() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handleMerchantRequest(AphrontRequest $request) {
|
||||
$merchant = $this->getMerchant();
|
||||
$title = $merchant->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Subscriptions'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$subscriptions = $this->buildSubscriptionsSection($merchant);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$subscriptions,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('subscriptions');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildSubscriptionsSection(PhortuneMerchant $merchant) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$subscriptions = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->setLimit(25)
|
||||
->execute();
|
||||
|
||||
$subscriptions_uri = $merchant->getSubscriptionListURI();
|
||||
|
||||
$table = id(new PhortuneSubscriptionTableView())
|
||||
->setUser($viewer)
|
||||
->setSubscriptions($subscriptions);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Subscriptions'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list')
|
||||
->setHref($subscriptions_uri)
|
||||
->setText(pht('View All Subscriptions')));
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($table);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,324 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneMerchantViewController
|
||||
extends PhortuneMerchantProfileController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needProfileImage(true)
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setMerchant($merchant);
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$title = pht(
|
||||
'Merchant %d %s',
|
||||
$merchant->getID(),
|
||||
$merchant->getName());
|
||||
|
||||
$providers = id(new PhortunePaymentProviderConfigQuery())
|
||||
->setViewer($viewer)
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->execute();
|
||||
|
||||
$details = $this->buildDetailsView($merchant, $providers);
|
||||
$curtain = $this->buildCurtainView($merchant);
|
||||
|
||||
$provider_list = $this->buildProviderList(
|
||||
$merchant,
|
||||
$providers);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$merchant,
|
||||
new PhortuneMerchantTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$navigation = $this->buildSideNavView('overview');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$details,
|
||||
$provider_list,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildDetailsView(
|
||||
PhortuneMerchant $merchant,
|
||||
array $providers) {
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($merchant);
|
||||
|
||||
$status_view = new PHUIStatusListView();
|
||||
|
||||
$have_any = false;
|
||||
$any_test = false;
|
||||
foreach ($providers as $provider_config) {
|
||||
$provider = $provider_config->buildProvider();
|
||||
if ($provider->isEnabled()) {
|
||||
$have_any = true;
|
||||
}
|
||||
if (!$provider->isAcceptingLivePayments()) {
|
||||
$any_test = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($have_any) {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Accepts Payments'))
|
||||
->setNote(pht('This merchant can accept payments.')));
|
||||
|
||||
if ($any_test) {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow')
|
||||
->setTarget(pht('Test Mode'))
|
||||
->setNote(pht('This merchant is accepting test payments.')));
|
||||
} else {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Live Mode'))
|
||||
->setNote(pht('This merchant is accepting live payments.')));
|
||||
}
|
||||
} else if ($providers) {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_REJECT, 'red')
|
||||
->setTarget(pht('No Enabled Providers'))
|
||||
->setNote(
|
||||
pht(
|
||||
'All of the payment providers for this merchant are '.
|
||||
'disabled.')));
|
||||
} else {
|
||||
$status_view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow')
|
||||
->setTarget(pht('No Providers'))
|
||||
->setNote(
|
||||
pht(
|
||||
'This merchant does not have any payment providers configured '.
|
||||
'yet, so it can not accept payments. Add a provider.')));
|
||||
}
|
||||
|
||||
$view->addProperty(pht('Status'), $status_view);
|
||||
|
||||
$invoice_from = $merchant->getInvoiceEmail();
|
||||
if (!$invoice_from) {
|
||||
$invoice_from = pht('No email address set');
|
||||
$invoice_from = phutil_tag('em', array(), $invoice_from);
|
||||
}
|
||||
$view->addProperty(pht('Invoice From'), $invoice_from);
|
||||
|
||||
$description = $merchant->getDescription();
|
||||
if (strlen($description)) {
|
||||
$description = new PHUIRemarkupView($viewer, $description);
|
||||
$view->addSectionHeader(
|
||||
pht('Description'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($description);
|
||||
}
|
||||
|
||||
$contact_info = $merchant->getContactInfo();
|
||||
if (strlen($contact_info)) {
|
||||
$contact_info = new PHUIRemarkupView($viewer, $contact_info);
|
||||
$view->addSectionHeader(
|
||||
pht('Contact Info'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($contact_info);
|
||||
}
|
||||
|
||||
$footer_info = $merchant->getInvoiceFooter();
|
||||
if (strlen($footer_info)) {
|
||||
$footer_info = new PHUIRemarkupView($viewer, $footer_info);
|
||||
$view->addSectionHeader(
|
||||
pht('Invoice Footer'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$view->addTextContent($footer_info);
|
||||
}
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Details'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhortuneMerchant $merchant) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$id = $merchant->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$merchant,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$curtain = $this->newCurtainView($merchant);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Merchant'))
|
||||
->setIcon('fa-pencil')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setHref($this->getApplicationURI("merchant/edit/{$id}/")));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Logo'))
|
||||
->setIcon('fa-camera')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setHref($this->getApplicationURI("merchant/picture/{$id}/")));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('New Invoice'))
|
||||
->setIcon('fa-fax')
|
||||
->setHref($this->getApplicationURI("merchant/{$id}/invoice/new/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$member_phids = $merchant->getMemberPHIDs();
|
||||
$handles = $viewer->loadHandles($member_phids);
|
||||
|
||||
$member_list = id(new PHUIObjectItemListView())
|
||||
->setSimple(true);
|
||||
|
||||
foreach ($member_phids as $member_phid) {
|
||||
$image_uri = $handles[$member_phid]->getImageURI();
|
||||
$image_href = $handles[$member_phid]->getURI();
|
||||
$person = $handles[$member_phid];
|
||||
|
||||
$member = id(new PHUIObjectItemView())
|
||||
->setImageURI($image_uri)
|
||||
->setHref($image_href)
|
||||
->setHeader($person->getFullName());
|
||||
|
||||
$member_list->addItem($member);
|
||||
}
|
||||
|
||||
$curtain->newPanel()
|
||||
->setHeaderText(pht('Managers'))
|
||||
->appendChild($member_list);
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
private function buildProviderList(
|
||||
PhortuneMerchant $merchant,
|
||||
array $providers) {
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$id = $merchant->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$merchant,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$provider_list = id(new PHUIObjectItemListView())
|
||||
->setFlush(true)
|
||||
->setNoDataString(pht('This merchant has no payment providers.'));
|
||||
|
||||
foreach ($providers as $provider_config) {
|
||||
$provider = $provider_config->buildProvider();
|
||||
$provider_id = $provider_config->getID();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($provider->getName());
|
||||
|
||||
if ($provider->isEnabled()) {
|
||||
if ($provider->isAcceptingLivePayments()) {
|
||||
$item->setStatusIcon('fa-check green');
|
||||
} else {
|
||||
$item->setStatusIcon('fa-warning yellow');
|
||||
$item->addIcon('fa-exclamation-triangle', pht('Test Mode'));
|
||||
}
|
||||
|
||||
$item->addAttribute($provider->getConfigureProvidesDescription());
|
||||
} else {
|
||||
// Don't show disabled providers to users who can't manage the merchant
|
||||
// account.
|
||||
if (!$can_edit) {
|
||||
continue;
|
||||
}
|
||||
$item->setDisabled(true);
|
||||
$item->addAttribute(
|
||||
phutil_tag('em', array(), pht('This payment provider is disabled.')));
|
||||
}
|
||||
|
||||
|
||||
if ($can_edit) {
|
||||
$edit_uri = $this->getApplicationURI(
|
||||
"/provider/edit/{$provider_id}/");
|
||||
$disable_uri = $this->getApplicationURI(
|
||||
"/provider/disable/{$provider_id}/");
|
||||
|
||||
if ($provider->isEnabled()) {
|
||||
$disable_icon = 'fa-times';
|
||||
$disable_name = pht('Disable');
|
||||
} else {
|
||||
$disable_icon = 'fa-check';
|
||||
$disable_name = pht('Enable');
|
||||
}
|
||||
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon($disable_icon)
|
||||
->setHref($disable_uri)
|
||||
->setName($disable_name)
|
||||
->setWorkflow(true));
|
||||
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($edit_uri)
|
||||
->setName(pht('Edit')));
|
||||
}
|
||||
|
||||
$provider_list->addItem($item);
|
||||
}
|
||||
|
||||
$add_action = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setHref($this->getApplicationURI('provider/edit/?merchantID='.$id))
|
||||
->setText(pht('Add Payment Provider'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setIcon('fa-plus');
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Payment Providers'))
|
||||
->addActionLink($add_action);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($provider_list);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,303 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortunePaymentMethodCreateController
|
||||
extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$account_id = $request->getURIData('accountID');
|
||||
|
||||
$account = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($account_id))
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$account_id = $account->getID();
|
||||
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getInt('merchantID')))
|
||||
->executeOne();
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cart_id = $request->getInt('cartID');
|
||||
$subscription_id = $request->getInt('subscriptionID');
|
||||
if ($cart_id) {
|
||||
$cancel_uri = $this->getApplicationURI("cart/{$cart_id}/checkout/");
|
||||
} else if ($subscription_id) {
|
||||
$cancel_uri = $this->getApplicationURI(
|
||||
"{$account_id}/subscription/edit/{$subscription_id}/");
|
||||
} else {
|
||||
$cancel_uri = $this->getApplicationURI($account->getID().'/');
|
||||
}
|
||||
|
||||
$providers = $this->loadCreatePaymentMethodProvidersForMerchant($merchant);
|
||||
if (!$providers) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'There are no payment providers enabled that can add payment '.
|
||||
'methods.'));
|
||||
}
|
||||
|
||||
if (count($providers) == 1) {
|
||||
// If there's only one provider, always choose it.
|
||||
$provider_id = head_key($providers);
|
||||
} else {
|
||||
$provider_id = $request->getInt('providerID');
|
||||
if (empty($providers[$provider_id])) {
|
||||
$choices = array();
|
||||
foreach ($providers as $provider) {
|
||||
$choices[] = $this->renderSelectProvider($provider);
|
||||
}
|
||||
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phortune-payment-method-list',
|
||||
),
|
||||
$choices);
|
||||
|
||||
return $this->newDialog()
|
||||
->setRenderDialogAsDiv(true)
|
||||
->setTitle(pht('Add Payment Method'))
|
||||
->appendParagraph(pht('Choose a payment method to add:'))
|
||||
->appendChild($content)
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
}
|
||||
|
||||
$provider = $providers[$provider_id];
|
||||
|
||||
$errors = array();
|
||||
$display_exception = null;
|
||||
if ($request->isFormPost() && $request->getBool('isProviderForm')) {
|
||||
$method = id(new PhortunePaymentMethod())
|
||||
->setAccountPHID($account->getPHID())
|
||||
->setAuthorPHID($viewer->getPHID())
|
||||
->setMerchantPHID($merchant->getPHID())
|
||||
->setProviderPHID($provider->getProviderConfig()->getPHID())
|
||||
->setStatus(PhortunePaymentMethod::STATUS_ACTIVE);
|
||||
|
||||
// Limit the rate at which you can attempt to add payment methods. This
|
||||
// is intended as a line of defense against using Phortune to validate a
|
||||
// large list of stolen credit card numbers.
|
||||
|
||||
PhabricatorSystemActionEngine::willTakeAction(
|
||||
array($viewer->getPHID()),
|
||||
new PhortuneAddPaymentMethodAction(),
|
||||
1);
|
||||
|
||||
if (!$errors) {
|
||||
$errors = $this->processClientErrors(
|
||||
$provider,
|
||||
$request->getStr('errors'));
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$client_token_raw = $request->getStr('token');
|
||||
$client_token = null;
|
||||
try {
|
||||
$client_token = phutil_json_decode($client_token_raw);
|
||||
} catch (PhutilJSONParserException $ex) {
|
||||
$errors[] = pht(
|
||||
'There was an error decoding token information submitted by the '.
|
||||
'client. Expected a JSON-encoded token dictionary, received: %s.',
|
||||
nonempty($client_token_raw, pht('nothing')));
|
||||
}
|
||||
|
||||
if (!$provider->validateCreatePaymentMethodToken($client_token)) {
|
||||
$errors[] = pht(
|
||||
'There was an error with the payment token submitted by the '.
|
||||
'client. Expected a valid dictionary, received: %s.',
|
||||
$client_token_raw);
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
try {
|
||||
$provider->createPaymentMethodFromRequest(
|
||||
$request,
|
||||
$method,
|
||||
$client_token);
|
||||
} catch (PhortuneDisplayException $exception) {
|
||||
$display_exception = $exception;
|
||||
} catch (Exception $ex) {
|
||||
$errors = array(
|
||||
pht('There was an error adding this payment method:'),
|
||||
$ex->getMessage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors && !$display_exception) {
|
||||
$method->save();
|
||||
|
||||
// If we added this method on a cart flow, return to the cart to
|
||||
// check out.
|
||||
if ($cart_id) {
|
||||
$next_uri = $this->getApplicationURI(
|
||||
"cart/{$cart_id}/checkout/?paymentMethodID=".$method->getID());
|
||||
} else if ($subscription_id) {
|
||||
$next_uri = new PhutilURI($cancel_uri);
|
||||
$next_uri->replaceQueryParam('added', true);
|
||||
} else {
|
||||
$account_uri = $this->getApplicationURI($account->getID().'/');
|
||||
$next_uri = new PhutilURI($account_uri);
|
||||
$next_uri->setFragment('payment');
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
} else {
|
||||
if ($display_exception) {
|
||||
$dialog_body = $display_exception->getView();
|
||||
} else {
|
||||
$dialog_body = id(new PHUIInfoView())
|
||||
->setErrors($errors);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Error Adding Payment Method'))
|
||||
->appendChild($dialog_body)
|
||||
->addCancelButton($request->getRequestURI());
|
||||
}
|
||||
}
|
||||
|
||||
$form = $provider->renderCreatePaymentMethodForm($request, $errors);
|
||||
|
||||
$form
|
||||
->setUser($viewer)
|
||||
->setAction($request->getRequestURI())
|
||||
->setWorkflow(true)
|
||||
->addHiddenInput('providerID', $provider_id)
|
||||
->addHiddenInput('cartID', $request->getInt('cartID'))
|
||||
->addHiddenInput('subscriptionID', $request->getInt('subscriptionID'))
|
||||
->addHiddenInput('isProviderForm', true)
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Add Payment Method'))
|
||||
->addCancelButton($cancel_uri));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Method'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Add Payment Method'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Add Payment Method'))
|
||||
->setHeaderIcon('fa-plus-square');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$box,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($provider->getPaymentMethodDescription())
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function renderSelectProvider(
|
||||
PhortunePaymentProvider $provider) {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$description = $provider->getPaymentMethodDescription();
|
||||
$icon_uri = $provider->getPaymentMethodIcon();
|
||||
$details = $provider->getPaymentMethodProviderDescription();
|
||||
|
||||
$this->requireResource('phortune-css');
|
||||
|
||||
$icon = id(new PHUIIconView())
|
||||
->setSpriteSheet(PHUIIconView::SPRITE_LOGIN)
|
||||
->setSpriteIcon($provider->getPaymentMethodIcon());
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setSize(PHUIButtonView::BIG)
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setIcon($icon)
|
||||
->setText($description)
|
||||
->setSubtext($details)
|
||||
->setMetadata(array('disableWorkflow' => true));
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->setAction($request->getRequestURI())
|
||||
->addHiddenInput('providerID', $provider->getProviderConfig()->getID())
|
||||
->appendChild($button);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
private function processClientErrors(
|
||||
PhortunePaymentProvider $provider,
|
||||
$client_errors_raw) {
|
||||
|
||||
$errors = array();
|
||||
|
||||
$client_errors = null;
|
||||
try {
|
||||
$client_errors = phutil_json_decode($client_errors_raw);
|
||||
} catch (PhutilJSONParserException $ex) {
|
||||
$errors[] = pht(
|
||||
'There was an error decoding error information submitted by the '.
|
||||
'client. Expected a JSON-encoded list of error codes, received: %s.',
|
||||
nonempty($client_errors_raw, pht('nothing')));
|
||||
}
|
||||
|
||||
foreach (array_unique($client_errors) as $key => $client_error) {
|
||||
$client_errors[$key] = $provider->translateCreatePaymentMethodErrorCode(
|
||||
$client_error);
|
||||
}
|
||||
|
||||
foreach (array_unique($client_errors) as $client_error) {
|
||||
switch ($client_error) {
|
||||
case PhortuneErrCode::ERR_CC_INVALID_NUMBER:
|
||||
$message = pht(
|
||||
'The card number you entered is not a valid card number. Check '.
|
||||
'that you entered it correctly.');
|
||||
break;
|
||||
case PhortuneErrCode::ERR_CC_INVALID_CVC:
|
||||
$message = pht(
|
||||
'The CVC code you entered is not a valid CVC code. Check that '.
|
||||
'you entered it correctly. The CVC code is a 3-digit or 4-digit '.
|
||||
'numeric code which usually appears on the back of the card.');
|
||||
break;
|
||||
case PhortuneErrCode::ERR_CC_INVALID_EXPIRY:
|
||||
$message = pht(
|
||||
'The card expiration date is not a valid expiration date. Check '.
|
||||
'that you entered it correctly. You can not add an expired card '.
|
||||
'as a payment method.');
|
||||
break;
|
||||
default:
|
||||
$message = $provider->getCreatePaymentMethodErrorMessage(
|
||||
$client_error);
|
||||
if (!$message) {
|
||||
$message = pht(
|
||||
"There was an unexpected error ('%s') processing payment ".
|
||||
"information.",
|
||||
$client_error);
|
||||
|
||||
phlog($message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$errors[$client_error] = $message;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortunePaymentMethodDisableController
|
||||
extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$method_id = $request->getURIData('id');
|
||||
|
||||
$method = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($method_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$method) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if ($method->getStatus() == PhortunePaymentMethod::STATUS_DISABLED) {
|
||||
return new Aphront400Response();
|
||||
}
|
||||
|
||||
$account = $method->getAccount();
|
||||
$account_id = $account->getID();
|
||||
$account_uri = $this->getApplicationURI("/account/billing/{$account_id}/");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
// TODO: ApplicationTransactions!!!!
|
||||
$method
|
||||
->setStatus(PhortunePaymentMethod::STATUS_DISABLED)
|
||||
->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($account_uri);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Remove Payment Method'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Remove the payment method "%s" from your account?',
|
||||
phutil_tag(
|
||||
'strong',
|
||||
array(),
|
||||
$method->getFullDisplayName())))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You will no longer be able to make payments using this payment '.
|
||||
'method.'))
|
||||
->addCancelButton($account_uri)
|
||||
->addSubmitButton(pht('Remove Payment Method'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,462 @@
|
|||
<?php
|
||||
|
||||
final class PhortunePaymentMethodCreateController
|
||||
extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$account_id = $request->getURIData('accountID');
|
||||
$account = id(new PhortuneAccountQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($account_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$account) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cart_id = $request->getInt('cartID');
|
||||
$subscription_id = $request->getInt('subscriptionID');
|
||||
$merchant_id = $request->getInt('merchantID');
|
||||
|
||||
if ($cart_id) {
|
||||
$cart = id(new PhortuneCartQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($cart_id))
|
||||
->executeOne();
|
||||
if (!$cart) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$subscription_phid = $cart->getSubscriptionPHID();
|
||||
if ($subscription_phid) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withPHIDs(array($subscription_phid))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
} else {
|
||||
$subscription = null;
|
||||
}
|
||||
|
||||
$merchant = $cart->getMerchant();
|
||||
|
||||
$cart_id = $cart->getID();
|
||||
$subscription_id = null;
|
||||
$merchant_id = null;
|
||||
|
||||
$next_uri = $cart->getCheckoutURI();
|
||||
} else if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withIDs(array($subscription_id))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cart = null;
|
||||
$merchant = $subscription->getMerchant();
|
||||
|
||||
$cart_id = null;
|
||||
$subscription_id = $subscription->getID();
|
||||
$merchant_id = null;
|
||||
|
||||
$next_uri = $subscription->getURI();
|
||||
} else if ($merchant_id) {
|
||||
$merchant_phids = $account->getMerchantPHIDs();
|
||||
if ($merchant_phids) {
|
||||
$merchant = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($merchant_id))
|
||||
->withPHIDs($merchant_phids)
|
||||
->executeOne();
|
||||
} else {
|
||||
$merchant = null;
|
||||
}
|
||||
|
||||
if (!$merchant) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$cart = null;
|
||||
$subscription = null;
|
||||
|
||||
$cart_id = null;
|
||||
$subscription_id = null;
|
||||
$merchant_id = $merchant->getID();
|
||||
|
||||
$next_uri = $account->getPaymentMethodsURI();
|
||||
} else {
|
||||
$next_uri = $account->getPaymentMethodsURI();
|
||||
|
||||
$merchant_phids = $account->getMerchantPHIDs();
|
||||
if ($merchant_phids) {
|
||||
$merchants = id(new PhortuneMerchantQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($merchant_phids)
|
||||
->needProfileImage(true)
|
||||
->execute();
|
||||
} else {
|
||||
$merchants = array();
|
||||
}
|
||||
|
||||
if (!$merchants) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('No Merchants'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You have not established a relationship with any merchants '.
|
||||
'yet. Create an order or subscription before adding payment '.
|
||||
'methods.'))
|
||||
->addCancelButton($next_uri);
|
||||
}
|
||||
|
||||
// If there's more than one merchant, ask the user to pick which one they
|
||||
// want to pay. If there's only one, just pick it for them.
|
||||
if (count($merchants) > 1) {
|
||||
$menu = $this->newMerchantMenu($merchants);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->appendInstructions(
|
||||
pht(
|
||||
'Choose the merchant you want to pay.'));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Choose a Merchant'))
|
||||
->appendForm($form)
|
||||
->appendChild($menu)
|
||||
->addCancelButton($next_uri);
|
||||
}
|
||||
|
||||
$cart = null;
|
||||
$subscription = null;
|
||||
$merchant = head($merchants);
|
||||
|
||||
$cart_id = null;
|
||||
$subscription_id = null;
|
||||
$merchant_id = $merchant->getID();
|
||||
}
|
||||
|
||||
$providers = $this->loadCreatePaymentMethodProvidersForMerchant($merchant);
|
||||
if (!$providers) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'There are no payment providers enabled that can add payment '.
|
||||
'methods.'));
|
||||
}
|
||||
|
||||
$state_params = array(
|
||||
'cartID' => $cart_id,
|
||||
'subscriptionID' => $subscription_id,
|
||||
'merchantID' => $merchant_id,
|
||||
);
|
||||
$state_params = array_filter($state_params);
|
||||
|
||||
$state_uri = new PhutilURI($request->getRequestURI());
|
||||
foreach ($state_params as $key => $value) {
|
||||
$state_uri->replaceQueryParam($key, $value);
|
||||
}
|
||||
|
||||
$provider_id = $request->getInt('providerID');
|
||||
if (isset($providers[$provider_id])) {
|
||||
$provider = $providers[$provider_id];
|
||||
} else {
|
||||
// If there's more than one provider, ask the user to pick how they
|
||||
// want to pay. If there's only one, just pick it.
|
||||
if (count($providers) > 1) {
|
||||
$menu = $this->newProviderMenu($providers, $state_uri);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Choose a Payment Method'))
|
||||
->appendChild($menu)
|
||||
->addCancelButton($next_uri);
|
||||
}
|
||||
|
||||
$provider = head($providers);
|
||||
}
|
||||
|
||||
$provider_id = $provider->getProviderConfig()->getID();
|
||||
|
||||
$state_params['providerID'] = $provider_id;
|
||||
|
||||
$errors = array();
|
||||
$display_exception = null;
|
||||
if ($request->isFormPost() && $request->getBool('isProviderForm')) {
|
||||
$method = id(new PhortunePaymentMethod())
|
||||
->setAccountPHID($account->getPHID())
|
||||
->setAuthorPHID($viewer->getPHID())
|
||||
->setMerchantPHID($merchant->getPHID())
|
||||
->setProviderPHID($provider->getProviderConfig()->getPHID())
|
||||
->setStatus(PhortunePaymentMethod::STATUS_ACTIVE);
|
||||
|
||||
// Limit the rate at which you can attempt to add payment methods. This
|
||||
// is intended as a line of defense against using Phortune to validate a
|
||||
// large list of stolen credit card numbers.
|
||||
|
||||
PhabricatorSystemActionEngine::willTakeAction(
|
||||
array($viewer->getPHID()),
|
||||
new PhortuneAddPaymentMethodAction(),
|
||||
1);
|
||||
|
||||
if (!$errors) {
|
||||
$errors = $this->processClientErrors(
|
||||
$provider,
|
||||
$request->getStr('errors'));
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$client_token_raw = $request->getStr('token');
|
||||
$client_token = null;
|
||||
try {
|
||||
$client_token = phutil_json_decode($client_token_raw);
|
||||
} catch (PhutilJSONParserException $ex) {
|
||||
$errors[] = pht(
|
||||
'There was an error decoding token information submitted by the '.
|
||||
'client. Expected a JSON-encoded token dictionary, received: %s.',
|
||||
nonempty($client_token_raw, pht('nothing')));
|
||||
}
|
||||
|
||||
if (!$provider->validateCreatePaymentMethodToken($client_token)) {
|
||||
$errors[] = pht(
|
||||
'There was an error with the payment token submitted by the '.
|
||||
'client. Expected a valid dictionary, received: %s.',
|
||||
$client_token_raw);
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
try {
|
||||
$provider->createPaymentMethodFromRequest(
|
||||
$request,
|
||||
$method,
|
||||
$client_token);
|
||||
} catch (PhortuneDisplayException $exception) {
|
||||
$display_exception = $exception;
|
||||
} catch (Exception $ex) {
|
||||
$errors = array(
|
||||
pht('There was an error adding this payment method:'),
|
||||
$ex->getMessage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors && !$display_exception) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $method->getApplicationTransactionTemplate()
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_CREATE)
|
||||
->setNewValue(true);
|
||||
|
||||
$editor = id(new PhortunePaymentMethodEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($method, $xactions);
|
||||
|
||||
$next_uri = new PhutilURI($next_uri);
|
||||
|
||||
// If we added this method on a cart flow, return to the cart to
|
||||
// checkout with this payment method selected.
|
||||
if ($cart_id) {
|
||||
$next_uri->replaceQueryParam('paymentMethodID', $method->getID());
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
} else {
|
||||
if ($display_exception) {
|
||||
$dialog_body = $display_exception->getView();
|
||||
} else {
|
||||
$dialog_body = id(new PHUIInfoView())
|
||||
->setErrors($errors);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Error Adding Payment Method'))
|
||||
->appendChild($dialog_body)
|
||||
->addCancelButton($request->getRequestURI());
|
||||
}
|
||||
}
|
||||
|
||||
$form = $provider->renderCreatePaymentMethodForm($request, $errors);
|
||||
|
||||
$form
|
||||
->setViewer($viewer)
|
||||
->setAction($request->getPath())
|
||||
->setWorkflow(true)
|
||||
->addHiddenInput('isProviderForm', true)
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Add Payment Method'))
|
||||
->addCancelButton($next_uri));
|
||||
|
||||
foreach ($state_params as $key => $value) {
|
||||
$form->addHiddenInput($key, $value);
|
||||
}
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Method'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Add Payment Method'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Add Payment Method'))
|
||||
->setHeaderIcon('fa-plus-square');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(
|
||||
array(
|
||||
$box,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($provider->getPaymentMethodDescription())
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function processClientErrors(
|
||||
PhortunePaymentProvider $provider,
|
||||
$client_errors_raw) {
|
||||
|
||||
$errors = array();
|
||||
|
||||
$client_errors = null;
|
||||
try {
|
||||
$client_errors = phutil_json_decode($client_errors_raw);
|
||||
} catch (PhutilJSONParserException $ex) {
|
||||
$errors[] = pht(
|
||||
'There was an error decoding error information submitted by the '.
|
||||
'client. Expected a JSON-encoded list of error codes, received: %s.',
|
||||
nonempty($client_errors_raw, pht('nothing')));
|
||||
}
|
||||
|
||||
foreach (array_unique($client_errors) as $key => $client_error) {
|
||||
$client_errors[$key] = $provider->translateCreatePaymentMethodErrorCode(
|
||||
$client_error);
|
||||
}
|
||||
|
||||
foreach (array_unique($client_errors) as $client_error) {
|
||||
switch ($client_error) {
|
||||
case PhortuneErrCode::ERR_CC_INVALID_NUMBER:
|
||||
$message = pht(
|
||||
'The card number you entered is not a valid card number. Check '.
|
||||
'that you entered it correctly.');
|
||||
break;
|
||||
case PhortuneErrCode::ERR_CC_INVALID_CVC:
|
||||
$message = pht(
|
||||
'The CVC code you entered is not a valid CVC code. Check that '.
|
||||
'you entered it correctly. The CVC code is a 3-digit or 4-digit '.
|
||||
'numeric code which usually appears on the back of the card.');
|
||||
break;
|
||||
case PhortuneErrCode::ERR_CC_INVALID_EXPIRY:
|
||||
$message = pht(
|
||||
'The card expiration date is not a valid expiration date. Check '.
|
||||
'that you entered it correctly. You can not add an expired card '.
|
||||
'as a payment method.');
|
||||
break;
|
||||
default:
|
||||
$message = $provider->getCreatePaymentMethodErrorMessage(
|
||||
$client_error);
|
||||
if (!$message) {
|
||||
$message = pht(
|
||||
"There was an unexpected error ('%s') processing payment ".
|
||||
"information.",
|
||||
$client_error);
|
||||
|
||||
phlog($message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$errors[$client_error] = $message;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private function newMerchantMenu(array $merchants) {
|
||||
assert_instances_of($merchants, 'PhortuneMerchant');
|
||||
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer)
|
||||
->setBig(true)
|
||||
->setFlush(true);
|
||||
|
||||
foreach ($merchants as $merchant) {
|
||||
$merchant_uri = id(new PhutilURI($request->getRequestURI()))
|
||||
->replaceQueryParam('merchantID', $merchant->getID());
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName($merchant->getObjectName())
|
||||
->setHeader($merchant->getName())
|
||||
->setHref($merchant_uri)
|
||||
->setClickable(true)
|
||||
->setImageURI($merchant->getProfileImageURI());
|
||||
|
||||
$menu->addItem($item);
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
private function newProviderMenu(array $providers, PhutilURI $state_uri) {
|
||||
assert_instances_of($providers, 'PhortunePaymentProvider');
|
||||
|
||||
$request = $this->getRequest();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$menu = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer)
|
||||
->setBig(true)
|
||||
->setFlush(true);
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
$provider_id = $provider->getProviderConfig()->getID();
|
||||
|
||||
$provider_uri = id(clone $state_uri)
|
||||
->replaceQueryParam('providerID', $provider_id);
|
||||
|
||||
$description = $provider->getPaymentMethodDescription();
|
||||
$icon_uri = $provider->getPaymentMethodIcon();
|
||||
$details = $provider->getPaymentMethodProviderDescription();
|
||||
|
||||
$icon = id(new PHUIIconView())
|
||||
->setSpriteSheet(PHUIIconView::SPRITE_LOGIN)
|
||||
->setSpriteIcon($icon_uri);
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($description)
|
||||
->setHref($provider_uri)
|
||||
->setClickable(true)
|
||||
->addAttribute($details)
|
||||
->setImageIcon($icon);
|
||||
|
||||
$menu->addItem($item);
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
final class PhortunePaymentMethodDisableController
|
||||
extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$method_id = $request->getURIData('id');
|
||||
|
||||
$method = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($method_id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$method) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if ($method->getStatus() == PhortunePaymentMethod::STATUS_DISABLED) {
|
||||
return new Aphront400Response();
|
||||
}
|
||||
|
||||
$subscription_id = $request->getInt('subscriptionID');
|
||||
if ($subscription_id) {
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($subscription_id))
|
||||
->withAccountPHIDs(array($method->getAccountPHID()))
|
||||
->withMerchantPHIDs(array($method->getMerchantPHID()))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
} else {
|
||||
$subscription = null;
|
||||
}
|
||||
|
||||
$account = $method->getAccount();
|
||||
$account_id = $account->getID();
|
||||
$account_uri = $account->getPaymentMethodsURI();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = $method->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortunePaymentMethodStatusTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(PhortunePaymentMethod::STATUS_DISABLED);
|
||||
|
||||
$editor = id(new PhortunePaymentMethodEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
$editor->applyTransactions($method, $xactions);
|
||||
|
||||
if ($subscription) {
|
||||
$next_uri = $subscription->getURI();
|
||||
} else {
|
||||
$next_uri = $account_uri;
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
}
|
||||
|
||||
$method_phid = $method->getPHID();
|
||||
$handles = $viewer->loadHandles(
|
||||
array(
|
||||
$method_phid,
|
||||
));
|
||||
|
||||
$method_handle = $handles[$method_phid];
|
||||
$method_display = $method_handle->renderLink();
|
||||
$method_display = phutil_tag('strong', array(), $method_display);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Remove Payment Method'))
|
||||
->addHiddenInput('subscriptionID', $subscription_id)
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Remove the payment method %s from your account?',
|
||||
$method_display))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You will no longer be able to make payments using this payment '.
|
||||
'method.'))
|
||||
->addCancelButton($account_uri)
|
||||
->addSubmitButton(pht('Remove Payment Method'));
|
||||
}
|
||||
|
||||
}
|
|
@ -20,25 +20,36 @@ final class PhortunePaymentMethodEditController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$next_uri = $method->getURI();
|
||||
|
||||
$account = $method->getAccount();
|
||||
$account_uri = $this->getApplicationURI($account->getID().'/');
|
||||
$v_name = $method->getName();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$v_name = $request->getStr('name');
|
||||
|
||||
$name = $request->getStr('name');
|
||||
$xactions = array();
|
||||
|
||||
// TODO: Use ApplicationTransactions
|
||||
$xactions[] = $method->getApplicationTransactionTemplate()
|
||||
->setTransactionType(
|
||||
PhortunePaymentMethodNameTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$method->setName($name);
|
||||
$method->save();
|
||||
$editor = id(new PhortunePaymentMethodEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($account_uri);
|
||||
$editor->applyTransactions($method, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($next_uri);
|
||||
}
|
||||
|
||||
$provider = $method->buildPaymentProvider();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->setViewer($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Name'))
|
||||
|
@ -54,7 +65,7 @@ final class PhortunePaymentMethodEditController
|
|||
->setValue($method->getDisplayExpires()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->addCancelButton($account_uri)
|
||||
->addCancelButton($next_uri)
|
||||
->setValue(pht('Save Changes')));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
|
@ -62,11 +73,12 @@ final class PhortunePaymentMethodEditController
|
|||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setForm($form);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($account->getName(), $account_uri);
|
||||
$crumbs->addTextCrumb($method->getDisplayName());
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
$crumbs->setBorder(true);
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($account->getName(), $account->getURI())
|
||||
->addTextCrumb(pht('Payment Methods'), $account->getPaymentMethodsURI())
|
||||
->addTextCrumb($method->getObjectName(), $method->getURI())
|
||||
->addTextCrumb(pht('Edit'))
|
||||
->setBorder(true);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Edit Payment Method'))
|
||||
|
@ -74,15 +86,15 @@ final class PhortunePaymentMethodEditController
|
|||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$box,
|
||||
));
|
||||
->setFooter(
|
||||
array(
|
||||
$box,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle(pht('Edit Payment Method'))
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneSubscriptionEditController extends PhortuneController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$added = $request->getBool('added');
|
||||
|
||||
$subscription = id(new PhortuneSubscriptionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($request->getURIData('id')))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$subscription) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
|
||||
$viewer,
|
||||
$request,
|
||||
$subscription->getURI());
|
||||
$merchant = $subscription->getMerchant();
|
||||
$account = $subscription->getAccount();
|
||||
|
||||
$title = pht('Subscription: %s', $subscription->getSubscriptionName());
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($subscription->getSubscriptionName());
|
||||
|
||||
$view_uri = $subscription->getURI();
|
||||
|
||||
$valid_methods = id(new PhortunePaymentMethodQuery())
|
||||
->setViewer($viewer)
|
||||
->withAccountPHIDs(array($account->getPHID()))
|
||||
->withStatuses(
|
||||
array(
|
||||
PhortunePaymentMethod::STATUS_ACTIVE,
|
||||
))
|
||||
->withMerchantPHIDs(array($merchant->getPHID()))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->execute();
|
||||
$valid_methods = mpull($valid_methods, null, 'getPHID');
|
||||
|
||||
$current_phid = $subscription->getDefaultPaymentMethodPHID();
|
||||
|
||||
$e_method = null;
|
||||
if ($current_phid && empty($valid_methods[$current_phid])) {
|
||||
$e_method = pht('Needs Update');
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
$default_method_phid = $request->getStr('defaultPaymentMethodPHID');
|
||||
if (!$default_method_phid) {
|
||||
$default_method_phid = null;
|
||||
$e_method = null;
|
||||
} else if (empty($valid_methods[$default_method_phid])) {
|
||||
$e_method = pht('Invalid');
|
||||
if ($default_method_phid == $current_phid) {
|
||||
$errors[] = pht(
|
||||
'This subscription is configured to autopay with a payment method '.
|
||||
'that has been deleted. Choose a valid payment method or disable '.
|
||||
'autopay.');
|
||||
} else {
|
||||
$errors[] = pht('You must select a valid default payment method.');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We should use transactions here, and move the validation logic
|
||||
// inside the Editor.
|
||||
|
||||
if (!$errors) {
|
||||
$subscription->setDefaultPaymentMethodPHID($default_method_phid);
|
||||
$subscription->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($view_uri);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the option to disable autopay.
|
||||
$disable_options = array(
|
||||
'' => pht('(Disable Autopay)'),
|
||||
);
|
||||
|
||||
// Don't require the user to make a valid selection if the current method
|
||||
// has become invalid.
|
||||
if ($current_phid && empty($valid_methods[$current_phid])) {
|
||||
$current_options = array(
|
||||
$current_phid => pht('<Deleted Payment Method>'),
|
||||
);
|
||||
} else {
|
||||
$current_options = array();
|
||||
}
|
||||
|
||||
// Add any available options.
|
||||
$valid_options = mpull($valid_methods, 'getFullDisplayName', 'getPHID');
|
||||
|
||||
$options = $disable_options + $current_options + $valid_options;
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$this->addAccountCrumb($crumbs, $account);
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Subscription %d', $subscription->getID()),
|
||||
$view_uri);
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
|
||||
$uri = $this->getApplicationURI($account->getID().'/card/new/');
|
||||
$uri = new PhutilURI($uri);
|
||||
$uri->replaceQueryParam('merchantID', $merchant->getID());
|
||||
$uri->replaceQueryParam('subscriptionID', $subscription->getID());
|
||||
|
||||
$add_method_button = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $uri,
|
||||
'class' => 'button button-grey',
|
||||
),
|
||||
pht('Add Payment Method...'));
|
||||
|
||||
$radio = id(new AphrontFormRadioButtonControl())
|
||||
->setName('defaultPaymentMethodPHID')
|
||||
->setLabel(pht('Autopay With'))
|
||||
->setValue($current_phid)
|
||||
->setError($e_method);
|
||||
|
||||
foreach ($options as $key => $value) {
|
||||
$radio->addButton($key, $value, null);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild($radio)
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setValue($add_method_button))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Save Changes'))
|
||||
->addCancelButton($view_uri));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setUser($viewer)
|
||||
->setHeaderText(pht('Subscription'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setFormErrors($errors)
|
||||
->appendChild($form);
|
||||
|
||||
if ($added) {
|
||||
$info_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_SUCCESS)
|
||||
->appendChild(pht('Payment method has been successfully added.'));
|
||||
$box->setInfoView($info_view);
|
||||
}
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Edit %s', $subscription->getSubscriptionName()))
|
||||
->setHeaderIcon('fa-pencil');
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$box,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue