@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
1<?php
2
3final class AphrontFormSelectControl extends AphrontFormControl {
4
5 protected function getCustomControlClass() {
6 return 'aphront-form-control-select';
7 }
8
9 private $options;
10 private $disabledOptions = array();
11
12 public function setOptions(array $options) {
13 $this->options = $options;
14 return $this;
15 }
16
17 public function getOptions() {
18 return $this->options;
19 }
20
21 public function setDisabledOptions(array $disabled) {
22 $this->disabledOptions = $disabled;
23 return $this;
24 }
25
26 protected function renderInput() {
27 return self::renderSelectTag(
28 $this->getValue(),
29 $this->getOptions(),
30 array(
31 'name' => $this->getName(),
32 'disabled' => $this->getDisabled() ? 'disabled' : null,
33 'id' => $this->getID(),
34 'aria-label' => $this->getAriaLabel(),
35 ),
36 $this->disabledOptions);
37 }
38
39 public static function renderSelectTag(
40 $selected,
41 array $options,
42 array $attrs = array(),
43 array $disabled = array()) {
44
45 $option_tags = self::renderOptions($selected, $options, $disabled);
46
47 return javelin_tag(
48 'select',
49 $attrs,
50 $option_tags);
51 }
52
53 private static function renderOptions(
54 $selected,
55 array $options,
56 array $disabled = array()) {
57 $disabled = array_fuse($disabled);
58
59 $tags = array();
60 $already_selected = false;
61 foreach ($options as $value => $thing) {
62 if (is_array($thing)) {
63 $tags[] = phutil_tag(
64 'optgroup',
65 array(
66 'label' => $value,
67 ),
68 self::renderOptions($selected, $thing));
69 } else {
70 // When there are a list of options including similar values like
71 // "0" and "" (the empty string), only select the first matching
72 // value. Ideally this should be more precise about matching, but we
73 // have 2,000 of these controls at this point so hold that for a
74 // broader rewrite.
75 if (!$already_selected && ($value == $selected)) {
76 $is_selected = 'selected';
77 $already_selected = true;
78 } else {
79 $is_selected = null;
80 }
81
82 $tags[] = phutil_tag(
83 'option',
84 array(
85 'selected' => $is_selected,
86 'value' => $value,
87 'disabled' => isset($disabled[$value]) ? 'disabled' : null,
88 ),
89 $thing);
90 }
91 }
92 return $tags;
93 }
94
95}