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 JFormHelper::loadFieldClass('list');
12
13 /**
14 * Form Field class for FOF
15 * Components installed on the site
16 *
17 * @package FrameworkOnFramework
18 * @since 2.1
19 */
20 class FOFFormFieldComponents extends JFormFieldList implements FOFFormField
21 {
22 protected $static;
23
24 protected $repeatable;
25
26 public $client_ids = null;
27
28 /** @var FOFTable The item being rendered in a repeatable form field */
29 public $item;
30
31 /** @var int A monotonically increasing number, denoting the row number in a repeatable view */
32 public $rowid;
33
34 /**
35 * Method to get certain otherwise inaccessible properties from the form field object.
36 *
37 * @param string $name The property name for which to the the value.
38 *
39 * @return mixed The property value or null.
40 *
41 * @since 2.1
42 */
43 public function __get($name)
44 {
45 switch ($name)
46 {
47 case 'static':
48 if (empty($this->static))
49 {
50 $this->static = $this->getStatic();
51 }
52
53 return $this->static;
54 break;
55
56 case 'repeatable':
57 if (empty($this->repeatable))
58 {
59 $this->repeatable = $this->getRepeatable();
60 }
61
62 return $this->repeatable;
63 break;
64
65 default:
66 return parent::__get($name);
67 }
68 }
69
70 /**
71 * Get the rendering of this field type for static display, e.g. in a single
72 * item view (typically a "read" task).
73 *
74 * @since 2.1
75 *
76 * @return string The field HTML
77 */
78 public function getStatic()
79 {
80 $class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
81
82 return '<span id="' . $this->id . '" ' . $class . '>' .
83 htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
84 '</span>';
85 }
86
87 /**
88 * Get the rendering of this field type for a repeatable (grid) display,
89 * e.g. in a view listing many item (typically a "browse" task)
90 *
91 * @since 2.1
92 *
93 * @return string The field HTML
94 */
95 public function getRepeatable()
96 {
97 $class = $this->element['class'] ? (string) $this->element['class'] : '';
98
99 return '<span class="' . $this->id . ' ' . $class . '">' .
100 htmlspecialchars(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
101 '</span>';
102 }
103
104 /**
105 * Get a list of all installed components and also translates them.
106 *
107 * The manifest_cache is used to get the extension names, since JInstaller is also
108 * translating those names in stead of the name column. Else some of the translations
109 * fails.
110 *
111 * @since 2.1
112 *
113 * @return array An array of JHtml options.
114 */
115 protected function getOptions()
116 {
117 $db = FOFPlatform::getInstance()->getDbo();
118
119 // Check for client_ids override
120 if ($this->client_ids !== null)
121 {
122 $client_ids = $this->client_ids;
123 }
124 else
125 {
126 $client_ids = $this->element['client_ids'];
127 }
128
129 $client_ids = explode(',', $client_ids);
130
131 // Calculate client_ids where clause
132 foreach ($client_ids as &$client_id)
133 {
134 $client_id = (int) trim($client_id);
135 $client_id = $db->q($client_id);
136 }
137
138 $query = $db->getQuery(true)
139 ->select(
140 array(
141 $db->qn('name'),
142 $db->qn('element'),
143 $db->qn('client_id'),
144 $db->qn('manifest_cache'),
145 )
146 )
147 ->from($db->qn('#__extensions'))
148 ->where($db->qn('type') . ' = ' . $db->q('component'))
149 ->where($db->qn('client_id') . ' IN (' . implode(',', $client_ids) . ')');
150 $db->setQuery($query);
151 $components = $db->loadObjectList('element');
152
153 // Convert to array of objects, so we can use sortObjects()
154 // Also translate component names with JText::_()
155 $aComponents = array();
156 $user = JFactory::getUser();
157
158 foreach ($components as $component)
159 {
160 // Don't show components in the list where the user doesn't have access for
161 // TODO: perhaps add an option for this
162 if (!$user->authorise('core.manage', $component->element))
163 {
164 continue;
165 }
166
167 $oData = (object) array(
168 'value' => $component->element,
169 'text' => $this->translate($component, 'component')
170 );
171 $aComponents[$component->element] = $oData;
172 }
173
174 // Reorder the components array, because the alphabetical
175 // ordering changed due to the JText::_() translation
176 uasort(
177 $aComponents,
178 function ($a, $b) {
179 return strcasecmp($a->text, $b->text);
180 }
181 );
182
183 return $aComponents;
184 }
185
186 /**
187 * Translate a list of objects with JText::_().
188 *
189 * @param array $item The array of objects
190 * @param string $type The extension type (e.g. component)
191 *
192 * @since 2.1
193 *
194 * @return string $text The translated name of the extension
195 *
196 * @see administrator/com_installer/models/extension.php
197 */
198 public function translate($item, $type)
199 {
200 $platform = FOFPlatform::getInstance();
201
202 // Map the manifest cache to $item. This is needed to get the name from the
203 // manifest_cache and NOT from the name column, else some JText::_() translations fails.
204 $mData = json_decode($item->manifest_cache);
205
206 if ($mData)
207 {
208 foreach ($mData as $key => $value)
209 {
210 if ($key == 'type')
211 {
212 // Ignore the type field
213 continue;
214 }
215
216 $item->$key = $value;
217 }
218 }
219
220 $lang = $platform->getLanguage();
221
222 switch ($type)
223 {
224 case 'component':
225 $source = JPATH_ADMINISTRATOR . '/components/' . $item->element;
226 $lang->load("$item->element.sys", JPATH_ADMINISTRATOR, null, false, false)
227 || $lang->load("$item->element.sys", $source, null, false, false)
228 || $lang->load("$item->element.sys", JPATH_ADMINISTRATOR, $lang->getDefault(), false, false)
229 || $lang->load("$item->element.sys", $source, $lang->getDefault(), false, false);
230 break;
231 }
232
233 $text = JText::_($item->name);
234
235 return $text;
236 }
237 }
238