|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* @package Redcore |
|
4
|
|
|
* @subpackage Translation |
|
5
|
|
|
* |
|
6
|
|
|
* @copyright Copyright (C) 2008 - 2021 redWEB.dk. All rights reserved. |
|
7
|
|
|
* @license GNU General Public License version 2 or later, see LICENSE. |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
defined('_JEXEC') or die; |
|
11
|
|
|
|
|
12
|
|
|
jimport('joomla.filesystem.folder'); |
|
|
|
|
|
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* A Translation helper. |
|
16
|
|
|
* |
|
17
|
|
|
* @package Redcore |
|
18
|
|
|
* @subpackage Translation |
|
19
|
|
|
* @since 1.0 |
|
20
|
|
|
*/ |
|
21
|
|
|
class RTranslationHelper |
|
22
|
|
|
{ |
|
23
|
|
|
/** |
|
24
|
|
|
* Defines if jQuery Migrate should be loaded in Frontend component/modules |
|
25
|
|
|
* |
|
26
|
|
|
* @var JRegistry |
|
|
|
|
|
|
27
|
|
|
*/ |
|
28
|
|
|
public static $pluginParams = null; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* Default language |
|
32
|
|
|
* |
|
33
|
|
|
* @var array |
|
34
|
|
|
* @since 1.0 |
|
35
|
|
|
*/ |
|
36
|
|
|
public static $siteLanguage = null; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* Include paths for searching for Params classes. |
|
40
|
|
|
* |
|
41
|
|
|
* @var array |
|
42
|
|
|
* @since 1.0 |
|
43
|
|
|
*/ |
|
44
|
|
|
public static $includePaths = array(); |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* Constructor |
|
48
|
|
|
*/ |
|
49
|
|
|
public function __construct() |
|
50
|
|
|
{ |
|
51
|
|
|
self::$pluginParams = new JRegistry; |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* Get default language |
|
56
|
|
|
* |
|
57
|
|
|
* @param string $client Name of the client to get (site|admin) |
|
58
|
|
|
* |
|
59
|
|
|
* @return string Name of the language ex. en-GB |
|
60
|
|
|
*/ |
|
61
|
|
|
public static function getSiteLanguage($client = 'site') |
|
62
|
|
|
{ |
|
63
|
|
|
if (!isset(self::$siteLanguage)) |
|
64
|
|
|
{ |
|
65
|
|
|
$db = JFactory::getDbo(); |
|
|
|
|
|
|
66
|
|
|
$oldTranslate = $db->translate; |
|
67
|
|
|
|
|
68
|
|
|
// We do not want to translate this value |
|
69
|
|
|
$db->translate = false; |
|
70
|
|
|
|
|
71
|
|
|
self::$siteLanguage = JComponentHelper::getParams('com_languages')->get($client); |
|
|
|
|
|
|
72
|
|
|
|
|
73
|
|
|
// We put translation check back on |
|
74
|
|
|
$db->translate = $oldTranslate; |
|
75
|
|
|
} |
|
76
|
|
|
|
|
77
|
|
|
return self::$siteLanguage; |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
/** |
|
81
|
|
|
* Get list of all translation tables with columns. It is here for backward compatibility below version 1.8.3 |
|
82
|
|
|
* |
|
83
|
|
|
* @return array Array or table with columns columns |
|
84
|
|
|
*/ |
|
85
|
|
|
public static function getInstalledTranslationTables() |
|
86
|
|
|
{ |
|
87
|
|
|
return RTranslationTable::getInstalledTranslationTables(); |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
|
|
/** |
|
91
|
|
|
* Checks if this is edit form and restricts table from translations |
|
92
|
|
|
* |
|
93
|
|
|
* @param array $translationTables List of translation tables |
|
94
|
|
|
* |
|
95
|
|
|
* @return array Array or table with columns columns |
|
96
|
|
|
*/ |
|
97
|
|
|
public static function removeFromEditForm($translationTables) |
|
98
|
|
|
{ |
|
99
|
|
|
$input = JFactory::getApplication()->input; |
|
100
|
|
|
$option = $input->getString('option', ''); |
|
101
|
|
|
$view = $input->getString('view', ''); |
|
102
|
|
|
$layout = $input->getString('layout', ''); |
|
103
|
|
|
$task = $input->getString('layout', ''); |
|
104
|
|
|
|
|
105
|
|
|
if ($layout == 'edit' || $task == 'edit') |
|
106
|
|
|
{ |
|
107
|
|
|
foreach ($translationTables as $tableKey => $translationTable) |
|
108
|
|
|
{ |
|
109
|
|
|
if (!empty($translationTable->formLinks)) |
|
110
|
|
|
{ |
|
111
|
|
|
foreach ($translationTable->formLinks as $formLink) |
|
112
|
|
|
{ |
|
113
|
|
|
$id = $input->getString($formLink['identifier'], ''); |
|
114
|
|
|
|
|
115
|
|
|
if ($option == $formLink['option'] && $view == $formLink['view'] && $layout == $formLink['layout'] && $id) |
|
116
|
|
|
{ |
|
117
|
|
|
unset($translationTables[$tableKey]); |
|
118
|
|
|
break; |
|
119
|
|
|
} |
|
120
|
|
|
} |
|
121
|
|
|
} |
|
122
|
|
|
} |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
return $translationTables; |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
/** |
|
129
|
|
|
* Add a filesystem path where Translation system should search for Params files. |
|
130
|
|
|
* You may either pass a string or an array of paths. |
|
131
|
|
|
* |
|
132
|
|
|
* @param mixed $path A filesystem path or array of filesystem paths to add. |
|
133
|
|
|
* |
|
134
|
|
|
* @return array An array of filesystem paths to find Params in. |
|
135
|
|
|
* |
|
136
|
|
|
* @since 1.0 |
|
137
|
|
|
*/ |
|
138
|
|
|
public static function addIncludePath($path = null) |
|
139
|
|
|
{ |
|
140
|
|
|
// Convert the passed path(s) to add to an array. |
|
141
|
|
|
settype($path, 'array'); |
|
142
|
|
|
|
|
143
|
|
|
// If we have new paths to add, do so. |
|
144
|
|
|
if (!empty($path)) |
|
145
|
|
|
{ |
|
146
|
|
|
// Check and add each individual new path. |
|
147
|
|
|
foreach ($path as $dir) |
|
148
|
|
|
{ |
|
149
|
|
|
// Sanitize path. |
|
150
|
|
|
$dir = trim($dir); |
|
151
|
|
|
|
|
152
|
|
|
// Add to the front of the list so that custom paths are searched first. |
|
153
|
|
|
if (!in_array($dir, self::$includePaths)) |
|
154
|
|
|
{ |
|
155
|
|
|
array_unshift(self::$includePaths, $dir); |
|
156
|
|
|
} |
|
157
|
|
|
} |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
return self::$includePaths; |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
* Loads form for Params field |
|
165
|
|
|
* |
|
166
|
|
|
* @param array $column Content element column |
|
167
|
|
|
* @param RTranslationContentElement $translationTable Translation table |
|
168
|
|
|
* @param mixed $data The data expected for the form. |
|
169
|
|
|
* @param string $controlName Name of the form control group |
|
170
|
|
|
* @param string $basepath Base path to use when loading files |
|
171
|
|
|
* |
|
172
|
|
|
* @return array Array or table with columns columns |
|
173
|
|
|
*/ |
|
174
|
|
|
public static function loadParamsForm($column, $translationTable, $data, $controlName = '', $basepath = JPATH_BASE) |
|
175
|
|
|
{ |
|
176
|
|
|
if (version_compare(JVERSION, '3.0', '<') && !empty($column['formname25'])) |
|
177
|
|
|
{ |
|
178
|
|
|
$formName = !empty($column['formname']) ? $column['formname25'] : $column['name']; |
|
179
|
|
|
} |
|
180
|
|
|
else |
|
181
|
|
|
{ |
|
182
|
|
|
$formName = !empty($column['formname']) ? $column['formname'] : $column['name']; |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
// Handle the optional arguments. |
|
186
|
|
|
$options = array(); |
|
187
|
|
|
$options['control'] = $controlName; |
|
188
|
|
|
$options['load_data'] = true; |
|
189
|
|
|
$formData = array(); |
|
190
|
|
|
|
|
191
|
|
|
if (!empty($data->{$column['name']})) |
|
192
|
|
|
{ |
|
193
|
|
|
$registry = new JRegistry; |
|
194
|
|
|
$registry->loadString($data->{$column['name']}); |
|
195
|
|
|
$formData[$column['name']] = $registry->toArray(); |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
// Load common and local language files. |
|
199
|
|
|
$lang = JFactory::getLanguage(); |
|
200
|
|
|
|
|
201
|
|
|
// Load language file |
|
202
|
|
|
$lang->load($translationTable->extension_name, $basepath, null, false, false) |
|
|
|
|
|
|
203
|
|
|
|| $lang->load($translationTable->extension_name, $basepath . "/components/" . $translationTable->extension_name, null, false, false) |
|
204
|
|
|
|| $lang->load($translationTable->extension_name, $basepath, $lang->getDefault(), false, false) |
|
205
|
|
|
|| $lang->load( |
|
206
|
|
|
$translationTable->extension_name, $basepath . "/components/" . $translationTable->extension_name, $lang->getDefault(), false, false |
|
207
|
|
|
); |
|
208
|
|
|
|
|
209
|
|
|
// Get the form. |
|
210
|
|
|
RForm::addFormPath($basepath . '/components/' . $translationTable->extension_name . '/models/forms'); |
|
211
|
|
|
RForm::addFormPath($basepath . '/administrator/components/' . $translationTable->extension_name . '/models/forms'); |
|
212
|
|
|
RForm::addFieldPath($basepath . '/components/' . $translationTable->extension_name . '/models/fields'); |
|
213
|
|
|
RForm::addFieldPath($basepath . '/administrator/components/' . $translationTable->extension_name . '/models/fields'); |
|
214
|
|
|
|
|
215
|
|
|
if (!empty($column['formpath'])) |
|
216
|
|
|
{ |
|
217
|
|
|
RForm::addFormPath($basepath . $column['formpath']); |
|
218
|
|
|
} |
|
219
|
|
|
|
|
220
|
|
|
if (!empty($column['fieldpath'])) |
|
221
|
|
|
{ |
|
222
|
|
|
RForm::addFieldPath($basepath . $column['fieldpath']); |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
$xpath = !empty($column['xpath']) ? $column['xpath'] : false; |
|
226
|
|
|
|
|
227
|
|
|
try |
|
228
|
|
|
{ |
|
229
|
|
|
$form = RForm::getInstance('com_redcore.params_' . $column['name'] . $controlName, $formName, $options, false, $xpath); |
|
230
|
|
|
|
|
231
|
|
|
// Allow for additional modification of the form, and events to be triggered. |
|
232
|
|
|
// We pass the data because plugins may require it. |
|
233
|
|
|
self::preprocessForm($form, $data, 'content', $column, $translationTable); |
|
234
|
|
|
|
|
235
|
|
|
// Load the data into the form after the plugins have operated. |
|
236
|
|
|
$form->bind($formData); |
|
237
|
|
|
} |
|
238
|
|
|
catch (Exception $e) |
|
239
|
|
|
{ |
|
240
|
|
|
return false; |
|
|
|
|
|
|
241
|
|
|
} |
|
242
|
|
|
|
|
243
|
|
|
if (empty($form)) |
|
244
|
|
|
{ |
|
245
|
|
|
return false; |
|
|
|
|
|
|
246
|
|
|
} |
|
247
|
|
|
|
|
248
|
|
|
return $form; |
|
|
|
|
|
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
/** |
|
252
|
|
|
* Method to allow derived classes to preprocess the form. |
|
253
|
|
|
* |
|
254
|
|
|
* @param JForm $form A JForm object. |
|
255
|
|
|
* @param mixed $data The data expected for the form. |
|
256
|
|
|
* @param string $group The name of the plugin group to import (defaults to "content"). |
|
257
|
|
|
* @param array $column Content element column |
|
258
|
|
|
* @param RedcoreTableTranslation_Table $translationTable Translation table |
|
259
|
|
|
* |
|
260
|
|
|
* @return void |
|
261
|
|
|
* |
|
262
|
|
|
* @see JFormField |
|
263
|
|
|
* @since 12.2 |
|
264
|
|
|
* @throws Exception if there is an error in the form event. |
|
265
|
|
|
*/ |
|
266
|
|
|
public static function preprocessForm(JForm $form, $data, $group = 'content', $column = array(), $translationTable = null) |
|
|
|
|
|
|
267
|
|
|
{ |
|
268
|
|
|
$tableName = str_replace('#__', '', $translationTable->name); |
|
269
|
|
|
|
|
270
|
|
|
if ($tableName == 'modules') |
|
271
|
|
|
{ |
|
272
|
|
|
$form = self::preprocessFormModules($form, $data); |
|
273
|
|
|
} |
|
274
|
|
|
elseif ($tableName == 'menus') |
|
275
|
|
|
{ |
|
276
|
|
|
$form = self::preprocessFormMenu($form, $data); |
|
277
|
|
|
} |
|
278
|
|
|
elseif ($tableName == 'plugins') |
|
279
|
|
|
{ |
|
280
|
|
|
$form = self::preprocessFormPlugins($form, $data); |
|
281
|
|
|
} |
|
282
|
|
|
|
|
283
|
|
|
// Import the appropriate plugin group. |
|
284
|
|
|
JPluginHelper::importPlugin($group); |
|
|
|
|
|
|
285
|
|
|
|
|
286
|
|
|
// Get the dispatcher. |
|
287
|
|
|
$dispatcher = RFactory::getDispatcher(); |
|
288
|
|
|
|
|
289
|
|
|
// Trigger the form preparation event. |
|
290
|
|
|
$results = $dispatcher->trigger('onContentPrepareForm', array($form, $data)); |
|
291
|
|
|
|
|
292
|
|
|
// Check for errors encountered while preparing the form. |
|
293
|
|
|
if (count($results) && in_array(false, $results, true)) |
|
294
|
|
|
{ |
|
295
|
|
|
// Get the last error. |
|
296
|
|
|
$error = $dispatcher->getError(); |
|
297
|
|
|
|
|
298
|
|
|
if (!($error instanceof Exception)) |
|
299
|
|
|
{ |
|
300
|
|
|
throw new Exception($error); |
|
301
|
|
|
} |
|
302
|
|
|
} |
|
303
|
|
|
} |
|
304
|
|
|
|
|
305
|
|
|
/** |
|
306
|
|
|
* Method to preprocess the form for modules |
|
307
|
|
|
* |
|
308
|
|
|
* @param JForm $form A form object. |
|
309
|
|
|
* @param mixed $data The data expected for the form. |
|
310
|
|
|
* |
|
311
|
|
|
* @return JForm |
|
312
|
|
|
* |
|
313
|
|
|
* @since 1.6 |
|
314
|
|
|
* @throws Exception if there is an error loading the form. |
|
315
|
|
|
*/ |
|
316
|
|
|
public static function preprocessFormModules(JForm $form, $data) |
|
317
|
|
|
{ |
|
318
|
|
|
jimport('joomla.filesystem.path'); |
|
|
|
|
|
|
319
|
|
|
|
|
320
|
|
|
$lang = JFactory::getLanguage(); |
|
321
|
|
|
$clientId = $data->client_id; |
|
322
|
|
|
$module = $data->module; |
|
323
|
|
|
|
|
324
|
|
|
$client = JApplicationHelper::getClientInfo($clientId); |
|
|
|
|
|
|
325
|
|
|
$formFile = JPath::clean($client->path . '/modules/' . $module . '/' . $module . '.xml'); |
|
|
|
|
|
|
326
|
|
|
|
|
327
|
|
|
// Load the core and/or local language file(s). |
|
328
|
|
|
$lang->load($module, $client->path, null, false, true) |
|
329
|
|
|
|| $lang->load($module, $client->path . '/modules/' . $module, null, false, true); |
|
330
|
|
|
|
|
331
|
|
|
if (file_exists($formFile)) |
|
332
|
|
|
{ |
|
333
|
|
|
// Get the module form. |
|
334
|
|
|
if (!$form->loadFile($formFile, false, '//config')) |
|
335
|
|
|
{ |
|
336
|
|
|
throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); |
|
|
|
|
|
|
337
|
|
|
} |
|
338
|
|
|
} |
|
339
|
|
|
|
|
340
|
|
|
return $form; |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
/** |
|
344
|
|
|
* Method to preprocess the form for plugins |
|
345
|
|
|
* |
|
346
|
|
|
* @param JForm $form A form object. |
|
347
|
|
|
* @param mixed $data The data expected for the form. |
|
348
|
|
|
* |
|
349
|
|
|
* @return JForm |
|
350
|
|
|
* |
|
351
|
|
|
* @since 1.6 |
|
352
|
|
|
* @throws Exception if there is an error loading the form. |
|
353
|
|
|
*/ |
|
354
|
|
|
public static function preprocessFormPlugins(JForm $form, $data) |
|
355
|
|
|
{ |
|
356
|
|
|
jimport('joomla.filesystem.path'); |
|
|
|
|
|
|
357
|
|
|
|
|
358
|
|
|
$lang = JFactory::getLanguage(); |
|
359
|
|
|
$extension = 'plg_' . $data->folder . '_' . $data->element; |
|
360
|
|
|
|
|
361
|
|
|
$formFile = JPath::clean(JPATH_PLUGINS . '/' . $data->folder . '/' . $data->element . '/' . $data->element . '.xml'); |
|
362
|
|
|
|
|
363
|
|
|
// Load the core and/or local language file(s). |
|
364
|
|
|
$lang->load(strtolower($extension), JPATH_ADMINISTRATOR, null, false, true) |
|
365
|
|
|
|| $lang->load(strtolower($extension), JPATH_PLUGINS . '/' . $data->folder . '/' . $data->element, null, false, true); |
|
366
|
|
|
$lang->load(strtolower($extension . '.sys'), JPATH_ADMINISTRATOR, null, false, true) |
|
367
|
|
|
|| $lang->load(strtolower($extension . '.sys'), JPATH_PLUGINS . '/' . $data->folder . '/' . $data->element, null, false, true); |
|
368
|
|
|
|
|
369
|
|
|
if (file_exists($formFile)) |
|
370
|
|
|
{ |
|
371
|
|
|
// Get the module form. |
|
372
|
|
|
if (!$form->loadFile($formFile, false, '//config')) |
|
373
|
|
|
{ |
|
374
|
|
|
throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); |
|
375
|
|
|
} |
|
376
|
|
|
} |
|
377
|
|
|
|
|
378
|
|
|
return $form; |
|
379
|
|
|
} |
|
380
|
|
|
|
|
381
|
|
|
/** |
|
382
|
|
|
* Method to preprocess the form for modules |
|
383
|
|
|
* |
|
384
|
|
|
* @param JForm $form A form object. |
|
385
|
|
|
* @param mixed $data The data expected for the form. |
|
386
|
|
|
* |
|
387
|
|
|
* @return JForm |
|
388
|
|
|
* |
|
389
|
|
|
* @since 1.6 |
|
390
|
|
|
* @throws Exception if there is an error loading the form. |
|
391
|
|
|
*/ |
|
392
|
|
|
public static function preprocessFormMenu(JForm $form, $data) |
|
393
|
|
|
{ |
|
394
|
|
|
jimport('joomla.filesystem.path'); |
|
|
|
|
|
|
395
|
|
|
$link = $data->link; |
|
396
|
|
|
$type = $data->type; |
|
397
|
|
|
$formFile = false; |
|
398
|
|
|
|
|
399
|
|
|
// Initialise form with component view params if available. |
|
400
|
|
|
if ($type == 'component') |
|
401
|
|
|
{ |
|
402
|
|
|
$link = htmlspecialchars_decode($link); |
|
403
|
|
|
|
|
404
|
|
|
// Parse the link arguments. |
|
405
|
|
|
$args = array(); |
|
406
|
|
|
parse_str(parse_url(htmlspecialchars_decode($link), PHP_URL_QUERY), $args); |
|
407
|
|
|
|
|
408
|
|
|
// Confirm that the option is defined. |
|
409
|
|
|
$option = ''; |
|
410
|
|
|
$base = ''; |
|
411
|
|
|
|
|
412
|
|
|
if (isset($args['option'])) |
|
413
|
|
|
{ |
|
414
|
|
|
// The option determines the base path to work with. |
|
415
|
|
|
$option = $args['option']; |
|
416
|
|
|
$base = JPATH_SITE . '/components/' . $option; |
|
417
|
|
|
} |
|
418
|
|
|
|
|
419
|
|
|
// Confirm a view is defined. |
|
420
|
|
|
$formFile = false; |
|
421
|
|
|
|
|
422
|
|
|
if (isset($args['view'])) |
|
423
|
|
|
{ |
|
424
|
|
|
$view = $args['view']; |
|
425
|
|
|
|
|
426
|
|
|
// Determine the layout to search for. |
|
427
|
|
|
if (isset($args['layout'])) |
|
428
|
|
|
{ |
|
429
|
|
|
$layout = $args['layout']; |
|
430
|
|
|
} |
|
431
|
|
|
else |
|
432
|
|
|
{ |
|
433
|
|
|
$layout = 'default'; |
|
434
|
|
|
} |
|
435
|
|
|
|
|
436
|
|
|
$formFile = false; |
|
437
|
|
|
|
|
438
|
|
|
// Check for the layout XML file. Use standard xml file if it exists. |
|
439
|
|
|
$tplFolders = array( |
|
440
|
|
|
$base . '/views/' . $view . '/tmpl', |
|
441
|
|
|
$base . '/view/' . $view . '/tmpl' |
|
442
|
|
|
); |
|
443
|
|
|
$path = JPath::find($tplFolders, $layout . '.xml'); |
|
444
|
|
|
|
|
445
|
|
|
if (is_file($path)) |
|
446
|
|
|
{ |
|
447
|
|
|
$formFile = $path; |
|
448
|
|
|
} |
|
449
|
|
|
|
|
450
|
|
|
// If custom layout, get the xml file from the template folder |
|
451
|
|
|
// template folder is first part of file name -- template:folder |
|
452
|
|
|
if (!$formFile && (strpos($layout, ':') > 0)) |
|
453
|
|
|
{ |
|
454
|
|
|
$temp = explode(':', $layout); |
|
455
|
|
|
$templatePath = JPATH::clean(JPATH_SITE . '/templates/' . $temp[0] . '/html/' . $option . '/' . $view . '/' . $temp[1] . '.xml'); |
|
|
|
|
|
|
456
|
|
|
|
|
457
|
|
|
if (is_file($templatePath)) |
|
458
|
|
|
{ |
|
459
|
|
|
$formFile = $templatePath; |
|
460
|
|
|
} |
|
461
|
|
|
} |
|
462
|
|
|
} |
|
463
|
|
|
|
|
464
|
|
|
// Now check for a view manifest file |
|
465
|
|
|
if (!$formFile) |
|
466
|
|
|
{ |
|
467
|
|
|
if (isset($view)) |
|
468
|
|
|
{ |
|
469
|
|
|
$metadataFolders = array( |
|
470
|
|
|
$base . '/view/' . $view, |
|
471
|
|
|
$base . '/views/' . $view |
|
472
|
|
|
); |
|
473
|
|
|
$metaPath = JPath::find($metadataFolders, 'metadata.xml'); |
|
474
|
|
|
|
|
475
|
|
|
if (is_file($path = JPath::clean($metaPath))) |
|
476
|
|
|
{ |
|
477
|
|
|
$formFile = $path; |
|
478
|
|
|
} |
|
479
|
|
|
} |
|
480
|
|
|
else |
|
481
|
|
|
{ |
|
482
|
|
|
// Now check for a component manifest file |
|
483
|
|
|
$path = JPath::clean($base . '/metadata.xml'); |
|
484
|
|
|
|
|
485
|
|
|
if (is_file($path)) |
|
486
|
|
|
{ |
|
487
|
|
|
$formFile = $path; |
|
488
|
|
|
} |
|
489
|
|
|
} |
|
490
|
|
|
} |
|
491
|
|
|
|
|
492
|
|
|
$lang = JFactory::getLanguage(); |
|
493
|
|
|
$lang->load($option, JPATH_BASE, null, false, false) |
|
494
|
|
|
|| $lang->load($option, JPATH_BASE . "/components/" . $option, null, false, false) |
|
495
|
|
|
|| $lang->load($option, JPATH_BASE, $lang->getDefault(), false, false) |
|
496
|
|
|
|| $lang->load($option, JPATH_BASE . "/components/" . $option, $lang->getDefault(), false, false); |
|
497
|
|
|
} |
|
498
|
|
|
|
|
499
|
|
|
if ($formFile) |
|
500
|
|
|
{ |
|
501
|
|
|
// If an XML file was found in the component, load it first. |
|
502
|
|
|
// We need to qualify the full path to avoid collisions with component file names. |
|
503
|
|
|
|
|
504
|
|
|
if ($form->loadFile($formFile, true, '/metadata') == false) |
|
505
|
|
|
{ |
|
506
|
|
|
throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); |
|
507
|
|
|
} |
|
508
|
|
|
} |
|
509
|
|
|
|
|
510
|
|
|
// Now load the component params. |
|
511
|
|
|
// TODO: Work out why 'fixing' this breaks JForm |
|
512
|
|
|
if ($isNew = false) |
|
|
|
|
|
|
513
|
|
|
{ |
|
514
|
|
|
$path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $option . '/config.xml'); |
|
|
|
|
|
|
515
|
|
|
} |
|
516
|
|
|
else |
|
517
|
|
|
{ |
|
518
|
|
|
$path = 'null'; |
|
519
|
|
|
} |
|
520
|
|
|
|
|
521
|
|
|
if (is_file($path)) |
|
522
|
|
|
{ |
|
523
|
|
|
// Add the component params last of all to the existing form. |
|
524
|
|
|
if (!$form->load($path, true, '/config')) |
|
525
|
|
|
{ |
|
526
|
|
|
throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); |
|
527
|
|
|
} |
|
528
|
|
|
} |
|
529
|
|
|
|
|
530
|
|
|
// Load the specific type file |
|
531
|
|
|
if (!$form->loadFile('item_' . $type, false, false)) |
|
532
|
|
|
{ |
|
533
|
|
|
throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); |
|
534
|
|
|
} |
|
535
|
|
|
|
|
536
|
|
|
return $form; |
|
537
|
|
|
} |
|
538
|
|
|
|
|
539
|
|
|
/** |
|
540
|
|
|
* Method to reset plugin translation keys |
|
541
|
|
|
* |
|
542
|
|
|
* @return void |
|
543
|
|
|
*/ |
|
544
|
|
|
public static function resetPluginTranslation() |
|
545
|
|
|
{ |
|
546
|
|
|
$user = JFactory::getUser(); |
|
547
|
|
|
$levels = implode(',', $user->getAuthorisedViewLevels()); |
|
548
|
|
|
|
|
549
|
|
|
$db = JFactory::getDbo(); |
|
550
|
|
|
$query = $db->getQuery(true) |
|
551
|
|
|
->select('folder AS type, element AS name, params') |
|
552
|
|
|
->from('#__extensions') |
|
553
|
|
|
->where('enabled = 1') |
|
554
|
|
|
->where('type =' . $db->quote('plugin')) |
|
555
|
|
|
->where('state IN (0,1)') |
|
556
|
|
|
->where('access IN (' . $levels . ')') |
|
557
|
|
|
->order('ordering'); |
|
558
|
|
|
|
|
559
|
|
|
$plugins = $db->setQuery($query)->loadObjectList(); |
|
560
|
|
|
|
|
561
|
|
|
foreach ($plugins as $plugin) |
|
562
|
|
|
{ |
|
563
|
|
|
$joomlaPlugin = JPluginHelper::getPlugin($plugin->type, $plugin->name); |
|
564
|
|
|
$joomlaPlugin->params = $plugin->params; |
|
565
|
|
|
} |
|
566
|
|
|
} |
|
567
|
|
|
|
|
568
|
|
|
/** |
|
569
|
|
|
* Method to check if the current application instance is an administrator instance |
|
570
|
|
|
* and that this is not an API call. |
|
571
|
|
|
* |
|
572
|
|
|
* @return bool true if this is admin and is not an API call |
|
573
|
|
|
* |
|
574
|
|
|
* @throws Exception |
|
575
|
|
|
*/ |
|
576
|
|
|
public static function isAdmin() |
|
577
|
|
|
{ |
|
578
|
|
|
$app = JFactory::getApplication(); |
|
579
|
|
|
$isApi = ($app->input->get('api') != null); |
|
580
|
|
|
|
|
581
|
|
|
return ((version_compare(JVERSION, '3.7', '<') ? $app->isAdmin() : $app->isClient('administrator')) && !$isApi); |
|
582
|
|
|
} |
|
583
|
|
|
|
|
584
|
|
|
/** |
|
585
|
|
|
* Checks to see if the language exists and then load it |
|
586
|
|
|
* |
|
587
|
|
|
* @param string $language Language name |
|
588
|
|
|
* @param bool $loadLanguage Loads the language if it exists |
|
589
|
|
|
* |
|
590
|
|
|
* @return boolean Returns true if language exists and we have switched to new language |
|
591
|
|
|
*/ |
|
592
|
|
|
public static function setLanguage($language, $loadLanguage = true) |
|
593
|
|
|
{ |
|
594
|
|
|
$languages = JLanguageHelper::getLanguages('sef'); |
|
|
|
|
|
|
595
|
|
|
$languageKeys = explode('-', $language); |
|
596
|
|
|
|
|
597
|
|
|
if (!empty($languageKeys[0]) && !empty($languages[$languageKeys[0]]->lang_code)) |
|
598
|
|
|
{ |
|
599
|
|
|
JFactory::getApplication()->input->set('lang', $language); |
|
600
|
|
|
$languageObject = new JLanguage($languages[$languageKeys[0]]->lang_code); |
|
|
|
|
|
|
601
|
|
|
|
|
602
|
|
|
if ($loadLanguage) |
|
603
|
|
|
{ |
|
604
|
|
|
$languageObject->load(); |
|
605
|
|
|
} |
|
606
|
|
|
|
|
607
|
|
|
return true; |
|
608
|
|
|
} |
|
609
|
|
|
|
|
610
|
|
|
return false; |
|
611
|
|
|
} |
|
612
|
|
|
|
|
613
|
|
|
/** |
|
614
|
|
|
* Checks if the current page is a translatable form. |
|
615
|
|
|
* |
|
616
|
|
|
* @param bool $isAdmin Informs us whether we are on frontend or backend |
|
617
|
|
|
* |
|
618
|
|
|
* @return void |
|
619
|
|
|
*/ |
|
620
|
|
|
public static function isTranslatableForm($isAdmin) |
|
621
|
|
|
{ |
|
622
|
|
|
// Current page values |
|
623
|
|
|
$input = JFactory::getApplication()->input; |
|
624
|
|
|
$option = $input->getString('option', ''); |
|
625
|
|
|
$view = $input->getString('view', ''); |
|
626
|
|
|
$layout = $input->getString('layout', ''); |
|
627
|
|
|
$task = $input->getString('task', ''); |
|
|
|
|
|
|
628
|
|
|
|
|
629
|
|
|
$translationTables = self::getInstalledTranslationTables(); |
|
630
|
|
|
|
|
631
|
|
|
foreach ($translationTables as $tableKey => $translationTable) |
|
632
|
|
|
{ |
|
633
|
|
|
if (!isset($translationTable->formLinks)) |
|
634
|
|
|
{ |
|
635
|
|
|
continue; |
|
636
|
|
|
} |
|
637
|
|
|
|
|
638
|
|
|
foreach ($translationTable->formLinks as $formLink) |
|
639
|
|
|
{ |
|
640
|
|
|
// Form values |
|
641
|
|
|
$tableAdmin = !empty($formLink['admin']) ? $formLink['admin'] : 'false'; |
|
642
|
|
|
$tableOption = $formLink['option']; |
|
643
|
|
|
$tableView = $formLink['view']; |
|
644
|
|
|
$tableLayout = !empty($formLink['layout']) ? $formLink['layout'] : 'edit'; |
|
645
|
|
|
$tableID = isset($formLink['identifier']) ? $formLink['identifier'] : 'id'; |
|
646
|
|
|
$showButton = !empty($formLink['showbutton']) ? $formLink['showbutton'] : 'true'; |
|
647
|
|
|
$htmlposition = !empty($formLink['htmlposition']) ? $formLink['htmlposition'] : '.btn-toolbar:first'; |
|
648
|
|
|
$checkPrimaryId = !empty($formLink['checkoriginalid']) ? $formLink['checkoriginalid'] : 'false'; |
|
649
|
|
|
$results = null; |
|
650
|
|
|
|
|
651
|
|
|
// Check if the form's frontend/backend options matches the current page |
|
652
|
|
|
$tableAdmin = $tableAdmin === 'true' ? true : false; |
|
653
|
|
|
|
|
654
|
|
|
if ($isAdmin != $tableAdmin) |
|
655
|
|
|
{ |
|
656
|
|
|
continue; |
|
657
|
|
|
} |
|
658
|
|
|
|
|
659
|
|
|
// Check whether form values matches the current page |
|
660
|
|
|
if ($option == $tableOption && $view == $tableView && $layout == $tableLayout) |
|
661
|
|
|
{ |
|
662
|
|
|
// Get id of item based on the form identifier. |
|
663
|
|
|
$itemID = $input->getInt($tableID, ''); |
|
664
|
|
|
|
|
665
|
|
|
// If the item doesn't have an ID, tell the user that they have to save the item first. |
|
666
|
|
|
if (empty($itemID)) |
|
667
|
|
|
{ |
|
668
|
|
|
self::renderTranslationModal(false, false, false, false); |
|
|
|
|
|
|
669
|
|
|
|
|
670
|
|
|
return; |
|
671
|
|
|
} |
|
672
|
|
|
|
|
673
|
|
|
if ($checkPrimaryId == 'true') |
|
674
|
|
|
{ |
|
675
|
|
|
// Check whether there's a relation between the current item and the translation element |
|
676
|
|
|
$db = JFactory::getDbo(); |
|
677
|
|
|
$query = $db->getQuery(true) |
|
678
|
|
|
->select($db->qn($translationTable->primaryKeys[0])) |
|
679
|
|
|
->from($db->qn($translationTable->table)) |
|
680
|
|
|
->where($db->qn($translationTable->primaryKeys[0]) . '=' . $db->q($itemID)); |
|
681
|
|
|
|
|
682
|
|
|
$db->setQuery($query); |
|
683
|
|
|
$results = $db->loadObjectList(); |
|
684
|
|
|
|
|
685
|
|
|
$checkPrimaryId = !empty($results) ? 'false' : 'true'; |
|
686
|
|
|
} |
|
687
|
|
|
|
|
688
|
|
|
// If there is, render a modal button & window in the toolbar |
|
689
|
|
|
if ($checkPrimaryId == 'false' && $showButton == 'true') |
|
690
|
|
|
{ |
|
691
|
|
|
$linkname = JText::_('LIB_REDCORE_TRANSLATION_NAME_BUTTON') . ' ' . $translationTable->title; |
|
692
|
|
|
$contentelement = str_replace('#__', '', $translationTable->table); |
|
693
|
|
|
|
|
694
|
|
|
self::renderTranslationModal($itemID, $linkname, $contentelement, $htmlposition); |
|
|
|
|
|
|
695
|
|
|
} |
|
696
|
|
|
} |
|
697
|
|
|
} |
|
698
|
|
|
} |
|
699
|
|
|
} |
|
700
|
|
|
|
|
701
|
|
|
/** |
|
702
|
|
|
* Renders a modal button & window for a translation element |
|
703
|
|
|
* |
|
704
|
|
|
* @param string $itemID The id of the current item being shown |
|
705
|
|
|
* @param array $linkname The text to be shown on the modal button |
|
706
|
|
|
* @param int $contentelement The current translation element |
|
707
|
|
|
* @param string $htmlposition The position on the page where the button should be moved to |
|
708
|
|
|
* |
|
709
|
|
|
* @return void |
|
710
|
|
|
*/ |
|
711
|
|
|
public static function renderTranslationModal($itemID, $linkname, $contentelement, $htmlposition) |
|
712
|
|
|
{ |
|
713
|
|
|
echo RLayoutHelper::render( |
|
714
|
|
|
'modal.iframe-full-page', |
|
715
|
|
|
array( |
|
716
|
|
|
'id' => $itemID, |
|
717
|
|
|
'header' => '', |
|
718
|
|
|
'linkName' => $linkname, |
|
719
|
|
|
'link' => JRoute::_('index.php?option=com_redcore&view=translation&task=translation.display&layout=modal-edit&translationTableName=' |
|
|
|
|
|
|
720
|
|
|
. $contentelement |
|
721
|
|
|
. '&id=' |
|
722
|
|
|
. $itemID |
|
723
|
|
|
. '&tmpl=component' |
|
724
|
|
|
), |
|
725
|
|
|
'linkClass' => 'btn btn-primary', |
|
726
|
|
|
'contentElement' => $contentelement, |
|
727
|
|
|
'htmlposition' => $htmlposition, |
|
728
|
|
|
) |
|
729
|
|
|
); |
|
730
|
|
|
} |
|
731
|
|
|
|
|
732
|
|
|
/** |
|
733
|
|
|
* Gets translation item status |
|
734
|
|
|
* |
|
735
|
|
|
* @param object $item Translate item object |
|
736
|
|
|
* @param array $columns List of columns used in translation |
|
737
|
|
|
* |
|
738
|
|
|
* @return string Translation Item status |
|
739
|
|
|
*/ |
|
740
|
|
|
public static function getTranslationItemStatus($item, $columns) |
|
741
|
|
|
{ |
|
742
|
|
|
if (empty($item->rctranslations_language)) |
|
743
|
|
|
{ |
|
744
|
|
|
return array('badge' => 'label label-danger', 'status' => 'JNONE'); |
|
|
|
|
|
|
745
|
|
|
} |
|
746
|
|
|
elseif ($item->rctranslations_state != 1) |
|
747
|
|
|
{ |
|
748
|
|
|
return array('badge' => 'label label-danger', 'status' => 'JUNPUBLISHED'); |
|
|
|
|
|
|
749
|
|
|
} |
|
750
|
|
|
else |
|
751
|
|
|
{ |
|
752
|
|
|
$originalValues = new JRegistry; |
|
753
|
|
|
|
|
754
|
|
|
if (is_array($item->rctranslations_originals)) |
|
755
|
|
|
{ |
|
756
|
|
|
$originalValues->loadArray($item->rctranslations_originals); |
|
757
|
|
|
} |
|
758
|
|
|
else |
|
759
|
|
|
{ |
|
760
|
|
|
$originalValues->loadString((string) $item->rctranslations_originals); |
|
761
|
|
|
} |
|
762
|
|
|
|
|
763
|
|
|
$translationStatus = array('badge' => 'label label-success', 'status' => 'COM_REDCORE_TRANSLATIONS_STATUS_TRANSLATED'); |
|
764
|
|
|
|
|
765
|
|
|
foreach ($columns as $column) |
|
766
|
|
|
{ |
|
767
|
|
|
if (md5($item->$column) != $originalValues->get($column)) |
|
768
|
|
|
{ |
|
769
|
|
|
$translationStatus = array('badge' => 'label label-warning', 'status' => 'COM_REDCORE_TRANSLATIONS_STATUS_CHANGED'); |
|
770
|
|
|
break; |
|
771
|
|
|
} |
|
772
|
|
|
} |
|
773
|
|
|
|
|
774
|
|
|
return $translationStatus; |
|
|
|
|
|
|
775
|
|
|
} |
|
776
|
|
|
} |
|
777
|
|
|
|
|
778
|
|
|
/** |
|
779
|
|
|
* Gets translation item id and returns it |
|
780
|
|
|
* |
|
781
|
|
|
* @param int $itemid Item id |
|
782
|
|
|
* @param string $langCode Language code |
|
783
|
|
|
* @param string $pk Primary key name |
|
784
|
|
|
* @param string $translationTableName Name of the translation table |
|
785
|
|
|
* |
|
786
|
|
|
* @return int Translations item id |
|
787
|
|
|
*/ |
|
788
|
|
|
public static function getTranslationItemId($itemid, $langCode, $pk, $translationTableName) |
|
789
|
|
|
{ |
|
790
|
|
|
$ids = explode('###', $itemid); |
|
791
|
|
|
|
|
792
|
|
|
$db = JFactory::getDbo(); |
|
793
|
|
|
$query = $db->getQuery(true) |
|
794
|
|
|
->select('rctranslations_id') |
|
795
|
|
|
->from($db->qn(RTranslationTable::getTranslationsTableName($translationTableName, '#__'))) |
|
796
|
|
|
->where('rctranslations_language=' . $db->q($langCode)); |
|
797
|
|
|
|
|
798
|
|
|
foreach ($pk as $key => $primaryKey) |
|
|
|
|
|
|
799
|
|
|
{ |
|
800
|
|
|
$query->where($db->qn($primaryKey) . ' = ' . $db->q($ids[$key])); |
|
801
|
|
|
} |
|
802
|
|
|
|
|
803
|
|
|
$db->setQuery($query); |
|
804
|
|
|
|
|
805
|
|
|
$result = $db->loadResult(); |
|
806
|
|
|
|
|
807
|
|
|
return $result; |
|
808
|
|
|
} |
|
809
|
|
|
|
|
810
|
|
|
/** |
|
811
|
|
|
* Checks if an array of data has any data |
|
812
|
|
|
* |
|
813
|
|
|
* @param array $data Array of data to be checked |
|
814
|
|
|
* @param array $excludes Array of keys to be excluded from validation |
|
815
|
|
|
* |
|
816
|
|
|
* @return boolean True if the array contains data |
|
817
|
|
|
*/ |
|
818
|
|
|
public static function validateEmptyTranslationData($data, $excludes = null) |
|
819
|
|
|
{ |
|
820
|
|
|
// Remove excluded keys from array |
|
821
|
|
|
foreach ($excludes as $exclude) |
|
822
|
|
|
{ |
|
823
|
|
|
unset($data[$exclude]); |
|
824
|
|
|
} |
|
825
|
|
|
|
|
826
|
|
|
// Check if the rest of the keys in the array are empty |
|
827
|
|
|
if (array_filter($data, 'strlen')) |
|
828
|
|
|
{ |
|
829
|
|
|
return true; |
|
830
|
|
|
} |
|
831
|
|
|
else |
|
832
|
|
|
{ |
|
833
|
|
|
return false; |
|
834
|
|
|
} |
|
835
|
|
|
} |
|
836
|
|
|
|
|
837
|
|
|
/** |
|
838
|
|
|
* Adds array to a JForm input |
|
839
|
|
|
* |
|
840
|
|
|
* @param string $form Form to be modified |
|
841
|
|
|
* @param string $index Index of the array |
|
842
|
|
|
* |
|
843
|
|
|
* @return string Modified form |
|
844
|
|
|
*/ |
|
845
|
|
|
public static function arrayifyTranslationJForm($form, $index) |
|
846
|
|
|
{ |
|
847
|
|
|
$pattern = '/name="jform/'; |
|
848
|
|
|
$replacement = 'name="jform[' . $index . ']'; |
|
849
|
|
|
$form = preg_replace($pattern, $replacement, $form); |
|
850
|
|
|
|
|
851
|
|
|
return $form; |
|
852
|
|
|
} |
|
853
|
|
|
|
|
854
|
|
|
/** |
|
855
|
|
|
* Returns an array of all content language codes (fx. en-GB) |
|
856
|
|
|
* |
|
857
|
|
|
* @return array All content language codes |
|
858
|
|
|
*/ |
|
859
|
|
|
public static function getAllContentLanguageCodes() |
|
860
|
|
|
{ |
|
861
|
|
|
$contentLanguages = JLanguageHelper::getLanguages(); |
|
862
|
|
|
|
|
863
|
|
|
$languageCodes = array(); |
|
864
|
|
|
|
|
865
|
|
|
foreach ($contentLanguages as $language) |
|
866
|
|
|
{ |
|
867
|
|
|
$languageCodes[] = $language->lang_code; |
|
868
|
|
|
} |
|
869
|
|
|
|
|
870
|
|
|
return $languageCodes; |
|
871
|
|
|
} |
|
872
|
|
|
} |
|
873
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.