PageRenderTime 42ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/applications/almanac/storage/AlmanacNamespace.php

http://github.com/facebook/phabricator
PHP | 242 lines | 170 code | 57 blank | 15 comment | 7 complexity | f8a2d75a769fe76683c2e4893d6da91e MD5 | raw file
Possible License(s): JSON, MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause, LGPL-2.0, MIT, LGPL-2.1, LGPL-3.0
  1. <?php
  2. final class AlmanacNamespace
  3. extends AlmanacDAO
  4. implements
  5. PhabricatorPolicyInterface,
  6. PhabricatorApplicationTransactionInterface,
  7. PhabricatorProjectInterface,
  8. AlmanacPropertyInterface,
  9. PhabricatorDestructibleInterface,
  10. PhabricatorNgramsInterface,
  11. PhabricatorConduitResultInterface {
  12. protected $name;
  13. protected $nameIndex;
  14. protected $mailKey;
  15. protected $viewPolicy;
  16. protected $editPolicy;
  17. private $almanacProperties = self::ATTACHABLE;
  18. public static function initializeNewNamespace() {
  19. return id(new self())
  20. ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
  21. ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN)
  22. ->attachAlmanacProperties(array());
  23. }
  24. protected function getConfiguration() {
  25. return array(
  26. self::CONFIG_AUX_PHID => true,
  27. self::CONFIG_COLUMN_SCHEMA => array(
  28. 'name' => 'text128',
  29. 'nameIndex' => 'bytes12',
  30. 'mailKey' => 'bytes20',
  31. ),
  32. self::CONFIG_KEY_SCHEMA => array(
  33. 'key_nameindex' => array(
  34. 'columns' => array('nameIndex'),
  35. 'unique' => true,
  36. ),
  37. 'key_name' => array(
  38. 'columns' => array('name'),
  39. ),
  40. ),
  41. ) + parent::getConfiguration();
  42. }
  43. public function generatePHID() {
  44. return PhabricatorPHID::generateNewPHID(
  45. AlmanacNamespacePHIDType::TYPECONST);
  46. }
  47. public function save() {
  48. AlmanacNames::validateName($this->getName());
  49. $this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
  50. if (!$this->mailKey) {
  51. $this->mailKey = Filesystem::readRandomCharacters(20);
  52. }
  53. return parent::save();
  54. }
  55. public function getURI() {
  56. return '/almanac/namespace/view/'.$this->getName().'/';
  57. }
  58. public function getNameLength() {
  59. return strlen($this->getName());
  60. }
  61. /**
  62. * Load the namespace which prevents use of an Almanac name, if one exists.
  63. */
  64. public static function loadRestrictedNamespace(
  65. PhabricatorUser $viewer,
  66. $name) {
  67. // For a name like "x.y.z", produce a list of controlling namespaces like
  68. // ("z", "y.x", "x.y.z").
  69. $names = array();
  70. $parts = explode('.', $name);
  71. for ($ii = 0; $ii < count($parts); $ii++) {
  72. $names[] = implode('.', array_slice($parts, -($ii + 1)));
  73. }
  74. // Load all the possible controlling namespaces.
  75. $namespaces = id(new AlmanacNamespaceQuery())
  76. ->setViewer(PhabricatorUser::getOmnipotentUser())
  77. ->withNames($names)
  78. ->execute();
  79. if (!$namespaces) {
  80. return null;
  81. }
  82. // Find the "nearest" (longest) namespace that exists. If both
  83. // "sub.domain.com" and "domain.com" exist, we only care about the policy
  84. // on the former.
  85. $namespaces = msort($namespaces, 'getNameLength');
  86. $namespace = last($namespaces);
  87. $can_edit = PhabricatorPolicyFilter::hasCapability(
  88. $viewer,
  89. $namespace,
  90. PhabricatorPolicyCapability::CAN_EDIT);
  91. if ($can_edit) {
  92. return null;
  93. }
  94. return $namespace;
  95. }
  96. /* -( AlmanacPropertyInterface )------------------------------------------- */
  97. public function attachAlmanacProperties(array $properties) {
  98. assert_instances_of($properties, 'AlmanacProperty');
  99. $this->almanacProperties = mpull($properties, null, 'getFieldName');
  100. return $this;
  101. }
  102. public function getAlmanacProperties() {
  103. return $this->assertAttached($this->almanacProperties);
  104. }
  105. public function hasAlmanacProperty($key) {
  106. $this->assertAttached($this->almanacProperties);
  107. return isset($this->almanacProperties[$key]);
  108. }
  109. public function getAlmanacProperty($key) {
  110. return $this->assertAttachedKey($this->almanacProperties, $key);
  111. }
  112. public function getAlmanacPropertyValue($key, $default = null) {
  113. if ($this->hasAlmanacProperty($key)) {
  114. return $this->getAlmanacProperty($key)->getFieldValue();
  115. } else {
  116. return $default;
  117. }
  118. }
  119. public function getAlmanacPropertyFieldSpecifications() {
  120. return array();
  121. }
  122. public function newAlmanacPropertyEditEngine() {
  123. throw new PhutilMethodNotImplementedException();
  124. }
  125. public function getAlmanacPropertySetTransactionType() {
  126. throw new PhutilMethodNotImplementedException();
  127. }
  128. public function getAlmanacPropertyDeleteTransactionType() {
  129. throw new PhutilMethodNotImplementedException();
  130. }
  131. /* -( PhabricatorPolicyInterface )----------------------------------------- */
  132. public function getCapabilities() {
  133. return array(
  134. PhabricatorPolicyCapability::CAN_VIEW,
  135. PhabricatorPolicyCapability::CAN_EDIT,
  136. );
  137. }
  138. public function getPolicy($capability) {
  139. switch ($capability) {
  140. case PhabricatorPolicyCapability::CAN_VIEW:
  141. return $this->getViewPolicy();
  142. case PhabricatorPolicyCapability::CAN_EDIT:
  143. return $this->getEditPolicy();
  144. }
  145. }
  146. public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
  147. return false;
  148. }
  149. /* -( PhabricatorApplicationTransactionInterface )------------------------- */
  150. public function getApplicationTransactionEditor() {
  151. return new AlmanacNamespaceEditor();
  152. }
  153. public function getApplicationTransactionTemplate() {
  154. return new AlmanacNamespaceTransaction();
  155. }
  156. /* -( PhabricatorDestructibleInterface )----------------------------------- */
  157. public function destroyObjectPermanently(
  158. PhabricatorDestructionEngine $engine) {
  159. $this->delete();
  160. }
  161. /* -( PhabricatorNgramsInterface )----------------------------------------- */
  162. public function newNgrams() {
  163. return array(
  164. id(new AlmanacNamespaceNameNgrams())
  165. ->setValue($this->getName()),
  166. );
  167. }
  168. /* -( PhabricatorConduitResultInterface )---------------------------------- */
  169. public function getFieldSpecificationsForConduit() {
  170. return array(
  171. id(new PhabricatorConduitSearchFieldSpecification())
  172. ->setKey('name')
  173. ->setType('string')
  174. ->setDescription(pht('The name of the namespace.')),
  175. );
  176. }
  177. public function getFieldValuesForConduit() {
  178. return array(
  179. 'name' => $this->getName(),
  180. );
  181. }
  182. public function getConduitSearchAttachments() {
  183. return array();
  184. }
  185. }