[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10 namespace Joomla\CMS\Form; 11 12 use Joomla\CMS\Filesystem\Path; 13 use Joomla\String\Normalise; 14 use Joomla\String\StringHelper; 15 16 // phpcs:disable PSR1.Files.SideEffects 17 \defined('JPATH_PLATFORM') or die; 18 // phpcs:enable PSR1.Files.SideEffects 19 20 /** 21 * Form's helper class. 22 * Provides a storage for filesystem's paths where Form's entities reside and methods for creating those entities. 23 * Also stores objects with entities' prototypes for further reusing. 24 * 25 * @since 1.7.0 26 */ 27 class FormHelper 28 { 29 /** 30 * Array with paths where entities(field, rule, form) can be found. 31 * 32 * Array's structure: 33 * 34 * paths: 35 * {ENTITY_NAME}: 36 * - /path/1 37 * - /path/2 38 * 39 * @var array 40 * @since 1.7.0 41 */ 42 protected static $paths; 43 44 /** 45 * The class namespaces. 46 * 47 * @var string 48 * @since 3.8.0 49 */ 50 protected static $prefixes = array('field' => array(), 'form' => array(), 'rule' => array(), 'filter' => array()); 51 52 /** 53 * Static array of Form's entity objects for re-use. 54 * Prototypes for all fields and rules are here. 55 * 56 * Array's structure: 57 * entities: 58 * {ENTITY_NAME}: 59 * {KEY}: {OBJECT} 60 * 61 * @var array 62 * @since 1.7.0 63 */ 64 protected static $entities = array('field' => array(), 'form' => array(), 'rule' => array(), 'filter' => array()); 65 66 /** 67 * Method to load a form field object given a type. 68 * 69 * @param string $type The field type. 70 * @param boolean $new Flag to toggle whether we should get a new instance of the object. 71 * 72 * @return FormField|boolean FormField object on success, false otherwise. 73 * 74 * @since 1.7.0 75 */ 76 public static function loadFieldType($type, $new = true) 77 { 78 return self::loadType('field', $type, $new); 79 } 80 81 /** 82 * Method to load a form rule object given a type. 83 * 84 * @param string $type The rule type. 85 * @param boolean $new Flag to toggle whether we should get a new instance of the object. 86 * 87 * @return FormRule|boolean FormRule object on success, false otherwise. 88 * 89 * @since 1.7.0 90 */ 91 public static function loadRuleType($type, $new = true) 92 { 93 return self::loadType('rule', $type, $new); 94 } 95 96 /** 97 * Method to load a form filter object given a type. 98 * 99 * @param string $type The rule type. 100 * @param boolean $new Flag to toggle whether we should get a new instance of the object. 101 * 102 * @return FormFilterInterface|boolean FormRule object on success, false otherwise. 103 * 104 * @since 4.0.0 105 */ 106 public static function loadFilterType($type, $new = true) 107 { 108 return self::loadType('filter', $type, $new); 109 } 110 111 /** 112 * Method to load a form entity object given a type. 113 * Each type is loaded only once and then used as a prototype for other objects of same type. 114 * Please, use this method only with those entities which support types (forms don't support them). 115 * 116 * @param string $entity The entity. 117 * @param string $type The entity type. 118 * @param boolean $new Flag to toggle whether we should get a new instance of the object. 119 * 120 * @return mixed Entity object on success, false otherwise. 121 * 122 * @since 1.7.0 123 */ 124 protected static function loadType($entity, $type, $new = true) 125 { 126 // Reference to an array with current entity's type instances 127 $types = &self::$entities[$entity]; 128 129 $key = md5($type); 130 131 // Return an entity object if it already exists and we don't need a new one. 132 if (isset($types[$key]) && $new === false) { 133 return $types[$key]; 134 } 135 136 $class = self::loadClass($entity, $type); 137 138 if ($class === false) { 139 return false; 140 } 141 142 // Instantiate a new type object. 143 $types[$key] = new $class(); 144 145 return $types[$key]; 146 } 147 148 /** 149 * Attempt to import the FormField class file if it isn't already imported. 150 * You can use this method outside of Form for loading a field for inheritance or composition. 151 * 152 * @param string $type Type of a field whose class should be loaded. 153 * 154 * @return string|boolean Class name on success or false otherwise. 155 * 156 * @since 1.7.0 157 */ 158 public static function loadFieldClass($type) 159 { 160 return self::loadClass('field', $type); 161 } 162 163 /** 164 * Attempt to import the FormRule class file if it isn't already imported. 165 * You can use this method outside of Form for loading a rule for inheritance or composition. 166 * 167 * @param string $type Type of a rule whose class should be loaded. 168 * 169 * @return string|boolean Class name on success or false otherwise. 170 * 171 * @since 1.7.0 172 */ 173 public static function loadRuleClass($type) 174 { 175 return self::loadClass('rule', $type); 176 } 177 178 /** 179 * Attempt to import the FormFilter class file if it isn't already imported. 180 * You can use this method outside of Form for loading a filter for inheritance or composition. 181 * 182 * @param string $type Type of a filter whose class should be loaded. 183 * 184 * @return string|boolean Class name on success or false otherwise. 185 * 186 * @since 4.0.0 187 */ 188 public static function loadFilterClass($type) 189 { 190 return self::loadClass('filter', $type); 191 } 192 193 /** 194 * Load a class for one of the form's entities of a particular type. 195 * Currently, it makes sense to use this method for the "field" and "rule" entities 196 * (but you can support more entities in your subclass). 197 * 198 * @param string $entity One of the form entities (field or rule). 199 * @param string $type Type of an entity. 200 * 201 * @return string|boolean Class name on success or false otherwise. 202 * 203 * @since 1.7.0 204 */ 205 protected static function loadClass($entity, $type) 206 { 207 // Check if there is a class in the registered namespaces 208 foreach (self::addPrefix($entity) as $prefix) { 209 // Treat underscores as namespace 210 $name = Normalise::toSpaceSeparated($type); 211 $name = str_ireplace(' ', '\\', ucwords($name)); 212 213 $subPrefix = ''; 214 215 if (strpos($name, '.')) { 216 list($subPrefix, $name) = explode('.', $name); 217 $subPrefix = ucfirst($subPrefix) . '\\'; 218 } 219 220 // Compile the classname 221 $class = rtrim($prefix, '\\') . '\\' . $subPrefix . ucfirst($name) . ucfirst($entity); 222 223 // Check if the class exists 224 if (class_exists($class)) { 225 return $class; 226 } 227 } 228 229 $prefix = 'J'; 230 231 if (strpos($type, '.')) { 232 list($prefix, $type) = explode('.', $type); 233 } 234 235 $class = StringHelper::ucfirst($prefix, '_') . 'Form' . StringHelper::ucfirst($entity, '_') . StringHelper::ucfirst($type, '_'); 236 237 if (class_exists($class)) { 238 return $class; 239 } 240 241 // Get the field search path array. 242 $paths = self::addPath($entity); 243 244 // If the type is complex, add the base type to the paths. 245 if ($pos = strpos($type, '_')) { 246 // Add the complex type prefix to the paths. 247 for ($i = 0, $n = \count($paths); $i < $n; $i++) { 248 // Derive the new path. 249 $path = $paths[$i] . '/' . strtolower(substr($type, 0, $pos)); 250 251 // If the path does not exist, add it. 252 if (!\in_array($path, $paths)) { 253 $paths[] = $path; 254 } 255 } 256 257 // Break off the end of the complex type. 258 $type = substr($type, $pos + 1); 259 } 260 261 // Try to find the class file. 262 $type = strtolower($type) . '.php'; 263 264 foreach ($paths as $path) { 265 $file = Path::find($path, $type); 266 267 if (!$file) { 268 continue; 269 } 270 271 require_once $file; 272 273 if (class_exists($class)) { 274 break; 275 } 276 } 277 278 // Check for all if the class exists. 279 return class_exists($class) ? $class : false; 280 } 281 282 /** 283 * Method to add a path to the list of field include paths. 284 * 285 * @param mixed $new A path or array of paths to add. 286 * 287 * @return array The list of paths that have been added. 288 * 289 * @since 1.7.0 290 */ 291 public static function addFieldPath($new = null) 292 { 293 return self::addPath('field', $new); 294 } 295 296 /** 297 * Method to add a path to the list of form include paths. 298 * 299 * @param mixed $new A path or array of paths to add. 300 * 301 * @return array The list of paths that have been added. 302 * 303 * @since 1.7.0 304 */ 305 public static function addFormPath($new = null) 306 { 307 return self::addPath('form', $new); 308 } 309 310 /** 311 * Method to add a path to the list of rule include paths. 312 * 313 * @param mixed $new A path or array of paths to add. 314 * 315 * @return array The list of paths that have been added. 316 * 317 * @since 1.7.0 318 */ 319 public static function addRulePath($new = null) 320 { 321 return self::addPath('rule', $new); 322 } 323 324 /** 325 * Method to add a path to the list of filter include paths. 326 * 327 * @param mixed $new A path or array of paths to add. 328 * 329 * @return array The list of paths that have been added. 330 * 331 * @since 4.0.0 332 */ 333 public static function addFilterPath($new = null) 334 { 335 return self::addPath('filter', $new); 336 } 337 338 /** 339 * Method to add a path to the list of include paths for one of the form's entities. 340 * Currently supported entities: field, rule and form. You are free to support your own in a subclass. 341 * 342 * @param string $entity Form's entity name for which paths will be added. 343 * @param mixed $new A path or array of paths to add. 344 * 345 * @return array The list of paths that have been added. 346 * 347 * @since 1.7.0 348 */ 349 protected static function addPath($entity, $new = null) 350 { 351 if (!isset(self::$paths[$entity])) { 352 self::$paths[$entity] = []; 353 } 354 355 // Reference to an array with paths for current entity 356 $paths = &self::$paths[$entity]; 357 358 // Force the new path(s) to an array. 359 settype($new, 'array'); 360 361 // Add the new paths to the stack if not already there. 362 foreach ($new as $path) { 363 $path = \trim($path); 364 365 if (!\in_array($path, $paths)) { 366 \array_unshift($paths, $path); 367 } 368 } 369 370 return $paths; 371 } 372 373 /** 374 * Method to add a namespace prefix to the list of field lookups. 375 * 376 * @param mixed $new A namespaces or array of namespaces to add. 377 * 378 * @return array The list of namespaces that have been added. 379 * 380 * @since 3.8.0 381 */ 382 public static function addFieldPrefix($new = null) 383 { 384 return self::addPrefix('field', $new); 385 } 386 387 /** 388 * Method to add a namespace to the list of form lookups. 389 * 390 * @param mixed $new A namespace or array of namespaces to add. 391 * 392 * @return array The list of namespaces that have been added. 393 * 394 * @since 3.8.0 395 */ 396 public static function addFormPrefix($new = null) 397 { 398 return self::addPrefix('form', $new); 399 } 400 401 /** 402 * Method to add a namespace to the list of rule lookups. 403 * 404 * @param mixed $new A namespace or array of namespaces to add. 405 * 406 * @return array The list of namespaces that have been added. 407 * 408 * @since 3.8.0 409 */ 410 public static function addRulePrefix($new = null) 411 { 412 return self::addPrefix('rule', $new); 413 } 414 415 /** 416 * Method to add a namespace to the list of filter lookups. 417 * 418 * @param mixed $new A namespace or array of namespaces to add. 419 * 420 * @return array The list of namespaces that have been added. 421 * 422 * @since 4.0.0 423 */ 424 public static function addFilterPrefix($new = null) 425 { 426 return self::addPrefix('filter', $new); 427 } 428 429 /** 430 * Method to add a namespace to the list of namespaces for one of the form's entities. 431 * Currently supported entities: field, rule and form. You are free to support your own in a subclass. 432 * 433 * @param string $entity Form's entity name for which paths will be added. 434 * @param mixed $new A namespace or array of namespaces to add. 435 * 436 * @return array The list of namespaces that have been added. 437 * 438 * @since 3.8.0 439 */ 440 protected static function addPrefix($entity, $new = null) 441 { 442 // Reference to an array with namespaces for current entity 443 $prefixes = &self::$prefixes[$entity]; 444 445 // Add the default entity's search namespace if not set. 446 if (empty($prefixes)) { 447 $prefixes[] = __NAMESPACE__ . '\\' . ucfirst($entity); 448 } 449 450 // Force the new namespace(s) to an array. 451 settype($new, 'array'); 452 453 // Add the new paths to the stack if not already there. 454 foreach ($new as $prefix) { 455 $prefix = trim($prefix); 456 457 if (\in_array($prefix, $prefixes)) { 458 continue; 459 } 460 461 array_unshift($prefixes, $prefix); 462 } 463 464 return $prefixes; 465 } 466 467 /** 468 * Parse the show on conditions 469 * 470 * @param string $showOn Show on conditions. 471 * @param string $formControl Form name. 472 * @param string $group The dot-separated form group path. 473 * 474 * @return array Array with show on conditions. 475 * 476 * @since 3.7.0 477 */ 478 public static function parseShowOnConditions($showOn, $formControl = null, $group = null) 479 { 480 // Process the showon data. 481 if (!$showOn) { 482 return array(); 483 } 484 485 $formPath = $formControl ?: ''; 486 487 if ($group) { 488 $groups = explode('.', $group); 489 490 // An empty formControl leads to invalid shown property 491 // Use the 1st part of the group instead to avoid. 492 if (empty($formPath) && isset($groups[0])) { 493 $formPath = $groups[0]; 494 array_shift($groups); 495 } 496 497 foreach ($groups as $group) { 498 $formPath .= '[' . $group . ']'; 499 } 500 } 501 502 $showOnData = array(); 503 $showOnParts = preg_split('#(\[AND\]|\[OR\])#', $showOn, -1, PREG_SPLIT_DELIM_CAPTURE); 504 $op = ''; 505 506 foreach ($showOnParts as $showOnPart) { 507 if (($showOnPart === '[AND]') || $showOnPart === '[OR]') { 508 $op = trim($showOnPart, '[]'); 509 continue; 510 } 511 512 $compareEqual = strpos($showOnPart, '!:') === false; 513 $showOnPartBlocks = explode(($compareEqual ? ':' : '!:'), $showOnPart, 2); 514 515 $dotPos = strpos($showOnPartBlocks[0], '.'); 516 517 if ($dotPos === false) { 518 $field = $formPath ? $formPath . '[' . $showOnPartBlocks[0] . ']' : $showOnPartBlocks[0]; 519 } else { 520 if ($dotPos === 0) { 521 $fieldName = substr($showOnPartBlocks[0], 1); 522 $field = $formControl ? $formControl . '[' . $fieldName . ']' : $fieldName; 523 } else { 524 if ($formControl) { 525 $field = $formControl . ('[' . str_replace('.', '][', $showOnPartBlocks[0]) . ']'); 526 } else { 527 $groupParts = explode('.', $showOnPartBlocks[0]); 528 $field = array_shift($groupParts) . '[' . join('][', $groupParts) . ']'; 529 } 530 } 531 } 532 533 $showOnData[] = array( 534 'field' => $field, 535 'values' => explode(',', $showOnPartBlocks[1]), 536 'sign' => $compareEqual === true ? '=' : '!=', 537 'op' => $op, 538 ); 539 540 if ($op !== '') { 541 $op = ''; 542 } 543 } 544 545 return $showOnData; 546 } 547 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |