1 <?php
2 /**
3 * @package FrameworkOnFramework
4 * @subpackage form
5 * @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
6 * @license GNU General Public License version 2 or later; see LICENSE.txt
7 */
8 // Protect from unauthorized access
9 defined('FOF_INCLUDED') or die;
10
11 JLoader::import('joomla.form.helper');
12
13 /**
14 * FOFForm's helper class.
15 * Provides a storage for filesystem's paths where FOFForm's entities reside and
16 * methods for creating those entities. Also stores objects with entities'
17 * prototypes for further reusing.
18 *
19 * @package FrameworkOnFramework
20 * @since 2.0
21 */
22 class FOFFormHelper extends JFormHelper
23 {
24 /**
25 * Method to load a form field object given a type.
26 *
27 * @param string $type The field type.
28 * @param boolean $new Flag to toggle whether we should get a new instance of the object.
29 *
30 * @return mixed JFormField object on success, false otherwise.
31 *
32 * @since 11.1
33 */
34 public static function loadFieldType($type, $new = true)
35 {
36 return self::loadType('field', $type, $new);
37 }
38
39 /**
40 * Method to load a form field object given a type.
41 *
42 * @param string $type The field type.
43 * @param boolean $new Flag to toggle whether we should get a new instance of the object.
44 *
45 * @return mixed JFormField object on success, false otherwise.
46 *
47 * @since 11.1
48 */
49 public static function loadHeaderType($type, $new = true)
50 {
51 return self::loadType('header', $type, $new);
52 }
53
54 /**
55 * Method to load a form entity object given a type.
56 * Each type is loaded only once and then used as a prototype for other objects of same type.
57 * Please, use this method only with those entities which support types (forms don't support them).
58 *
59 * @param string $entity The entity.
60 * @param string $type The entity type.
61 * @param boolean $new Flag to toggle whether we should get a new instance of the object.
62 *
63 * @return mixed Entity object on success, false otherwise.
64 *
65 * @since 11.1
66 */
67 protected static function loadType($entity, $type, $new = true)
68 {
69 // Reference to an array with current entity's type instances
70 $types = &self::$entities[$entity];
71
72 $key = md5($type);
73
74 // Return an entity object if it already exists and we don't need a new one.
75 if (isset($types[$key]) && $new === false)
76 {
77 return $types[$key];
78 }
79
80 $class = self::loadClass($entity, $type);
81
82 if ($class !== false)
83 {
84 // Instantiate a new type object.
85 $types[$key] = new $class;
86
87 return $types[$key];
88 }
89 else
90 {
91 return false;
92 }
93 }
94
95 /**
96 * Attempt to import the JFormField class file if it isn't already imported.
97 * You can use this method outside of JForm for loading a field for inheritance or composition.
98 *
99 * @param string $type Type of a field whose class should be loaded.
100 *
101 * @return mixed Class name on success or false otherwise.
102 *
103 * @since 11.1
104 */
105 public static function loadFieldClass($type)
106 {
107 return self::loadClass('field', $type);
108 }
109
110 /**
111 * Attempt to import the FOFFormHeader class file if it isn't already imported.
112 * You can use this method outside of JForm for loading a field for inheritance or composition.
113 *
114 * @param string $type Type of a field whose class should be loaded.
115 *
116 * @return mixed Class name on success or false otherwise.
117 *
118 * @since 11.1
119 */
120 public static function loadHeaderClass($type)
121 {
122 return self::loadClass('header', $type);
123 }
124
125 /**
126 * Load a class for one of the form's entities of a particular type.
127 * Currently, it makes sense to use this method for the "field" and "rule" entities
128 * (but you can support more entities in your subclass).
129 *
130 * @param string $entity One of the form entities (field or rule).
131 * @param string $type Type of an entity.
132 *
133 * @return mixed Class name on success or false otherwise.
134 *
135 * @since 2.0
136 */
137 public static function loadClass($entity, $type)
138 {
139 if (strpos($type, '.'))
140 {
141 list($prefix, $type) = explode('.', $type);
142 $altPrefix = $prefix;
143 }
144 else
145 {
146 $prefix = 'FOF';
147 $altPrefix = 'J';
148 }
149
150 $class = JString::ucfirst($prefix, '_') . 'Form' . JString::ucfirst($entity, '_') . JString::ucfirst($type, '_');
151 $altClass = JString::ucfirst($altPrefix, '_') . 'Form' . JString::ucfirst($entity, '_') . JString::ucfirst($type, '_');
152
153 if (class_exists($class))
154 {
155 return $class;
156 }
157 elseif (class_exists($altClass))
158 {
159 return $altClass;
160 }
161
162 // Get the field search path array.
163 $paths = self::addPath($entity);
164
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
174 // If the path does not exist, add it.
175 if (!in_array($path, $paths))
176 {
177 $paths[] = $path;
178 }
179 }
180
181 // Break off the end of the complex type.
182 $type = substr($type, $pos + 1);
183 }
184
185 // Try to find the class file.
186 $type = strtolower($type) . '.php';
187 $filesystem = FOFPlatform::getInstance()->getIntegrationObject('filesystem');
188
189 foreach ($paths as $path)
190 {
191 if ($file = $filesystem->pathFind($path, $type))
192 {
193 require_once $file;
194
195 if (class_exists($class))
196 {
197 break;
198 }
199 elseif (class_exists($altClass))
200 {
201 break;
202 }
203 }
204 }
205
206 // Check for all if the class exists.
207 if (class_exists($class))
208 {
209 return $class;
210 }
211 elseif (class_exists($altClass))
212 {
213 return $altClass;
214 }
215 else
216 {
217 return false;
218 }
219 }
220
221 /**
222 * Method to add a path to the list of header include paths.
223 *
224 * @param mixed $new A path or array of paths to add.
225 *
226 * @return array The list of paths that have been added.
227 */
228 public static function addHeaderPath($new = null)
229 {
230 return self::addPath('header', $new);
231 }
232 }
233