/libraries/joomla/form/helper.php

https://github.com/pjwiseman/joomla-cms · PHP · 315 lines · 111 code · 36 blank · 168 comment · 12 complexity · 6be49b76f6db3819553c6a72843ca6b6 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Form
  5. *
  6. * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. jimport('joomla.filesystem.path');
  11. /**
  12. * JForm's helper class.
  13. * Provides a storage for filesystem's paths where JForm's entities reside and methods for creating those entities.
  14. * Also stores objects with entities' prototypes for further reusing.
  15. *
  16. * @since 11.1
  17. */
  18. class JFormHelper
  19. {
  20. /**
  21. * Array with paths where entities(field, rule, form) can be found.
  22. *
  23. * Array's structure:
  24. * <code>
  25. * paths:
  26. * {ENTITY_NAME}:
  27. * - /path/1
  28. * - /path/2
  29. * </code>
  30. *
  31. * @var array
  32. * @since 11.1
  33. *
  34. */
  35. protected static $paths;
  36. /**
  37. * Static array of JForm's entity objects for re-use.
  38. * Prototypes for all fields and rules are here.
  39. *
  40. * Array's structure:
  41. * <code>
  42. * entities:
  43. * {ENTITY_NAME}:
  44. * {KEY}: {OBJECT}
  45. * </code>
  46. *
  47. * @var array
  48. * @since 11.1
  49. */
  50. protected static $entities = array();
  51. /**
  52. * Method to load a form field object given a type.
  53. *
  54. * @param string $type The field type.
  55. * @param boolean $new Flag to toggle whether we should get a new instance of the object.
  56. *
  57. * @return mixed JFormField object on success, false otherwise.
  58. *
  59. * @since 11.1
  60. */
  61. public static function loadFieldType($type, $new = true)
  62. {
  63. return self::loadType('field', $type, $new);
  64. }
  65. /**
  66. * Method to load a form rule object given a type.
  67. *
  68. * @param string $type The rule type.
  69. * @param boolean $new Flag to toggle whether we should get a new instance of the object.
  70. *
  71. * @return mixed JFormRule object on success, false otherwise.
  72. *
  73. * @since 11.1
  74. */
  75. public static function loadRuleType($type, $new = true)
  76. {
  77. return self::loadType('rule', $type, $new);
  78. }
  79. /**
  80. * Method to load a form entity object given a type.
  81. * Each type is loaded only once and then used as a prototype for other objects of same type.
  82. * Please, use this method only with those entities which support types (forms don't support them).
  83. *
  84. * @param string $entity The entity.
  85. * @param string $type The entity type.
  86. * @param boolean $new Flag to toggle whether we should get a new instance of the object.
  87. *
  88. * @return mixed Entity object on success, false otherwise.
  89. *
  90. * @since 11.1
  91. */
  92. protected static function loadType($entity, $type, $new = true)
  93. {
  94. // Reference to an array with current entity's type instances
  95. $types = &self::$entities[$entity];
  96. $key = md5($type);
  97. // Return an entity object if it already exists and we don't need a new one.
  98. if (isset($types[$key]) && $new === false)
  99. {
  100. return $types[$key];
  101. }
  102. $class = self::loadClass($entity, $type);
  103. if ($class === false)
  104. {
  105. return false;
  106. }
  107. // Instantiate a new type object.
  108. $types[$key] = new $class;
  109. return $types[$key];
  110. }
  111. /**
  112. * Attempt to import the JFormField class file if it isn't already imported.
  113. * You can use this method outside of JForm for loading a field for inheritance or composition.
  114. *
  115. * @param string $type Type of a field whose class should be loaded.
  116. *
  117. * @return mixed Class name on success or false otherwise.
  118. *
  119. * @since 11.1
  120. */
  121. public static function loadFieldClass($type)
  122. {
  123. return self::loadClass('field', $type);
  124. }
  125. /**
  126. * Attempt to import the JFormRule class file if it isn't already imported.
  127. * You can use this method outside of JForm for loading a rule for inheritance or composition.
  128. *
  129. * @param string $type Type of a rule whose class should be loaded.
  130. *
  131. * @return mixed Class name on success or false otherwise.
  132. *
  133. * @since 11.1
  134. */
  135. public static function loadRuleClass($type)
  136. {
  137. return self::loadClass('rule', $type);
  138. }
  139. /**
  140. * Load a class for one of the form's entities of a particular type.
  141. * Currently, it makes sense to use this method for the "field" and "rule" entities
  142. * (but you can support more entities in your subclass).
  143. *
  144. * @param string $entity One of the form entities (field or rule).
  145. * @param string $type Type of an entity.
  146. *
  147. * @return mixed Class name on success or false otherwise.
  148. *
  149. * @since 11.1
  150. */
  151. protected static function loadClass($entity, $type)
  152. {
  153. $prefix = 'J';
  154. if (strpos($type, '.'))
  155. {
  156. list($prefix, $type) = explode('.', $type);
  157. }
  158. $class = JString::ucfirst($prefix, '_') . 'Form' . JString::ucfirst($entity, '_') . JString::ucfirst($type, '_');
  159. if (class_exists($class))
  160. {
  161. return $class;
  162. }
  163. // Get the field search path array.
  164. $paths = self::addPath($entity);
  165. // If the type is complex, add the base type to the paths.
  166. if ($pos = strpos($type, '_'))
  167. {
  168. // Add the complex type prefix to the paths.
  169. for ($i = 0, $n = count($paths); $i < $n; $i++)
  170. {
  171. // Derive the new path.
  172. $path = $paths[$i] . '/' . strtolower(substr($type, 0, $pos));
  173. // If the path does not exist, add it.
  174. if (!in_array($path, $paths))
  175. {
  176. $paths[] = $path;
  177. }
  178. }
  179. // Break off the end of the complex type.
  180. $type = substr($type, $pos + 1);
  181. }
  182. // Try to find the class file.
  183. $type = strtolower($type) . '.php';
  184. foreach ($paths as $path)
  185. {
  186. $file = JPath::find($path, $type);
  187. if (!$file)
  188. {
  189. continue;
  190. }
  191. require_once $file;
  192. if (class_exists($class))
  193. {
  194. break;
  195. }
  196. }
  197. // Check for all if the class exists.
  198. return class_exists($class) ? $class : false;
  199. }
  200. /**
  201. * Method to add a path to the list of field include paths.
  202. *
  203. * @param mixed $new A path or array of paths to add.
  204. *
  205. * @return array The list of paths that have been added.
  206. *
  207. * @since 11.1
  208. */
  209. public static function addFieldPath($new = null)
  210. {
  211. return self::addPath('field', $new);
  212. }
  213. /**
  214. * Method to add a path to the list of form include paths.
  215. *
  216. * @param mixed $new A path or array of paths to add.
  217. *
  218. * @return array The list of paths that have been added.
  219. *
  220. * @since 11.1
  221. */
  222. public static function addFormPath($new = null)
  223. {
  224. return self::addPath('form', $new);
  225. }
  226. /**
  227. * Method to add a path to the list of rule include paths.
  228. *
  229. * @param mixed $new A path or array of paths to add.
  230. *
  231. * @return array The list of paths that have been added.
  232. *
  233. * @since 11.1
  234. */
  235. public static function addRulePath($new = null)
  236. {
  237. return self::addPath('rule', $new);
  238. }
  239. /**
  240. * Method to add a path to the list of include paths for one of the form's entities.
  241. * Currently supported entities: field, rule and form. You are free to support your own in a subclass.
  242. *
  243. * @param string $entity Form's entity name for which paths will be added.
  244. * @param mixed $new A path or array of paths to add.
  245. *
  246. * @return array The list of paths that have been added.
  247. *
  248. * @since 11.1
  249. */
  250. protected static function addPath($entity, $new = null)
  251. {
  252. // Reference to an array with paths for current entity
  253. $paths = &self::$paths[$entity];
  254. // Add the default entity's search path if not set.
  255. if (empty($paths))
  256. {
  257. // While we support limited number of entities (form, field and rule)
  258. // we can do this simple pluralisation:
  259. $entity_plural = $entity . 's';
  260. /*
  261. * But when someday we would want to support more entities, then we should consider adding
  262. * an inflector class to "libraries/joomla/utilities" and use it here (or somebody can use a real inflector in his subclass).
  263. * See also: pluralization snippet by Paul Osman in JControllerForm's constructor.
  264. */
  265. $paths[] = __DIR__ . '/' . $entity_plural;
  266. }
  267. // Force the new path(s) to an array.
  268. settype($new, 'array');
  269. // Add the new paths to the stack if not already there.
  270. foreach ($new as $path)
  271. {
  272. if (!in_array($path, $paths))
  273. {
  274. array_unshift($paths, trim($path));
  275. }
  276. }
  277. return $paths;
  278. }
  279. }