3 final class PhabricatorProfileMenuItemConfiguration
4 extends PhabricatorSearchDAO
6 PhabricatorPolicyInterface
,
7 PhabricatorExtendedPolicyInterface
,
8 PhabricatorApplicationTransactionInterface
,
9 PhabricatorIndexableInterface
{
11 protected $profilePHID;
12 protected $menuItemKey;
13 protected $builtinKey;
14 protected $menuItemOrder;
15 protected $visibility;
16 protected $customPHID;
17 protected $menuItemProperties = array();
19 private $profileObject = self
::ATTACHABLE
;
20 private $menuItem = self
::ATTACHABLE
;
21 private $isHeadItem = false;
22 private $isTailItem = false;
24 const VISIBILITY_DEFAULT
= 'default';
25 const VISIBILITY_VISIBLE
= 'visible';
26 const VISIBILITY_DISABLED
= 'disabled';
28 public function getTableName() {
29 // For now, this class uses an older table name.
30 return 'search_profilepanelconfiguration';
33 public static function initializeNewBuiltin() {
35 ->setVisibility(self
::VISIBILITY_VISIBLE
);
38 public static function initializeNewItem(
40 PhabricatorProfileMenuItem
$item,
43 return self
::initializeNewBuiltin()
44 ->setProfilePHID($profile_object->getPHID())
45 ->setMenuItemKey($item->getMenuItemKey())
46 ->attachMenuItem($item)
47 ->attachProfileObject($profile_object)
48 ->setCustomPHID($custom_phid);
51 protected function getConfiguration() {
53 self
::CONFIG_AUX_PHID
=> true,
54 self
::CONFIG_SERIALIZATION
=> array(
55 'menuItemProperties' => self
::SERIALIZATION_JSON
,
57 self
::CONFIG_COLUMN_SCHEMA
=> array(
58 'menuItemKey' => 'text64',
59 'builtinKey' => 'text64?',
60 'menuItemOrder' => 'uint32?',
61 'customPHID' => 'phid?',
62 'visibility' => 'text32',
64 self
::CONFIG_KEY_SCHEMA
=> array(
65 'key_profile' => array(
66 'columns' => array('profilePHID', 'menuItemOrder'),
69 ) + parent
::getConfiguration();
72 public function generatePHID() {
73 return PhabricatorPHID
::generateNewPHID(
74 PhabricatorProfileMenuItemPHIDType
::TYPECONST
);
77 public function attachMenuItem(PhabricatorProfileMenuItem
$item) {
78 $this->menuItem
= $item;
82 public function getMenuItem() {
83 return $this->assertAttached($this->menuItem
);
86 public function attachProfileObject($profile_object) {
87 $this->profileObject
= $profile_object;
91 public function getProfileObject() {
92 return $this->assertAttached($this->profileObject
);
95 public function setMenuItemProperty($key, $value) {
96 $this->menuItemProperties
[$key] = $value;
100 public function getMenuItemProperty($key, $default = null) {
101 return idx($this->menuItemProperties
, $key, $default);
104 public function getMenuItemTypeName() {
105 return $this->getMenuItem()->getMenuItemTypeName();
108 public function getDisplayName() {
109 return $this->getMenuItem()->getDisplayName($this);
112 public function canMakeDefault() {
113 return $this->getMenuItem()->canMakeDefault($this);
116 public function canHideMenuItem() {
117 return $this->getMenuItem()->canHideMenuItem($this);
120 public function shouldEnableForObject($object) {
121 return $this->getMenuItem()->shouldEnableForObject($object);
124 public function willGetMenuItemViewList(array $items) {
125 return $this->getMenuItem()->willGetMenuItemViewList($items);
128 public function getMenuItemViewList() {
129 return $this->getMenuItem()->getMenuItemViewList($this);
132 public function validateTransactions(array $map) {
133 $item = $this->getMenuItem();
135 $fields = $item->buildEditEngineFields($this);
137 foreach ($fields as $field) {
138 $field_key = $field->getKey();
140 $xactions = idx($map, $field_key, array());
141 $value = $this->getMenuItemProperty($field_key);
143 $field_errors = $item->validateTransactions(
148 foreach ($field_errors as $error) {
156 public function getSortVector() {
157 // Sort custom items above global items.
158 if ($this->getCustomPHID()) {
164 // Sort "head" items above other items and "tail" items after other items.
165 if ($this->getIsHeadItem()) {
167 } else if ($this->getIsTailItem()) {
173 // Sort items with an explicit order above items without an explicit order,
174 // so any newly created builtins go to the bottom.
175 $order = $this->getMenuItemOrder();
176 if ($order !== null) {
182 return id(new PhutilSortVector())
184 ->addInt($force_position)
186 ->addInt((int)$order)
187 ->addInt((int)$this->getID());
190 public function isDisabled() {
191 if (!$this->canHideMenuItem()) {
194 return ($this->getVisibility() === self
::VISIBILITY_DISABLED
);
197 public function isDefault() {
198 return ($this->getVisibility() === self
::VISIBILITY_DEFAULT
);
201 public function getItemIdentifier() {
202 $id = $this->getID();
208 return $this->getBuiltinKey();
211 public function getDefaultMenuItemKey() {
212 if ($this->getBuiltinKey()) {
213 return $this->getBuiltinKey();
216 return $this->getPHID();
219 public function newPageContent() {
220 return $this->getMenuItem()->newPageContent($this);
223 public function setIsHeadItem($is_head_item) {
224 $this->isHeadItem
= $is_head_item;
228 public function getIsHeadItem() {
229 return $this->isHeadItem
;
232 public function setIsTailItem($is_tail_item) {
233 $this->isTailItem
= $is_tail_item;
237 public function getIsTailItem() {
238 return $this->isTailItem
;
241 public function matchesIdentifier($identifier) {
242 if (!strlen($identifier)) {
246 if (ctype_digit($identifier)) {
247 if ((int)$this->getID() === (int)$identifier) {
252 if ((string)$this->getBuiltinKey() === (string)$identifier) {
259 public function getAffectedObjectPHIDs() {
260 return $this->getMenuItem()->getAffectedObjectPHIDs($this);
263 public function getProfileMenuTypeDescription() {
264 $profile_phid = $this->getProfilePHID();
266 $home_phid = id(new PhabricatorHomeApplication())->getPHID();
267 if ($profile_phid === $home_phid) {
268 return pht('Home Menu');
271 $favorites_phid = id(new PhabricatorFavoritesApplication())->getPHID();
272 if ($profile_phid === $favorites_phid) {
273 return pht('Favorites Menu');
276 switch (phid_get_type($profile_phid)) {
277 case PhabricatorProjectProjectPHIDType
::TYPECONST
:
278 return pht('Project Menu');
279 case PhabricatorDashboardPortalPHIDType
::TYPECONST
:
280 return pht('Portal Menu');
283 return pht('Profile Menu');
286 public function newUsageSortVector() {
287 // Used to sort items in contexts where we're showing the usage of an
288 // object in menus, like "Dashboard Used By" on Dashboard pages.
290 // Sort usage as a custom item after usage as a global item.
291 if ($this->getCustomPHID()) {
297 return id(new PhutilSortVector())
298 ->addInt($is_personal)
299 ->addInt($this->getID());
303 /* -( PhabricatorPolicyInterface )----------------------------------------- */
306 public function getCapabilities() {
308 PhabricatorPolicyCapability
::CAN_VIEW
,
309 PhabricatorPolicyCapability
::CAN_EDIT
,
314 public function getPolicy($capability) {
315 return PhabricatorPolicies
::getMostOpenPolicy();
319 public function hasAutomaticCapability($capability, PhabricatorUser
$viewer) {
320 return $this->getProfileObject()->hasAutomaticCapability(
326 /* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
329 public function getExtendedPolicy($capability, PhabricatorUser
$viewer) {
330 // If this is an item with a custom PHID (like a personal menu item),
331 // we only require that the user can edit the corresponding custom
332 // object (usually their own user profile), not the object that the
333 // menu appears on (which may be an Application like Favorites or Home).
334 if ($capability == PhabricatorPolicyCapability
::CAN_EDIT
) {
335 if ($this->getCustomPHID()) {
338 $this->getCustomPHID(),
347 $this->getProfileObject(),
354 /* -( PhabricatorApplicationTransactionInterface )------------------------- */
357 public function getApplicationTransactionEditor() {
358 return new PhabricatorProfileMenuEditor();
361 public function getApplicationTransactionTemplate() {
362 return new PhabricatorProfileMenuItemConfigurationTransaction();