[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |