code4interactive /
forms
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Code4\Forms\Fields; |
||
| 4 | |||
| 5 | use Code4\View\Attributes; |
||
| 6 | |||
| 7 | abstract class AbstractField implements FieldsInterface { |
||
| 8 | |||
| 9 | protected $name; |
||
| 10 | |||
| 11 | protected $title; |
||
| 12 | |||
| 13 | protected $label; |
||
| 14 | |||
| 15 | /** |
||
| 16 | * @var string Index elementu w pliku konfiguracyjnym |
||
| 17 | */ |
||
| 18 | protected $fieldName; |
||
| 19 | |||
| 20 | protected $id; |
||
| 21 | |||
| 22 | protected $attributes; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * List of all properties |
||
| 26 | * @var array |
||
| 27 | */ |
||
| 28 | protected $properties = []; |
||
| 29 | |||
| 30 | protected $value; |
||
| 31 | |||
| 32 | protected $rules; |
||
| 33 | protected $customRules; |
||
| 34 | |||
| 35 | protected $optionKeys; |
||
| 36 | |||
| 37 | protected $_viewNamespace = 'forms::'; |
||
| 38 | protected $_view; //Widok do załadowania |
||
| 39 | protected $_type; //Typ elementu (np text, password) ten sam widok tylko inny typ |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Pola specjalne dla których nie nadajemy automatycznie klas (form-control) itp. |
||
| 43 | * @var array |
||
| 44 | */ |
||
| 45 | protected $specialFields = [ |
||
| 46 | 'separator', 'header', 'htmlTag' |
||
| 47 | ]; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * Constructs base element |
||
| 51 | * @param $fieldName |
||
| 52 | * @param array $data |
||
| 53 | */ |
||
| 54 | public function __construct($fieldName, $data = []) { |
||
| 55 | $this->fieldName = $fieldName; |
||
| 56 | $this->parseBaseData($data); |
||
| 57 | } |
||
| 58 | |||
| 59 | /** |
||
| 60 | * Parses base data passed to field. More field specific data has to be parsed in classes extending AbstractField |
||
| 61 | * @param array $data |
||
| 62 | */ |
||
| 63 | public function parseBaseData($data) { |
||
| 64 | //Attributes |
||
| 65 | if (array_key_exists('attributes', $data)) { |
||
| 66 | $this->attributes($data['attributes']); |
||
| 67 | unset($data['attributes']); |
||
| 68 | } |
||
| 69 | |||
| 70 | //Name |
||
| 71 | if (array_key_exists('name', $data)) { |
||
| 72 | $this->name = $data['name']; |
||
| 73 | unset($data['name']); |
||
| 74 | } else { |
||
| 75 | $this->name = $this->fieldName; |
||
| 76 | } |
||
| 77 | |||
| 78 | //Pre set title |
||
| 79 | $this->title($this->name); |
||
| 80 | |||
| 81 | //Values |
||
| 82 | if (array_key_exists('value', $data)) { |
||
| 83 | $this->setValue($data['value']); |
||
| 84 | unset($data['value']); |
||
| 85 | } |
||
| 86 | |||
| 87 | //Rules |
||
| 88 | if (array_key_exists('rules', $data)) { |
||
| 89 | $this->rules($data['rules']); |
||
| 90 | unset($data['rules']); |
||
| 91 | } |
||
| 92 | |||
| 93 | //Setting remaining properties |
||
| 94 | //Title |
||
| 95 | if (array_key_exists('title', $data)) { |
||
| 96 | $this->title($data['title']); |
||
| 97 | unset($data['title']); |
||
| 98 | } |
||
| 99 | |||
| 100 | //Title |
||
| 101 | if (array_key_exists('label', $data)) { |
||
| 102 | $this->label($data['label']); |
||
|
0 ignored issues
–
show
|
|||
| 103 | unset($data['label']); |
||
| 104 | } |
||
| 105 | |||
| 106 | foreach ($data as $propertyName => $value) { |
||
| 107 | $this->setProperty($propertyName, $value); |
||
| 108 | } |
||
| 109 | |||
| 110 | //If classes not set - default = form-control |
||
| 111 | if (!$this->attributes()->has('class') && !in_array($this->_type,$this->specialFields)) { |
||
| 112 | $this->attributes()->add('class', 'form-control'); |
||
| 113 | } |
||
| 114 | |||
| 115 | } |
||
| 116 | |||
| 117 | /** |
||
| 118 | * Gets or sets attributes |
||
| 119 | * @param null|array $data |
||
| 120 | * @return Attributes |
||
| 121 | */ |
||
| 122 | public function attributes($data = null) { |
||
| 123 | if ($data !== null) { |
||
| 124 | $this->attributes = new Attributes($data); |
||
| 125 | } |
||
| 126 | if (is_null($this->attributes)) { |
||
| 127 | $this->attributes = new Attributes(); |
||
| 128 | } |
||
| 129 | return $this->attributes; |
||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * Sets or gets value |
||
| 134 | * @param $value |
||
| 135 | * @param $key |
||
| 136 | * @return FieldsInterface|mixed $this |
||
| 137 | */ |
||
| 138 | public function value($value = null, $key = null) { |
||
| 139 | |||
| 140 | if ($value === null) { |
||
| 141 | if (is_array($this->value) && count($this->value) == 1) { |
||
| 142 | return (string)$this->value[0]; |
||
| 143 | } |
||
| 144 | if (is_array($this->value) && count($this->value) > 1) { |
||
| 145 | return $this->value; |
||
| 146 | } |
||
| 147 | return (string)$this->value; |
||
| 148 | } |
||
| 149 | |||
| 150 | // Store value as array if string or numeric |
||
| 151 | if (is_string($value) || is_numeric($value) || is_bool($value)) { |
||
| 152 | $this->value = [$value]; |
||
| 153 | return $this; |
||
| 154 | } |
||
| 155 | |||
| 156 | //If value is assoc array store only keys |
||
| 157 | //Usually key=>value pairs represent value=>description eg. in select fields |
||
| 158 | if (is_array($value) && $this->isAssoc($value)) { |
||
| 159 | $this->value = []; |
||
| 160 | foreach ($value as $k=>$v) { |
||
| 161 | $this->value[] = $k; |
||
| 162 | } |
||
| 163 | return $this; |
||
| 164 | } |
||
| 165 | |||
| 166 | //Normal array of values (checkboxes) |
||
| 167 | if (is_array($value)) { |
||
| 168 | $this->value = $value; |
||
| 169 | return $this; |
||
| 170 | } |
||
| 171 | |||
| 172 | //Values are in object. To extract them we need property names (keys) |
||
| 173 | //$optionKeys is used also to extract value=>description for option field |
||
| 174 | //So in config $optionsKeys is an 2 element array |
||
| 175 | if (is_object($value)) { |
||
| 176 | if (is_null($key) && count($this->optionKeys) == 2) { |
||
| 177 | $key = $this->optionKeys[0]; |
||
| 178 | } |
||
| 179 | |||
| 180 | //If still no key - try using name as key?? |
||
| 181 | if (is_null($key)) { |
||
| 182 | $key = $this->name; |
||
| 183 | } |
||
| 184 | |||
| 185 | if (!$key) { |
||
| 186 | return $this; |
||
| 187 | } |
||
| 188 | |||
| 189 | $this->value = []; |
||
| 190 | //iterating over $value object because it may be an collection eg. results from DB |
||
| 191 | foreach($value as $objectKey=>$o) { |
||
| 192 | if (is_object($o) && property_exists($o, $key)) { |
||
| 193 | $this->value[] = $o->$key; |
||
| 194 | } else { |
||
| 195 | //If passed object is not an iterable collection loop will iterate over properties |
||
| 196 | if ($objectKey == $key) { |
||
| 197 | $this->value[] = $o; |
||
| 198 | return $this; |
||
| 199 | } |
||
| 200 | } |
||
| 201 | } |
||
| 202 | return $this; |
||
| 203 | } |
||
| 204 | return $this; |
||
| 205 | } |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Shortcut for values() method. Used to set value of field after initiation from config. Is needed for fields |
||
| 209 | * with checked traits where method is overrided |
||
| 210 | * @param null $value |
||
| 211 | * @param null $key |
||
| 212 | * @return FieldsInterface|mixed |
||
| 213 | */ |
||
| 214 | public function setValue($value = null, $key = null) { |
||
| 215 | return $this->value($value, $key); |
||
| 216 | } |
||
| 217 | |||
| 218 | /** |
||
| 219 | * @param null $id |
||
| 220 | * @return string|FieldsInterface |
||
| 221 | */ |
||
| 222 | View Code Duplication | public function id($id = null) { |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 223 | if (is_null($id)) { |
||
| 224 | return $this->id; |
||
| 225 | } else { |
||
| 226 | $this->id = $id; |
||
| 227 | } |
||
| 228 | return $this; |
||
| 229 | } |
||
| 230 | |||
| 231 | /** |
||
| 232 | * @param null $name |
||
| 233 | * @return string|FieldsInterface |
||
| 234 | */ |
||
| 235 | View Code Duplication | public function name($name = null) { |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 236 | if (is_null($name)) { |
||
| 237 | return $this->name; |
||
| 238 | } else { |
||
| 239 | $this->name = $name; |
||
| 240 | } |
||
| 241 | return $this; |
||
| 242 | } |
||
| 243 | |||
| 244 | /** |
||
| 245 | * @param null $title |
||
| 246 | * @return string|FieldsInterface |
||
| 247 | */ |
||
| 248 | public function title($title = null) { |
||
| 249 | if (is_null($title)) { |
||
| 250 | return $this->title; |
||
| 251 | } else { |
||
| 252 | $this->title = $title; |
||
| 253 | } |
||
| 254 | return $this; |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * @param null $_type |
||
| 259 | * @return string|FieldsInterface |
||
| 260 | */ |
||
| 261 | public function _type($_type = null) { |
||
| 262 | if (is_null($_type)) { |
||
| 263 | return $this->_type; |
||
| 264 | } else { |
||
| 265 | $this->_type = $_type; |
||
| 266 | } |
||
| 267 | return $this; |
||
| 268 | } |
||
| 269 | |||
| 270 | /** |
||
| 271 | * Sets or retrives rules for field and child fields |
||
| 272 | * @param null $rules |
||
| 273 | * @return string|FieldsInterface |
||
| 274 | */ |
||
| 275 | public function rules($rules = null) { |
||
| 276 | if (is_null($rules)) { |
||
| 277 | return $this->rules; |
||
| 278 | } else { |
||
| 279 | $this->rules = $rules; |
||
| 280 | } |
||
| 281 | return $this; |
||
| 282 | } |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Returns name=>rules array for validator |
||
| 286 | * @return array |
||
| 287 | */ |
||
| 288 | public function getRulesForValidator() { |
||
| 289 | if ($this->rules == '') { |
||
| 290 | return []; |
||
| 291 | } |
||
| 292 | |||
| 293 | return [$this->getDotNotatedName() => $this->rules]; |
||
| 294 | } |
||
| 295 | |||
| 296 | /** |
||
| 297 | * Returns name of field in 'dot' notation. Eg. field[] -> field, field[test] -> field.test |
||
| 298 | * @return string |
||
| 299 | */ |
||
| 300 | public function getDotNotatedName() { |
||
| 301 | $name = $this->name(); |
||
| 302 | |||
| 303 | //multi value fields are validated as single value |
||
| 304 | $name = str_replace('[]','',$name); |
||
| 305 | |||
| 306 | //if in config field field is named field[test][tes2] replace that to: field.test.test2 |
||
| 307 | $pattern = '/\[{1}([^\]]+)\]{1}/'; |
||
| 308 | //preg_replace("/\[{1}([^\]]+)\]{1}/", ".$1", $input_lines); |
||
| 309 | $name = preg_replace($pattern, ".$1", $name); |
||
| 310 | return $name; |
||
| 311 | } |
||
| 312 | |||
| 313 | /** |
||
| 314 | * Adds rule if it don't exist |
||
| 315 | * @param $rule |
||
| 316 | * @return $this |
||
| 317 | */ |
||
| 318 | View Code Duplication | public function addRule($rule) { |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 319 | $rules = explode("|", $this->rules); |
||
| 320 | if (array_search($rule, $rules) === false) { |
||
| 321 | array_push($rules, $rule); |
||
| 322 | } |
||
| 323 | $this->rules = trim(implode("|", $rules), "|"); |
||
| 324 | return $this; |
||
| 325 | } |
||
| 326 | |||
| 327 | /** |
||
| 328 | * Removes rule from field |
||
| 329 | * @param $rule |
||
| 330 | * @return $this |
||
| 331 | */ |
||
| 332 | View Code Duplication | public function removeRule($rule) { |
|
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 333 | $rules = explode("|", $this->rules); |
||
| 334 | if (($index = array_search($rule, $rules)) !== false) { |
||
| 335 | unset($rules[$index]); |
||
| 336 | } |
||
| 337 | $this->rules = trim(implode("|", $rules), "|"); |
||
| 338 | return $this; |
||
| 339 | } |
||
| 340 | |||
| 341 | /** |
||
| 342 | * @param null $customRules |
||
| 343 | * @return string|FieldsInterface |
||
| 344 | */ |
||
| 345 | public function customRules($customRules = null) { |
||
| 346 | if (is_null($customRules)) { |
||
| 347 | return $this->customRules; |
||
| 348 | } else { |
||
| 349 | $this->customRules[] = $customRules; |
||
| 350 | } |
||
| 351 | return $this; |
||
| 352 | } |
||
| 353 | |||
| 354 | /** |
||
| 355 | * Renders element |
||
| 356 | * @return \Illuminate\View\View |
||
| 357 | */ |
||
| 358 | public function render() { |
||
| 359 | if (isset($this->group) && count($this->group)) { $view = 'group'; } |
||
|
0 ignored issues
–
show
The property
group does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
Loading history...
|
|||
| 360 | else { $view = $this->_view; } |
||
| 361 | return view($this->_viewNamespace.$view, ['el'=>$this])->render(); |
||
| 362 | } |
||
| 363 | |||
| 364 | /** |
||
| 365 | * @return string |
||
| 366 | */ |
||
| 367 | public function __toString() { |
||
| 368 | return $this->render(); |
||
| 369 | } |
||
| 370 | |||
| 371 | /** |
||
| 372 | * Sets property |
||
| 373 | * @param string $propertyName |
||
| 374 | * @param mixed $value |
||
| 375 | * @return $this |
||
| 376 | */ |
||
| 377 | public function setProperty($propertyName, $value) { |
||
| 378 | if (property_exists($this, $propertyName)) { |
||
| 379 | $this->$propertyName = $value; |
||
| 380 | } else { |
||
| 381 | $this->properties[$propertyName] = $value; |
||
| 382 | } |
||
| 383 | return $this; |
||
| 384 | } |
||
| 385 | |||
| 386 | /** |
||
| 387 | * Gets property |
||
| 388 | * @param string $propertyName |
||
| 389 | * @return mixed |
||
| 390 | */ |
||
| 391 | public function getProperty($propertyName) { |
||
| 392 | if (property_exists($this, $propertyName)) { |
||
| 393 | return $this->$propertyName; |
||
| 394 | } else |
||
| 395 | { |
||
| 396 | return array_key_exists($propertyName, $this->properties) ? $this->properties[$propertyName] : ''; |
||
| 397 | } |
||
| 398 | } |
||
| 399 | |||
| 400 | /** |
||
| 401 | * Magic methods |
||
| 402 | * @param $method |
||
| 403 | * @param $args |
||
| 404 | * @return AbstractField|mixed |
||
| 405 | */ |
||
| 406 | public function __call($method, $args) { |
||
| 407 | if (count($args) == 0) { |
||
| 408 | return $this->getProperty($method); |
||
| 409 | } |
||
| 410 | |||
| 411 | if (count($args) == 1) { |
||
| 412 | return $this->setProperty($method, $args[0]); |
||
| 413 | } |
||
| 414 | } |
||
| 415 | |||
| 416 | |||
| 417 | /** |
||
| 418 | * Checks if passed array is associative or indexed |
||
| 419 | * @param $arr |
||
| 420 | * @return bool |
||
| 421 | */ |
||
| 422 | private function isAssoc($arr) { |
||
| 423 | return array_keys($arr) !== range(0, count($arr) - 1); |
||
| 424 | } |
||
| 425 | |||
| 426 | |||
| 427 | } |
If you implement
__calland you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.This is often the case, when
__callis implemented by a parent class and only the child class knows which methods exist: