mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-28 16:30:59 +01:00
Badges v0.1
Summary: Basic plumbing for Badges application. - You can make Badges. - You can look at a list of them. - They can be edited. - They can be assigned to people. - You can revoke them from people. - You can subscribe to them. Test Plan: Make Badges with various options. Give them to people. Take them away from people. Reviewers: lpriestley, epriestley Reviewed By: epriestley Subscribers: tycho.tatitscheff, johnny-bit, epriestley, Korvin Maniphest Tasks: T6526 Differential Revision: https://secure.phabricator.com/D13626
This commit is contained in:
parent
fdd6351a64
commit
ffadf64751
34 changed files with 2317 additions and 8 deletions
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
return array(
|
||||
'names' => array(
|
||||
'core.pkg.css' => 'b5cc2f39',
|
||||
'core.pkg.css' => 'f79ebe46',
|
||||
'core.pkg.js' => 'a590b451',
|
||||
'darkconsole.pkg.js' => 'e7393ebb',
|
||||
'differential.pkg.css' => '9451634c',
|
||||
|
@ -142,10 +142,10 @@ return array(
|
|||
'rsrc/css/phui/phui-info-view.css' => '5b16bac6',
|
||||
'rsrc/css/phui/phui-list.css' => '125599df',
|
||||
'rsrc/css/phui/phui-object-box.css' => '407eaf5a',
|
||||
'rsrc/css/phui/phui-object-item-list-view.css' => 'fc19bfc1',
|
||||
'rsrc/css/phui/phui-object-item-list-view.css' => 'a1b990b7',
|
||||
'rsrc/css/phui/phui-pager.css' => 'bea33d23',
|
||||
'rsrc/css/phui/phui-pinboard-view.css' => '2495140e',
|
||||
'rsrc/css/phui/phui-property-list-view.css' => '1baf23eb',
|
||||
'rsrc/css/phui/phui-property-list-view.css' => 'aeb09581',
|
||||
'rsrc/css/phui/phui-remarkup-preview.css' => '867f85b3',
|
||||
'rsrc/css/phui/phui-spacing.css' => '042804d6',
|
||||
'rsrc/css/phui/phui-status.css' => '888cedb8',
|
||||
|
@ -797,10 +797,10 @@ return array(
|
|||
'phui-inline-comment-view-css' => '9fadd6b8',
|
||||
'phui-list-view-css' => '125599df',
|
||||
'phui-object-box-css' => '407eaf5a',
|
||||
'phui-object-item-list-view-css' => 'fc19bfc1',
|
||||
'phui-object-item-list-view-css' => 'a1b990b7',
|
||||
'phui-pager-css' => 'bea33d23',
|
||||
'phui-pinboard-view-css' => '2495140e',
|
||||
'phui-property-list-view-css' => '1baf23eb',
|
||||
'phui-property-list-view-css' => 'aeb09581',
|
||||
'phui-remarkup-preview-css' => '867f85b3',
|
||||
'phui-spacing-css' => '042804d6',
|
||||
'phui-status-list-view-css' => '888cedb8',
|
||||
|
|
54
resources/sql/autopatches/20150712.badges.1.sql
Normal file
54
resources/sql/autopatches/20150712.badges.1.sql
Normal file
|
@ -0,0 +1,54 @@
|
|||
CREATE TABLE {$NAMESPACE}_badges.badges_badge (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARBINARY(64) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
flavor VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
description LONGTEXT NOT NULL,
|
||||
icon VARCHAR(255) NOT NULL,
|
||||
quality VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
viewPolicy VARBINARY(64) NOT NULL,
|
||||
editPolicy VARBINARY(64) NOT NULL,
|
||||
creatorPHID varbinary(64) NOT NULL,
|
||||
UNIQUE KEY `key_phid` (phid),
|
||||
KEY `key_creator` (creatorPHID, dateModified)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
|
||||
CREATE TABLE {$NAMESPACE}_badges.badges_transaction (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
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),
|
||||
commentVersion INT UNSIGNED NOT NULL,
|
||||
transactionType VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
oldValue LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
newValue LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
contentSource LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
metadata LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
UNIQUE KEY `key_phid` (phid),
|
||||
KEY `key_object` (objectPHID)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
|
||||
CREATE TABLE {$NAMESPACE}_badges.edge (
|
||||
src VARBINARY(64) NOT NULL,
|
||||
type INT UNSIGNED NOT NULL,
|
||||
dst VARBINARY(64) NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
seq INT UNSIGNED NOT NULL,
|
||||
dataID INT UNSIGNED,
|
||||
PRIMARY KEY (src, type, dst),
|
||||
KEY `src` (src, type, dateCreated, seq),
|
||||
UNIQUE KEY `key_dst` (dst, type, src)
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
||||
|
||||
CREATE TABLE {$NAMESPACE}_badges.edgedata (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
data LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT}
|
||||
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -1617,6 +1617,29 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php',
|
||||
'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
|
||||
'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php',
|
||||
'PhabricatorBadgeHasRecipientEdgeType' => 'applications/badges/edge/PhabricatorBadgeHasRecipientEdgeType.php',
|
||||
'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php',
|
||||
'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php',
|
||||
'PhabricatorBadgesController' => 'applications/badges/controller/PhabricatorBadgesController.php',
|
||||
'PhabricatorBadgesCreateCapability' => 'applications/badges/capability/PhabricatorBadgesCreateCapability.php',
|
||||
'PhabricatorBadgesDAO' => 'applications/badges/storage/PhabricatorBadgesDAO.php',
|
||||
'PhabricatorBadgesDefaultEditCapability' => 'applications/badges/capability/PhabricatorBadgesDefaultEditCapability.php',
|
||||
'PhabricatorBadgesDefaultViewCapability' => 'applications/badges/capability/PhabricatorBadgesDefaultViewCapability.php',
|
||||
'PhabricatorBadgesEditController' => 'applications/badges/controller/PhabricatorBadgesEditController.php',
|
||||
'PhabricatorBadgesEditIconController' => 'applications/badges/controller/PhabricatorBadgesEditIconController.php',
|
||||
'PhabricatorBadgesEditRecipientsController' => 'applications/badges/controller/PhabricatorBadgesEditRecipientsController.php',
|
||||
'PhabricatorBadgesEditor' => 'applications/badges/editor/PhabricatorBadgesEditor.php',
|
||||
'PhabricatorBadgesIcon' => 'applications/badges/icon/PhabricatorBadgesIcon.php',
|
||||
'PhabricatorBadgesListController' => 'applications/badges/controller/PhabricatorBadgesListController.php',
|
||||
'PhabricatorBadgesPHIDType' => 'applications/badges/phid/PhabricatorBadgesPHIDType.php',
|
||||
'PhabricatorBadgesQuery' => 'applications/badges/query/PhabricatorBadgesQuery.php',
|
||||
'PhabricatorBadgesRecipientsListView' => 'applications/badges/view/PhabricatorBadgesRecipientsListView.php',
|
||||
'PhabricatorBadgesRemoveRecipientsController' => 'applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php',
|
||||
'PhabricatorBadgesSchemaSpec' => 'applications/badges/storage/PhabricatorBadgesSchemaSpec.php',
|
||||
'PhabricatorBadgesSearchEngine' => 'applications/badges/query/PhabricatorBadgesSearchEngine.php',
|
||||
'PhabricatorBadgesTransaction' => 'applications/badges/storage/PhabricatorBadgesTransaction.php',
|
||||
'PhabricatorBadgesTransactionQuery' => 'applications/badges/query/PhabricatorBadgesTransactionQuery.php',
|
||||
'PhabricatorBadgesViewController' => 'applications/badges/controller/PhabricatorBadgesViewController.php',
|
||||
'PhabricatorBarePageUIExample' => 'applications/uiexample/examples/PhabricatorBarePageUIExample.php',
|
||||
'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
|
||||
'PhabricatorBaseURISetupCheck' => 'applications/config/check/PhabricatorBaseURISetupCheck.php',
|
||||
|
@ -2561,6 +2584,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php',
|
||||
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
|
||||
'PhabricatorRecipientHasBadgeEdgeType' => 'applications/badges/edge/PhabricatorRecipientHasBadgeEdgeType.php',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
|
||||
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
|
||||
'PhabricatorRegistrationProfile' => 'applications/people/storage/PhabricatorRegistrationProfile.php',
|
||||
|
@ -5339,6 +5363,36 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthValidateController' => 'PhabricatorAuthController',
|
||||
'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorAutoEventListener' => 'PhabricatorEventListener',
|
||||
'PhabricatorBadgeHasRecipientEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorBadgesApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorBadgesBadge' => array(
|
||||
'PhabricatorBadgesDAO',
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorSubscribableInterface',
|
||||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorBadgesController' => 'PhabricatorController',
|
||||
'PhabricatorBadgesCreateCapability' => 'PhabricatorPolicyCapability',
|
||||
'PhabricatorBadgesDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorBadgesDefaultEditCapability' => 'PhabricatorPolicyCapability',
|
||||
'PhabricatorBadgesDefaultViewCapability' => 'PhabricatorPolicyCapability',
|
||||
'PhabricatorBadgesEditController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesEditIconController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesEditRecipientsController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorBadgesIcon' => 'Phobject',
|
||||
'PhabricatorBadgesListController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorBadgesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorBadgesRecipientsListView' => 'AphrontTagView',
|
||||
'PhabricatorBadgesRemoveRecipientsController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'PhabricatorBadgesSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorBadgesTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorBadgesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorBadgesViewController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBarePageUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorBarePageView' => 'AphrontPageView',
|
||||
'PhabricatorBaseURISetupCheck' => 'PhabricatorSetupCheck',
|
||||
|
@ -6448,6 +6502,7 @@ phutil_register_library_map(array(
|
|||
'Iterator',
|
||||
),
|
||||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
|
||||
'PhabricatorRegistrationProfile' => 'Phobject',
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesApplication extends PhabricatorApplication {
|
||||
|
||||
public function getName() {
|
||||
return pht('Badges');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
return '/badges/';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Achievements and Notority');
|
||||
}
|
||||
|
||||
public function getFontIcon() {
|
||||
return 'fa-trophy';
|
||||
}
|
||||
|
||||
public function getFlavorText() {
|
||||
return pht('Build self esteem through gamification.');
|
||||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
return self::GROUP_UTILITIES;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isPrototype() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/badges/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhabricatorBadgesListController',
|
||||
'create/'
|
||||
=> 'PhabricatorBadgesEditController',
|
||||
'edit/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhabricatorBadgesEditController',
|
||||
'view/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhabricatorBadgesViewController',
|
||||
'icon/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorBadgesEditIconController',
|
||||
'icon/'
|
||||
=> 'PhabricatorBadgesEditIconController',
|
||||
'recipients/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorBadgesEditRecipientsController',
|
||||
'recipients/(?P<id>[1-9]\d*)/remove/'
|
||||
=> 'PhabricatorBadgesRemoveRecipientsController',
|
||||
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCustomCapabilities() {
|
||||
return array(
|
||||
PhabricatorBadgesCreateCapability::CAPABILITY => array(
|
||||
'default' => PhabricatorPolicies::POLICY_ADMIN,
|
||||
'caption' => pht('Default create policy for badges.'),
|
||||
),
|
||||
PhabricatorBadgesDefaultEditCapability::CAPABILITY => array(
|
||||
'default' => PhabricatorPolicies::POLICY_ADMIN,
|
||||
'caption' => pht('Default edit policy for badges.'),
|
||||
'template' => PhabricatorBadgesPHIDType::TYPECONST,
|
||||
),
|
||||
PhabricatorBadgesDefaultViewCapability::CAPABILITY => array(
|
||||
'caption' => pht('Default view policy for badges.'),
|
||||
'template' => PhabricatorBadgesPHIDType::TYPECONST,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesCreateCapability
|
||||
extends PhabricatorPolicyCapability {
|
||||
|
||||
const CAPABILITY = 'badges.default.create';
|
||||
|
||||
public function getCapabilityName() {
|
||||
return pht('Can Create Badges');
|
||||
}
|
||||
|
||||
public function describeCapabilityRejection() {
|
||||
return pht('You do not have permission to create badges.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesDefaultEditCapability
|
||||
extends PhabricatorPolicyCapability {
|
||||
|
||||
const CAPABILITY = 'badges.default.edit';
|
||||
|
||||
public function getCapabilityName() {
|
||||
return pht('Default Edit Badges');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesDefaultViewCapability extends
|
||||
PhabricatorPolicyCapability {
|
||||
|
||||
const CAPABILITY = 'badges.default.view';
|
||||
|
||||
public function getCapabilityName() {
|
||||
return pht('Default View Policy');
|
||||
}
|
||||
|
||||
public function shouldAllowPublicPolicySetting() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorBadgesController extends PhabricatorController {}
|
|
@ -0,0 +1,222 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesEditController
|
||||
extends PhabricatorBadgesController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if ($id) {
|
||||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$is_new = false;
|
||||
} else {
|
||||
$badge = PhabricatorBadgesBadge::initializeNewBadge($viewer);
|
||||
$is_new = true;
|
||||
}
|
||||
|
||||
if ($is_new) {
|
||||
$title = pht('Create Badge');
|
||||
$button_text = pht('Create Badge');
|
||||
$cancel_uri = $this->getApplicationURI();
|
||||
} else {
|
||||
$title = pht(
|
||||
'Edit %s',
|
||||
$badge->getName());
|
||||
$button_text = pht('Save Changes');
|
||||
$cancel_uri = $this->getApplicationURI('view/'.$id.'/');
|
||||
}
|
||||
|
||||
$e_name = true;
|
||||
$v_name = $badge->getName();
|
||||
|
||||
$v_icon = $badge->getIcon();
|
||||
|
||||
$v_flav = $badge->getFlavor();
|
||||
$v_desc = $badge->getDescription();
|
||||
$v_qual = $badge->getQuality();
|
||||
$v_stat = $badge->getStatus();
|
||||
|
||||
$v_edit = $badge->getEditPolicy();
|
||||
$v_view = $badge->getViewPolicy();
|
||||
|
||||
$validation_exception = null;
|
||||
if ($request->isFormPost()) {
|
||||
$v_name = $request->getStr('name');
|
||||
$v_flav = $request->getStr('flavor');
|
||||
$v_desc = $request->getStr('description');
|
||||
$v_icon = $request->getStr('icon');
|
||||
$v_stat = $request->getStr('status');
|
||||
$v_qual = $request->getStr('quality');
|
||||
|
||||
$v_view = $request->getStr('viewPolicy');
|
||||
$v_edit = $request->getStr('editPolicy');
|
||||
|
||||
$type_name = PhabricatorBadgesTransaction::TYPE_NAME;
|
||||
$type_flav = PhabricatorBadgesTransaction::TYPE_FLAVOR;
|
||||
$type_desc = PhabricatorBadgesTransaction::TYPE_DESCRIPTION;
|
||||
$type_icon = PhabricatorBadgesTransaction::TYPE_ICON;
|
||||
$type_qual = PhabricatorBadgesTransaction::TYPE_QUALITY;
|
||||
$type_stat = PhabricatorBadgesTransaction::TYPE_STATUS;
|
||||
|
||||
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_name)
|
||||
->setNewValue($v_name);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_flav)
|
||||
->setNewValue($v_flav);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_desc)
|
||||
->setNewValue($v_desc);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_icon)
|
||||
->setNewValue($v_icon);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_qual)
|
||||
->setNewValue($v_qual);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_stat)
|
||||
->setNewValue($v_stat);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_view)
|
||||
->setNewValue($v_view);
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType($type_edit)
|
||||
->setNewValue($v_edit);
|
||||
|
||||
$editor = id(new PhabricatorBadgesEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true);
|
||||
|
||||
try {
|
||||
$editor->applyTransactions($badge, $xactions);
|
||||
$return_uri = $this->getApplicationURI('view/'.$badge->getID().'/');
|
||||
return id(new AphrontRedirectResponse())->setURI($return_uri);
|
||||
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
$validation_exception = $ex;
|
||||
|
||||
$e_name = $ex->getShortMessage($type_name);
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_new) {
|
||||
$icon_uri = $this->getApplicationURI('icon/');
|
||||
} else {
|
||||
$icon_uri = $this->getApplicationURI('icon/'.$badge->getID().'/');
|
||||
}
|
||||
$icon_display = PhabricatorBadgesIcon::renderIconForChooser($v_icon);
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($viewer)
|
||||
->setObject($badge)
|
||||
->execute();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setName('name')
|
||||
->setLabel(pht('Name'))
|
||||
->setValue($v_name)
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setName('flavor')
|
||||
->setLabel(pht('Flavor Text'))
|
||||
->setValue($v_flav))
|
||||
->appendChild(
|
||||
id(new AphrontFormChooseButtonControl())
|
||||
->setLabel(pht('Icon'))
|
||||
->setName('icon')
|
||||
->setDisplayValue($icon_display)
|
||||
->setButtonText(pht('Choose Icon...'))
|
||||
->setChooseURI($icon_uri)
|
||||
->setValue($v_icon))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setName('quality')
|
||||
->setLabel(pht('Quality'))
|
||||
->setValue($v_qual)
|
||||
->setOptions($badge->getQualityNameMap()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Status'))
|
||||
->setName('status')
|
||||
->setValue($v_stat)
|
||||
->setOptions($badge->getStatusNameMap()))
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($viewer)
|
||||
->setName('description')
|
||||
->setLabel(pht('Description'))
|
||||
->setValue($v_desc))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('viewPolicy')
|
||||
->setPolicyObject($badge)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
|
||||
->setValue($v_view)
|
||||
->setPolicies($policies))
|
||||
->appendChild(
|
||||
id(new AphrontFormPolicyControl())
|
||||
->setName('editPolicy')
|
||||
->setPolicyObject($badge)
|
||||
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
|
||||
->setValue($v_edit)
|
||||
->setPolicies($policies))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($button_text)
|
||||
->addCancelButton($cancel_uri));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
if ($is_new) {
|
||||
$crumbs->addTextCrumb(pht('Create Badge'));
|
||||
} else {
|
||||
$crumbs->addTextCrumb(
|
||||
$badge->getName(),
|
||||
'/badges/view/'.$badge->getID().'/');
|
||||
$crumbs->addTextCrumb(pht('Edit'));
|
||||
}
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setValidationException($validation_exception)
|
||||
->setHeaderText($title)
|
||||
->appendChild($form);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$box,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesEditIconController
|
||||
extends PhabricatorBadgesController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
if ($id) {
|
||||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$cancel_uri =
|
||||
$this->getApplicationURI('view/'.$badge->getID().'/');
|
||||
$badge_icon = $badge->getIcon();
|
||||
} else {
|
||||
$this->requireApplicationCapability(
|
||||
PhabricatorBadgesCreateCapability::CAPABILITY);
|
||||
|
||||
$cancel_uri = '/badges/';
|
||||
$badge_icon = $request->getStr('value');
|
||||
}
|
||||
|
||||
require_celerity_resource('project-icon-css');
|
||||
Javelin::initBehavior('phabricator-tooltips');
|
||||
|
||||
$badge_icons = PhabricatorBadgesIcon::getIconMap();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$v_icon = $request->getStr('icon');
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent(
|
||||
array(
|
||||
'value' => $v_icon,
|
||||
'display' => PhabricatorBadgesIcon::renderIconForChooser($v_icon),
|
||||
));
|
||||
}
|
||||
|
||||
$ii = 0;
|
||||
$buttons = array();
|
||||
foreach ($badge_icons as $icon => $label) {
|
||||
$view = id(new PHUIIconView())
|
||||
->setIconFont($icon);
|
||||
|
||||
$aural = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'aural' => true,
|
||||
),
|
||||
pht('Choose "%s" Icon', $label));
|
||||
|
||||
if ($icon == $badge_icon) {
|
||||
$class_extra = ' selected';
|
||||
} else {
|
||||
$class_extra = null;
|
||||
}
|
||||
|
||||
$buttons[] = javelin_tag(
|
||||
'button',
|
||||
array(
|
||||
'class' => 'icon-button'.$class_extra,
|
||||
'name' => 'icon',
|
||||
'value' => $icon,
|
||||
'type' => 'submit',
|
||||
'sigil' => 'has-tooltip',
|
||||
'meta' => array(
|
||||
'tip' => $label,
|
||||
),
|
||||
),
|
||||
array(
|
||||
$aural,
|
||||
$view,
|
||||
));
|
||||
if ((++$ii % 4) == 0) {
|
||||
$buttons[] = phutil_tag('br');
|
||||
}
|
||||
}
|
||||
|
||||
$buttons = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'icon-grid',
|
||||
),
|
||||
$buttons);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Choose Badge Icon'))
|
||||
->appendChild($buttons)
|
||||
->addCancelButton($cancel_uri);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesEditRecipientsController
|
||||
extends PhabricatorBadgesController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needRecipients(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$recipient_phids = $badge->getRecipientPHIDs();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$recipient_spec = array();
|
||||
|
||||
$remove = $request->getStr('remove');
|
||||
if ($remove) {
|
||||
$recipient_spec['-'] = array_fuse(array($remove));
|
||||
}
|
||||
|
||||
$add_recipients = $request->getArr('phids');
|
||||
if ($add_recipients) {
|
||||
$recipient_spec['+'] = array_fuse($add_recipients);
|
||||
}
|
||||
|
||||
$type_recipient = PhabricatorBadgeHasRecipientEdgeType::EDGECONST;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $type_recipient)
|
||||
->setNewValue($recipient_spec);
|
||||
|
||||
$editor = id(new PhabricatorBadgesEditor($badge))
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($badge, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($request->getRequestURI());
|
||||
}
|
||||
|
||||
$recipient_phids = array_reverse($recipient_phids);
|
||||
$handles = $this->loadViewerHandles($recipient_phids);
|
||||
|
||||
$state = array();
|
||||
foreach ($handles as $handle) {
|
||||
$state[] = array(
|
||||
'phid' => $handle->getPHID(),
|
||||
'name' => $handle->getFullName(),
|
||||
);
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$badge,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$form_box = null;
|
||||
$title = pht('Add Recipient');
|
||||
if ($can_edit) {
|
||||
$header_name = pht('Edit Recipients');
|
||||
$view_uri = $this->getApplicationURI('view/'.$badge->getID().'/');
|
||||
|
||||
$form = new AphrontFormView();
|
||||
$form
|
||||
->setUser($viewer)
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setName('phids')
|
||||
->setLabel(pht('Add Recipients'))
|
||||
->setDatasource(new PhabricatorPeopleDatasource()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->addCancelButton($view_uri)
|
||||
->setValue(pht('Add Recipients')));
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setForm($form);
|
||||
}
|
||||
|
||||
$recipient_list = id(new PhabricatorBadgesRecipientsListView())
|
||||
->setBadge($badge)
|
||||
->setHandles($handles)
|
||||
->setUser($viewer);
|
||||
|
||||
$badge_url = $this->getApplicationURI('view/'.$id.'/');
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($badge->getName(), $badge_url);
|
||||
$crumbs->addTextCrumb(pht('Recipients'));
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$form_box,
|
||||
$recipient_list,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesListController
|
||||
extends PhabricatorBadgesController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$query_key = $request->getURIData('queryKey');
|
||||
$controller = id(new PhabricatorApplicationSearchController())
|
||||
->setQueryKey($query_key)
|
||||
->setSearchEngine(new PhabricatorBadgesSearchEngine())
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
public function buildSideNavView() {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
id(new PhabricatorBadgesSearchEngine())
|
||||
->setViewer($user)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
|
||||
$can_create = $this->hasApplicationCapability(
|
||||
PhabricatorBadgesCreateCapability::CAPABILITY);
|
||||
|
||||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Create Badge'))
|
||||
->setHref($this->getApplicationURI('create/'))
|
||||
->setIcon('fa-plus-square')
|
||||
->setDisabled(!$can_create)
|
||||
->setWorkflow(!$can_create));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesRemoveRecipientsController
|
||||
extends PhabricatorBadgesController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needRecipients(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$recipient_phids = $badge->getRecipientPHIDs();
|
||||
$remove_phid = $request->getStr('phid');
|
||||
|
||||
if (!in_array($remove_phid, $recipient_phids)) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$recipients_uri =
|
||||
$this->getApplicationURI('recipients/'.$badge->getID().'/');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$recipient_spec = array();
|
||||
$recipient_spec['-'] = array($remove_phid => $remove_phid);
|
||||
|
||||
$type_recipient = PhabricatorBadgeHasRecipientEdgeType::EDGECONST;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorBadgesTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue('edge:type', $type_recipient)
|
||||
->setNewValue($recipient_spec);
|
||||
|
||||
$editor = id(new PhabricatorBadgesEditor($badge))
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
->setContinueOnMissingFields(true)
|
||||
->applyTransactions($badge, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($recipients_uri);
|
||||
}
|
||||
|
||||
$handle = id(new PhabricatorHandleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($remove_phid))
|
||||
->executeOne();
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($viewer)
|
||||
->setTitle(pht('Really Revoke Badge?'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Really revoke the badge "%s" from %s?',
|
||||
phutil_tag('strong', array(), $badge->getName()),
|
||||
phutil_tag('strong', array(), $handle->getName())))
|
||||
->addCancelButton($recipients_uri)
|
||||
->addSubmitButton(pht('Revoke Badge'));
|
||||
|
||||
return $dialog;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesViewController
|
||||
extends PhabricatorBadgesController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needRecipients(true)
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($badge->getName());
|
||||
$title = $badge->getName();
|
||||
|
||||
if ($badge->isClosed()) {
|
||||
$status_icon = 'fa-ban';
|
||||
$status_color = 'dark';
|
||||
} else {
|
||||
$status_icon = 'fa-check';
|
||||
$status_color = 'bluegrey';
|
||||
}
|
||||
$status_name = idx(
|
||||
PhabricatorBadgesBadge::getStatusNameMap(),
|
||||
$badge->getStatus());
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($badge->getName())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($badge)
|
||||
->setStatus($status_icon, $status_color, $status_name);
|
||||
|
||||
$properties = $this->buildPropertyListView($badge);
|
||||
$actions = $this->buildActionListView($badge);
|
||||
$properties->setActionList($actions);
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->addPropertyList($properties);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$badge,
|
||||
new PhabricatorBadgesTransactionQuery());
|
||||
$timeline
|
||||
->setShouldTerminate(true);
|
||||
|
||||
$recipient_phids = $badge->getRecipientPHIDs();
|
||||
$recipient_phids = array_reverse($recipient_phids);
|
||||
$handles = $this->loadViewerHandles($recipient_phids);
|
||||
|
||||
$recipient_list = id(new PhabricatorBadgesRecipientsListView())
|
||||
->setBadge($badge)
|
||||
->setHandles($handles)
|
||||
->setUser($viewer);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$box,
|
||||
$recipient_list,
|
||||
$timeline,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
'pageObjects' => array($badge->getPHID()),
|
||||
));
|
||||
}
|
||||
|
||||
private function buildPropertyListView(PhabricatorBadgesBadge $badge) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setUser($viewer)
|
||||
->setObject($badge);
|
||||
|
||||
$quality = idx($badge->getQualityNameMap(), $badge->getQuality());
|
||||
$icon = idx($badge->getIconNameMap(), $badge->getIcon());
|
||||
|
||||
$view->addProperty(
|
||||
pht('Quality'),
|
||||
$quality);
|
||||
|
||||
$view->addProperty(
|
||||
pht('Icon'),
|
||||
$icon);
|
||||
|
||||
$view->addProperty(
|
||||
pht('Flavor'),
|
||||
$badge->getFlavor());
|
||||
|
||||
$view->invokeWillRenderEvent();
|
||||
|
||||
$description = $badge->getDescription();
|
||||
if (strlen($description)) {
|
||||
$description = PhabricatorMarkupEngine::renderOneObject(
|
||||
id(new PhabricatorMarkupOneOff())->setContent($description),
|
||||
'default',
|
||||
$viewer);
|
||||
|
||||
$view->addSectionHeader(pht('Description'));
|
||||
$view->addTextContent($description);
|
||||
}
|
||||
|
||||
$badge = id(new PHUIBadgeView())
|
||||
->setIcon($badge->getIcon())
|
||||
->setHeader($badge->getName())
|
||||
->setSubhead($badge->getFlavor())
|
||||
->setQuality($badge->getQuality());
|
||||
|
||||
$view->addTextContent($badge);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildActionListView(PhabricatorBadgesBadge $badge) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $badge->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$badge,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$view = id(new PhabricatorActionListView())
|
||||
->setUser($viewer)
|
||||
->setObject($badge);
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Badge'))
|
||||
->setIcon('fa-pencil')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit)
|
||||
->setHref($this->getApplicationURI("/edit/{$id}/")));
|
||||
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName('Manage Recipients')
|
||||
->setIcon('fa-users')
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref($this->getApplicationURI("/recipients/{$id}/")));
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgeHasRecipientEdgeType
|
||||
extends PhabricatorEdgeType {
|
||||
|
||||
const EDGECONST = 59;
|
||||
|
||||
public function getInverseEdgeConstant() {
|
||||
return PhabricatorRecipientHasBadgeEdgeType::EDGECONST;
|
||||
}
|
||||
|
||||
public function shouldWriteInverseTransactions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTransactionAddString(
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s awarded %s recipients(s): %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getTransactionRemoveString(
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s revoked %s recipients(s): %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getTransactionEditString(
|
||||
$actor,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited recipient(s), awarded %s: %s; revoked %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedAddString(
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s awarded %s recipient(s) for %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$object,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getFeedRemoveString(
|
||||
$actor,
|
||||
$object,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s revoked %s recipient(s) for %s: %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$object,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedEditString(
|
||||
$actor,
|
||||
$object,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited recipient(s) for %s, awarded %s: %s; revoked %s: %s.',
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRecipientHasBadgeEdgeType
|
||||
extends PhabricatorEdgeType {
|
||||
|
||||
const EDGECONST = 58;
|
||||
|
||||
public function getInverseEdgeConstant() {
|
||||
return PhabricatorBadgeHasRecipientEdgeType::EDGECONST;
|
||||
}
|
||||
|
||||
public function shouldWriteInverseTransactions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getTransactionAddString(
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s added %s badge(s): %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getTransactionRemoveString(
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s revoked %s badge(s): %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getTransactionEditString(
|
||||
$actor,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited badge(s), added %s: %s; revoked %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedAddString(
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges) {
|
||||
|
||||
return pht(
|
||||
'%s added %s badge(s) for %s: %s.',
|
||||
$actor,
|
||||
$add_count,
|
||||
$object,
|
||||
$add_edges);
|
||||
}
|
||||
|
||||
public function getFeedRemoveString(
|
||||
$actor,
|
||||
$object,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s revoked %s badge(s) for %s: %s.',
|
||||
$actor,
|
||||
$rem_count,
|
||||
$object,
|
||||
$rem_edges);
|
||||
}
|
||||
|
||||
public function getFeedEditString(
|
||||
$actor,
|
||||
$object,
|
||||
$total_count,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges) {
|
||||
|
||||
return pht(
|
||||
'%s edited badge(s) for %s, added %s: %s; revoked %s: %s.',
|
||||
$actor,
|
||||
$object,
|
||||
$add_count,
|
||||
$add_edges,
|
||||
$rem_count,
|
||||
$rem_edges);
|
||||
}
|
||||
}
|
194
src/applications/badges/editor/PhabricatorBadgesEditor.php
Normal file
194
src/applications/badges/editor/PhabricatorBadgesEditor.php
Normal file
|
@ -0,0 +1,194 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
public function getEditorApplicationClass() {
|
||||
return 'PhabricatorBadgesApplication';
|
||||
}
|
||||
|
||||
public function getEditorObjectsDescription() {
|
||||
return pht('Badges');
|
||||
}
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = PhabricatorBadgesTransaction::TYPE_NAME;
|
||||
$types[] = PhabricatorBadgesTransaction::TYPE_FLAVOR;
|
||||
$types[] = PhabricatorBadgesTransaction::TYPE_DESCRIPTION;
|
||||
$types[] = PhabricatorBadgesTransaction::TYPE_ICON;
|
||||
$types[] = PhabricatorBadgesTransaction::TYPE_STATUS;
|
||||
$types[] = PhabricatorBadgesTransaction::TYPE_QUALITY;
|
||||
|
||||
$types[] = PhabricatorTransactions::TYPE_EDGE;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorBadgesTransaction::TYPE_NAME:
|
||||
return $object->getName();
|
||||
case PhabricatorBadgesTransaction::TYPE_FLAVOR:
|
||||
return $object->getFlavor();
|
||||
case PhabricatorBadgesTransaction::TYPE_DESCRIPTION:
|
||||
return $object->getDescription();
|
||||
case PhabricatorBadgesTransaction::TYPE_ICON:
|
||||
return $object->getIcon();
|
||||
case PhabricatorBadgesTransaction::TYPE_QUALITY:
|
||||
return $object->getQuality();
|
||||
case PhabricatorBadgesTransaction::TYPE_STATUS:
|
||||
return $object->getStatus();
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorBadgesTransaction::TYPE_NAME:
|
||||
case PhabricatorBadgesTransaction::TYPE_FLAVOR:
|
||||
case PhabricatorBadgesTransaction::TYPE_DESCRIPTION:
|
||||
case PhabricatorBadgesTransaction::TYPE_ICON:
|
||||
case PhabricatorBadgesTransaction::TYPE_STATUS:
|
||||
case PhabricatorBadgesTransaction::TYPE_QUALITY:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$type = $xaction->getTransactionType();
|
||||
switch ($type) {
|
||||
case PhabricatorBadgesTransaction::TYPE_NAME:
|
||||
$object->setName($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorBadgesTransaction::TYPE_FLAVOR:
|
||||
$object->setFlavor($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorBadgesTransaction::TYPE_DESCRIPTION:
|
||||
$object->setDescription($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorBadgesTransaction::TYPE_ICON:
|
||||
$object->setIcon($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorBadgesTransaction::TYPE_QUALITY:
|
||||
$object->setQuality($xaction->getNewValue());
|
||||
return;
|
||||
case PhabricatorBadgesTransaction::TYPE_STATUS:
|
||||
$object->setStatus($xaction->getNewValue());
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomInternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
$type = $xaction->getTransactionType();
|
||||
switch ($type) {
|
||||
case PhabricatorBadgesTransaction::TYPE_NAME:
|
||||
case PhabricatorBadgesTransaction::TYPE_FLAVOR:
|
||||
case PhabricatorBadgesTransaction::TYPE_DESCRIPTION:
|
||||
case PhabricatorBadgesTransaction::TYPE_ICON:
|
||||
case PhabricatorBadgesTransaction::TYPE_STATUS:
|
||||
case PhabricatorBadgesTransaction::TYPE_QUALITY:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
protected function validateTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
$type,
|
||||
array $xactions) {
|
||||
|
||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||
|
||||
switch ($type) {
|
||||
case PhabricatorBadgesTransaction::TYPE_NAME:
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
$object->getName(),
|
||||
$xactions);
|
||||
|
||||
if ($missing) {
|
||||
$error = new PhabricatorApplicationTransactionValidationError(
|
||||
$type,
|
||||
pht('Required'),
|
||||
pht('Badge name is required.'),
|
||||
nonempty(last($xactions), null));
|
||||
|
||||
$error->setIsMissingFieldError(true);
|
||||
$errors[] = $error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
protected function shouldPublishFeedStory(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
|
||||
return id(new PhabricatorMacroReplyHandler())
|
||||
->setMailReceiver($object);
|
||||
}
|
||||
|
||||
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
|
||||
$name = $object->getName();
|
||||
$id = $object->getID();
|
||||
$name = pht('Badge %d', $id);
|
||||
return id(new PhabricatorMetaMTAMail())
|
||||
->setSubject($name)
|
||||
->addHeader('Thread-Topic', $name);
|
||||
}
|
||||
|
||||
protected function getMailTo(PhabricatorLiskDAO $object) {
|
||||
return array(
|
||||
$this->requireActor()->getPHID(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function buildMailBody(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
||||
$description = $object->getDescription();
|
||||
$body = parent::buildMailBody($object, $xactions);
|
||||
|
||||
if (strlen($description)) {
|
||||
$body->addTextSection(
|
||||
pht('BADGE DESCRIPTION'),
|
||||
$object->getDescription());
|
||||
}
|
||||
|
||||
$body->addLinkSection(
|
||||
pht('BADGE DETAIL'),
|
||||
PhabricatorEnv::getProductionURI('/badge/view/'.$object->getID().'/'));
|
||||
return $body;
|
||||
}
|
||||
|
||||
protected function getMailSubjectPrefix() {
|
||||
return pht('[Badge]');
|
||||
}
|
||||
|
||||
}
|
53
src/applications/badges/icon/PhabricatorBadgesIcon.php
Normal file
53
src/applications/badges/icon/PhabricatorBadgesIcon.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesIcon extends Phobject {
|
||||
|
||||
public static function getIconMap() {
|
||||
return
|
||||
array(
|
||||
'fa-star' => pht('Superstar'),
|
||||
'fa-user' => pht('Average Person'),
|
||||
'fa-bug' => pht('Ladybug'),
|
||||
'fa-users' => pht('Triplets'),
|
||||
|
||||
'fa-book' => pht('Nominomicon'),
|
||||
'fa-rocket' => pht('Escape Route'),
|
||||
'fa-life-ring' => pht('Foam Circle'),
|
||||
'fa-birthday-cake' => pht('Cake Day'),
|
||||
|
||||
'fa-camera-retro' => pht('Leica Enthusiast'),
|
||||
'fa-beer' => pht('Liquid Lunch'),
|
||||
'fa-gift' => pht('Free Stuff'),
|
||||
'fa-eye' => pht('Eye See You'),
|
||||
|
||||
'fa-heart' => pht('Love is Love'),
|
||||
'fa-trophy' => pht('Winner at Things'),
|
||||
'fa-umbrella' => pht('Rain Defender'),
|
||||
'fa-graduation-cap' => pht('In Debt'),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public static function getLabel($key) {
|
||||
$map = self::getIconMap();
|
||||
return $map[$key];
|
||||
}
|
||||
|
||||
public static function getAPIName($key) {
|
||||
return substr($key, 3);
|
||||
}
|
||||
|
||||
public static function renderIconForChooser($icon) {
|
||||
$badge_icons = self::getIconMap();
|
||||
|
||||
return phutil_tag(
|
||||
'span',
|
||||
array(),
|
||||
array(
|
||||
id(new PHUIIconView())->setIconFont($icon),
|
||||
' ',
|
||||
idx($badge_icons, $icon, pht('Unknown Icon')),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
47
src/applications/badges/phid/PhabricatorBadgesPHIDType.php
Normal file
47
src/applications/badges/phid/PhabricatorBadgesPHIDType.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesPHIDType extends PhabricatorPHIDType {
|
||||
|
||||
const TYPECONST = 'BDGE';
|
||||
|
||||
public function getTypeName() {
|
||||
return pht('Badge');
|
||||
}
|
||||
|
||||
public function newObject() {
|
||||
return new PhabricatorBadgesBadge();
|
||||
}
|
||||
|
||||
public function getPHIDTypeApplicationClass() {
|
||||
return 'PhabricatorBadgesApplication';
|
||||
}
|
||||
|
||||
protected function buildQueryForObjects(
|
||||
PhabricatorObjectQuery $query,
|
||||
array $phids) {
|
||||
|
||||
return id(new PhabricatorBadgesQuery())
|
||||
->withPHIDs($phids);
|
||||
}
|
||||
|
||||
public function loadHandles(
|
||||
PhabricatorHandleQuery $query,
|
||||
array $handles,
|
||||
array $objects) {
|
||||
|
||||
foreach ($handles as $phid => $handle) {
|
||||
$badge = $objects[$phid];
|
||||
|
||||
$id = $badge->getID();
|
||||
$name = $badge->getName();
|
||||
|
||||
if ($badge->isClosed()) {
|
||||
$handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
|
||||
}
|
||||
|
||||
$handle->setName($name);
|
||||
$handle->setURI("/badges/view/{$id}/");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
113
src/applications/badges/query/PhabricatorBadgesQuery.php
Normal file
113
src/applications/badges/query/PhabricatorBadgesQuery.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesQuery
|
||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $qualities;
|
||||
private $statuses;
|
||||
private $recipientPHIDs;
|
||||
|
||||
private $needRecipients;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withPHIDs(array $phids) {
|
||||
$this->phids = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withQualities(array $qualities) {
|
||||
$this->qualities = $qualities;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withStatuses(array $statuses) {
|
||||
$this->statuses = $statuses;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withRecipientPHIDs(array $recipient_phids) {
|
||||
$this->recipientPHIDs = $recipient_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function needRecipients($need_recipients) {
|
||||
$this->needRecipients = $need_recipients;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
return $this->loadStandardPage($this->newResultObject());
|
||||
}
|
||||
|
||||
public function newResultObject() {
|
||||
return new PhabricatorBadgesBadge();
|
||||
}
|
||||
|
||||
protected function didFilterPage(array $badges) {
|
||||
|
||||
if ($this->needRecipients) {
|
||||
$edge_query = id(new PhabricatorEdgeQuery())
|
||||
->withSourcePHIDs(mpull($badges, 'getPHID'))
|
||||
->withEdgeTypes(
|
||||
array(
|
||||
PhabricatorBadgeHasRecipientEdgeType::EDGECONST,
|
||||
));
|
||||
$edge_query->execute();
|
||||
|
||||
foreach ($badges as $badge) {
|
||||
$phids = $edge_query->getDestinationPHIDs(
|
||||
array(
|
||||
$badge->getPHID(),
|
||||
));
|
||||
$badge->attachRecipientPHIDs($phids);
|
||||
}
|
||||
}
|
||||
|
||||
return $badges;
|
||||
}
|
||||
|
||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->qualities !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'quality IN (%Ls)',
|
||||
$this->qualities);
|
||||
}
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'status IN (%Ls)',
|
||||
$this->statuses);
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
return 'PhabricatorBadgesApplication';
|
||||
}
|
||||
|
||||
}
|
143
src/applications/badges/query/PhabricatorBadgesSearchEngine.php
Normal file
143
src/applications/badges/query/PhabricatorBadgesSearchEngine.php
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
public function getResultTypeDescription() {
|
||||
return pht('Badge');
|
||||
}
|
||||
|
||||
public function getApplicationClassName() {
|
||||
return 'PhabricatorBadgesApplication';
|
||||
}
|
||||
|
||||
public function newQuery() {
|
||||
return new PhabricatorBadgesQuery();
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter(
|
||||
'statuses',
|
||||
$this->readListFromRequest($request, 'statuses'));
|
||||
|
||||
$saved->setParameter(
|
||||
'qualities',
|
||||
$this->readListFromRequest($request, 'qualities'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
protected function buildCustomSearchFields() {
|
||||
return array(
|
||||
id(new PhabricatorSearchCheckboxesField())
|
||||
->setKey('qualities')
|
||||
->setLabel(pht('Quality'))
|
||||
->setOptions(
|
||||
id(new PhabricatorBadgesBadge())
|
||||
->getQualityNameMap()),
|
||||
id(new PhabricatorSearchCheckboxesField())
|
||||
->setKey('statuses')
|
||||
->setLabel(pht('Status'))
|
||||
->setOptions(
|
||||
id(new PhabricatorBadgesBadge())
|
||||
->getStatusNameMap()),
|
||||
);
|
||||
}
|
||||
|
||||
protected function buildQueryFromParameters(array $map) {
|
||||
$query = $this->newQuery();
|
||||
|
||||
if ($map['statuses']) {
|
||||
$query->withStatuses($map['statuses']);
|
||||
}
|
||||
|
||||
if ($map['qualities']) {
|
||||
$query->withQualities($map['qualities']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/badges/'.$path;
|
||||
}
|
||||
|
||||
protected function getBuiltinQueryNames() {
|
||||
$names = array();
|
||||
|
||||
$names['open'] = pht('Active Badges');
|
||||
$names['all'] = pht('All Badges');
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
case 'open':
|
||||
return $query->setParameter(
|
||||
'statuses',
|
||||
array(
|
||||
PhabricatorBadgesBadge::STATUS_OPEN,
|
||||
));
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
protected function getRequiredHandlePHIDsForResultList(
|
||||
array $badges,
|
||||
PhabricatorSavedQuery $query) {
|
||||
|
||||
$phids = array();
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $badges,
|
||||
PhabricatorSavedQuery $query,
|
||||
array $handles) {
|
||||
assert_instances_of($badges, 'PhabricatorBadgesBadge');
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$list = id(new PHUIObjectItemListView());
|
||||
foreach ($badges as $badge) {
|
||||
|
||||
$quality = idx($badge->getQualityNameMap(), $badge->getQuality());
|
||||
$mini_badge = id(new PHUIBadgeMiniView())
|
||||
->setHeader($badge->getName())
|
||||
->setIcon($badge->getIcon())
|
||||
->setQuality($badge->getQuality());
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($badge->getName())
|
||||
->setBadge($mini_badge)
|
||||
->setHref('/badges/view/'.$badge->getID().'/')
|
||||
->addAttribute($quality)
|
||||
->addAttribute($badge->getFlavor());
|
||||
|
||||
if ($badge->isClosed()) {
|
||||
$item->setDisabled(true);
|
||||
$item->addIcon('fa-ban', pht('Archived'));
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$result = new PhabricatorApplicationSearchResultView();
|
||||
$result->setObjectList($list);
|
||||
$result->setNoDataString(pht('No badges found.'));
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesTransactionQuery
|
||||
extends PhabricatorApplicationTransactionQuery {
|
||||
|
||||
public function getTemplateApplicationTransaction() {
|
||||
return new PhabricatorBadgesTransaction();
|
||||
}
|
||||
|
||||
}
|
197
src/applications/badges/storage/PhabricatorBadgesBadge.php
Normal file
197
src/applications/badges/storage/PhabricatorBadgesBadge.php
Normal file
|
@ -0,0 +1,197 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
|
||||
implements
|
||||
PhabricatorPolicyInterface,
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorSubscribableInterface,
|
||||
PhabricatorFlaggableInterface,
|
||||
PhabricatorDestructibleInterface {
|
||||
|
||||
protected $name;
|
||||
protected $flavor;
|
||||
protected $description;
|
||||
protected $icon;
|
||||
protected $quality;
|
||||
protected $viewPolicy;
|
||||
protected $editPolicy;
|
||||
protected $status;
|
||||
protected $creatorPHID;
|
||||
|
||||
private $recipientPHIDs = self::ATTACHABLE;
|
||||
|
||||
const STATUS_OPEN = 'open';
|
||||
const STATUS_CLOSED = 'closed';
|
||||
|
||||
const DEFAULT_ICON = 'fa-star';
|
||||
const DEFAULT_QUALITY = 'green';
|
||||
|
||||
const POOR = 'grey';
|
||||
const COMMON = 'white';
|
||||
const UNCOMMON = 'green';
|
||||
const RARE = 'blue';
|
||||
const EPIC = 'indigo';
|
||||
const LEGENDARY = 'orange';
|
||||
const HEIRLOOM = 'yellow';
|
||||
|
||||
public static function getStatusNameMap() {
|
||||
return array(
|
||||
self::STATUS_OPEN => pht('Active'),
|
||||
self::STATUS_CLOSED => pht('Archived'),
|
||||
);
|
||||
}
|
||||
|
||||
public static function getQualityNameMap() {
|
||||
return array(
|
||||
self::POOR => pht('Poor'),
|
||||
self::COMMON => pht('Common'),
|
||||
self::UNCOMMON => pht('Uncommon'),
|
||||
self::RARE => pht('Rare'),
|
||||
self::EPIC => pht('Epic'),
|
||||
self::LEGENDARY => pht('Legendary'),
|
||||
self::HEIRLOOM => pht('Heirloom'),
|
||||
);
|
||||
}
|
||||
|
||||
public static function getIconNameMap() {
|
||||
return PhabricatorBadgesIcon::getIconMap();
|
||||
}
|
||||
|
||||
public static function initializeNewBadge(PhabricatorUser $actor) {
|
||||
$app = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($actor)
|
||||
->withClasses(array('PhabricatorBadgesApplication'))
|
||||
->executeOne();
|
||||
|
||||
$view_policy =
|
||||
$app->getPolicy(PhabricatorBadgesDefaultViewCapability::CAPABILITY);
|
||||
|
||||
$edit_policy =
|
||||
$app->getPolicy(PhabricatorBadgesDefaultEditCapability::CAPABILITY);
|
||||
|
||||
return id(new PhabricatorBadgesBadge())
|
||||
->setIcon(self::DEFAULT_ICON)
|
||||
->setQuality(self::DEFAULT_QUALITY)
|
||||
->setCreatorPHID($actor->getPHID())
|
||||
->setViewPolicy($view_policy)
|
||||
->setEditPolicy($edit_policy)
|
||||
->setStatus(self::STATUS_OPEN);
|
||||
}
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
self::CONFIG_COLUMN_SCHEMA => array(
|
||||
'name' => 'text255',
|
||||
'flavor' => 'text255',
|
||||
'description' => 'text',
|
||||
'icon' => 'text255',
|
||||
'quality' => 'text255',
|
||||
'status' => 'text32',
|
||||
),
|
||||
self::CONFIG_KEY_SCHEMA => array(
|
||||
'key_creator' => array(
|
||||
'columns' => array('creatorPHID', 'dateModified'),
|
||||
),
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function generatePHID() {
|
||||
return
|
||||
PhabricatorPHID::generateNewPHID(PhabricatorBadgesPHIDType::TYPECONST);
|
||||
}
|
||||
|
||||
public function isClosed() {
|
||||
return ($this->getStatus() == self::STATUS_CLOSED);
|
||||
}
|
||||
|
||||
public function attachRecipientPHIDs(array $phids) {
|
||||
$this->recipientPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRecipientPHIDs() {
|
||||
return $this->assertAttached($this->recipientPHIDs);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
||||
public function getCapabilities() {
|
||||
return array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
);
|
||||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
switch ($capability) {
|
||||
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||
return $this->getViewPolicy();
|
||||
case PhabricatorPolicyCapability::CAN_EDIT:
|
||||
return $this->getEditPolicy();
|
||||
}
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
||||
public function getApplicationTransactionEditor() {
|
||||
return new PhabricatorBadgesEditor();
|
||||
}
|
||||
|
||||
public function getApplicationTransactionObject() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTemplate() {
|
||||
return new PhabricatorBadgesTransaction();
|
||||
}
|
||||
|
||||
public function willRenderTimeline(
|
||||
PhabricatorApplicationTransactionView $timeline,
|
||||
AphrontRequest $request) {
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorSubscribableInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function isAutomaticallySubscribed($phid) {
|
||||
return ($this->creatorPHID == $phid);
|
||||
}
|
||||
|
||||
public function shouldShowSubscribersProperty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldAllowSubscription($phid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
||||
public function destroyObjectPermanently(
|
||||
PhabricatorDestructionEngine $engine) {
|
||||
|
||||
$this->openTransaction();
|
||||
$this->delete();
|
||||
$this->saveTransaction();
|
||||
}
|
||||
|
||||
}
|
9
src/applications/badges/storage/PhabricatorBadgesDAO.php
Normal file
9
src/applications/badges/storage/PhabricatorBadgesDAO.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorBadgesDAO extends PhabricatorLiskDAO {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'badges';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesSchemaSpec
|
||||
extends PhabricatorConfigSchemaSpec {
|
||||
|
||||
public function buildSchemata() {
|
||||
$this->buildEdgeSchemata(new PhabricatorBadgesBadge());
|
||||
}
|
||||
|
||||
}
|
195
src/applications/badges/storage/PhabricatorBadgesTransaction.php
Normal file
195
src/applications/badges/storage/PhabricatorBadgesTransaction.php
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesTransaction
|
||||
extends PhabricatorApplicationTransaction {
|
||||
|
||||
const TYPE_NAME = 'badges:name';
|
||||
const TYPE_DESCRIPTION = 'badges:description';
|
||||
const TYPE_QUALITY = 'badges:quality';
|
||||
const TYPE_ICON = 'badges:icon';
|
||||
const TYPE_STATUS = 'badges:status';
|
||||
const TYPE_FLAVOR = 'badges:flavor';
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'badges';
|
||||
}
|
||||
|
||||
public function getApplicationTransactionType() {
|
||||
return PhabricatorBadgesPHIDType::TYPECONST;
|
||||
}
|
||||
|
||||
public function getApplicationTransactionCommentObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created this badge.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed this badge from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$old,
|
||||
$new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_FLAVOR:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s set the flavor text for this badge.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s updated the flavor text for this badge.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_DESCRIPTION:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s set the description for this badge.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s updated the description for this badge.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_ICON:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s set the icon for this badge as "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
} else {
|
||||
$icon_map = PhabricatorBadgesBadge::getIconNameMap();
|
||||
$icon_new = idx($icon_map, $new, $new);
|
||||
$icon_old = idx($icon_map, $old, $old);
|
||||
return pht(
|
||||
'%s updated the icon for this badge from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$icon_old,
|
||||
$icon_new);
|
||||
}
|
||||
break;
|
||||
case self::TYPE_QUALITY:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s set the quality for this badge as "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$new);
|
||||
} else {
|
||||
$qual_map = PhabricatorBadgesBadge::getQualityNameMap();
|
||||
$qual_new = idx($qual_map, $new, $new);
|
||||
$qual_old = idx($qual_map, $old, $old);
|
||||
return pht(
|
||||
'%s updated the quality for this badge from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$qual_old,
|
||||
$qual_new);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTitle();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
'%s created %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
|
||||
} else {
|
||||
return pht(
|
||||
'%s renamed %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
break;
|
||||
case self::TYPE_FLAVOR:
|
||||
return pht(
|
||||
'%s updated the flavor text for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_ICON:
|
||||
return pht(
|
||||
'%s updated the icon for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_QUALITY:
|
||||
return pht(
|
||||
'%s updated the quality level for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return pht(
|
||||
'%s updated the description for %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case PhabricatorBadgesBadge::STATUS_OPEN:
|
||||
return pht(
|
||||
'%s activated %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case PhabricatorBadgesBadge::STATUS_CLOSED:
|
||||
return pht(
|
||||
'%s archived %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
}
|
||||
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return ($old === null);
|
||||
}
|
||||
return parent::shouldHide();
|
||||
}
|
||||
|
||||
public function hasChangeDetails() {
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_DESCRIPTION:
|
||||
return ($this->getOldValue() !== null);
|
||||
}
|
||||
|
||||
return parent::hasChangeDetails();
|
||||
}
|
||||
|
||||
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||
return $this->renderTextCorpusChangeDetails(
|
||||
$viewer,
|
||||
$this->getOldValue(),
|
||||
$this->getNewValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesRecipientsListView extends AphrontTagView {
|
||||
|
||||
private $badge;
|
||||
private $handles;
|
||||
|
||||
public function setBadge(PhabricatorBadgesBadge $badge) {
|
||||
$this->badge = $badge;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setHandles(array $handles) {
|
||||
$this->handles = $handles;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getTagContent() {
|
||||
|
||||
$viewer = $this->user;
|
||||
|
||||
$badge = $this->badge;
|
||||
$handles = $this->handles;
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$badge,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setNoDataString(pht('This badge does not have any recipients.'));
|
||||
|
||||
foreach ($handles as $handle) {
|
||||
$remove_uri = '/badges/recipients/'.
|
||||
$badge->getID().'/remove/?phid='.$handle->getPHID();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($handle->getFullName())
|
||||
->setHref($handle->getURI())
|
||||
->setImageURI($handle->getImageURI());
|
||||
|
||||
if ($can_edit) {
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-times')
|
||||
->setName(pht('Remove'))
|
||||
->setHref($remove_uri)
|
||||
->setWorkflow(true));
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Recipients'))
|
||||
->setObjectList($list);
|
||||
|
||||
return $box;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,7 @@ final class PhabricatorTokensApplication extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getFontIcon() {
|
||||
return 'fa-trophy';
|
||||
return 'fa-thumbs-up';
|
||||
}
|
||||
|
||||
public function getTitleGlyph() {
|
||||
|
|
|
@ -89,7 +89,7 @@ final class PHUIBadgeExample extends PhabricatorUIExample {
|
|||
$badges2[] = id(new PHUIBadgeView())
|
||||
->setIcon('fa-users')
|
||||
->setHeader(pht('Security Team'))
|
||||
->setSubhead(pht('<sripts>alert(1);</script>'))
|
||||
->setSubhead(pht('<script>alert(1);</script>'))
|
||||
->setQuality(PHUIBadgeView::EPIC)
|
||||
->setSource('Projects (automatic)')
|
||||
->addByline(pht('Dec 31, 1969'))
|
||||
|
@ -152,7 +152,7 @@ final class PHUIBadgeExample extends PhabricatorUIExample {
|
|||
$flex2->addItems($badges2);
|
||||
|
||||
$box2 = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Acheivements'))
|
||||
->setHeaderText(pht('Achievements'))
|
||||
->appendChild($flex2);
|
||||
|
||||
$flex3 = new PHUIBadgeBoxView();
|
||||
|
|
|
@ -1182,6 +1182,80 @@ final class PhabricatorUSEnglishTranslation
|
|||
'%s Task',
|
||||
'%s Tasks',
|
||||
),
|
||||
'%s added %s badge(s) for %s: %s.' => array(
|
||||
array(
|
||||
'%s added a badge for %s: %3$s.',
|
||||
'%s added badges for %s: %3$s.',
|
||||
),
|
||||
),
|
||||
'%s added %s badge(s): %s.' => array(
|
||||
array(
|
||||
'%s added a badge: %3$s.',
|
||||
'%s added badges: %3$s.',
|
||||
),
|
||||
),
|
||||
'%s awarded %s recipient(s) for %s: %s.' => array(
|
||||
array(
|
||||
'%s awarded %3$s to %4$s.',
|
||||
'%s awarded %3$s to multiple recipients: %4$s.',
|
||||
),
|
||||
),
|
||||
'%s awarded %s recipients(s): %s.' => array(
|
||||
array(
|
||||
'%s awarded a recipient: %3$s.',
|
||||
'%s awarded multiple recipients: %3$s.',
|
||||
),
|
||||
),
|
||||
'%s edited badge(s) for %s, added %s: %s; revoked %s: %s.' => array(
|
||||
array(
|
||||
'%s edited badges for %s, added %s: %s; revoked %s: %s.',
|
||||
'%s edited badges for %s, added %s: %s; revoked %s: %s.',
|
||||
),
|
||||
),
|
||||
'%s edited badge(s), added %s: %s; revoked %s: %s.' => array(
|
||||
array(
|
||||
'%s edited badges, added %s: %s; revoked %s: %s.',
|
||||
'%s edited badges, added %s: %s; revoked %s: %s.',
|
||||
),
|
||||
),
|
||||
'%s edited recipient(s) for %s, awarded %s: %s; revoked %s: %s.' => array(
|
||||
array(
|
||||
'%s edited recipients for %s, awarded %s: %s; revoked %s: %s.',
|
||||
'%s edited recipients for %s, awarded %s: %s; revoked %s: %s.',
|
||||
),
|
||||
),
|
||||
'%s edited recipient(s), awarded %s: %s; revoked %s: %s.' => array(
|
||||
array(
|
||||
'%s edited recipients, awarded %s: %s; revoked %s: %s.',
|
||||
'%s edited recipients, awarded %s: %s; revoked %s: %s.',
|
||||
),
|
||||
),
|
||||
'%s revoked %s badge(s) for %s: %s.' => array(
|
||||
array(
|
||||
'%s revoked a badge for %3$s: %4$s.',
|
||||
'%s revoked multiple badges for %3$s: %4$s.',
|
||||
),
|
||||
),
|
||||
'%s revoked %s badge(s): %s.' => array(
|
||||
array(
|
||||
'%s revoked a badge: %3$s.',
|
||||
'%s revoked multiple badges: %3$s.',
|
||||
),
|
||||
),
|
||||
'%s revoked %s recipient(s) for %s: %s.' => array(
|
||||
array(
|
||||
'%s revoked %3$s from %4$s.',
|
||||
'%s revoked multiple recipients for %3$s: %4$s.',
|
||||
),
|
||||
),
|
||||
|
||||
'%s revoked %s recipients(s): %s.' => array(
|
||||
array(
|
||||
'%s revoked a recipient: %3$s.',
|
||||
'%s revoked multiple recipients: %3$s.',
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
|||
'db.almanac' => array(),
|
||||
'db.multimeter' => array(),
|
||||
'db.spaces' => array(),
|
||||
'db.badges' => array(),
|
||||
'0000.legacy.sql' => array(
|
||||
'legacy' => 0,
|
||||
),
|
||||
|
|
|
@ -23,6 +23,7 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
private $fontIcon;
|
||||
private $imageIcon;
|
||||
private $titleText;
|
||||
private $badge;
|
||||
|
||||
const AGE_FRESH = 'fresh';
|
||||
const AGE_STALE = 'stale';
|
||||
|
@ -99,6 +100,11 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setBadge(PHUIBadgeMiniView $badge) {
|
||||
$this->badge = $badge;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTitleText($title_text) {
|
||||
$this->titleText = $title_text;
|
||||
return $this;
|
||||
|
@ -588,6 +594,15 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
$status);
|
||||
}
|
||||
|
||||
if ($this->badge) {
|
||||
$column0 = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-object-item-col0 phui-object-item-badge',
|
||||
),
|
||||
$this->badge);
|
||||
}
|
||||
|
||||
$column1 = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
|
|
|
@ -617,6 +617,17 @@ ul.phui-object-item-list-view .phui-object-item-selected
|
|||
border: none;
|
||||
}
|
||||
|
||||
/* - Badges ---------------------------------------------------------------- */
|
||||
|
||||
.phui-object-item-col0.phui-object-item-badge {
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.phui-object-item-col0.phui-object-item-badge .phui-icon-view {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
|
||||
/* - Dashboards ------------------------------------------------------------ */
|
||||
|
||||
.phui-object-box .phui-object-item-list-view .phui-object-item-frame {
|
||||
|
|
|
@ -98,6 +98,12 @@
|
|||
border-width: 1px 0 0;
|
||||
}
|
||||
|
||||
.phui-property-list-container + .phui-property-list-text-content {
|
||||
border-color: {$thinblueborder};
|
||||
border-style: solid;
|
||||
border-width: 1px 0 0;
|
||||
}
|
||||
|
||||
.phui-property-list-section-noninitial .phui-property-list-section-header {
|
||||
border-top: none;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue