Remove product literal strings in "pht()", part 6
[phabricator.git] / src / applications / project / engine / PhabricatorBoardResponseEngine.php
blob81e56d211635ee3a3081e4a84be5844af938ca27
1 <?php
3 final class PhabricatorBoardResponseEngine extends Phobject {
5 private $viewer;
6 private $objects;
7 private $boardPHID;
8 private $visiblePHIDs = array();
9 private $updatePHIDs = array();
10 private $ordering;
11 private $sounds;
13 public function setViewer(PhabricatorUser $viewer) {
14 $this->viewer = $viewer;
15 return $this;
18 public function getViewer() {
19 return $this->viewer;
22 public function setBoardPHID($board_phid) {
23 $this->boardPHID = $board_phid;
24 return $this;
27 public function getBoardPHID() {
28 return $this->boardPHID;
31 public function setObjects(array $objects) {
32 $this->objects = $objects;
33 return $this;
36 public function getObjects() {
37 return $this->objects;
40 public function setVisiblePHIDs(array $visible_phids) {
41 $this->visiblePHIDs = $visible_phids;
42 return $this;
45 public function getVisiblePHIDs() {
46 return $this->visiblePHIDs;
49 public function setUpdatePHIDs(array $update_phids) {
50 $this->updatePHIDs = $update_phids;
51 return $this;
54 public function getUpdatePHIDs() {
55 return $this->updatePHIDs;
58 public function setOrdering(PhabricatorProjectColumnOrder $ordering) {
59 $this->ordering = $ordering;
60 return $this;
63 public function getOrdering() {
64 return $this->ordering;
67 public function setSounds(array $sounds) {
68 $this->sounds = $sounds;
69 return $this;
72 public function getSounds() {
73 return $this->sounds;
76 public function buildResponse() {
77 $viewer = $this->getViewer();
78 $board_phid = $this->getBoardPHID();
79 $ordering = $this->getOrdering();
81 $update_phids = $this->getUpdatePHIDs();
82 $update_phids = array_fuse($update_phids);
84 $visible_phids = $this->getVisiblePHIDs();
85 $visible_phids = array_fuse($visible_phids);
87 $all_phids = $update_phids + $visible_phids;
89 // Load all the other tasks that are visible in the affected columns and
90 // perform layout for them.
92 if ($this->objects !== null) {
93 $all_objects = $this->getObjects();
94 $all_objects = mpull($all_objects, null, 'getPHID');
95 } else {
96 $all_objects = id(new ManiphestTaskQuery())
97 ->setViewer($viewer)
98 ->withPHIDs($all_phids)
99 ->execute();
100 $all_objects = mpull($all_objects, null, 'getPHID');
103 // NOTE: The board layout engine is sensitive to PHID input order, and uses
104 // the input order as a component of the "natural" column ordering if no
105 // explicit ordering is specified. Rearrange the PHIDs in ID order.
107 $all_objects = msort($all_objects, 'getID');
108 $ordered_phids = mpull($all_objects, 'getPHID');
110 $layout_engine = id(new PhabricatorBoardLayoutEngine())
111 ->setViewer($viewer)
112 ->setBoardPHIDs(array($board_phid))
113 ->setObjectPHIDs($ordered_phids)
114 ->executeLayout();
116 $natural = array();
118 $update_columns = array();
119 foreach ($update_phids as $update_phid) {
120 $update_columns += $layout_engine->getObjectColumns(
121 $board_phid,
122 $update_phid);
125 foreach ($update_columns as $column_phid => $column) {
126 $column_object_phids = $layout_engine->getColumnObjectPHIDs(
127 $board_phid,
128 $column_phid);
129 $natural[$column_phid] = array_values($column_object_phids);
132 if ($ordering) {
133 $vectors = $ordering->getSortVectorsForObjects($all_objects);
134 $header_keys = $ordering->getHeaderKeysForObjects($all_objects);
135 $headers = $ordering->getHeadersForObjects($all_objects);
136 $headers = mpull($headers, 'toDictionary');
137 } else {
138 $vectors = array();
139 $header_keys = array();
140 $headers = array();
143 $templates = $this->newCardTemplates();
145 $cards = array();
146 foreach ($all_objects as $card_phid => $object) {
147 $card = array(
148 'vectors' => array(),
149 'headers' => array(),
150 'properties' => array(),
151 'nodeHTMLTemplate' => null,
154 if ($ordering) {
155 $order_key = $ordering->getColumnOrderKey();
157 $vector = idx($vectors, $card_phid);
158 if ($vector !== null) {
159 $card['vectors'][$order_key] = $vector;
162 $header = idx($header_keys, $card_phid);
163 if ($header !== null) {
164 $card['headers'][$order_key] = $header;
167 $card['properties'] = self::newTaskProperties($object);
170 if (isset($templates[$card_phid])) {
171 $card['nodeHTMLTemplate'] = hsprintf('%s', $templates[$card_phid]);
172 $card['update'] = true;
173 } else {
174 $card['update'] = false;
177 $card['vectors'] = (object)$card['vectors'];
178 $card['headers'] = (object)$card['headers'];
179 $card['properties'] = (object)$card['properties'];
181 $cards[$card_phid] = $card;
184 // Mark cards which are currently visible on the client but not visible
185 // on the board on the server for removal from the client view of the
186 // board state.
187 foreach ($visible_phids as $card_phid) {
188 if (!isset($cards[$card_phid])) {
189 $cards[$card_phid] = array(
190 'remove' => true,
195 $payload = array(
196 'columnMaps' => $natural,
197 'cards' => $cards,
198 'headers' => $headers,
199 'sounds' => $this->getSounds(),
202 return id(new AphrontAjaxResponse())
203 ->setContent($payload);
206 public static function newTaskProperties($task) {
207 return array(
208 'points' => (double)$task->getPoints(),
209 'status' => $task->getStatus(),
210 'priority' => (int)$task->getPriority(),
211 'owner' => $task->getOwnerPHID(),
215 private function loadExcludedProjectPHIDs() {
216 $viewer = $this->getViewer();
217 $board_phid = $this->getBoardPHID();
219 $exclude_phids = array($board_phid);
221 $descendants = id(new PhabricatorProjectQuery())
222 ->setViewer($viewer)
223 ->withAncestorProjectPHIDs($exclude_phids)
224 ->execute();
226 foreach ($descendants as $descendant) {
227 $exclude_phids[] = $descendant->getPHID();
230 return array_fuse($exclude_phids);
233 private function newCardTemplates() {
234 $viewer = $this->getViewer();
236 $update_phids = $this->getUpdatePHIDs();
237 if (!$update_phids) {
238 return array();
240 $update_phids = array_fuse($update_phids);
242 if ($this->objects === null) {
243 $objects = id(new ManiphestTaskQuery())
244 ->setViewer($viewer)
245 ->withPHIDs($update_phids)
246 ->needProjectPHIDs(true)
247 ->execute();
248 } else {
249 $objects = $this->getObjects();
250 $objects = mpull($objects, null, 'getPHID');
251 $objects = array_select_keys($objects, $update_phids);
254 if (!$objects) {
255 return array();
258 $excluded_phids = $this->loadExcludedProjectPHIDs();
260 $rendering_engine = id(new PhabricatorBoardRenderingEngine())
261 ->setViewer($viewer)
262 ->setObjects($objects)
263 ->setExcludedProjectPHIDs($excluded_phids);
265 $templates = array();
266 foreach ($objects as $object) {
267 $object_phid = $object->getPHID();
269 $card = $rendering_engine->renderCard($object_phid);
270 $item = $card->getItem();
271 $template = hsprintf('%s', $item);
273 $templates[$object_phid] = $template;
276 return $templates;