[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 abstract class PhabricatorApplicationConfigOptions extends Phobject { 4 5 abstract public function getName(); 6 abstract public function getDescription(); 7 abstract public function getOptions(); 8 9 public function validateOption(PhabricatorConfigOption $option, $value) { 10 if ($value === $option->getDefault()) { 11 return; 12 } 13 14 if ($value === null) { 15 return; 16 } 17 18 if ($option->isCustomType()) { 19 return $option->getCustomObject()->validateOption($option, $value); 20 } 21 22 switch ($option->getType()) { 23 case 'bool': 24 if ($value !== true && 25 $value !== false) { 26 throw new PhabricatorConfigValidationException( 27 pht( 28 "Option '%s' is of type bool, but value is not true or false.", 29 $option->getKey())); 30 } 31 break; 32 case 'int': 33 if (!is_int($value)) { 34 throw new PhabricatorConfigValidationException( 35 pht( 36 "Option '%s' is of type int, but value is not an integer.", 37 $option->getKey())); 38 } 39 break; 40 case 'string': 41 if (!is_string($value)) { 42 throw new PhabricatorConfigValidationException( 43 pht( 44 "Option '%s' is of type string, but value is not a string.", 45 $option->getKey())); 46 } 47 break; 48 case 'class': 49 $symbols = id(new PhutilSymbolLoader()) 50 ->setType('class') 51 ->setAncestorClass($option->getBaseClass()) 52 ->setConcreteOnly(true) 53 ->selectSymbolsWithoutLoading(); 54 $names = ipull($symbols, 'name', 'name'); 55 if (empty($names[$value])) { 56 throw new PhabricatorConfigValidationException( 57 pht( 58 "Option '%s' value must name a class extending '%s'.", 59 $option->getKey(), 60 $option->getBaseClass())); 61 } 62 break; 63 case 'set': 64 $valid = true; 65 if (!is_array($value)) { 66 throw new PhabricatorConfigValidationException( 67 pht( 68 "Option '%s' must be a set, but value is not an array.", 69 $option->getKey())); 70 } 71 foreach ($value as $v) { 72 if ($v !== true) { 73 throw new PhabricatorConfigValidationException( 74 pht( 75 "Option '%s' must be a set, but array contains values other ". 76 "than 'true'.", 77 $option->getKey())); 78 } 79 } 80 break; 81 case 'list<regex>': 82 $valid = true; 83 if (!is_array($value)) { 84 throw new PhabricatorConfigValidationException( 85 pht( 86 "Option '%s' must be a list of regular expressions, but value ". 87 "is not an array.", 88 $option->getKey())); 89 } 90 if ($value && array_keys($value) != range(0, count($value) - 1)) { 91 throw new PhabricatorConfigValidationException( 92 pht( 93 "Option '%s' must be a list of regular expressions, but the ". 94 "value is a map with unnatural keys.", 95 $option->getKey())); 96 } 97 foreach ($value as $v) { 98 $ok = @preg_match($v, ''); 99 if ($ok === false) { 100 throw new PhabricatorConfigValidationException( 101 pht( 102 "Option '%s' must be a list of regular expressions, but the ". 103 "value '%s' is not a valid regular expression.", 104 $option->getKey(), 105 $v)); 106 } 107 } 108 break; 109 case 'list<string>': 110 $valid = true; 111 if (!is_array($value)) { 112 throw new PhabricatorConfigValidationException( 113 pht( 114 "Option '%s' must be a list of strings, but value is not ". 115 "an array.", 116 $option->getKey())); 117 } 118 if ($value && array_keys($value) != range(0, count($value) - 1)) { 119 throw new PhabricatorConfigValidationException( 120 pht( 121 "Option '%s' must be a list of strings, but the value is a ". 122 "map with unnatural keys.", 123 $option->getKey())); 124 } 125 foreach ($value as $v) { 126 if (!is_string($v)) { 127 throw new PhabricatorConfigValidationException( 128 pht( 129 "Option '%s' must be a list of strings, but it contains one ". 130 "or more non-strings.", 131 $option->getKey())); 132 } 133 } 134 break; 135 case 'wild': 136 default: 137 break; 138 } 139 140 $this->didValidateOption($option, $value); 141 } 142 143 protected function didValidateOption( 144 PhabricatorConfigOption $option, 145 $value) { 146 // Hook for subclasses to do complex validation. 147 return; 148 } 149 150 /** 151 * Hook to render additional hints based on, e.g., the viewing user, request, 152 * or other context. For example, this is used to show workspace IDs when 153 * configuring `asana.workspace-id`. 154 * 155 * @param PhabricatorConfigOption Option being rendered. 156 * @param AphrontRequest Active request. 157 * @return wild Additional contextual description 158 * information. 159 */ 160 public function renderContextualDescription( 161 PhabricatorConfigOption $option, 162 AphrontRequest $request) { 163 return null; 164 } 165 166 public function getKey() { 167 $class = get_class($this); 168 $matches = null; 169 if (preg_match('/^Phabricator(.*)ConfigOptions$/', $class, $matches)) { 170 return strtolower($matches[1]); 171 } 172 return strtolower(get_class($this)); 173 } 174 175 final protected function newOption($key, $type, $default) { 176 return id(new PhabricatorConfigOption()) 177 ->setKey($key) 178 ->setType($type) 179 ->setDefault($default) 180 ->setGroup($this); 181 } 182 183 final public static function loadAll($external_only = false) { 184 $symbols = id(new PhutilSymbolLoader()) 185 ->setAncestorClass('PhabricatorApplicationConfigOptions') 186 ->setConcreteOnly(true) 187 ->selectAndLoadSymbols(); 188 189 $groups = array(); 190 foreach ($symbols as $symbol) { 191 if ($external_only && $symbol['library'] == 'phabricator') { 192 continue; 193 } 194 195 $obj = newv($symbol['name'], array()); 196 $key = $obj->getKey(); 197 if (isset($groups[$key])) { 198 $pclass = get_class($groups[$key]); 199 $nclass = $symbol['name']; 200 201 throw new Exception( 202 "Multiple PhabricatorApplicationConfigOptions subclasses have the ". 203 "same key ('{$key}'): {$pclass}, {$nclass}."); 204 } 205 $groups[$key] = $obj; 206 } 207 208 return $groups; 209 } 210 211 final public static function loadAllOptions($external_only = false) { 212 $groups = self::loadAll($external_only); 213 214 $options = array(); 215 foreach ($groups as $group) { 216 foreach ($group->getOptions() as $option) { 217 $key = $option->getKey(); 218 if (isset($options[$key])) { 219 throw new Exception( 220 "Mulitple PhabricatorApplicationConfigOptions subclasses contain ". 221 "an option named '{$key}'!"); 222 } 223 $options[$key] = $option; 224 } 225 } 226 227 return $options; 228 } 229 230 /** 231 * Deformat a HEREDOC for use in remarkup by converting line breaks to 232 * spaces. 233 */ 234 final protected function deformat($string) { 235 return preg_replace('/(?<=\S)\n(?=\S)/', ' ', $string); 236 } 237 238 }
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 |