@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 154 lines 3.9 kB view raw
1<?php 2 3final class AphrontFormTokenizerControl extends AphrontFormControl { 4 5 private $datasource; 6 private $disableBehavior; 7 private $limit; 8 private $placeholder; 9 private $handles; 10 private $initialValue; 11 12 public function setDatasource(PhabricatorTypeaheadDatasource $datasource) { 13 $this->datasource = $datasource; 14 return $this; 15 } 16 17 public function setDisableBehavior($disable) { 18 $this->disableBehavior = $disable; 19 return $this; 20 } 21 22 protected function getCustomControlClass() { 23 return 'aphront-form-control-tokenizer'; 24 } 25 26 public function setLimit($limit) { 27 $this->limit = $limit; 28 return $this; 29 } 30 31 public function setPlaceholder($placeholder) { 32 $this->placeholder = $placeholder; 33 return $this; 34 } 35 36 public function setInitialValue(array $initial_value) { 37 $this->initialValue = $initial_value; 38 return $this; 39 } 40 41 public function getInitialValue() { 42 return $this->initialValue; 43 } 44 45 public function willRender() { 46 // Load the handles now so we'll get a bulk load later on when we actually 47 // render them. 48 $this->loadHandles(); 49 } 50 51 protected function renderInput() { 52 $name = $this->getName(); 53 54 $handles = $this->loadHandles(); 55 $handles = iterator_to_array($handles); 56 57 if ($this->getID()) { 58 $id = $this->getID(); 59 } else { 60 $id = celerity_generate_unique_node_id(); 61 } 62 63 $datasource = $this->datasource; 64 if (!$datasource) { 65 throw new Exception( 66 pht('You must set a datasource to use a TokenizerControl.')); 67 } 68 $datasource->setViewer($this->getUser()); 69 70 $placeholder = null; 71 if (!phutil_nonempty_string($this->placeholder)) { 72 $placeholder = $datasource->getPlaceholderText(); 73 } 74 75 $values = nonempty($this->getValue(), array()); 76 $tokens = $datasource->renderTokens($values); 77 78 foreach ($tokens as $token) { 79 $token->setInputName($this->getName()); 80 } 81 82 $template = id(new AphrontTokenizerTemplateView()) 83 ->setName($name) 84 ->setID($id) 85 ->setValue($tokens); 86 87 $initial_value = $this->getInitialValue(); 88 if ($initial_value !== null) { 89 $template->setInitialValue($initial_value); 90 } 91 92 $username = null; 93 if ($this->hasViewer()) { 94 $username = $this->getViewer()->getUsername(); 95 } 96 97 $datasource_uri = $datasource->getDatasourceURI(); 98 $browse_uri = $datasource->getBrowseURI(); 99 if ($browse_uri) { 100 $template->setBrowseURI($browse_uri); 101 } 102 103 if (!$this->disableBehavior) { 104 Javelin::initBehavior('aphront-basic-tokenizer', array( 105 'id' => $id, 106 'src' => $datasource_uri, 107 'value' => mpull($tokens, 'getValue', 'getKey'), 108 'icons' => mpull($tokens, 'getIcon', 'getKey'), 109 'types' => mpull($tokens, 'getTokenType', 'getKey'), 110 'colors' => mpull($tokens, 'getColor', 'getKey'), 111 'availabilityColors' => mpull( 112 $tokens, 113 'getAvailabilityColor', 114 'getKey'), 115 'limit' => $this->limit, 116 'username' => $username, 117 'placeholder' => $placeholder, 118 'browseURI' => $browse_uri, 119 'disabled' => $this->getDisabled(), 120 )); 121 } 122 123 return $template->render(); 124 } 125 126 private function loadHandles() { 127 if ($this->handles === null) { 128 $viewer = $this->getUser(); 129 if (!$viewer) { 130 throw new Exception( 131 pht( 132 'Call %s before rendering tokenizers. '. 133 'Use %s on %s to do this easily.', 134 'setUser()', 135 'appendControl()', 136 'AphrontFormView')); 137 } 138 139 $values = nonempty($this->getValue(), array()); 140 141 $phids = array(); 142 foreach ($values as $value) { 143 if (!PhabricatorTypeaheadDatasource::isFunctionToken($value)) { 144 $phids[] = $value; 145 } 146 } 147 148 $this->handles = $viewer->loadHandles($phids); 149 } 150 151 return $this->handles; 152 } 153 154}