[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/nuance/source/ -> NuanceSourceDefinition.php (source)

   1  <?php
   2  
   3  abstract class NuanceSourceDefinition extends Phobject {
   4  
   5    private $actor;
   6    private $sourceObject;
   7  
   8    public function setActor(PhabricatorUser $actor) {
   9      $this->actor = $actor;
  10      return $this;
  11    }
  12    public function getActor() {
  13      return $this->actor;
  14    }
  15    public function requireActor() {
  16      $actor = $this->getActor();
  17      if (!$actor) {
  18        throw new Exception('You must "setActor()" first!');
  19      }
  20      return $actor;
  21    }
  22  
  23    public function setSourceObject(NuanceSource $source) {
  24      $source->setType($this->getSourceTypeConstant());
  25      $this->sourceObject = $source;
  26      return $this;
  27    }
  28    public function getSourceObject() {
  29      return $this->sourceObject;
  30    }
  31    public function requireSourceObject() {
  32      $source = $this->getSourceObject();
  33      if (!$source) {
  34        throw new Exception('You must "setSourceObject()" first!');
  35      }
  36      return $source;
  37    }
  38  
  39    public static function getSelectOptions() {
  40      $definitions = self::getAllDefinitions();
  41  
  42      $options = array();
  43      foreach ($definitions as $definition) {
  44        $key = $definition->getSourceTypeConstant();
  45        $name = $definition->getName();
  46        $options[$key] = $name;
  47      }
  48  
  49      return $options;
  50    }
  51  
  52    /**
  53     * Gives a @{class:NuanceSourceDefinition} object for a given
  54     * @{class:NuanceSource}. Note you still need to @{method:setActor}
  55     * before the @{class:NuanceSourceDefinition} object will be useful.
  56     */
  57    public static function getDefinitionForSource(NuanceSource $source) {
  58      $definitions = self::getAllDefinitions();
  59      $map = mpull($definitions, null, 'getSourceTypeConstant');
  60      $definition = $map[$source->getType()];
  61      $definition->setSourceObject($source);
  62  
  63      return $definition;
  64    }
  65  
  66    public static function getAllDefinitions() {
  67      static $definitions;
  68  
  69      if ($definitions === null) {
  70        $objects = id(new PhutilSymbolLoader())
  71          ->setAncestorClass(__CLASS__)
  72          ->loadObjects();
  73        foreach ($objects as $definition) {
  74          $key = $definition->getSourceTypeConstant();
  75          $name = $definition->getName();
  76          if (isset($definitions[$key])) {
  77            $conflict = $definitions[$key];
  78            throw new Exception(sprintf(
  79              'Defintion %s conflicts with definition %s. This is a programming '.
  80              'error.',
  81              $conflict,
  82              $name));
  83          }
  84        }
  85        $definitions = $objects;
  86      }
  87      return $definitions;
  88    }
  89  
  90    /**
  91     * A human readable string like "Twitter" or "Phabricator Form".
  92     */
  93    abstract public function getName();
  94  
  95    /**
  96     * This should be a any VARCHAR(32).
  97     *
  98     * @{method:getAllDefinitions} will throw if you choose a string that
  99     * collides with another @{class:NuanceSourceDefinition} class.
 100     */
 101    abstract public function getSourceTypeConstant();
 102  
 103    /**
 104     * Code to create and update @{class:NuanceItem}s and
 105     * @{class:NuanceRequestor}s via daemons goes here.
 106     *
 107     * If that does not make sense for the @{class:NuanceSource} you are
 108     * defining, simply return null. For example,
 109     * @{class:NuancePhabricatorFormSourceDefinition} since these are one-way
 110     * contact forms.
 111     */
 112    abstract public function updateItems();
 113  
 114    private function loadSourceObjectPolicies(
 115      PhabricatorUser $user,
 116      NuanceSource $source) {
 117  
 118      $user = $this->requireActor();
 119      $source = $this->requireSourceObject();
 120      return id(new PhabricatorPolicyQuery())
 121        ->setViewer($user)
 122        ->setObject($source)
 123        ->execute();
 124    }
 125  
 126    final public function getEditTitle() {
 127      $source = $this->requireSourceObject();
 128      if ($source->getPHID()) {
 129        $title = pht('Edit "%s" source.', $source->getName());
 130      } else {
 131        $title = pht('Create a new "%s" source.', $this->getName());
 132      }
 133  
 134      return $title;
 135    }
 136  
 137    final public function buildEditLayout(AphrontRequest $request) {
 138      $actor = $this->requireActor();
 139      $source = $this->requireSourceObject();
 140  
 141      $form_errors = array();
 142      $error_messages = array();
 143      $transactions = array();
 144      $validation_exception = null;
 145      if ($request->isFormPost()) {
 146        $transactions = $this->buildTransactions($request);
 147        try {
 148          $editor = id(new NuanceSourceEditor())
 149            ->setActor($actor)
 150            ->setContentSourceFromRequest($request)
 151            ->setContinueOnNoEffect(true)
 152            ->applyTransactions($source, $transactions);
 153  
 154          return id(new AphrontRedirectResponse())
 155            ->setURI($source->getURI());
 156  
 157        } catch (PhabricatorApplicationTransactionValidationException $ex) {
 158          $validation_exception = $ex;
 159        }
 160  
 161      }
 162  
 163      $form = $this->renderEditForm($validation_exception);
 164      $layout = id(new PHUIObjectBoxView())
 165        ->setHeaderText($this->getEditTitle())
 166        ->setValidationException($validation_exception)
 167        ->setFormErrors($error_messages)
 168        ->setForm($form);
 169  
 170      return $layout;
 171    }
 172  
 173    /**
 174     * Code to create a form to edit the @{class:NuanceItem} you are defining.
 175     *
 176     * return @{class:AphrontFormView}
 177     */
 178    private function renderEditForm(
 179      PhabricatorApplicationTransactionValidationException $ex = null) {
 180      $user = $this->requireActor();
 181      $source = $this->requireSourceObject();
 182      $policies = $this->loadSourceObjectPolicies($user, $source);
 183      $e_name = null;
 184      if ($ex) {
 185        $e_name = $ex->getShortMessage(NuanceSourceTransaction::TYPE_NAME);
 186      }
 187  
 188      $form = id(new AphrontFormView())
 189        ->setUser($user)
 190        ->appendChild(
 191          id(new AphrontFormTextControl())
 192          ->setLabel(pht('Name'))
 193          ->setName('name')
 194          ->setError($e_name)
 195          ->setValue($source->getName()))
 196        ->appendChild(
 197          id(new AphrontFormSelectControl())
 198          ->setLabel(pht('Type'))
 199          ->setName('type')
 200          ->setOptions(self::getSelectOptions())
 201          ->setValue($source->getType()));
 202  
 203      $form = $this->augmentEditForm($form, $ex);
 204  
 205      $form
 206        ->appendChild(
 207          id(new AphrontFormPolicyControl())
 208          ->setUser($user)
 209          ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
 210          ->setPolicyObject($source)
 211          ->setPolicies($policies)
 212          ->setName('viewPolicy'))
 213        ->appendChild(
 214          id(new AphrontFormPolicyControl())
 215          ->setUser($user)
 216          ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
 217          ->setPolicyObject($source)
 218          ->setPolicies($policies)
 219          ->setName('editPolicy'))
 220        ->appendChild(
 221          id(new AphrontFormSubmitControl())
 222          ->addCancelButton($source->getURI())
 223          ->setValue(pht('Save')));
 224  
 225      return $form;
 226    }
 227  
 228    /**
 229     * return @{class:AphrontFormView}
 230     */
 231    protected function augmentEditForm(
 232      AphrontFormView $form,
 233      PhabricatorApplicationTransactionValidationException $ex = null) {
 234  
 235      return $form;
 236    }
 237  
 238    /**
 239     * Hook to build up @{class:PhabricatorTransactions}.
 240     *
 241     * return array $transactions
 242     */
 243    protected function buildTransactions(AphrontRequest $request) {
 244      $transactions = array();
 245  
 246      $transactions[] = id(new NuanceSourceTransaction())
 247        ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)
 248        ->setNewValue($request->getStr('editPolicy'));
 249      $transactions[] = id(new NuanceSourceTransaction())
 250        ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
 251        ->setNewValue($request->getStr('viewPolicy'));
 252     $transactions[] = id(new NuanceSourceTransaction())
 253        ->setTransactionType(NuanceSourceTransaction::TYPE_NAME)
 254        ->setNewvalue($request->getStr('name'));
 255  
 256      return $transactions;
 257    }
 258  
 259    abstract public function renderView();
 260  
 261    abstract public function renderListView();
 262  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1