Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/drydock/logtype/DrydockLogType.php b/src/applications/drydock/logtype/DrydockLogType.php
index aa1f4fc4e0..7faab42dfe 100644
--- a/src/applications/drydock/logtype/DrydockLogType.php
+++ b/src/applications/drydock/logtype/DrydockLogType.php
@@ -1,69 +1,41 @@
<?php
abstract class DrydockLogType extends Phobject {
private $viewer;
private $log;
abstract public function getLogTypeName();
abstract public function getLogTypeIcon(array $data);
abstract public function renderLog(array $data);
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
public function getViewer() {
return $this->viewer;
}
final public function setLog(DrydockLog $log) {
$this->log = $log;
return $this;
}
final public function getLog() {
return $this->log;
}
final public function getLogTypeConstant() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('LOGCONST');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'LOGCONST'));
- }
-
- $limit = self::getLogTypeConstantByteLimit();
- if (!is_string($const) || (strlen($const) > $limit)) {
- throw new Exception(
- pht(
- '"%s" class "%s" has an invalid "%s" property. Field constants '.
- 'must be strings and no more than %s bytes in length.',
- __CLASS__,
- get_class($this),
- 'LOGCONST',
- new PhutilNumber($limit)));
- }
-
- return $const;
- }
-
- final private static function getLogTypeConstantByteLimit() {
- return 64;
+ return $this->getPhobjectClassConstant('LOGCONST', 64);
}
final public static function getAllLogTypes() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getLogTypeConstant')
->execute();
}
}
diff --git a/src/applications/harbormaster/artifact/HarbormasterArtifact.php b/src/applications/harbormaster/artifact/HarbormasterArtifact.php
index a0d3a86101..8d3d8dd169 100644
--- a/src/applications/harbormaster/artifact/HarbormasterArtifact.php
+++ b/src/applications/harbormaster/artifact/HarbormasterArtifact.php
@@ -1,88 +1,60 @@
<?php
abstract class HarbormasterArtifact extends Phobject {
private $buildArtifact;
abstract public function getArtifactTypeName();
public function getArtifactTypeSummary() {
return $this->getArtifactTypeDescription();
}
abstract public function getArtifactTypeDescription();
abstract public function getArtifactParameterSpecification();
abstract public function getArtifactParameterDescriptions();
abstract public function willCreateArtifact(PhabricatorUser $actor);
public function validateArtifactData(array $artifact_data) {
$artifact_spec = $this->getArtifactParameterSpecification();
PhutilTypeSpec::checkMap($artifact_data, $artifact_spec);
}
public function renderArtifactSummary(PhabricatorUser $viewer) {
return null;
}
public function releaseArtifact(PhabricatorUser $actor) {
return;
}
public function getArtifactDataExample() {
return null;
}
public function setBuildArtifact(HarbormasterBuildArtifact $build_artifact) {
$this->buildArtifact = $build_artifact;
return $this;
}
public function getBuildArtifact() {
return $this->buildArtifact;
}
final public function getArtifactConstant() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('ARTIFACTCONST');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'ARTIFACTCONST'));
- }
-
- $limit = self::getArtifactConstantByteLimit();
- if (!is_string($const) || (strlen($const) > $limit)) {
- throw new Exception(
- pht(
- '"%s" class "%s" has an invalid "%s" property. Action constants '.
- 'must be strings and no more than %s bytes in length.',
- __CLASS__,
- get_class($this),
- 'ARTIFACTCONST',
- new PhutilNumber($limit)));
- }
-
- return $const;
- }
-
- final public static function getArtifactConstantByteLimit() {
- return 32;
+ return $this->getPhobjectClassConstant('ARTIFACTCONST', 32);
}
final public static function getAllArtifactTypes() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getArtifactConstant')
->execute();
}
final public static function getArtifactType($type) {
return idx(self::getAllArtifactTypes(), $type);
}
}
diff --git a/src/applications/harbormaster/stepgroup/HarbormasterBuildStepGroup.php b/src/applications/harbormaster/stepgroup/HarbormasterBuildStepGroup.php
index bb439b75b4..5806861836 100644
--- a/src/applications/harbormaster/stepgroup/HarbormasterBuildStepGroup.php
+++ b/src/applications/harbormaster/stepgroup/HarbormasterBuildStepGroup.php
@@ -1,52 +1,40 @@
<?php
abstract class HarbormasterBuildStepGroup extends Phobject {
abstract public function getGroupName();
abstract public function getGroupOrder();
public function isEnabled() {
return true;
}
public function shouldShowIfEmpty() {
return true;
}
final public function getGroupKey() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('GROUPKEY');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'GROUPKEY'));
- }
-
- return $const;
+ return $this->getPhobjectClassConstant('GROUPKEY');
}
final public static function getAllGroups() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getGroupKey')
->setSortMethod('getGroupOrder')
->execute();
}
final public static function getAllEnabledGroups() {
$groups = self::getAllGroups();
foreach ($groups as $key => $group) {
if (!$group->isEnabled()) {
unset($groups[$key]);
}
}
return $groups;
}
}
diff --git a/src/applications/herald/action/HeraldAction.php b/src/applications/herald/action/HeraldAction.php
index 02a9dfa60a..f4217cd4db 100644
--- a/src/applications/herald/action/HeraldAction.php
+++ b/src/applications/herald/action/HeraldAction.php
@@ -1,407 +1,379 @@
<?php
abstract class HeraldAction extends Phobject {
private $adapter;
private $viewer;
private $applyLog = array();
const STANDARD_NONE = 'standard.none';
const STANDARD_PHID_LIST = 'standard.phid.list';
const STANDARD_TEXT = 'standard.text';
const DO_STANDARD_EMPTY = 'do.standard.empty';
const DO_STANDARD_NO_EFFECT = 'do.standard.no-effect';
const DO_STANDARD_INVALID = 'do.standard.invalid';
const DO_STANDARD_UNLOADABLE = 'do.standard.unloadable';
const DO_STANDARD_PERMISSION = 'do.standard.permission';
const DO_STANDARD_INVALID_ACTION = 'do.standard.invalid-action';
const DO_STANDARD_WRONG_RULE_TYPE = 'do.standard.wrong-rule-type';
abstract public function getHeraldActionName();
abstract public function supportsObject($object);
abstract public function supportsRuleType($rule_type);
abstract public function applyEffect($object, HeraldEffect $effect);
abstract public function renderActionDescription($value);
protected function renderActionEffectDescription($type, $data) {
return null;
}
public function getActionGroupKey() {
return null;
}
public function getActionsForObject($object) {
return array($this->getActionConstant() => $this);
}
protected function getDatasource() {
throw new PhutilMethodNotImplementedException();
}
protected function getDatasourceValueMap() {
return null;
}
public function getHeraldActionStandardType() {
throw new PhutilMethodNotImplementedException();
}
public function getHeraldActionValueType() {
switch ($this->getHeraldActionStandardType()) {
case self::STANDARD_NONE:
return new HeraldEmptyFieldValue();
case self::STANDARD_TEXT:
return new HeraldTextFieldValue();
case self::STANDARD_PHID_LIST:
$tokenizer = id(new HeraldTokenizerFieldValue())
->setKey($this->getHeraldActionName())
->setDatasource($this->getDatasource());
$value_map = $this->getDatasourceValueMap();
if ($value_map !== null) {
$tokenizer->setValueMap($value_map);
}
return $tokenizer;
}
throw new PhutilMethodNotImplementedException();
}
public function willSaveActionValue($value) {
try {
$type = $this->getHeraldActionStandardType();
} catch (PhutilMethodNotImplementedException $ex) {
return $value;
}
switch ($type) {
case self::STANDARD_PHID_LIST:
return array_keys($value);
}
return $value;
}
public function getEditorValue(PhabricatorUser $viewer, $target) {
try {
$type = $this->getHeraldActionStandardType();
} catch (PhutilMethodNotImplementedException $ex) {
return $target;
}
switch ($type) {
case self::STANDARD_PHID_LIST:
$handles = $viewer->loadHandles($target);
$handles = iterator_to_array($handles);
return mpull($handles, 'getName', 'getPHID');
}
return $target;
}
final public function setAdapter(HeraldAdapter $adapter) {
$this->adapter = $adapter;
return $this;
}
final public function getAdapter() {
return $this->adapter;
}
final public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
return $this;
}
final public function getViewer() {
return $this->viewer;
}
final public function getActionConstant() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('ACTIONCONST');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'ACTIONCONST'));
- }
-
- $limit = self::getActionConstantByteLimit();
- if (!is_string($const) || (strlen($const) > $limit)) {
- throw new Exception(
- pht(
- '"%s" class "%s" has an invalid "%s" property. Action constants '.
- 'must be strings and no more than %s bytes in length.',
- __CLASS__,
- get_class($this),
- 'ACTIONCONST',
- new PhutilNumber($limit)));
- }
-
- return $const;
- }
-
- final public static function getActionConstantByteLimit() {
- return 64;
+ return $this->getPhobjectClassConstant('ACTIONCONST', 64);
}
final public static function getAllActions() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getActionConstant')
->execute();
}
protected function logEffect($type, $data = null) {
if (!is_string($type)) {
throw new Exception(
pht(
'Effect type passed to "%s" must be a scalar string.',
'logEffect()'));
}
$this->applyLog[] = array(
'type' => $type,
'data' => $data,
);
return $this;
}
final public function getApplyTranscript(HeraldEffect $effect) {
$context = $this->applyLog;
$this->applyLog = array();
return new HeraldApplyTranscript($effect, true, $context);
}
protected function getActionEffectMap() {
throw new PhutilMethodNotImplementedException();
}
private function getActionEffectSpec($type) {
$map = $this->getActionEffectMap() + $this->getStandardEffectMap();
return idx($map, $type, array());
}
final public function renderActionEffectIcon($type, $data) {
$map = $this->getActionEffectSpec($type);
return idx($map, 'icon');
}
final public function renderActionEffectColor($type, $data) {
$map = $this->getActionEffectSpec($type);
return idx($map, 'color');
}
final public function renderActionEffectName($type, $data) {
$map = $this->getActionEffectSpec($type);
return idx($map, 'name');
}
protected function renderHandleList($phids) {
if (!is_array($phids)) {
return pht('(Invalid List)');
}
return $this->getViewer()
->renderHandleList($phids)
->setAsInline(true)
->render();
}
protected function loadStandardTargets(
array $phids,
array $allowed_types,
array $current_value) {
$phids = array_fuse($phids);
if (!$phids) {
$this->logEffect(self::DO_STANDARD_EMPTY);
}
$current_value = array_fuse($current_value);
$no_effect = array();
foreach ($phids as $phid) {
if (isset($current_value[$phid])) {
$no_effect[] = $phid;
unset($phids[$phid]);
}
}
if ($no_effect) {
$this->logEffect(self::DO_STANDARD_NO_EFFECT, $no_effect);
}
if (!$phids) {
return;
}
$allowed_types = array_fuse($allowed_types);
$invalid = array();
foreach ($phids as $phid) {
$type = phid_get_type($phid);
if ($type == PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
$invalid[] = $phid;
unset($phids[$phid]);
continue;
}
if ($allowed_types && empty($allowed_types[$type])) {
$invalid[] = $phid;
unset($phids[$phid]);
continue;
}
}
if ($invalid) {
$this->logEffect(self::DO_STANDARD_INVALID, $invalid);
}
if (!$phids) {
return;
}
$targets = id(new PhabricatorObjectQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($phids)
->execute();
$targets = mpull($targets, null, 'getPHID');
$unloadable = array();
foreach ($phids as $phid) {
if (empty($targets[$phid])) {
$unloadable[] = $phid;
unset($phids[$phid]);
}
}
if ($unloadable) {
$this->logEffect(self::DO_STANDARD_UNLOADABLE, $unloadable);
}
if (!$phids) {
return;
}
$adapter = $this->getAdapter();
$object = $adapter->getObject();
if ($object instanceof PhabricatorPolicyInterface) {
$no_permission = array();
foreach ($targets as $phid => $target) {
if (!($target instanceof PhabricatorUser)) {
continue;
}
$can_view = PhabricatorPolicyFilter::hasCapability(
$target,
$object,
PhabricatorPolicyCapability::CAN_VIEW);
if ($can_view) {
continue;
}
$no_permission[] = $phid;
unset($targets[$phid]);
}
}
if ($no_permission) {
$this->logEffect(self::DO_STANDARD_PERMISSION, $no_permission);
}
return $targets;
}
protected function getStandardEffectMap() {
return array(
self::DO_STANDARD_EMPTY => array(
'icon' => 'fa-ban',
'color' => 'grey',
'name' => pht('No Targets'),
),
self::DO_STANDARD_NO_EFFECT => array(
'icon' => 'fa-circle-o',
'color' => 'grey',
'name' => pht('No Effect'),
),
self::DO_STANDARD_INVALID => array(
'icon' => 'fa-ban',
'color' => 'red',
'name' => pht('Invalid Targets'),
),
self::DO_STANDARD_UNLOADABLE => array(
'icon' => 'fa-ban',
'color' => 'red',
'name' => pht('Unloadable Targets'),
),
self::DO_STANDARD_PERMISSION => array(
'icon' => 'fa-lock',
'color' => 'red',
'name' => pht('No Permission'),
),
self::DO_STANDARD_INVALID_ACTION => array(
'icon' => 'fa-ban',
'color' => 'red',
'name' => pht('Invalid Action'),
),
self::DO_STANDARD_WRONG_RULE_TYPE => array(
'icon' => 'fa-ban',
'color' => 'red',
'name' => pht('Wrong Rule Type'),
),
);
}
final public function renderEffectDescription($type, $data) {
$result = $this->renderActionEffectDescription($type, $data);
if ($result !== null) {
return $result;
}
switch ($type) {
case self::DO_STANDARD_EMPTY:
return pht(
'This action specifies no targets.');
case self::DO_STANDARD_NO_EFFECT:
return pht(
'This action has no effect on %s target(s): %s.',
new PhutilNumber(count($data)),
$this->renderHandleList($data));
case self::DO_STANDARD_INVALID:
return pht(
'%s target(s) are invalid or of the wrong type: %s.',
new PhutilNumber(count($data)),
$this->renderHandleList($data));
case self::DO_STANDARD_UNLOADABLE:
return pht(
'%s target(s) could not be loaded: %s.',
new PhutilNumber(count($data)),
$this->renderHandleList($data));
case self::DO_STANDARD_PERMISSION:
return pht(
'%s target(s) do not have permission to see this object: %s.',
new PhutilNumber(count($data)),
$this->renderHandleList($data));
case self::DO_STANDARD_INVALID_ACTION:
return pht(
'No implementation is available for rule "%s".',
$data);
case self::DO_STANDARD_WRONG_RULE_TYPE:
return pht(
'This action does not support rules of type "%s".',
$data);
}
return null;
}
}
diff --git a/src/applications/herald/action/HeraldActionGroup.php b/src/applications/herald/action/HeraldActionGroup.php
index a087909609..ad4fecd6b6 100644
--- a/src/applications/herald/action/HeraldActionGroup.php
+++ b/src/applications/herald/action/HeraldActionGroup.php
@@ -1,28 +1,16 @@
<?php
abstract class HeraldActionGroup extends HeraldGroup {
final public function getGroupKey() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('ACTIONGROUPKEY');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'ACTIONGROUPKEY'));
- }
-
- return $const;
+ return $this->getPhobjectClassConstant('ACTIONGROUPKEY');
}
final public static function getAllActionGroups() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getGroupKey')
->setSortMethod('getSortKey')
->execute();
}
}
diff --git a/src/applications/herald/field/HeraldField.php b/src/applications/herald/field/HeraldField.php
index a6d2e580c2..2aba443077 100644
--- a/src/applications/herald/field/HeraldField.php
+++ b/src/applications/herald/field/HeraldField.php
@@ -1,210 +1,188 @@
<?php
abstract class HeraldField extends Phobject {
private $adapter;
const STANDARD_BOOL = 'standard.bool';
const STANDARD_TEXT = 'standard.text';
const STANDARD_TEXT_LIST = 'standard.text.list';
const STANDARD_TEXT_MAP = 'standard.text.map';
const STANDARD_PHID = 'standard.phid';
const STANDARD_PHID_LIST = 'standard.phid.list';
const STANDARD_PHID_BOOL = 'standard.phid.bool';
const STANDARD_PHID_NULLABLE = 'standard.phid.nullable';
abstract public function getHeraldFieldName();
abstract public function getHeraldFieldValue($object);
public function getFieldGroupKey() {
return null;
}
protected function getHeraldFieldStandardType() {
throw new PhutilMethodNotImplementedException();
}
protected function getDatasource() {
throw new PhutilMethodNotImplementedException();
}
protected function getDatasourceValueMap() {
return null;
}
public function getHeraldFieldConditions() {
$standard_type = $this->getHeraldFieldStandardType();
switch ($standard_type) {
case self::STANDARD_BOOL:
return array(
HeraldAdapter::CONDITION_IS_TRUE,
HeraldAdapter::CONDITION_IS_FALSE,
);
case self::STANDARD_TEXT:
return array(
HeraldAdapter::CONDITION_CONTAINS,
HeraldAdapter::CONDITION_NOT_CONTAINS,
HeraldAdapter::CONDITION_IS,
HeraldAdapter::CONDITION_IS_NOT,
HeraldAdapter::CONDITION_REGEXP,
);
case self::STANDARD_PHID:
return array(
HeraldAdapter::CONDITION_IS_ANY,
HeraldAdapter::CONDITION_IS_NOT_ANY,
);
case self::STANDARD_PHID_LIST:
return array(
HeraldAdapter::CONDITION_INCLUDE_ALL,
HeraldAdapter::CONDITION_INCLUDE_ANY,
HeraldAdapter::CONDITION_INCLUDE_NONE,
HeraldAdapter::CONDITION_EXISTS,
HeraldAdapter::CONDITION_NOT_EXISTS,
);
case self::STANDARD_PHID_BOOL:
return array(
HeraldAdapter::CONDITION_EXISTS,
HeraldAdapter::CONDITION_NOT_EXISTS,
);
case self::STANDARD_PHID_NULLABLE:
return array(
HeraldAdapter::CONDITION_IS_ANY,
HeraldAdapter::CONDITION_IS_NOT_ANY,
HeraldAdapter::CONDITION_EXISTS,
HeraldAdapter::CONDITION_NOT_EXISTS,
);
case self::STANDARD_TEXT_LIST:
return array(
HeraldAdapter::CONDITION_CONTAINS,
HeraldAdapter::CONDITION_REGEXP,
);
case self::STANDARD_TEXT_MAP:
return array(
HeraldAdapter::CONDITION_CONTAINS,
HeraldAdapter::CONDITION_REGEXP,
HeraldAdapter::CONDITION_REGEXP_PAIR,
);
}
throw new Exception(
pht(
'Herald field "%s" has unknown standard type "%s".',
get_class($this),
$standard_type));
}
public function getHeraldFieldValueType($condition) {
$standard_type = $this->getHeraldFieldStandardType();
switch ($standard_type) {
case self::STANDARD_BOOL:
case self::STANDARD_PHID_BOOL:
return new HeraldEmptyFieldValue();
case self::STANDARD_TEXT:
case self::STANDARD_TEXT_LIST:
case self::STANDARD_TEXT_MAP:
return new HeraldTextFieldValue();
case self::STANDARD_PHID:
case self::STANDARD_PHID_NULLABLE:
case self::STANDARD_PHID_LIST:
switch ($condition) {
case HeraldAdapter::CONDITION_EXISTS:
case HeraldAdapter::CONDITION_NOT_EXISTS:
return new HeraldEmptyFieldValue();
default:
$tokenizer = id(new HeraldTokenizerFieldValue())
->setKey($this->getHeraldFieldName())
->setDatasource($this->getDatasource());
$value_map = $this->getDatasourceValueMap();
if ($value_map !== null) {
$tokenizer->setValueMap($value_map);
}
return $tokenizer;
}
break;
}
throw new Exception(
pht(
'Herald field "%s" has unknown standard type "%s".',
get_class($this),
$standard_type));
}
abstract public function supportsObject($object);
public function getFieldsForObject($object) {
return array($this->getFieldConstant() => $this);
}
public function renderConditionValue(
PhabricatorUser $viewer,
$condition,
$value) {
$value_type = $this->getHeraldFieldValueType($condition);
$value_type->setViewer($viewer);
return $value_type->renderFieldValue($value);
}
public function getEditorValue(
PhabricatorUser $viewer,
$condition,
$value) {
$value_type = $this->getHeraldFieldValueType($condition);
$value_type->setViewer($viewer);
return $value_type->renderEditorValue($value);
}
final public function setAdapter(HeraldAdapter $adapter) {
$this->adapter = $adapter;
return $this;
}
final public function getAdapter() {
return $this->adapter;
}
final public function getFieldConstant() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('FIELDCONST');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'FIELDCONST'));
- }
-
- $limit = self::getFieldConstantByteLimit();
- if (!is_string($const) || (strlen($const) > $limit)) {
- throw new Exception(
- pht(
- '"%s" class "%s" has an invalid "%s" property. Field constants '.
- 'must be strings and no more than %s bytes in length.',
- __CLASS__,
- get_class($this),
- 'FIELDCONST',
- new PhutilNumber($limit)));
- }
-
- return $const;
+ return $this->getPhobjectClassConstant(
+ 'FIELDCONST',
+ self::getFieldConstantByteLimit());
}
final public static function getFieldConstantByteLimit() {
return 64;
}
final public static function getAllFields() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getFieldConstant')
->execute();
}
}
diff --git a/src/applications/herald/field/HeraldFieldGroup.php b/src/applications/herald/field/HeraldFieldGroup.php
index adb7fbe372..9e13f17cb7 100644
--- a/src/applications/herald/field/HeraldFieldGroup.php
+++ b/src/applications/herald/field/HeraldFieldGroup.php
@@ -1,28 +1,16 @@
<?php
abstract class HeraldFieldGroup extends HeraldGroup {
final public function getGroupKey() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('FIELDGROUPKEY');
- if ($const === false) {
- throw new Exception(
- pht(
- '"%s" class "%s" must define a "%s" property.',
- __CLASS__,
- get_class($this),
- 'FIELDGROUPKEY'));
- }
-
- return $const;
+ return $this->getPhobjectClassConstant('FIELDGROUPKEY');
}
final public static function getAllFieldGroups() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getGroupKey')
->setSortMethod('getSortKey')
->execute();
}
}
diff --git a/src/applications/phid/type/PhabricatorPHIDType.php b/src/applications/phid/type/PhabricatorPHIDType.php
index c69075bdad..a8502b12f7 100644
--- a/src/applications/phid/type/PhabricatorPHIDType.php
+++ b/src/applications/phid/type/PhabricatorPHIDType.php
@@ -1,212 +1,202 @@
<?php
abstract class PhabricatorPHIDType extends Phobject {
final public function getTypeConstant() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('TYPECONST');
- if ($const === false) {
- throw new Exception(
- pht(
- '%s class "%s" must define a %s property.',
- __CLASS__,
- get_class($this),
- 'TYPECONST'));
- }
+ $const = $this->getPhobjectClassConstant('TYPECONST');
if (!is_string($const) || !preg_match('/^[A-Z]{4}$/', $const)) {
throw new Exception(
pht(
'%s class "%s" has an invalid %s property. PHID '.
'constants must be a four character uppercase string.',
__CLASS__,
get_class($this),
'TYPECONST'));
}
return $const;
}
abstract public function getTypeName();
public function newObject() {
return null;
}
public function getTypeIcon() {
// Default to the application icon if the type doesn't specify one.
$application_class = $this->getPHIDTypeApplicationClass();
if ($application_class) {
$application = newv($application_class, array());
return $application->getFontIcon();
}
return null;
}
/**
* Get the class name for the application this type belongs to.
*
* @return string|null Class name of the corresponding application, or null
* if the type is not bound to an application.
*/
public function getPHIDTypeApplicationClass() {
// TODO: Some day this should probably be abstract, but for now it only
// affects global search and there's no real burning need to go classify
// every PHID type.
return null;
}
/**
* Build a @{class:PhabricatorPolicyAwareQuery} to load objects of this type
* by PHID.
*
* If you can not build a single query which satisfies this requirement, you
* can provide a dummy implementation for this method and overload
* @{method:loadObjects} instead.
*
* @param PhabricatorObjectQuery Query being executed.
* @param list<phid> PHIDs to load.
* @return PhabricatorPolicyAwareQuery Query object which loads the
* specified PHIDs when executed.
*/
abstract protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids);
/**
* Load objects of this type, by PHID. For most PHID types, it is only
* necessary to implement @{method:buildQueryForObjects} to get object
* loading to work.
*
* @param PhabricatorObjectQuery Query being executed.
* @param list<phid> PHIDs to load.
* @return list<wild> Corresponding objects.
*/
public function loadObjects(
PhabricatorObjectQuery $query,
array $phids) {
$object_query = $this->buildQueryForObjects($query, $phids)
->setViewer($query->getViewer())
->setParentQuery($query);
// If the user doesn't have permission to use the application at all,
// just mark all the PHIDs as filtered. This primarily makes these
// objects show up as "Restricted" instead of "Unknown" when loaded as
// handles, which is technically true.
if (!$object_query->canViewerUseQueryApplication()) {
$object_query->addPolicyFilteredPHIDs(array_fuse($phids));
return array();
}
return $object_query->execute();
}
/**
* Populate provided handles with application-specific data, like titles and
* URIs.
*
* NOTE: The `$handles` and `$objects` lists are guaranteed to be nonempty
* and have the same keys: subclasses are expected to load information only
* for handles with visible objects.
*
* Because of this guarantee, a safe implementation will typically look like*
*
* foreach ($handles as $phid => $handle) {
* $object = $objects[$phid];
*
* $handle->setStuff($object->getStuff());
* // ...
* }
*
* In general, an implementation should call `setName()` and `setURI()` on
* each handle at a minimum. See @{class:PhabricatorObjectHandle} for other
* handle properties.
*
* @param PhabricatorHandleQuery Issuing query object.
* @param list<PhabricatorObjectHandle> Handles to populate with data.
* @param list<Object> Objects for these PHIDs loaded by
* @{method:buildQueryForObjects()}.
* @return void
*/
abstract public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects);
public function canLoadNamedObject($name) {
return false;
}
public function loadNamedObjects(
PhabricatorObjectQuery $query,
array $names) {
throw new PhutilMethodNotImplementedException();
}
/**
* Get all known PHID types.
*
* To get PHID types a given user has access to, see
* @{method:getAllInstalledTypes}.
*
* @return dict<string, PhabricatorPHIDType> Map of type constants to types.
*/
final public static function getAllTypes() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getTypeConstant')
->execute();
}
/**
* Get all PHID types of applications installed for a given viewer.
*
* @param PhabricatorUser Viewing user.
* @return dict<string, PhabricatorPHIDType> Map of constants to installed
* types.
*/
public static function getAllInstalledTypes(PhabricatorUser $viewer) {
$all_types = self::getAllTypes();
$installed_types = array();
$app_classes = array();
foreach ($all_types as $key => $type) {
$app_class = $type->getPHIDTypeApplicationClass();
if ($app_class === null) {
// If the PHID type isn't bound to an application, include it as
// installed.
$installed_types[$key] = $type;
continue;
}
// Otherwise, we need to check if this application is installed before
// including the PHID type.
$app_classes[$app_class][$key] = $type;
}
if ($app_classes) {
$apps = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withInstalled(true)
->withClasses(array_keys($app_classes))
->execute();
foreach ($apps as $app_class => $app) {
$installed_types += $app_classes[$app_class];
}
}
return $installed_types;
}
}
diff --git a/src/applications/policy/capability/PhabricatorPolicyCapability.php b/src/applications/policy/capability/PhabricatorPolicyCapability.php
index b7ff6a060b..36b8ea87c0 100644
--- a/src/applications/policy/capability/PhabricatorPolicyCapability.php
+++ b/src/applications/policy/capability/PhabricatorPolicyCapability.php
@@ -1,88 +1,66 @@
<?php
abstract class PhabricatorPolicyCapability extends Phobject {
const CAN_VIEW = 'view';
const CAN_EDIT = 'edit';
const CAN_JOIN = 'join';
/**
* Get the unique key identifying this capability. This key must be globally
* unique. Application capabilities should be namespaced. For example:
*
* application.create
*
* @return string Globally unique capability key.
*/
final public function getCapabilityKey() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('CAPABILITY');
- if ($const === false) {
- throw new Exception(
- pht(
- '%s class "%s" must define a %s property.',
- __CLASS__,
- get_class($this),
- 'CAPABILITY'));
- }
-
- if (!is_string($const)) {
- throw new Exception(
- pht(
- '%s class "%s" has an invalid %s property. '.
- 'Capability constants must be a string.',
- __CLASS__,
- get_class($this),
- 'CAPABILITY'));
- }
-
- return $const;
+ return $this->getPhobjectClassConstant('CAPABILITY');
}
/**
* Return a human-readable descriptive name for this capability, like
* "Can View".
*
* @return string Human-readable name describing the capability.
*/
abstract public function getCapabilityName();
/**
* Return a human-readable string describing what not having this capability
* prevents the user from doing. For example:
*
* - You do not have permission to edit this object.
* - You do not have permission to create new tasks.
*
* @return string Human-readable name describing what failing a check for this
* capability prevents the user from doing.
*/
public function describeCapabilityRejection() {
return null;
}
/**
* Can this capability be set to "public"? Broadly, this is only appropriate
* for view and view-related policies.
*
* @return bool True to allow the "public" policy. Returns false by default.
*/
public function shouldAllowPublicPolicySetting() {
return false;
}
final public static function getCapabilityByKey($key) {
return idx(self::getCapabilityMap(), $key);
}
final public static function getCapabilityMap() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getCapabilityKey')
->execute();
}
}
diff --git a/src/infrastructure/edges/type/PhabricatorEdgeType.php b/src/infrastructure/edges/type/PhabricatorEdgeType.php
index c86af5c027..1729256050 100644
--- a/src/infrastructure/edges/type/PhabricatorEdgeType.php
+++ b/src/infrastructure/edges/type/PhabricatorEdgeType.php
@@ -1,219 +1,209 @@
<?php
/**
* Defines an edge type.
*
* Edges are typed, directed connections between two objects. They are used to
* represent most simple relationships, like when a user is subscribed to an
* object or an object is a member of a project.
*
* @task load Loading Types
*/
abstract class PhabricatorEdgeType extends Phobject {
final public function getEdgeConstant() {
- $class = new ReflectionClass($this);
-
- $const = $class->getConstant('EDGECONST');
- if ($const === false) {
- throw new Exception(
- pht(
- '%s class "%s" must define an %s property.',
- __CLASS__,
- get_class($this),
- 'EDGECONST'));
- }
+ $const = $this->getPhobjectClassConstant('EDGECONST');
if (!is_int($const) || ($const <= 0)) {
throw new Exception(
pht(
'%s class "%s" has an invalid %s property. '.
'Edge constants must be positive integers.',
__CLASS__,
get_class($this),
'EDGECONST'));
}
return $const;
}
public function getInverseEdgeConstant() {
return null;
}
public function shouldPreventCycles() {
return false;
}
public function shouldWriteInverseTransactions() {
return false;
}
public function getTransactionPreviewString($actor) {
return pht(
'%s edited edge metadata.',
$actor);
}
public function getTransactionAddString(
$actor,
$add_count,
$add_edges) {
return pht(
'%s added %s edge(s): %s.',
$actor,
$add_count,
$add_edges);
}
public function getTransactionRemoveString(
$actor,
$rem_count,
$rem_edges) {
return pht(
'%s removed %s edge(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 %s edge(s), added %s: %s; removed %s: %s.',
$actor,
$total_count,
$add_count,
$add_edges,
$rem_count,
$rem_edges);
}
public function getFeedAddString(
$actor,
$object,
$add_count,
$add_edges) {
return pht(
'%s added %s edge(s) to %s: %s.',
$actor,
$add_count,
$object,
$add_edges);
}
public function getFeedRemoveString(
$actor,
$object,
$rem_count,
$rem_edges) {
return pht(
'%s removed %s edge(s) from %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 %s edge(s) for %s, added %s: %s; removed %s: %s.',
$actor,
$total_count,
$object,
$add_count,
$add_edges,
$rem_count,
$rem_edges);
}
/* -( Loading Types )------------------------------------------------------ */
/**
* @task load
*/
public static function getAllTypes() {
static $type_map;
if ($type_map === null) {
$types = id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getEdgeConstant')
->execute();
// Check that all the inverse edge definitions actually make sense. If
// edge type A says B is its inverse, B must exist and say that A is its
// inverse.
foreach ($types as $const => $type) {
$inverse = $type->getInverseEdgeConstant();
if ($inverse === null) {
continue;
}
if (empty($types[$inverse])) {
throw new Exception(
pht(
'Edge type "%s" ("%d") defines an inverse type ("%d") which '.
'does not exist.',
get_class($type),
$const,
$inverse));
}
$inverse_inverse = $types[$inverse]->getInverseEdgeConstant();
if ($inverse_inverse !== $const) {
throw new Exception(
pht(
'Edge type "%s" ("%d") defines an inverse type ("%d"), but that '.
'inverse type defines a different type ("%d") as its '.
'inverse.',
get_class($type),
$const,
$inverse,
$inverse_inverse));
}
}
$type_map = $types;
}
return $type_map;
}
/**
* @task load
*/
public static function getByConstant($const) {
$type = idx(self::getAllTypes(), $const);
if (!$type) {
throw new Exception(
pht('Unknown edge constant "%s"!', $const));
}
return $type;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Apr 28, 10:43 AM (1 d, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
106577
Default Alt Text
(40 KB)

Event Timeline