Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / view / AphrontDialogView.php
blobb8b00a6b3eabbca7c98d8a9d78fa44ccc67007e7
1 <?php
3 final class AphrontDialogView
4 extends AphrontView
5 implements AphrontResponseProducerInterface {
7 private $title;
8 private $shortTitle;
9 private $submitButton;
10 private $cancelURI;
11 private $cancelText = 'Cancel';
12 private $submitURI;
13 private $hidden = array();
14 private $class;
15 private $renderAsForm = true;
16 private $formID;
17 private $footers = array();
18 private $isStandalone;
19 private $method = 'POST';
20 private $disableWorkflowOnSubmit;
21 private $disableWorkflowOnCancel;
22 private $width = 'default';
23 private $errors = array();
24 private $flush;
25 private $validationException;
26 private $objectList;
27 private $resizeX;
28 private $resizeY;
31 const WIDTH_DEFAULT = 'default';
32 const WIDTH_FORM = 'form';
33 const WIDTH_FULL = 'full';
35 public function setMethod($method) {
36 $this->method = $method;
37 return $this;
40 public function setIsStandalone($is_standalone) {
41 $this->isStandalone = $is_standalone;
42 return $this;
45 public function setErrors(array $errors) {
46 $this->errors = $errors;
47 return $this;
50 public function getIsStandalone() {
51 return $this->isStandalone;
54 public function setSubmitURI($uri) {
55 $this->submitURI = $uri;
56 return $this;
59 public function setTitle($title) {
60 $this->title = $title;
61 return $this;
64 public function getTitle() {
65 return $this->title;
68 public function setShortTitle($short_title) {
69 $this->shortTitle = $short_title;
70 return $this;
73 public function getShortTitle() {
74 return $this->shortTitle;
77 public function setResizeY($resize_y) {
78 $this->resizeY = $resize_y;
79 return $this;
82 public function getResizeY() {
83 return $this->resizeY;
86 public function setResizeX($resize_x) {
87 $this->resizeX = $resize_x;
88 return $this;
91 public function getResizeX() {
92 return $this->resizeX;
95 public function addSubmitButton($text = null) {
96 if (!$text) {
97 $text = pht('Okay');
100 $this->submitButton = $text;
101 return $this;
104 public function addCancelButton($uri, $text = null) {
105 if (!$text) {
106 $text = pht('Cancel');
109 $this->cancelURI = $uri;
110 $this->cancelText = $text;
111 return $this;
114 public function addFooter($footer) {
115 $this->footers[] = $footer;
116 return $this;
119 public function addHiddenInput($key, $value) {
120 if (is_array($value)) {
121 foreach ($value as $hidden_key => $hidden_value) {
122 $this->hidden[] = array($key.'['.$hidden_key.']', $hidden_value);
124 } else {
125 $this->hidden[] = array($key, $value);
127 return $this;
130 public function setClass($class) {
131 $this->class = $class;
132 return $this;
135 public function setFlush($flush) {
136 $this->flush = $flush;
137 return $this;
140 public function setRenderDialogAsDiv() {
141 // TODO: This API is awkward.
142 $this->renderAsForm = false;
143 return $this;
146 public function setFormID($id) {
147 $this->formID = $id;
148 return $this;
151 public function setWidth($width) {
152 $this->width = $width;
153 return $this;
156 public function setObjectList(PHUIObjectItemListView $list) {
157 $this->objectList = true;
158 $box = id(new PHUIObjectBoxView())
159 ->setObjectList($list);
160 return $this->appendChild($box);
163 public function appendRemarkup($remarkup) {
164 $viewer = $this->getViewer();
165 $view = new PHUIRemarkupView($viewer, $remarkup);
167 $view_tag = phutil_tag(
168 'div',
169 array(
170 'class' => 'aphront-dialog-view-paragraph',
172 $view);
174 return $this->appendChild($view_tag);
177 public function appendParagraph($paragraph) {
178 return $this->appendParagraphTag($paragraph);
181 public function appendCommand($command) {
182 $command_tag = phutil_tag('tt', array(), $command);
183 return $this->appendParagraphTag(
184 $command_tag,
185 'aphront-dialog-view-command');
188 private function appendParagraphTag($content, $classes = null) {
189 if ($classes) {
190 $classes = (array)$classes;
191 } else {
192 $classes = array();
195 array_unshift($classes, 'aphront-dialog-view-paragraph');
197 $paragraph_tag = phutil_tag(
198 'p',
199 array(
200 'class' => implode(' ', $classes),
202 $content);
204 return $this->appendChild($paragraph_tag);
208 public function appendList(array $items) {
209 $listitems = array();
210 foreach ($items as $item) {
211 $listitems[] = phutil_tag(
212 'li',
213 array(
214 'class' => 'remarkup-list-item',
216 $item);
218 return $this->appendChild(
219 phutil_tag(
220 'ul',
221 array(
222 'class' => 'remarkup-list',
224 $listitems));
227 public function appendForm(AphrontFormView $form) {
228 return $this->appendChild($form->buildLayoutView());
231 public function setDisableWorkflowOnSubmit($disable_workflow_on_submit) {
232 $this->disableWorkflowOnSubmit = $disable_workflow_on_submit;
233 return $this;
236 public function getDisableWorkflowOnSubmit() {
237 return $this->disableWorkflowOnSubmit;
240 public function setDisableWorkflowOnCancel($disable_workflow_on_cancel) {
241 $this->disableWorkflowOnCancel = $disable_workflow_on_cancel;
242 return $this;
245 public function getDisableWorkflowOnCancel() {
246 return $this->disableWorkflowOnCancel;
249 public function setValidationException(
250 PhabricatorApplicationTransactionValidationException $ex = null) {
251 $this->validationException = $ex;
252 return $this;
255 public function render() {
256 require_celerity_resource('aphront-dialog-view-css');
258 $buttons = array();
259 if ($this->submitButton) {
260 $meta = array();
261 if ($this->disableWorkflowOnSubmit) {
262 $meta['disableWorkflow'] = true;
265 $buttons[] = javelin_tag(
266 'button',
267 array(
268 'name' => '__submit__',
269 'sigil' => '__default__',
270 'type' => 'submit',
271 'meta' => $meta,
273 $this->submitButton);
276 if ($this->cancelURI) {
277 $meta = array();
278 if ($this->disableWorkflowOnCancel) {
279 $meta['disableWorkflow'] = true;
282 $buttons[] = javelin_tag(
283 'a',
284 array(
285 'href' => $this->cancelURI,
286 'class' => 'button button-grey',
287 'name' => '__cancel__',
288 'sigil' => 'jx-workflow-button',
289 'meta' => $meta,
291 $this->cancelText);
294 if (!$this->hasViewer()) {
295 throw new Exception(
296 pht(
297 'You must call %s when rendering an %s.',
298 'setViewer()',
299 __CLASS__));
302 $classes = array();
303 $classes[] = 'aphront-dialog-view';
304 $classes[] = $this->class;
305 if ($this->flush) {
306 $classes[] = 'aphront-dialog-flush';
309 switch ($this->width) {
310 case self::WIDTH_FORM:
311 case self::WIDTH_FULL:
312 $classes[] = 'aphront-dialog-view-width-'.$this->width;
313 break;
314 case self::WIDTH_DEFAULT:
315 break;
316 default:
317 throw new Exception(
318 pht(
319 "Unknown dialog width '%s'!",
320 $this->width));
323 if ($this->isStandalone) {
324 $classes[] = 'aphront-dialog-view-standalone';
327 if ($this->objectList) {
328 $classes[] = 'aphront-dialog-object-list';
331 $attributes = array(
332 'class' => implode(' ', $classes),
333 'sigil' => 'jx-dialog',
334 'role' => 'dialog',
337 $form_attributes = array(
338 'action' => $this->submitURI,
339 'method' => $this->method,
340 'id' => $this->formID,
343 $hidden_inputs = array();
344 $hidden_inputs[] = phutil_tag(
345 'input',
346 array(
347 'type' => 'hidden',
348 'name' => '__dialog__',
349 'value' => '1',
352 foreach ($this->hidden as $desc) {
353 list($key, $value) = $desc;
354 $hidden_inputs[] = javelin_tag(
355 'input',
356 array(
357 'type' => 'hidden',
358 'name' => $key,
359 'value' => $value,
360 'sigil' => 'aphront-dialog-application-input',
364 if (!$this->renderAsForm) {
365 $buttons = array(
366 phabricator_form(
367 $this->getViewer(),
368 $form_attributes,
369 array_merge($hidden_inputs, $buttons)),
373 $children = $this->renderChildren();
375 $errors = $this->errors;
377 $ex = $this->validationException;
378 $exception_errors = null;
379 if ($ex) {
380 foreach ($ex->getErrors() as $error) {
381 $errors[] = $error->getMessage();
385 if ($errors) {
386 $children = array(
387 id(new PHUIInfoView())->setErrors($errors),
388 $children,
392 $header = new PHUIHeaderView();
393 $header->setHeader($this->title);
395 $footer = null;
396 if ($this->footers) {
397 $footer = phutil_tag(
398 'div',
399 array(
400 'class' => 'aphront-dialog-foot',
402 $this->footers);
405 $resize = null;
406 if ($this->resizeX || $this->resizeY) {
407 $resize = javelin_tag(
408 'div',
409 array(
410 'class' => 'aphront-dialog-resize',
411 'sigil' => 'jx-dialog-resize',
412 'meta' => array(
413 'resizeX' => $this->resizeX,
414 'resizeY' => $this->resizeY,
419 $tail = null;
420 if ($buttons || $footer) {
421 $tail = phutil_tag(
422 'div',
423 array(
424 'class' => 'aphront-dialog-tail grouped',
426 array(
427 $buttons,
428 $footer,
429 $resize,
433 $content = array(
434 phutil_tag(
435 'div',
436 array(
437 'class' => 'aphront-dialog-head',
439 $header),
440 phutil_tag('div',
441 array(
442 'class' => 'aphront-dialog-body grouped',
444 $children),
445 $tail,
448 if ($this->renderAsForm) {
449 return phabricator_form(
450 $this->getViewer(),
451 $form_attributes + $attributes,
452 array($hidden_inputs, $content));
453 } else {
454 return javelin_tag(
455 'div',
456 $attributes,
457 $content);
462 /* -( AphrontResponseProducerInterface )----------------------------------- */
465 public function produceAphrontResponse() {
466 return id(new AphrontDialogResponse())
467 ->setDialog($this);