Path: blob/master/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
12242 views
<?php12abstract class PhabricatorStandardCustomField3extends PhabricatorCustomField {45private $rawKey;6private $fieldKey;7private $fieldName;8private $fieldValue;9private $fieldDescription;10private $fieldConfig;11private $applicationField;12private $strings = array();13private $caption;14private $fieldError;15private $required;16private $default;17private $isCopyable;18private $hasStorageValue;19private $isBuiltin;20private $isEnabled = true;2122abstract public function getFieldType();2324public static function buildStandardFields(25PhabricatorCustomField $template,26array $config,27$builtin = false) {2829$types = id(new PhutilClassMapQuery())30->setAncestorClass(__CLASS__)31->setUniqueMethod('getFieldType')32->execute();3334$fields = array();35foreach ($config as $key => $value) {36$type = idx($value, 'type', 'text');37if (empty($types[$type])) {38// TODO: We should have better typechecking somewhere, and then make39// this more serious.40continue;41}4243$namespace = $template->getStandardCustomFieldNamespace();44$full_key = "std:{$namespace}:{$key}";4546$template = clone $template;47$standard = id(clone $types[$type])48->setRawStandardFieldKey($key)49->setFieldKey($full_key)50->setFieldConfig($value)51->setApplicationField($template);5253if ($builtin) {54$standard->setIsBuiltin(true);55}5657$field = $template->setProxy($standard);58$fields[] = $field;59}6061return $fields;62}6364public function setApplicationField(65PhabricatorStandardCustomFieldInterface $application_field) {66$this->applicationField = $application_field;67return $this;68}6970public function getApplicationField() {71return $this->applicationField;72}7374public function setFieldName($name) {75$this->fieldName = $name;76return $this;77}7879public function getFieldValue() {80return $this->fieldValue;81}8283public function setFieldValue($value) {84$this->fieldValue = $value;85return $this;86}8788public function setCaption($caption) {89$this->caption = $caption;90return $this;91}9293public function getCaption() {94return $this->caption;95}9697public function setFieldDescription($description) {98$this->fieldDescription = $description;99return $this;100}101102public function setIsBuiltin($is_builtin) {103$this->isBuiltin = $is_builtin;104return $this;105}106107public function getIsBuiltin() {108return $this->isBuiltin;109}110111public function setFieldConfig(array $config) {112foreach ($config as $key => $value) {113switch ($key) {114case 'name':115$this->setFieldName($value);116break;117case 'description':118$this->setFieldDescription($value);119break;120case 'strings':121$this->setStrings($value);122break;123case 'caption':124$this->setCaption($value);125break;126case 'required':127if ($value) {128$this->setRequired($value);129$this->setFieldError(true);130}131break;132case 'default':133$this->setFieldValue($value);134break;135case 'copy':136$this->setIsCopyable($value);137break;138case 'type':139// We set this earlier on.140break;141}142}143$this->fieldConfig = $config;144return $this;145}146147public function getFieldConfigValue($key, $default = null) {148return idx($this->fieldConfig, $key, $default);149}150151public function setFieldError($field_error) {152$this->fieldError = $field_error;153return $this;154}155156public function getFieldError() {157return $this->fieldError;158}159160public function setRequired($required) {161$this->required = $required;162return $this;163}164165public function getRequired() {166return $this->required;167}168169public function setRawStandardFieldKey($raw_key) {170$this->rawKey = $raw_key;171return $this;172}173174public function getRawStandardFieldKey() {175return $this->rawKey;176}177178public function setIsEnabled($is_enabled) {179$this->isEnabled = $is_enabled;180return $this;181}182183public function getIsEnabled() {184return $this->isEnabled;185}186187public function isFieldEnabled() {188return $this->getIsEnabled();189}190191192/* -( PhabricatorCustomField )--------------------------------------------- */193194195public function setFieldKey($field_key) {196$this->fieldKey = $field_key;197return $this;198}199200public function getFieldKey() {201return $this->fieldKey;202}203204public function getFieldName() {205return coalesce($this->fieldName, parent::getFieldName());206}207208public function getFieldDescription() {209return coalesce($this->fieldDescription, parent::getFieldDescription());210}211212public function setStrings(array $strings) {213$this->strings = $strings;214return;215}216217public function getString($key, $default = null) {218return idx($this->strings, $key, $default);219}220221public function setIsCopyable($is_copyable) {222$this->isCopyable = $is_copyable;223return $this;224}225226public function getIsCopyable() {227return $this->isCopyable;228}229230public function shouldUseStorage() {231try {232$object = $this->newStorageObject();233return true;234} catch (PhabricatorCustomFieldImplementationIncompleteException $ex) {235return false;236}237}238239public function getValueForStorage() {240return $this->getFieldValue();241}242243public function setValueFromStorage($value) {244return $this->setFieldValue($value);245}246247public function didSetValueFromStorage() {248$this->hasStorageValue = true;249return $this;250}251252public function getOldValueForApplicationTransactions() {253if ($this->hasStorageValue) {254return $this->getValueForStorage();255} else {256return null;257}258}259260public function shouldAppearInApplicationTransactions() {261return true;262}263264public function shouldAppearInEditView() {265return $this->getFieldConfigValue('edit', true);266}267268public function readValueFromRequest(AphrontRequest $request) {269$value = $request->getStr($this->getFieldKey());270if (!strlen($value)) {271$value = null;272}273$this->setFieldValue($value);274}275276public function getInstructionsForEdit() {277return $this->getFieldConfigValue('instructions');278}279280public function getPlaceholder() {281return $this->getFieldConfigValue('placeholder', null);282}283284public function renderEditControl(array $handles) {285return id(new AphrontFormTextControl())286->setName($this->getFieldKey())287->setCaption($this->getCaption())288->setValue($this->getFieldValue())289->setError($this->getFieldError())290->setLabel($this->getFieldName())291->setPlaceholder($this->getPlaceholder());292}293294public function newStorageObject() {295return $this->getApplicationField()->newStorageObject();296}297298public function shouldAppearInPropertyView() {299return $this->getFieldConfigValue('view', true);300}301302public function renderPropertyViewValue(array $handles) {303if (!strlen($this->getFieldValue())) {304return null;305}306return $this->getFieldValue();307}308309public function shouldAppearInApplicationSearch() {310return $this->getFieldConfigValue('search', false);311}312313protected function newStringIndexStorage() {314return $this->getApplicationField()->newStringIndexStorage();315}316317protected function newNumericIndexStorage() {318return $this->getApplicationField()->newNumericIndexStorage();319}320321public function buildFieldIndexes() {322return array();323}324325public function buildOrderIndex() {326return null;327}328329public function readApplicationSearchValueFromRequest(330PhabricatorApplicationSearchEngine $engine,331AphrontRequest $request) {332return;333}334335public function applyApplicationSearchConstraintToQuery(336PhabricatorApplicationSearchEngine $engine,337PhabricatorCursorPagedPolicyAwareQuery $query,338$value) {339return;340}341342public function appendToApplicationSearchForm(343PhabricatorApplicationSearchEngine $engine,344AphrontFormView $form,345$value) {346return;347}348349public function validateApplicationTransactions(350PhabricatorApplicationTransactionEditor $editor,351$type,352array $xactions) {353354$this->setFieldError(null);355356$errors = parent::validateApplicationTransactions(357$editor,358$type,359$xactions);360361if ($this->getRequired()) {362$value = $this->getOldValueForApplicationTransactions();363364$transaction = null;365foreach ($xactions as $xaction) {366$value = $xaction->getNewValue();367if (!$this->isValueEmpty($value)) {368$transaction = $xaction;369break;370}371}372if ($this->isValueEmpty($value)) {373$error = new PhabricatorApplicationTransactionValidationError(374$type,375pht('Required'),376pht('%s is required.', $this->getFieldName()),377$transaction);378$error->setIsMissingFieldError(true);379$errors[] = $error;380$this->setFieldError(pht('Required'));381}382}383384return $errors;385}386387protected function isValueEmpty($value) {388if (is_array($value)) {389return empty($value);390}391return !strlen($value);392}393394public function getApplicationTransactionTitle(395PhabricatorApplicationTransaction $xaction) {396$author_phid = $xaction->getAuthorPHID();397$old = $xaction->getOldValue();398$new = $xaction->getNewValue();399400if (!$old) {401return pht(402'%s set %s to %s.',403$xaction->renderHandleLink($author_phid),404$this->getFieldName(),405$new);406} else if (!$new) {407return pht(408'%s removed %s.',409$xaction->renderHandleLink($author_phid),410$this->getFieldName());411} else {412return pht(413'%s changed %s from %s to %s.',414$xaction->renderHandleLink($author_phid),415$this->getFieldName(),416$old,417$new);418}419}420421public function getApplicationTransactionTitleForFeed(422PhabricatorApplicationTransaction $xaction) {423424$author_phid = $xaction->getAuthorPHID();425$object_phid = $xaction->getObjectPHID();426427$old = $xaction->getOldValue();428$new = $xaction->getNewValue();429430if (!$old) {431return pht(432'%s set %s to %s on %s.',433$xaction->renderHandleLink($author_phid),434$this->getFieldName(),435$new,436$xaction->renderHandleLink($object_phid));437} else if (!$new) {438return pht(439'%s removed %s on %s.',440$xaction->renderHandleLink($author_phid),441$this->getFieldName(),442$xaction->renderHandleLink($object_phid));443} else {444return pht(445'%s changed %s from %s to %s on %s.',446$xaction->renderHandleLink($author_phid),447$this->getFieldName(),448$old,449$new,450$xaction->renderHandleLink($object_phid));451}452}453454public function getHeraldFieldValue() {455return $this->getFieldValue();456}457458public function getFieldControlID($key = null) {459$key = coalesce($key, $this->getRawStandardFieldKey());460return 'std:control:'.$key;461}462463public function shouldAppearInGlobalSearch() {464return $this->getFieldConfigValue('fulltext', false);465}466467public function updateAbstractDocument(468PhabricatorSearchAbstractDocument $document) {469470$field_key = $this->getFieldConfigValue('fulltext');471472// If the caller or configuration didn't specify a valid field key,473// generate one automatically from the field index.474if (!is_string($field_key) || (strlen($field_key) != 4)) {475$field_key = '!'.substr($this->getFieldIndex(), 0, 3);476}477478$field_value = $this->getFieldValue();479if (strlen($field_value)) {480$document->addField($field_key, $field_value);481}482}483484protected function newStandardEditField() {485$short = $this->getModernFieldKey();486487return parent::newStandardEditField()488->setEditTypeKey($short)489->setIsCopyable($this->getIsCopyable());490}491492public function shouldAppearInConduitTransactions() {493return true;494}495496public function shouldAppearInConduitDictionary() {497return true;498}499500public function getModernFieldKey() {501if ($this->getIsBuiltin()) {502return $this->getRawStandardFieldKey();503} else {504return 'custom.'.$this->getRawStandardFieldKey();505}506}507508public function getConduitDictionaryValue() {509return $this->getFieldValue();510}511512public function newExportData() {513return $this->getFieldValue();514}515516}517518519