protected function newEditField($object, PhabricatorEditField $template)
 {
     $setting_property = PhabricatorUserPreferencesTransaction::PROPERTY_SETTING;
     $setting_key = $this->getSettingKey();
     $value = $object->getPreference($setting_key);
     $xaction_type = PhabricatorUserPreferencesTransaction::TYPE_SETTING;
     $label = $this->getSettingName();
     $template->setKey($setting_key)->setLabel($label)->setValue($value)->setTransactionType($xaction_type)->setMetadataValue($setting_property, $setting_key);
     $instructions = $this->getControlInstructions();
     if (strlen($instructions)) {
         $template->setControlInstructions($instructions);
     }
     return $template;
 }
 protected function getValueForTransaction()
 {
     $new = parent::getValueForTransaction();
     $edge_types = array(PhabricatorTransactions::TYPE_EDGE => true, PhabricatorTransactions::TYPE_SUBSCRIBERS => true);
     if (isset($edge_types[$this->getTransactionType()])) {
         if ($this->originalValue !== null) {
             // If we're building an edge transaction and the request has data
             // about the original value the user saw when they loaded the form,
             // interpret the edit as a mixture of "+" and "-" operations instead
             // of a single "=" operation. This limits our exposure to race
             // conditions by making most concurrent edits merge correctly.
             $new = parent::getValueForTransaction();
             $old = $this->originalValue;
             $add = array_diff($new, $old);
             $rem = array_diff($old, $new);
             $value = array();
             if ($add) {
                 $value['+'] = array_fuse($add);
             }
             if ($rem) {
                 $value['-'] = array_fuse($rem);
             }
             return $value;
         } else {
             if (!is_array($new)) {
                 throw new Exception(print_r($new, true));
             }
             return array('=' => array_fuse($new));
         }
     }
     return $new;
 }
 public function getConduitEditTypes()
 {
     $field = $this->getCustomField();
     if (!$field->shouldAppearInConduitTransactions()) {
         return array();
     }
     return parent::getConduitEditTypes();
 }
 public function getConduitEditTypes()
 {
     if (!$this->getUseEdgeTransactions()) {
         return parent::getConduitEditTypes();
     }
     $transaction_type = $this->getTransactionType();
     if ($transaction_type === null) {
         return array();
     }
     $type_key = $this->getEditTypeKey();
     $strings = $this->transactionDescriptions;
     $base = $this->getEditType();
     $add = id(clone $base)->setEditType($type_key . '.add')->setEdgeOperation('+')->setDescription(idx($strings, '+'))->setValueDescription(pht('List of PHIDs to add.'));
     $rem = id(clone $base)->setEditType($type_key . '.remove')->setEdgeOperation('-')->setDescription(idx($strings, '-'))->setValueDescription(pht('List of PHIDs to remove.'));
     $set = id(clone $base)->setEditType($type_key . '.set')->setEdgeOperation('=')->setDescription(idx($strings, '='))->setValueDescription(pht('List of PHIDs to set.'));
     return array($add, $rem, $set);
 }
 protected function getValueFromField(PhabricatorEditField $other)
 {
     return $other->getValue();
 }
 private function isCommentField(PhabricatorEditField $field)
 {
     // TODO: This is a little bit hacky.
     if ($field->getKey() == 'comment') {
         return true;
     }
     if ($field->getIsLocked()) {
         return false;
     }
     if ($field->getIsHidden()) {
         return false;
     }
     return true;
 }
 protected function newConduitEditTypes()
 {
     if (!$this->getUseEdgeTransactions()) {
         return parent::newConduitEditTypes();
     }
     $transaction_type = $this->getTransactionType();
     if ($transaction_type === null) {
         return array();
     }
     $type_key = $this->getEditTypeKey();
     $base = $this->getEditType();
     $add = id(clone $base)->setEditType($type_key . '.add')->setEdgeOperation('+')->setConduitTypeDescription(pht('List of PHIDs to add.'))->setConduitParameterType($this->getConduitParameterType());
     $rem = id(clone $base)->setEditType($type_key . '.remove')->setEdgeOperation('-')->setConduitTypeDescription(pht('List of PHIDs to remove.'))->setConduitParameterType($this->getConduitParameterType());
     $set = id(clone $base)->setEditType($type_key . '.set')->setEdgeOperation('=')->setConduitTypeDescription(pht('List of PHIDs to set.'))->setConduitParameterType($this->getConduitParameterType());
     return array($add, $rem, $set);
 }
 protected function getValidationExceptionShortMessage(PhabricatorApplicationTransactionValidationException $ex, PhabricatorEditField $field)
 {
     // Settings fields all have the same transaction type so we need to make
     // sure the transaction is changing the same setting before matching an
     // error to a given field.
     $xaction_type = $field->getTransactionType();
     if ($xaction_type == PhabricatorUserPreferencesTransaction::TYPE_SETTING) {
         $property = PhabricatorUserPreferencesTransaction::PROPERTY_SETTING;
         $field_setting = idx($field->getMetadata(), $property);
         foreach ($ex->getErrors() as $error) {
             if ($error->getType() !== $xaction_type) {
                 continue;
             }
             $xaction = $error->getTransaction();
             if (!$xaction) {
                 continue;
             }
             $xaction_setting = $xaction->getMetadataValue($property);
             if ($xaction_setting != $field_setting) {
                 continue;
             }
             $short_message = $error->getShortMessage();
             if ($short_message !== null) {
                 return $short_message;
             }
         }
         return null;
     }
     return parent::getValidationExceptionShortMessage($ex, $field);
 }
 protected function getValidationExceptionShortMessage(PhabricatorApplicationTransactionValidationException $ex, PhabricatorEditField $field)
 {
     $xaction_type = $field->getTransactionType();
     if ($xaction_type === null) {
         return null;
     }
     return $ex->getShortMessage($xaction_type);
 }
 public function appendToForm(AphrontFormView $form)
 {
     $form->setEncType('multipart/form-data');
     return parent::appendToForm($form);
 }