2015-07-06 22:15:33 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class HeraldField extends Phobject {
|
|
|
|
|
|
|
|
private $adapter;
|
|
|
|
|
2015-07-06 22:15:47 +02:00
|
|
|
const STANDARD_BOOL = 'standard.bool';
|
2015-07-06 22:17:14 +02:00
|
|
|
const STANDARD_TEXT = 'standard.text';
|
2015-07-07 20:53:17 +02:00
|
|
|
const STANDARD_TEXT_LIST = 'standard.text.list';
|
|
|
|
const STANDARD_TEXT_MAP = 'standard.text.map';
|
2015-07-06 22:15:47 +02:00
|
|
|
const STANDARD_PHID = 'standard.phid';
|
2015-07-16 23:11:44 +02:00
|
|
|
const STANDARD_PHID_LIST = 'standard.phid.list';
|
2015-07-07 20:53:17 +02:00
|
|
|
const STANDARD_PHID_BOOL = 'standard.phid.bool';
|
2015-07-06 22:17:14 +02:00
|
|
|
const STANDARD_PHID_NULLABLE = 'standard.phid.nullable';
|
2015-07-06 22:15:47 +02:00
|
|
|
|
2015-07-06 22:15:33 +02:00
|
|
|
abstract public function getHeraldFieldName();
|
|
|
|
abstract public function getHeraldFieldValue($object);
|
2015-07-06 22:15:47 +02:00
|
|
|
|
2015-07-16 23:11:44 +02:00
|
|
|
protected function getHeraldFieldStandardType() {
|
|
|
|
throw new PhutilMethodNotImplementedException();
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:15:47 +02:00
|
|
|
public function getHeraldFieldConditions() {
|
2015-07-16 23:11:44 +02:00
|
|
|
$standard_type = $this->getHeraldFieldStandardType();
|
|
|
|
switch ($standard_type) {
|
2015-07-06 22:15:47 +02:00
|
|
|
case self::STANDARD_BOOL:
|
|
|
|
return array(
|
|
|
|
HeraldAdapter::CONDITION_IS_TRUE,
|
|
|
|
HeraldAdapter::CONDITION_IS_FALSE,
|
|
|
|
);
|
2015-07-06 22:17:14 +02:00
|
|
|
case self::STANDARD_TEXT:
|
|
|
|
return array(
|
|
|
|
HeraldAdapter::CONDITION_CONTAINS,
|
|
|
|
HeraldAdapter::CONDITION_NOT_CONTAINS,
|
|
|
|
HeraldAdapter::CONDITION_IS,
|
|
|
|
HeraldAdapter::CONDITION_IS_NOT,
|
|
|
|
HeraldAdapter::CONDITION_REGEXP,
|
|
|
|
);
|
2015-07-06 22:15:47 +02:00
|
|
|
case self::STANDARD_PHID:
|
|
|
|
return array(
|
|
|
|
HeraldAdapter::CONDITION_IS_ANY,
|
|
|
|
HeraldAdapter::CONDITION_IS_NOT_ANY,
|
|
|
|
);
|
2015-07-16 23:11:44 +02:00
|
|
|
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,
|
|
|
|
);
|
2015-07-07 20:53:17 +02:00
|
|
|
case self::STANDARD_PHID_BOOL:
|
|
|
|
return array(
|
|
|
|
HeraldAdapter::CONDITION_EXISTS,
|
|
|
|
HeraldAdapter::CONDITION_NOT_EXISTS,
|
|
|
|
);
|
2015-07-06 22:17:14 +02:00
|
|
|
case self::STANDARD_PHID_NULLABLE:
|
|
|
|
return array(
|
|
|
|
HeraldAdapter::CONDITION_IS_ANY,
|
|
|
|
HeraldAdapter::CONDITION_IS_NOT_ANY,
|
|
|
|
HeraldAdapter::CONDITION_EXISTS,
|
|
|
|
HeraldAdapter::CONDITION_NOT_EXISTS,
|
|
|
|
);
|
2015-07-07 20:53:17 +02:00
|
|
|
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,
|
|
|
|
);
|
2015-07-06 22:15:47 +02:00
|
|
|
}
|
|
|
|
|
2015-07-16 23:11:44 +02:00
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Herald field "%s" has unknown standard type "%s".',
|
|
|
|
get_class($this),
|
|
|
|
$standard_type));
|
2015-07-06 22:15:47 +02:00
|
|
|
}
|
|
|
|
|
2015-07-16 23:11:44 +02:00
|
|
|
public function getHeraldFieldValueType($condition) {
|
|
|
|
$standard_type = $this->getHeraldFieldStandardType();
|
|
|
|
switch ($standard_type) {
|
|
|
|
case self::STANDARD_BOOL:
|
|
|
|
case self::STANDARD_PHID_BOOL:
|
|
|
|
return HeraldAdapter::VALUE_NONE;
|
|
|
|
case self::STANDARD_TEXT:
|
|
|
|
case self::STANDARD_TEXT_LIST:
|
|
|
|
case self::STANDARD_TEXT_MAP:
|
|
|
|
return HeraldAdapter::VALUE_TEXT;
|
|
|
|
}
|
2015-07-06 22:15:47 +02:00
|
|
|
|
2015-07-16 23:11:44 +02:00
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Herald field "%s" has unknown standard type "%s".',
|
|
|
|
get_class($this),
|
|
|
|
$standard_type));
|
|
|
|
}
|
2015-07-06 22:15:33 +02:00
|
|
|
|
|
|
|
abstract public function supportsObject($object);
|
|
|
|
|
|
|
|
public function getFieldsForObject($object) {
|
|
|
|
return array($this->getFieldConstant() => $this);
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:17:01 +02:00
|
|
|
public function renderConditionValue(
|
|
|
|
PhabricatorUser $viewer,
|
|
|
|
$value) {
|
|
|
|
|
|
|
|
// TODO: While this is less of a mess than it used to be, it would still
|
|
|
|
// be nice to push this down into individual fields better eventually and
|
|
|
|
// stop guessing which values are PHIDs and which aren't.
|
|
|
|
|
|
|
|
if (!is_array($value)) {
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
$type_unknown = PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
|
|
|
|
|
|
|
|
foreach ($value as $key => $val) {
|
|
|
|
if (is_string($val)) {
|
|
|
|
if (phid_get_type($val) !== $type_unknown) {
|
|
|
|
$value[$key] = $viewer->renderHandle($val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return phutil_implode_html(', ', $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getEditorValue(
|
|
|
|
PhabricatorUser $viewer,
|
|
|
|
$value) {
|
|
|
|
|
|
|
|
// TODO: This should be better structured and pushed down into individual
|
|
|
|
// fields. As it is used to manually build tokenizer tokens, it can
|
|
|
|
// probably be removed entirely.
|
|
|
|
|
|
|
|
if (is_array($value)) {
|
|
|
|
$handles = $viewer->loadHandles($value);
|
|
|
|
$value_map = array();
|
|
|
|
foreach ($value as $k => $phid) {
|
|
|
|
$value_map[$phid] = $handles[$phid]->getName();
|
|
|
|
}
|
|
|
|
$value = $value_map;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:15:33 +02:00
|
|
|
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'));
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:15:58 +02:00
|
|
|
$limit = self::getFieldConstantByteLimit();
|
|
|
|
if (!is_string($const) || (strlen($const) > $limit)) {
|
2015-07-06 22:15:33 +02:00
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'"%s" class "%s" has an invalid "%s" property. Field constants '.
|
2015-07-06 22:15:58 +02:00
|
|
|
'must be strings and no more than %s bytes in length.',
|
2015-07-06 22:15:33 +02:00
|
|
|
__CLASS__,
|
|
|
|
get_class($this),
|
2015-07-06 22:15:58 +02:00
|
|
|
'FIELDCONST',
|
|
|
|
new PhutilNumber($limit)));
|
2015-07-06 22:15:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return $const;
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:15:58 +02:00
|
|
|
final public static function getFieldConstantByteLimit() {
|
|
|
|
return 64;
|
|
|
|
}
|
|
|
|
|
2015-07-06 22:15:33 +02:00
|
|
|
final public static function getAllFields() {
|
|
|
|
return id(new PhutilClassMapQuery())
|
|
|
|
->setAncestorClass(__CLASS__)
|
|
|
|
->setUniqueMethod('getFieldConstant')
|
|
|
|
->execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|