1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package Com_Localise |
4
|
|
|
* @subpackage helper |
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.txt |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
defined('_JEXEC') or die; |
11
|
|
|
|
12
|
|
|
use Joomla\Github\Github; |
13
|
|
|
|
14
|
|
|
jimport('joomla.filesystem.folder'); |
15
|
|
|
jimport('joomla.filesystem.path'); |
16
|
|
|
jimport("joomla.utilities.date"); |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Localise Helper class |
20
|
|
|
* |
21
|
|
|
* @package Extensions.Components |
22
|
|
|
* @subpackage Localise |
23
|
|
|
* @since 4.0 |
24
|
|
|
*/ |
25
|
|
|
abstract class LocaliseHelper |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* Array containing the origin information |
29
|
|
|
* |
30
|
|
|
* @var array |
31
|
|
|
* @since 4.0 |
32
|
|
|
*/ |
33
|
|
|
protected static $origins = array('site' => null, 'administrator' => null, 'installation' => null); |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Array containing the package information |
37
|
|
|
* |
38
|
|
|
* @var array |
39
|
|
|
* @since 4.0 |
40
|
|
|
*/ |
41
|
|
|
protected static $packages = array(); |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Prepares the component submenu |
45
|
|
|
* |
46
|
|
|
* @param string $vName Name of the active view |
47
|
|
|
* |
48
|
|
|
* @return void |
49
|
|
|
* |
50
|
|
|
* @since 4.0 |
51
|
|
|
*/ |
52
|
|
|
public static function addSubmenu($vName) |
53
|
|
|
{ |
54
|
|
|
JHtmlSidebar::addEntry( |
55
|
|
|
JText::_('COM_LOCALISE_SUBMENU_LANGUAGES'), |
56
|
|
|
'index.php?option=com_localise&view=languages', |
57
|
|
|
$vName == 'languages' |
58
|
|
|
); |
59
|
|
|
|
60
|
|
|
JHtmlSidebar::addEntry( |
61
|
|
|
JText::_('COM_LOCALISE_SUBMENU_TRANSLATIONS'), |
62
|
|
|
'index.php?option=com_localise&view=translations', |
63
|
|
|
$vName == 'translations' |
64
|
|
|
); |
65
|
|
|
|
66
|
|
|
JHtmlSidebar::addEntry( |
67
|
|
|
JText::_('COM_LOCALISE_SUBMENU_PACKAGES'), |
68
|
|
|
'index.php?option=com_localise&view=packages', |
69
|
|
|
$vName == 'packages' |
70
|
|
|
); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Determines if a given path is writable in the current environment |
75
|
|
|
* |
76
|
|
|
* @param string $path Path to check |
77
|
|
|
* |
78
|
|
|
* @return boolean True if writable |
79
|
|
|
* |
80
|
|
|
* @since 4.0 |
81
|
|
|
*/ |
82
|
|
|
public static function isWritable($path) |
83
|
|
|
{ |
84
|
|
|
if (JFactory::getConfig()->get('config.ftp_enable')) |
85
|
|
|
{ |
86
|
|
|
return true; |
87
|
|
|
} |
88
|
|
|
else |
89
|
|
|
{ |
90
|
|
|
while (!file_exists($path)) |
91
|
|
|
{ |
92
|
|
|
$path = dirname($path); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
return is_writable($path) || JPath::isOwner($path) || JPath::canChmod($path); |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Check if the installation path exists |
101
|
|
|
* |
102
|
|
|
* @return boolean True if the installation path exists |
103
|
|
|
* |
104
|
|
|
* @since 4.0 |
105
|
|
|
*/ |
106
|
|
|
public static function hasInstallation() |
107
|
|
|
{ |
108
|
|
|
return is_dir(LOCALISEPATH_INSTALLATION); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Retrieve the packages array |
113
|
|
|
* |
114
|
|
|
* @return array |
115
|
|
|
* |
116
|
|
|
* @since 4.0 |
117
|
|
|
*/ |
118
|
|
|
public static function getPackages() |
119
|
|
|
{ |
120
|
|
|
if (empty(static::$packages)) |
121
|
|
|
{ |
122
|
|
|
static::scanPackages(); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
return static::$packages; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Scans the filesystem for language files in each package |
130
|
|
|
* |
131
|
|
|
* @return void |
132
|
|
|
* |
133
|
|
|
* @since 4.0 |
134
|
|
|
*/ |
135
|
|
|
protected static function scanPackages() |
136
|
|
|
{ |
137
|
|
|
$model = JModelLegacy::getInstance('Packages', 'LocaliseModel', array('ignore_request' => true)); |
138
|
|
|
$model->setState('list.start', 0); |
139
|
|
|
$model->setState('list.limit', 0); |
140
|
|
|
$packages = $model->getItems(); |
141
|
|
|
|
142
|
|
|
foreach ($packages as $package) |
143
|
|
|
{ |
144
|
|
|
static::$packages[$package->name] = $package; |
145
|
|
|
|
146
|
|
|
foreach ($package->administrator as $file) |
147
|
|
|
{ |
148
|
|
|
static::$origins['administrator'][$file] = $package->name; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
foreach ($package->site as $file) |
152
|
|
|
{ |
153
|
|
|
static::$origins['site'][$file] = $package->name; |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Retrieves the origin information |
160
|
|
|
* |
161
|
|
|
* @param string $filename The filename to check |
162
|
|
|
* @param string $client The client to check |
163
|
|
|
* |
164
|
|
|
* @return string Origin data |
165
|
|
|
* |
166
|
|
|
* @since 4.0 |
167
|
|
|
*/ |
168
|
|
|
public static function getOrigin($filename, $client) |
169
|
|
|
{ |
170
|
|
|
if ($filename == 'override') |
171
|
|
|
{ |
172
|
|
|
return '_override'; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
// If the $origins array doesn't contain data, fill it |
176
|
|
|
if (empty(static::$origins['site'])) |
177
|
|
|
{ |
178
|
|
|
static::scanPackages(); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
if (isset(static::$origins[$client][$filename])) |
182
|
|
|
{ |
183
|
|
|
return static::$origins[$client][$filename]; |
184
|
|
|
} |
185
|
|
|
else |
186
|
|
|
{ |
187
|
|
|
return '_thirdparty'; |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Scans the filesystem |
193
|
|
|
* |
194
|
|
|
* @param string $client The client to scan |
195
|
|
|
* @param string $type The extension type to scan |
196
|
|
|
* |
197
|
|
|
* @return array |
198
|
|
|
* |
199
|
|
|
* @since 4.0 |
200
|
|
|
*/ |
201
|
|
|
public static function getScans($client = '', $type = '') |
202
|
|
|
{ |
203
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
204
|
|
|
$suffixes = explode(',', $params->get('suffixes', '.sys')); |
205
|
|
|
|
206
|
|
|
$filter_type = $type ? $type : '.'; |
207
|
|
|
$filter_client = $client ? $client : '.'; |
208
|
|
|
$scans = array(); |
209
|
|
|
|
210
|
|
|
// Scan installation folders |
211
|
|
|
if (preg_match("/$filter_client/", 'installation')) |
212
|
|
|
{ |
213
|
|
|
// TODO ;-) |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
// Scan administrator folders |
217
|
|
|
if (preg_match("/$filter_client/", 'administrator')) |
218
|
|
|
{ |
219
|
|
|
// Scan administrator components folders |
220
|
|
View Code Duplication |
if (preg_match("/$filter_type/", 'component')) |
|
|
|
|
221
|
|
|
{ |
222
|
|
|
$scans[] = array( |
223
|
|
|
'prefix' => '', |
224
|
|
|
'suffix' => '', |
225
|
|
|
'type' => 'component', |
226
|
|
|
'client' => 'administrator', |
227
|
|
|
'path' => LOCALISEPATH_ADMINISTRATOR . '/components/', |
228
|
|
|
'folder' => '' |
229
|
|
|
); |
230
|
|
|
|
231
|
|
|
foreach ($suffixes as $suffix) |
232
|
|
|
{ |
233
|
|
|
$scans[] = array( |
234
|
|
|
'prefix' => '', |
235
|
|
|
'suffix' => $suffix, |
236
|
|
|
'type' => 'component', |
237
|
|
|
'client' => 'administrator', |
238
|
|
|
'path' => LOCALISEPATH_ADMINISTRATOR . '/components/', |
239
|
|
|
'folder' => '' |
240
|
|
|
); |
241
|
|
|
} |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
// Scan administrator modules folders |
245
|
|
View Code Duplication |
if (preg_match("/$filter_type/", 'module')) |
|
|
|
|
246
|
|
|
{ |
247
|
|
|
$scans[] = array( |
248
|
|
|
'prefix' => '', |
249
|
|
|
'suffix' => '', |
250
|
|
|
'type' => 'module', |
251
|
|
|
'client' => 'administrator', |
252
|
|
|
'path' => LOCALISEPATH_ADMINISTRATOR . '/modules/', |
253
|
|
|
'folder' => '' |
254
|
|
|
); |
255
|
|
|
|
256
|
|
|
foreach ($suffixes as $suffix) |
257
|
|
|
{ |
258
|
|
|
$scans[] = array( |
259
|
|
|
'prefix' => '', |
260
|
|
|
'suffix' => $suffix, |
261
|
|
|
'type' => 'module', |
262
|
|
|
'client' => 'administrator', |
263
|
|
|
'path' => LOCALISEPATH_ADMINISTRATOR . '/modules/', |
264
|
|
|
'folder' => '' |
265
|
|
|
); |
266
|
|
|
} |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
// Scan administrator templates folders |
270
|
|
View Code Duplication |
if (preg_match("/$filter_type/", 'template')) |
|
|
|
|
271
|
|
|
{ |
272
|
|
|
$scans[] = array( |
273
|
|
|
'prefix' => 'tpl_', |
274
|
|
|
'suffix' => '', |
275
|
|
|
'type' => 'template', |
276
|
|
|
'client' => 'administrator', |
277
|
|
|
'path' => LOCALISEPATH_ADMINISTRATOR . '/templates/', |
278
|
|
|
'folder' => '' |
279
|
|
|
); |
280
|
|
|
|
281
|
|
|
foreach ($suffixes as $suffix) |
282
|
|
|
{ |
283
|
|
|
$scans[] = array( |
284
|
|
|
'prefix' => 'tpl_', |
285
|
|
|
'suffix' => $suffix, |
286
|
|
|
'type' => 'template', |
287
|
|
|
'client' => 'administrator', |
288
|
|
|
'path' => LOCALISEPATH_ADMINISTRATOR . '/templates/', |
289
|
|
|
'folder' => '' |
290
|
|
|
); |
291
|
|
|
} |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
// Scan plugins folders |
295
|
|
|
if (preg_match("/$filter_type/", 'plugin')) |
296
|
|
|
{ |
297
|
|
|
$plugin_types = JFolder::folders(JPATH_PLUGINS); |
298
|
|
|
|
299
|
|
|
foreach ($plugin_types as $plugin_type) |
300
|
|
|
{ |
301
|
|
|
// Scan administrator language folders as this is where plugin languages are installed |
302
|
|
|
$scans[] = array( |
303
|
|
|
'prefix' => 'plg_' . $plugin_type . '_', |
304
|
|
|
'suffix' => '', |
305
|
|
|
'type' => 'plugin', |
306
|
|
|
'client' => 'administrator', |
307
|
|
|
'path' => JPATH_PLUGINS . "/$plugin_type/", |
308
|
|
|
'folder' => '' |
309
|
|
|
); |
310
|
|
|
|
311
|
|
|
foreach ($suffixes as $suffix) |
312
|
|
|
{ |
313
|
|
|
$scans[] = array( |
314
|
|
|
'prefix' => 'plg_' . $plugin_type . '_', |
315
|
|
|
'suffix' => $suffix, |
316
|
|
|
'type' => 'plugin', |
317
|
|
|
'client' => 'administrator', |
318
|
|
|
'path' => JPATH_PLUGINS . "/$plugin_type/", |
319
|
|
|
'folder' => '' |
320
|
|
|
); |
321
|
|
|
} |
322
|
|
|
} |
323
|
|
|
} |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
// Scan site folders |
327
|
|
|
if (preg_match("/$filter_client/", 'site')) |
328
|
|
|
{ |
329
|
|
|
// Scan site components folders |
330
|
|
View Code Duplication |
if (preg_match("/$filter_type/", 'component')) |
|
|
|
|
331
|
|
|
{ |
332
|
|
|
$scans[] = array( |
333
|
|
|
'prefix' => '', |
334
|
|
|
'suffix' => '', |
335
|
|
|
'type' => 'component', |
336
|
|
|
'client' => 'site', |
337
|
|
|
'path' => LOCALISEPATH_SITE . '/components/', |
338
|
|
|
'folder' => '' |
339
|
|
|
); |
340
|
|
|
|
341
|
|
|
foreach ($suffixes as $suffix) |
342
|
|
|
{ |
343
|
|
|
$scans[] = array( |
344
|
|
|
'prefix' => '', |
345
|
|
|
'suffix' => $suffix, |
346
|
|
|
'type' => 'component', |
347
|
|
|
'client' => 'site', |
348
|
|
|
'path' => LOCALISEPATH_SITE . '/components/', |
349
|
|
|
'folder' => '' |
350
|
|
|
); |
351
|
|
|
} |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
// Scan site modules folders |
355
|
|
View Code Duplication |
if (preg_match("/$filter_type/", 'module')) |
|
|
|
|
356
|
|
|
{ |
357
|
|
|
$scans[] = array( |
358
|
|
|
'prefix' => '', |
359
|
|
|
'suffix' => '', |
360
|
|
|
'type' => 'module', |
361
|
|
|
'client' => 'site', |
362
|
|
|
'path' => LOCALISEPATH_SITE . '/modules/', |
363
|
|
|
'folder' => '' |
364
|
|
|
); |
365
|
|
|
|
366
|
|
|
foreach ($suffixes as $suffix) |
367
|
|
|
{ |
368
|
|
|
$scans[] = array( |
369
|
|
|
'prefix' => '', |
370
|
|
|
'suffix' => $suffix, |
371
|
|
|
'type' => 'module', |
372
|
|
|
'client' => 'site', |
373
|
|
|
'path' => LOCALISEPATH_SITE . '/modules/', |
374
|
|
|
'folder' => '' |
375
|
|
|
); |
376
|
|
|
} |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
// Scan site templates folders |
380
|
|
View Code Duplication |
if (preg_match("/$filter_type/", 'template')) |
|
|
|
|
381
|
|
|
{ |
382
|
|
|
$scans[] = array( |
383
|
|
|
'prefix' => 'tpl_', |
384
|
|
|
'suffix' => '', |
385
|
|
|
'type' => 'template', |
386
|
|
|
'client' => 'site', |
387
|
|
|
'path' => LOCALISEPATH_SITE . '/templates/', |
388
|
|
|
'folder' => '' |
389
|
|
|
); |
390
|
|
|
|
391
|
|
|
foreach ($suffixes as $suffix) |
392
|
|
|
{ |
393
|
|
|
$scans[] = array( |
394
|
|
|
'prefix' => 'tpl_', |
395
|
|
|
'suffix' => $suffix, |
396
|
|
|
'type' => 'template', |
397
|
|
|
'client' => 'site', |
398
|
|
|
'path' => LOCALISEPATH_SITE . '/templates/', |
399
|
|
|
'folder' => '' |
400
|
|
|
); |
401
|
|
|
} |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
return $scans; |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
/** |
409
|
|
|
* Get file ID in the database for the given file path |
410
|
|
|
* |
411
|
|
|
* @param string $path Path to lookup |
412
|
|
|
* |
413
|
|
|
* @return integer File ID |
414
|
|
|
* |
415
|
|
|
* @since 4.0 |
416
|
|
|
*/ |
417
|
|
|
public static function getFileId($path) |
418
|
|
|
{ |
419
|
|
|
static $fileIds = null; |
420
|
|
|
|
421
|
|
View Code Duplication |
if (!isset($fileIds)) |
|
|
|
|
422
|
|
|
{ |
423
|
|
|
$db = JFactory::getDbo(); |
424
|
|
|
|
425
|
|
|
$db->setQuery( |
426
|
|
|
$db->getQuery(true) |
427
|
|
|
->select($db->quoteName(array('id', 'path'))) |
428
|
|
|
->from($db->quoteName('#__localise')) |
429
|
|
|
); |
430
|
|
|
|
431
|
|
|
$fileIds = $db->loadObjectList('path'); |
432
|
|
|
} |
433
|
|
|
|
434
|
|
|
if (is_file($path) || preg_match('/.ini$/', $path)) |
435
|
|
|
{ |
436
|
|
|
if (!array_key_exists($path, $fileIds)) |
437
|
|
|
{ |
438
|
|
|
JTable::addIncludePath(JPATH_COMPONENT . '/tables'); |
439
|
|
|
|
440
|
|
|
/* @type LocaliseTableLocalise $table */ |
441
|
|
|
$table = JTable::getInstance('Localise', 'LocaliseTable'); |
442
|
|
|
$table->path = $path; |
443
|
|
|
$table->store(); |
444
|
|
|
|
445
|
|
|
$fileIds[$path] = new stdClass; |
446
|
|
|
$fileIds[$path]->id = $table->id; |
447
|
|
|
} |
448
|
|
|
|
449
|
|
|
return $fileIds[$path]->id; |
450
|
|
|
} |
451
|
|
|
else |
452
|
|
|
{ |
453
|
|
|
$id = 0; |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
return $id; |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* Get file path in the database for the given file id |
461
|
|
|
* |
462
|
|
|
* @param integer $id Id to lookup |
463
|
|
|
* |
464
|
|
|
* @return string File Path |
465
|
|
|
* |
466
|
|
|
* @since 4.0 |
467
|
|
|
*/ |
468
|
|
|
public static function getFilePath($id) |
469
|
|
|
{ |
470
|
|
|
static $filePaths = null; |
471
|
|
|
|
472
|
|
View Code Duplication |
if (!isset($filePaths)) |
|
|
|
|
473
|
|
|
{ |
474
|
|
|
$db = JFactory::getDbo(); |
475
|
|
|
|
476
|
|
|
$db->setQuery( |
477
|
|
|
$db->getQuery(true) |
478
|
|
|
->select($db->quoteName(array('id', 'path'))) |
479
|
|
|
->from($db->quoteName('#__localise')) |
480
|
|
|
); |
481
|
|
|
|
482
|
|
|
$filePaths = $db->loadObjectList('id'); |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
return array_key_exists("$id", $filePaths) ? |
486
|
|
|
$filePaths["$id"]->path : ''; |
487
|
|
|
} |
488
|
|
|
|
489
|
|
|
/** |
490
|
|
|
* Determine if a package at given path is core or not. |
491
|
|
|
* |
492
|
|
|
* @param string $path Path to lookup |
493
|
|
|
* |
494
|
|
|
* @return mixed null if file is invalid | True if core else false. |
495
|
|
|
* |
496
|
|
|
* @since 4.0 |
497
|
|
|
*/ |
498
|
|
|
public static function isCorePackage($path) |
499
|
|
|
{ |
500
|
|
|
if (is_file($path) || preg_match('/.ini$/', $path)) |
501
|
|
|
{ |
502
|
|
|
$xml = simplexml_load_file($path); |
503
|
|
|
|
504
|
|
|
return ((string) $xml->attributes()->core) == 'true'; |
505
|
|
|
} |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
/** |
509
|
|
|
* Find a translation file |
510
|
|
|
* |
511
|
|
|
* @param string $client Client to lookup |
512
|
|
|
* @param string $tag Language tag to lookup |
513
|
|
|
* @param string $filename Filename to lookup |
514
|
|
|
* |
515
|
|
|
* @return string Path to the requested file |
516
|
|
|
* |
517
|
|
|
* @since 4.0 |
518
|
|
|
*/ |
519
|
|
|
public static function findTranslationPath($client, $tag, $filename) |
520
|
|
|
{ |
521
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
522
|
|
|
$priority = $params->get('priority', '0') == '0' ? 'global' : 'local'; |
523
|
|
|
$path = static::getTranslationPath($client, $tag, $filename, $priority); |
524
|
|
|
|
525
|
|
|
if (!is_file($path)) |
526
|
|
|
{ |
527
|
|
|
$priority = $params->get('priority', '0') == '0' ? 'local' : 'global'; |
528
|
|
|
$path = static::getTranslationPath($client, $tag, $filename, $priority); |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
return $path; |
532
|
|
|
} |
533
|
|
|
|
534
|
|
|
/** |
535
|
|
|
* Get a translation path |
536
|
|
|
* |
537
|
|
|
* @param string $client Client to lookup |
538
|
|
|
* @param string $tag Language tag to lookup |
539
|
|
|
* @param string $filename Filename to lookup |
540
|
|
|
* @param string $storage Storage location to check |
541
|
|
|
* |
542
|
|
|
* @return string Path to the requested file |
543
|
|
|
* |
544
|
|
|
* @since 4.0 |
545
|
|
|
*/ |
546
|
|
|
public static function getTranslationPath($client, $tag, $filename, $storage) |
547
|
|
|
{ |
548
|
|
|
if ($filename == 'override') |
549
|
|
|
{ |
550
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/overrides/$tag.override.ini"; |
551
|
|
|
} |
552
|
|
|
elseif ($filename == 'joomla') |
553
|
|
|
{ |
554
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/$tag/$tag.ini"; |
555
|
|
|
} |
556
|
|
|
elseif ($storage == 'global') |
557
|
|
|
{ |
558
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/$tag/$tag.$filename.ini"; |
559
|
|
|
} |
560
|
|
|
else |
561
|
|
|
{ |
562
|
|
|
$parts = explode('.', $filename); |
563
|
|
|
$extension = $parts[0]; |
564
|
|
|
|
565
|
|
|
switch (substr($extension, 0, 3)) |
566
|
|
|
{ |
567
|
|
View Code Duplication |
case 'com': |
|
|
|
|
568
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/components/$extension/language/$tag/$tag.$filename.ini"; |
569
|
|
|
|
570
|
|
|
break; |
571
|
|
|
|
572
|
|
View Code Duplication |
case 'mod': |
|
|
|
|
573
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/modules/$extension/language/$tag/$tag.$filename.ini"; |
574
|
|
|
|
575
|
|
|
break; |
576
|
|
|
|
577
|
|
|
case 'plg': |
578
|
|
|
$parts = explode('_', $extension); |
579
|
|
|
$group = $parts[1]; |
580
|
|
|
$parts = explode('.', $filename); |
581
|
|
|
$pluginname = $parts[0]; |
582
|
|
|
$plugin = substr($pluginname, 5 + strlen($group)); |
583
|
|
|
$path = JPATH_PLUGINS . "/$group/$plugin/language/$tag/$tag.$filename.ini"; |
584
|
|
|
|
585
|
|
|
break; |
586
|
|
|
|
587
|
|
View Code Duplication |
case 'tpl': |
|
|
|
|
588
|
|
|
$template = substr($extension, 4); |
589
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/templates/$template/language/$tag/$tag.$filename.ini"; |
590
|
|
|
|
591
|
|
|
break; |
592
|
|
|
|
593
|
|
|
case 'lib': |
594
|
|
|
$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/$tag/$tag.$filename.ini"; |
595
|
|
|
|
596
|
|
|
if (!is_file($path)) |
597
|
|
|
{ |
598
|
|
|
$path = $client == 'administrator' ? 'LOCALISEPATH_' . 'SITE' : 'LOCALISEPATH_' . 'ADMINISTRATOR' . "/language/$tag/$tag.$filename.ini"; |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
break; |
602
|
|
|
|
603
|
|
|
default : |
604
|
|
|
$path = ''; |
605
|
|
|
|
606
|
|
|
break; |
607
|
|
|
} |
608
|
|
|
} |
609
|
|
|
|
610
|
|
|
return $path; |
611
|
|
|
} |
612
|
|
|
|
613
|
|
|
/** |
614
|
|
|
* Load a language file for translating the package name |
615
|
|
|
* |
616
|
|
|
* @param string $extension The extension to load |
617
|
|
|
* @param string $client The client from where to load the file |
618
|
|
|
* |
619
|
|
|
* @return void |
620
|
|
|
* |
621
|
|
|
* @since 4.0 |
622
|
|
|
*/ |
623
|
|
|
public static function loadLanguage($extension, $client) |
624
|
|
|
{ |
625
|
|
|
$extension = strtolower($extension); |
626
|
|
|
$lang = JFactory::getLanguage(); |
627
|
|
|
$prefix = substr($extension, 0, 3); |
628
|
|
|
|
629
|
|
|
switch ($prefix) |
630
|
|
|
{ |
631
|
|
View Code Duplication |
case 'com': |
|
|
|
|
632
|
|
|
$lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)), null, false, true) |
633
|
|
|
|| $lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)) . "/components/$extension/", null, false, true); |
634
|
|
|
|
635
|
|
|
break; |
636
|
|
|
|
637
|
|
View Code Duplication |
case 'mod': |
|
|
|
|
638
|
|
|
$lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)), null, false, true) |
639
|
|
|
|| $lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)) . "/modules/$extension/", null, false, true); |
640
|
|
|
|
641
|
|
|
break; |
642
|
|
|
|
643
|
|
|
case 'plg': |
644
|
|
|
$lang->load($extension, 'LOCALISEPATH_' . 'ADMINISTRATOR', null, false, true) |
645
|
|
|
|| $lang->load($extension, LOCALISEPATH_ADMINISTRATOR . "/components/$extension/", null, false, true); |
646
|
|
|
|
647
|
|
|
break; |
648
|
|
|
|
649
|
|
View Code Duplication |
case 'tpl': |
|
|
|
|
650
|
|
|
$template = substr($extension, 4); |
651
|
|
|
$lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)), null, false, true) |
652
|
|
|
|| $lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)) . "/templates/$template/", null, false, true); |
653
|
|
|
|
654
|
|
|
break; |
655
|
|
|
|
656
|
|
|
case 'lib': |
657
|
|
|
case 'fil': |
658
|
|
|
case 'pkg': |
659
|
|
|
$lang->load($extension, JPATH_ROOT, null, false, true); |
660
|
|
|
|
661
|
|
|
break; |
662
|
|
|
} |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
/** |
666
|
|
|
* Parses the sections of a language file |
667
|
|
|
* |
668
|
|
|
* @param string $filename The filename to parse |
669
|
|
|
* |
670
|
|
|
* @return array Array containing the file data |
671
|
|
|
* |
672
|
|
|
* @since 4.0 |
673
|
|
|
*/ |
674
|
|
|
public static function parseSections($filename) |
675
|
|
|
{ |
676
|
|
|
static $sections = array(); |
677
|
|
|
|
678
|
|
|
if (!array_key_exists($filename, $sections)) |
679
|
|
|
{ |
680
|
|
|
if (file_exists($filename)) |
681
|
|
|
{ |
682
|
|
|
$error = ''; |
683
|
|
|
|
684
|
|
|
if (!defined('_QQ_')) |
685
|
|
|
{ |
686
|
|
|
define('_QQ_', '"'); |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
ini_set('track_errors', '1'); |
690
|
|
|
|
691
|
|
|
$contents = file_get_contents($filename); |
692
|
|
|
$contents = str_replace('_QQ_', '"\""', $contents); |
693
|
|
|
$strings = @parse_ini_string($contents, true); |
694
|
|
|
|
695
|
|
|
if (!empty($php_errormsg)) |
696
|
|
|
{ |
697
|
|
|
$error = "Error parsing " . basename($filename) . ": $php_errormsg"; |
698
|
|
|
} |
699
|
|
|
|
700
|
|
|
ini_restore('track_errors'); |
701
|
|
|
|
702
|
|
|
if ($strings !== false) |
703
|
|
|
{ |
704
|
|
|
$default = array(); |
705
|
|
|
|
706
|
|
|
foreach ($strings as $key => $value) |
707
|
|
|
{ |
708
|
|
|
if (is_string($value)) |
709
|
|
|
{ |
710
|
|
|
$default[$key] = $value; |
711
|
|
|
|
712
|
|
|
unset($strings[$key]); |
713
|
|
|
} |
714
|
|
|
else |
715
|
|
|
{ |
716
|
|
|
break; |
717
|
|
|
} |
718
|
|
|
} |
719
|
|
|
|
720
|
|
|
if (!empty($default)) |
721
|
|
|
{ |
722
|
|
|
$strings = array_merge(array('Default' => $default), $strings); |
723
|
|
|
} |
724
|
|
|
|
725
|
|
|
$keys = array(); |
726
|
|
|
|
727
|
|
|
foreach ($strings as $section => $value) |
728
|
|
|
{ |
729
|
|
|
foreach ($value as $key => $string) |
730
|
|
|
{ |
731
|
|
|
$keys[$key] = $strings[$section][$key]; |
732
|
|
|
} |
733
|
|
|
} |
734
|
|
|
} |
735
|
|
|
else |
736
|
|
|
{ |
737
|
|
|
$keys = false; |
738
|
|
|
} |
739
|
|
|
|
740
|
|
|
$sections[$filename] = array('sections' => $strings, 'keys' => $keys, 'error' => $error); |
741
|
|
|
} |
742
|
|
|
else |
743
|
|
|
{ |
744
|
|
|
$sections[$filename] = array('sections' => array(), 'keys' => array(), 'error' => ''); |
745
|
|
|
} |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
if (!empty($sections[$filename]['error'])) |
749
|
|
|
{ |
750
|
|
|
$model = JModelLegacy::getInstance('Translation', 'LocaliseModel'); |
751
|
|
|
$model->setError($sections[$filename]['error']); |
752
|
|
|
} |
753
|
|
|
|
754
|
|
|
return $sections[$filename]; |
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
/** |
758
|
|
|
* Gets the files to use as source reference from Github |
759
|
|
|
* |
760
|
|
|
* @param array $gh_data Array with the required data |
761
|
|
|
* |
762
|
|
|
* @return array |
763
|
|
|
* |
764
|
|
|
* @since 4.11 |
765
|
|
|
*/ |
766
|
|
|
public static function getSourceGithubfiles($gh_data = array()) |
767
|
|
|
{ |
768
|
|
|
if (!empty($gh_data)) |
769
|
|
|
{ |
770
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
771
|
|
|
$ref_tag = $params->get('reference', 'en-GB'); |
772
|
|
|
$saved_ref = $params->get('customisedref', '0'); |
773
|
|
|
$allow_develop = $params->get('gh_allow_develop', 0); |
774
|
|
|
$gh_client = $gh_data['github_client']; |
775
|
|
|
$customisedref = $saved_ref; |
776
|
|
|
$last_sources = self::getLastsourcereference(); |
777
|
|
|
$last_source = $last_sources[$gh_client]; |
778
|
|
|
|
779
|
|
|
$versions_path = JPATH_ROOT |
780
|
|
|
. '/administrator/components/com_localise/customisedref/stable_joomla_releases.txt'; |
781
|
|
|
|
782
|
|
|
$versions_file = file_get_contents($versions_path); |
783
|
|
|
$versions = preg_split("/\\r\\n|\\r|\\n/", $versions_file); |
784
|
|
|
|
785
|
|
|
if ($saved_ref != '0' && !in_array($customisedref, $versions)) |
786
|
|
|
{ |
787
|
|
|
// Ensure from translations view that we have updated the last one released only when no maches. |
788
|
|
|
$search_releases = self::getReleases(); |
|
|
|
|
789
|
|
|
$versions_file = file_get_contents($versions_path); |
790
|
|
|
$versions = preg_split("/\\r\\n|\\r|\\n/", $versions_file); |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
$installed_version = new JVersion; |
794
|
|
|
$installed_version = $installed_version->getShortVersion(); |
795
|
|
|
|
796
|
|
|
$core_paths['administrator'] = 'administrator/language/en-GB'; |
|
|
|
|
797
|
|
|
$core_paths['site'] = 'language/en-GB'; |
798
|
|
|
$core_paths['installation'] = 'installation/language/en-GB'; |
799
|
|
|
|
800
|
|
|
if ($saved_ref == '0') |
801
|
|
|
{ |
802
|
|
|
// It will use core language folders. |
803
|
|
|
$customisedref = "Local installed instance ($installed_version??)"; |
804
|
|
|
} |
805
|
|
|
else |
806
|
|
|
{ |
807
|
|
|
// It will use language folders with other stored versions. |
808
|
|
|
$custom_client_path = JPATH_ROOT . '/media/com_localise/customisedref/github/' |
809
|
|
|
. $gh_data['github_client'] |
810
|
|
|
. '/' |
811
|
|
|
. $customisedref; |
812
|
|
|
$custom_client_path = JFolder::makeSafe($custom_client_path); |
813
|
|
|
} |
814
|
|
|
|
815
|
|
|
// If reference tag is not en-GB is not required try it |
816
|
|
|
if ($ref_tag != 'en-GB' && $allow_develop == 1) |
817
|
|
|
{ |
818
|
|
|
JFactory::getApplication()->enqueueMessage( |
819
|
|
|
JText::_('COM_LOCALISE_ERROR_GETTING_UNALLOWED_CONFIGURATION'), |
820
|
|
|
'warning'); |
821
|
|
|
|
822
|
|
|
return false; |
823
|
|
|
} |
824
|
|
|
|
825
|
|
|
// If not knowed Joomla version is not required try it |
826
|
|
|
if ($saved_ref != '0' && !in_array($customisedref, $versions) && $allow_develop == 1) |
827
|
|
|
{ |
828
|
|
|
JFactory::getApplication()->enqueueMessage( |
829
|
|
|
JText::sprintf('COM_LOCALISE_ERROR_GITHUB_GETTING_LOCAL_INSTALLED_FILES', $customisedref), |
830
|
|
|
'warning'); |
831
|
|
|
|
832
|
|
|
$option = '0'; |
833
|
|
|
$revert = self::setCustomisedsource($option); |
|
|
|
|
834
|
|
|
$save_last = self::saveLastsourcereference($gh_data['github_client'], ''); |
|
|
|
|
835
|
|
|
|
836
|
|
|
return false; |
837
|
|
|
} |
838
|
|
|
|
839
|
|
|
// If feature is disabled but last used files are disctinct to default ones |
840
|
|
|
// Is required make notice that we are coming back to local installed instance version. |
841
|
|
|
if ($saved_ref != '0' && !empty($last_source) && $last_source != '0' && $allow_develop == 0) |
842
|
|
|
{ |
843
|
|
|
$customisedref = $installed_version; |
|
|
|
|
844
|
|
|
|
845
|
|
|
JFactory::getApplication()->enqueueMessage( |
846
|
|
|
JText::sprintf('COM_LOCALISE_NOTICE_DISABLED_ALLOW_DEVELOP_WITHOUT_LOCAL_SET', |
847
|
|
|
$last_source, |
848
|
|
|
$installed_version, |
849
|
|
|
$gh_client |
850
|
|
|
), |
851
|
|
|
'notice' |
852
|
|
|
); |
853
|
|
|
|
854
|
|
|
$option = '0'; |
855
|
|
|
$revert = self::setCustomisedsource($option); |
|
|
|
|
856
|
|
|
$save_last = self::saveLastsourcereference($gh_data['github_client'], ''); |
|
|
|
|
857
|
|
|
|
858
|
|
|
return true; |
859
|
|
|
} |
860
|
|
|
|
861
|
|
|
// If not knowed Joomla version and feature is disabled is not required try it |
862
|
|
|
if ($saved_ref != '0' && !in_array($customisedref, $versions) && $allow_develop == 0) |
863
|
|
|
{ |
864
|
|
|
return false; |
865
|
|
|
} |
866
|
|
|
|
867
|
|
|
// If configured to local installed instance there is nothing to get from Github |
868
|
|
|
if ($saved_ref == '0') |
869
|
|
|
{ |
870
|
|
|
$save_last = self::saveLastsourcereference($gh_data['github_client'], ''); |
|
|
|
|
871
|
|
|
|
872
|
|
|
return true; |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
$xml_file = $custom_client_path . '/en-GB.xml'; |
|
|
|
|
876
|
|
|
|
877
|
|
|
// Unrequired move or update files again |
878
|
|
|
if ($saved_ref != '0' && $installed_version == $last_source && JFile::exists($xml_file)) |
879
|
|
|
{ |
880
|
|
|
return false; |
881
|
|
|
} |
882
|
|
|
|
883
|
|
|
$gh_data['allow_develop'] = $allow_develop; |
884
|
|
|
$gh_data['customisedref'] = $customisedref; |
885
|
|
|
$gh_target = self::getCustomisedsource($gh_data); |
886
|
|
|
$gh_paths = array(); |
887
|
|
|
$gh_user = $gh_target['user']; |
888
|
|
|
$gh_project = $gh_target['project']; |
889
|
|
|
$gh_branch = $gh_target['branch']; |
890
|
|
|
$gh_token = $params->get('gh_token', ''); |
891
|
|
|
$gh_paths['administrator'] = 'administrator/language/en-GB'; |
892
|
|
|
$gh_paths['site'] = 'language/en-GB'; |
893
|
|
|
$gh_paths['installation'] = 'installation/language/en-GB'; |
894
|
|
|
|
895
|
|
|
$reference_client_path = JPATH_ROOT . '/' . $gh_paths[$gh_client]; |
896
|
|
|
$reference_client_path = JFolder::makeSafe($reference_client_path); |
897
|
|
|
|
898
|
|
|
if (JFile::exists($xml_file)) |
899
|
|
|
{ |
900
|
|
|
// We have done this trunk and is not required get the files from Github again. |
901
|
|
|
$update_files = self::updateSourcereference($gh_client, $custom_client_path); |
902
|
|
|
|
903
|
|
|
if ($update_files == false) |
|
|
|
|
904
|
|
|
{ |
905
|
|
|
return false; |
906
|
|
|
} |
907
|
|
|
|
908
|
|
|
$save_last = self::saveLastsourcereference($gh_data['github_client'], $customisedref); |
|
|
|
|
909
|
|
|
|
910
|
|
|
return true; |
911
|
|
|
} |
912
|
|
|
|
913
|
|
|
$options = new JRegistry; |
914
|
|
|
|
915
|
|
View Code Duplication |
if (!empty($gh_token)) |
|
|
|
|
916
|
|
|
{ |
917
|
|
|
$options->set('gh.token', $gh_token); |
918
|
|
|
$github = new Github($options); |
919
|
|
|
} |
920
|
|
|
else |
921
|
|
|
{ |
922
|
|
|
// Without a token runs fatal. |
923
|
|
|
// $github = new JGithub; |
924
|
|
|
|
925
|
|
|
// Trying with a 'read only' public repositories token |
926
|
|
|
// But base 64 encoded to avoid Github alarms sharing it. |
927
|
|
|
$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA=='); |
928
|
|
|
$options->set('gh.token', $gh_token); |
929
|
|
|
$github = new Github($options); |
930
|
|
|
} |
931
|
|
|
|
932
|
|
|
try |
933
|
|
|
{ |
934
|
|
|
$repostoryfiles = $github->repositories->contents->get( |
935
|
|
|
$gh_user, |
936
|
|
|
$gh_project, |
937
|
|
|
$gh_paths[$gh_client], |
938
|
|
|
$gh_branch |
939
|
|
|
); |
940
|
|
|
} |
941
|
|
|
catch (Exception $e) |
942
|
|
|
{ |
943
|
|
|
JFactory::getApplication()->enqueueMessage( |
944
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_REPOSITORY_FILES'), |
945
|
|
|
'warning'); |
946
|
|
|
|
947
|
|
|
return false; |
948
|
|
|
} |
949
|
|
|
|
950
|
|
|
if (!JFolder::exists($custom_client_path)) |
951
|
|
|
{ |
952
|
|
|
$create_folder = self::createFolder($gh_data, $index = 'true'); |
953
|
|
|
|
954
|
|
|
if ($create_folder == false) |
|
|
|
|
955
|
|
|
{ |
956
|
|
|
return false; |
957
|
|
|
} |
958
|
|
|
} |
959
|
|
|
|
960
|
|
|
$all_files_list = self::getLanguagefileslist($custom_client_path); |
961
|
|
|
$ini_files_list = self::getInifileslist($custom_client_path); |
|
|
|
|
962
|
|
|
|
963
|
|
|
$files_to_include = array(); |
964
|
|
|
|
965
|
|
|
foreach ($repostoryfiles as $repostoryfile) |
966
|
|
|
{ |
967
|
|
|
$file_to_include = $repostoryfile->name; |
968
|
|
|
$file_path = JFolder::makeSafe($custom_client_path . '/' . $file_to_include); |
969
|
|
|
$reference_file_path = JFolder::makeSafe($reference_client_path . '/' . $file_to_include); |
|
|
|
|
970
|
|
|
|
971
|
|
|
$custom_file = $github->repositories->contents->get( |
972
|
|
|
$gh_user, |
973
|
|
|
$gh_project, |
974
|
|
|
$repostoryfile->path, |
975
|
|
|
$gh_branch |
976
|
|
|
); |
977
|
|
|
|
978
|
|
|
$files_to_include[] = $file_to_include; |
979
|
|
|
|
980
|
|
|
if (!empty($custom_file) && isset($custom_file->content)) |
981
|
|
|
{ |
982
|
|
|
$file_to_include = $repostoryfile->name; |
|
|
|
|
983
|
|
|
$file_contents = base64_decode($custom_file->content); |
984
|
|
|
JFile::write($file_path, $file_contents); |
985
|
|
|
|
986
|
|
|
if (!JFile::exists($file_path)) |
987
|
|
|
{ |
988
|
|
|
JFactory::getApplication()->enqueueMessage( |
989
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_DEV_FILE'), |
990
|
|
|
'warning'); |
991
|
|
|
|
992
|
|
|
return false; |
993
|
|
|
} |
994
|
|
|
} |
995
|
|
|
} |
996
|
|
|
|
997
|
|
|
if (!empty($all_files_list) && !empty($files_to_include)) |
998
|
|
|
{ |
999
|
|
|
// For files not present yet. |
1000
|
|
|
$files_to_delete = array_diff($all_files_list, $files_to_include); |
1001
|
|
|
|
1002
|
|
|
if (!empty($files_to_delete)) |
1003
|
|
|
{ |
1004
|
|
|
foreach ($files_to_delete as $file_to_delete) |
1005
|
|
|
{ |
1006
|
|
|
if ($file_to_delete != 'index.html') |
1007
|
|
|
{ |
1008
|
|
|
$file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete); |
1009
|
|
|
JFile::delete($file_path); |
1010
|
|
|
|
1011
|
|
|
if (JFile::exists($file_path)) |
1012
|
|
|
{ |
1013
|
|
|
JFactory::getApplication()->enqueueMessage( |
1014
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_FILE_TO_DELETE_IS_PRESENT'), |
1015
|
|
|
'warning'); |
1016
|
|
|
|
1017
|
|
|
return false; |
1018
|
|
|
} |
1019
|
|
|
} |
1020
|
|
|
} |
1021
|
|
|
} |
1022
|
|
|
} |
1023
|
|
|
|
1024
|
|
|
if (JFile::exists($xml_file)) |
1025
|
|
|
{ |
1026
|
|
|
// We have done this trunk. |
1027
|
|
|
|
1028
|
|
|
// So we can move the customised source reference files to core client folder |
1029
|
|
|
$update_files = self::updateSourcereference($gh_client, $custom_client_path); |
1030
|
|
|
|
1031
|
|
|
if ($update_files == false) |
|
|
|
|
1032
|
|
|
{ |
1033
|
|
|
return false; |
1034
|
|
|
} |
1035
|
|
|
|
1036
|
|
|
$save_last = self::saveLastsourcereference($gh_data['github_client'], $customisedref); |
|
|
|
|
1037
|
|
|
|
1038
|
|
|
JFactory::getApplication()->enqueueMessage( |
1039
|
|
|
JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_GETS_A_SOURCE_FULL_SET', $customisedref), |
1040
|
|
|
'notice'); |
1041
|
|
|
|
1042
|
|
|
return true; |
1043
|
|
|
} |
1044
|
|
|
|
1045
|
|
|
JFactory::getApplication()->enqueueMessage( |
1046
|
|
|
JText::sprintf('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_GET_A_FULL_SOURCE_SET', $customisedref), |
1047
|
|
|
'warning'); |
1048
|
|
|
|
1049
|
|
|
return false; |
1050
|
|
|
} |
1051
|
|
|
|
1052
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_NO_DATA_PRESENT'), 'warning'); |
1053
|
|
|
|
1054
|
|
|
return false; |
1055
|
|
|
} |
1056
|
|
|
|
1057
|
|
|
/** |
1058
|
|
|
* Gets the stable Joomla releases list. |
1059
|
|
|
* |
1060
|
|
|
* @return array |
1061
|
|
|
* |
1062
|
|
|
* @since 4.11 |
1063
|
|
|
*/ |
1064
|
|
|
public static function getReleases() |
1065
|
|
|
{ |
1066
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
1067
|
|
|
$versions_path = JPATH_ROOT |
1068
|
|
|
. '/administrator/components/com_localise/customisedref/stable_joomla_releases.txt'; |
1069
|
|
|
$versions_file = file_get_contents($versions_path); |
1070
|
|
|
$versions = preg_split("/\\r\\n|\\r|\\n/", $versions_file); |
1071
|
|
|
|
1072
|
|
|
$gh_user = 'joomla'; |
1073
|
|
|
$gh_project = 'joomla-cms'; |
1074
|
|
|
$gh_token = $params->get('gh_token', ''); |
1075
|
|
|
|
1076
|
|
|
$options = new JRegistry; |
1077
|
|
|
|
1078
|
|
View Code Duplication |
if (!empty($gh_token)) |
|
|
|
|
1079
|
|
|
{ |
1080
|
|
|
$options->set('gh.token', $gh_token); |
1081
|
|
|
$github = new Github($options); |
1082
|
|
|
} |
1083
|
|
|
else |
1084
|
|
|
{ |
1085
|
|
|
// Without a token runs fatal. |
1086
|
|
|
// $github = new JGithub; |
1087
|
|
|
|
1088
|
|
|
// Trying with a 'read only' public repositories token |
1089
|
|
|
// But base 64 encoded to avoid Github alarms sharing it. |
1090
|
|
|
$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA=='); |
1091
|
|
|
$options->set('gh.token', $gh_token); |
1092
|
|
|
$github = new Github($options); |
1093
|
|
|
} |
1094
|
|
|
|
1095
|
|
|
try |
1096
|
|
|
{ |
1097
|
|
|
$releases = $github->repositories->get( |
1098
|
|
|
$gh_user, |
1099
|
|
|
$gh_project . '/releases' |
1100
|
|
|
); |
1101
|
|
|
|
1102
|
|
View Code Duplication |
foreach ($releases as $release) |
|
|
|
|
1103
|
|
|
{ |
1104
|
|
|
$tag_name = $release->tag_name; |
1105
|
|
|
$tag_part = explode(".", $tag_name); |
1106
|
|
|
$undoted = str_replace('.', '', $tag_name); |
1107
|
|
|
$excluded = 0; |
1108
|
|
|
|
1109
|
|
|
if (version_compare(JVERSION[0], '2', 'eq')) |
1110
|
|
|
{ |
1111
|
|
|
$excluded = 1; |
1112
|
|
|
} |
1113
|
|
|
elseif (version_compare(JVERSION[0], '3', 'eq')) |
1114
|
|
|
{ |
1115
|
|
|
if ($tag_part[0] != '3') |
1116
|
|
|
{ |
1117
|
|
|
$excluded = 1; |
1118
|
|
|
} |
1119
|
|
|
} |
1120
|
|
|
elseif (version_compare(JVERSION[0], '4', 'ge')) |
1121
|
|
|
{ |
1122
|
|
|
if ($tag_part[0] == '4' || $tag_part[0] == '3') |
1123
|
|
|
{ |
1124
|
|
|
$excluded = 0; |
1125
|
|
|
} |
1126
|
|
|
else |
1127
|
|
|
{ |
1128
|
|
|
$excluded = 1; |
1129
|
|
|
} |
1130
|
|
|
} |
1131
|
|
|
|
1132
|
|
|
// Filtering by "is_numeric" disable betas or similar releases. |
1133
|
|
|
if ($params->get('pre_stable', '0') == '0') |
1134
|
|
|
{ |
1135
|
|
|
if (!in_array($tag_name, $versions) && is_numeric($undoted) && $excluded == 0) |
1136
|
|
|
{ |
1137
|
|
|
$versions[] = $tag_name; |
1138
|
|
|
JFactory::getApplication()->enqueueMessage( |
1139
|
|
|
JText::sprintf('COM_LOCALISE_NOTICE_NEW_VERSION_DETECTED', $tag_name), |
1140
|
|
|
'notice'); |
1141
|
|
|
} |
1142
|
|
|
} |
1143
|
|
|
else |
1144
|
|
|
{ |
1145
|
|
|
if (!in_array($tag_name, $versions) && $excluded == 0) |
1146
|
|
|
{ |
1147
|
|
|
$versions[] = $tag_name; |
1148
|
|
|
JFactory::getApplication()->enqueueMessage( |
1149
|
|
|
JText::sprintf('COM_LOCALISE_NOTICE_NEW_VERSION_DETECTED', $tag_name), |
1150
|
|
|
'notice'); |
1151
|
|
|
} |
1152
|
|
|
} |
1153
|
|
|
} |
1154
|
|
|
} |
1155
|
|
|
catch (Exception $e) |
1156
|
|
|
{ |
1157
|
|
|
JFactory::getApplication()->enqueueMessage( |
1158
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_RELEASES'), |
1159
|
|
|
'warning'); |
1160
|
|
|
} |
1161
|
|
|
|
1162
|
|
|
arsort($versions); |
1163
|
|
|
|
1164
|
|
|
$versions_file = ''; |
1165
|
|
|
|
1166
|
|
|
foreach ($versions as $id => $version) |
1167
|
|
|
{ |
1168
|
|
|
if (!empty($version)) |
1169
|
|
|
{ |
1170
|
|
|
$versions_file .= $version . "\n"; |
1171
|
|
|
} |
1172
|
|
|
} |
1173
|
|
|
|
1174
|
|
|
JFile::write($versions_path, $versions_file); |
1175
|
|
|
|
1176
|
|
|
return $versions; |
1177
|
|
|
} |
1178
|
|
|
|
1179
|
|
|
/** |
1180
|
|
|
* Save the last en-GB source version used as reference. |
1181
|
|
|
* |
1182
|
|
|
* @param string $client The client |
1183
|
|
|
* |
1184
|
|
|
* @param string $customisedref The version number |
1185
|
|
|
* |
1186
|
|
|
* @return boolean |
1187
|
|
|
* |
1188
|
|
|
* @since 4.11 |
1189
|
|
|
*/ |
1190
|
|
|
public static function saveLastsourcereference($client = '', $customisedref = '') |
1191
|
|
|
{ |
1192
|
|
|
$last_reference_file = JPATH_COMPONENT_ADMINISTRATOR |
1193
|
|
|
. '/customisedref/' |
1194
|
|
|
. $client |
1195
|
|
|
. '_last_source_ref.txt'; |
1196
|
|
|
|
1197
|
|
|
$file_contents = $customisedref . "\n"; |
1198
|
|
|
|
1199
|
|
|
if (!JFile::write($last_reference_file, $file_contents)) |
1200
|
|
|
{ |
1201
|
|
|
return false; |
1202
|
|
|
} |
1203
|
|
|
|
1204
|
|
|
return true; |
1205
|
|
|
} |
1206
|
|
|
|
1207
|
|
|
/** |
1208
|
|
|
* Gets the last en-GB source reference version moved to the core folders. |
1209
|
|
|
* |
1210
|
|
|
* @return array |
1211
|
|
|
* |
1212
|
|
|
* @since 4.11 |
1213
|
|
|
*/ |
1214
|
|
|
public static function getLastsourcereference() |
1215
|
|
|
{ |
1216
|
|
|
$last_source_reference = array(); |
1217
|
|
|
$last_source_reference['administrator'] = ''; |
1218
|
|
|
$last_source_reference['site'] = ''; |
1219
|
|
|
$last_source_reference['installation'] = ''; |
1220
|
|
|
|
1221
|
|
|
$clients = array('administrator', 'site', 'installation'); |
1222
|
|
|
|
1223
|
|
|
foreach ($clients as $client) |
1224
|
|
|
{ |
1225
|
|
|
$last_reference_file = JPATH_COMPONENT_ADMINISTRATOR |
1226
|
|
|
. '/customisedref/' |
1227
|
|
|
. $client |
1228
|
|
|
. '_last_source_ref.txt'; |
1229
|
|
|
|
1230
|
|
|
if (JFile::exists($last_reference_file)) |
1231
|
|
|
{ |
1232
|
|
|
$file_contents = file_get_contents($last_reference_file); |
1233
|
|
|
$lines = preg_split("/\\r\\n|\\r|\\n/", $file_contents); |
1234
|
|
|
|
1235
|
|
|
foreach ($lines as $line) |
1236
|
|
|
{ |
1237
|
|
|
if (!empty($line)) |
1238
|
|
|
{ |
1239
|
|
|
$last_source_reference[$client] = $line; |
1240
|
|
|
} |
1241
|
|
|
} |
1242
|
|
|
} |
1243
|
|
|
} |
1244
|
|
|
|
1245
|
|
|
return $last_source_reference; |
1246
|
|
|
} |
1247
|
|
|
|
1248
|
|
|
/** |
1249
|
|
|
* Gets the reference name to use at Github |
1250
|
|
|
* |
1251
|
|
|
* @param array $gh_data Array with the required data |
1252
|
|
|
* |
1253
|
|
|
* @return array |
1254
|
|
|
* |
1255
|
|
|
* @since 4.11 |
1256
|
|
|
*/ |
1257
|
|
|
public static function getCustomisedsource($gh_data = array()) |
1258
|
|
|
{ |
1259
|
|
|
$source_ref = $gh_data['customisedref']; |
1260
|
|
|
$allow_develop = $gh_data['allow_develop']; |
|
|
|
|
1261
|
|
|
|
1262
|
|
|
$sources = array(); |
1263
|
|
|
|
1264
|
|
|
// Detailing it we can handle exceptions and add other Github users or projects. |
1265
|
|
|
// To get the language files for a determined Joomla's version that is not present from main Github repository. |
1266
|
|
|
$sources['3.4.1']['user'] = 'joomla'; |
1267
|
|
|
$sources['3.4.1']['project'] = 'joomla-cms'; |
1268
|
|
|
$sources['3.4.1']['branch'] = '3.4.1'; |
1269
|
|
|
|
1270
|
|
|
if (array_key_exists($source_ref, $sources)) |
1271
|
|
|
{ |
1272
|
|
|
return ($sources[$source_ref]); |
1273
|
|
|
} |
1274
|
|
|
|
1275
|
|
|
// For undefined REF 0 or unlisted cases due Joomla releases at Github are following a version name patern. |
1276
|
|
|
$sources[$source_ref]['user'] = 'joomla'; |
1277
|
|
|
$sources[$source_ref]['project'] = 'joomla-cms'; |
1278
|
|
|
$sources[$source_ref]['branch'] = $source_ref; |
1279
|
|
|
|
1280
|
|
|
return ($sources[$source_ref]); |
1281
|
|
|
} |
1282
|
|
|
|
1283
|
|
|
/** |
1284
|
|
|
* Keep updated the customised client path including only the common files present in develop. |
1285
|
|
|
* |
1286
|
|
|
* @param string $client The client |
1287
|
|
|
* |
1288
|
|
|
* @param string $custom_client_path The path where the new source reference is stored |
1289
|
|
|
* |
1290
|
|
|
* @return boolean |
1291
|
|
|
* |
1292
|
|
|
* @since 4.11 |
1293
|
|
|
*/ |
1294
|
|
|
public static function updateSourcereference($client, $custom_client_path) |
1295
|
|
|
{ |
1296
|
|
|
$develop_client_path = JPATH_ROOT . '/media/com_localise/develop/github/joomla-cms/en-GB/' . $client; |
1297
|
|
|
$develop_client_path = JFolder::makeSafe($develop_client_path); |
1298
|
|
|
|
1299
|
|
|
$custom_ini_files_list = self::getInifileslist($custom_client_path); |
1300
|
|
|
$last_ini_files_list = self::getInifileslist($develop_client_path); |
1301
|
|
|
|
1302
|
|
|
$files_to_exclude = array(); |
|
|
|
|
1303
|
|
|
|
1304
|
|
View Code Duplication |
if (!JFile::exists($develop_client_path . '/en-GB.xml')) |
|
|
|
|
1305
|
|
|
{ |
1306
|
|
|
JFactory::getApplication()->enqueueMessage( |
1307
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_TARGET_FILES'), |
1308
|
|
|
'warning'); |
1309
|
|
|
|
1310
|
|
|
return false; |
1311
|
|
|
} |
1312
|
|
|
elseif (!JFile::exists($custom_client_path . '/en-GB.xml')) |
1313
|
|
|
{ |
1314
|
|
|
JFactory::getApplication()->enqueueMessage( |
1315
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_SOURCE_FILES'), |
1316
|
|
|
'warning'); |
1317
|
|
|
|
1318
|
|
|
return false; |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
// This one is for files not present within last in dev yet. |
1322
|
|
|
// Due have no sense add old language files to translate or revise for the comming soon package. |
1323
|
|
|
|
1324
|
|
|
$files_to_exclude = array_diff($custom_ini_files_list, $last_ini_files_list); |
1325
|
|
|
|
1326
|
|
|
if (!empty($files_to_exclude)) |
1327
|
|
|
{ |
1328
|
|
|
$errors = 0; |
1329
|
|
|
|
1330
|
|
|
foreach ($files_to_exclude as $file_to_delete) |
1331
|
|
|
{ |
1332
|
|
|
$custom_file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete); |
1333
|
|
|
|
1334
|
|
|
if (!JFile::delete($custom_file_path)) |
1335
|
|
|
{ |
1336
|
|
|
$errors++; |
1337
|
|
|
} |
1338
|
|
|
} |
1339
|
|
|
|
1340
|
|
|
if ($errors > 0) |
1341
|
|
|
{ |
1342
|
|
|
JFactory::getApplication()->enqueueMessage( |
1343
|
|
|
JText::sprintf('COM_LOCALISE_ERROR_DELETING_EXTRA_SOURCE_FILES', $errors), |
1344
|
|
|
'warning'); |
1345
|
|
|
|
1346
|
|
|
return false; |
1347
|
|
|
} |
1348
|
|
|
} |
1349
|
|
|
|
1350
|
|
|
return true; |
1351
|
|
|
} |
1352
|
|
|
|
1353
|
|
|
/** |
1354
|
|
|
* Keep updated the core path with the selected source files as reference (used at previous working mode). |
1355
|
|
|
* |
1356
|
|
|
* @param string $client The client |
1357
|
|
|
* |
1358
|
|
|
* @param string $custom_client_path The path where the new source reference is stored |
1359
|
|
|
* |
1360
|
|
|
* @param string $reference_client_path The path where the old source reference is stored |
1361
|
|
|
* |
1362
|
|
|
* @return boolean |
1363
|
|
|
* |
1364
|
|
|
* @since 4.11 |
1365
|
|
|
*/ |
1366
|
|
|
public static function updateSourcereferencedirectly($client, $custom_client_path, $reference_client_path) |
1367
|
|
|
{ |
1368
|
|
|
$develop_client_path = JPATH_ROOT . '/media/com_localise/develop/github/joomla-cms/en-GB/' . $client; |
1369
|
|
|
$develop_client_path = JFolder::makeSafe($develop_client_path); |
1370
|
|
|
|
1371
|
|
|
$custom_ini_files_list = self::getInifileslist($custom_client_path); |
1372
|
|
|
$last_ini_files_list = self::getInifileslist($develop_client_path); |
1373
|
|
|
|
1374
|
|
|
$files_to_exclude = array(); |
|
|
|
|
1375
|
|
|
|
1376
|
|
View Code Duplication |
if (!JFile::exists($develop_client_path . '/en-GB.xml')) |
|
|
|
|
1377
|
|
|
{ |
1378
|
|
|
JFactory::getApplication()->enqueueMessage( |
1379
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_TARGET_FILES'), |
1380
|
|
|
'warning'); |
1381
|
|
|
|
1382
|
|
|
return false; |
1383
|
|
|
} |
1384
|
|
|
elseif (!JFile::exists($custom_client_path . '/en-GB.xml')) |
1385
|
|
|
{ |
1386
|
|
|
JFactory::getApplication()->enqueueMessage( |
1387
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_SOURCE_FILES'), |
1388
|
|
|
'warning'); |
1389
|
|
|
|
1390
|
|
|
return false; |
1391
|
|
|
} |
1392
|
|
|
|
1393
|
|
|
// This one is for core files not present within last in dev yet. |
1394
|
|
|
// Due have no sense add old language files to translate for the comming soon package. |
1395
|
|
|
|
1396
|
|
|
$files_to_exclude = array_diff($custom_ini_files_list, $last_ini_files_list); |
1397
|
|
|
|
1398
|
|
|
if (!empty($files_to_exclude)) |
1399
|
|
|
{ |
1400
|
|
|
foreach ($files_to_exclude as $file_to_delete) |
1401
|
|
|
{ |
1402
|
|
|
$custom_file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete); |
1403
|
|
|
$actual_file_path = JFolder::makeSafe($reference_client_path . "/" . $file_to_delete); |
1404
|
|
|
|
1405
|
|
|
JFile::delete($custom_file_path); |
1406
|
|
|
|
1407
|
|
|
// Also verify if the same file is also present in core language folder. |
1408
|
|
|
|
1409
|
|
|
if (JFile::exists($actual_file_path)) |
1410
|
|
|
{ |
1411
|
|
|
JFile::delete($actual_file_path); |
1412
|
|
|
|
1413
|
|
|
JFactory::getApplication()->enqueueMessage( |
1414
|
|
|
JText::sprintf('COM_LOCALISE_OLD_FILE_DELETED', $file_to_delete), |
1415
|
|
|
'notice'); |
1416
|
|
|
} |
1417
|
|
|
} |
1418
|
|
|
|
1419
|
|
|
// Getting the new list again |
1420
|
|
|
$custom_ini_files_list = self::getInifileslist($custom_client_path); |
1421
|
|
|
} |
1422
|
|
|
|
1423
|
|
|
$errors = 0; |
1424
|
|
|
|
1425
|
|
|
foreach ($custom_ini_files_list as $customised_source_file) |
1426
|
|
|
{ |
1427
|
|
|
$source_path = $custom_client_path . '/' . $customised_source_file; |
1428
|
|
|
$file_contents = file_get_contents($source_path); |
1429
|
|
|
$target_path = $reference_client_path . '/' . $customised_source_file; |
1430
|
|
|
|
1431
|
|
|
if (!JFile::write($target_path, $file_contents)) |
1432
|
|
|
{ |
1433
|
|
|
$errors++; |
1434
|
|
|
} |
1435
|
|
|
} |
1436
|
|
|
|
1437
|
|
|
if ($errors > 0) |
1438
|
|
|
{ |
1439
|
|
|
JFactory::getApplication()->enqueueMessage( |
1440
|
|
|
JText::sprintf('COM_LOCALISE_ERROR_SAVING_FILES_AT_CORE_FOLDER', $errors), |
1441
|
|
|
'warning'); |
1442
|
|
|
|
1443
|
|
|
return false; |
1444
|
|
|
} |
1445
|
|
|
|
1446
|
|
|
return true; |
1447
|
|
|
} |
1448
|
|
|
|
1449
|
|
|
/** |
1450
|
|
|
* Gets from zero or keept updated the files in develop to use as target reference from Github |
1451
|
|
|
* |
1452
|
|
|
* @param array $gh_data Array with the required data |
1453
|
|
|
* |
1454
|
|
|
* @return array |
1455
|
|
|
* |
1456
|
|
|
* @since 4.11 |
1457
|
|
|
*/ |
1458
|
|
|
public static function getTargetgithubfiles($gh_data = array()) |
1459
|
|
|
{ |
1460
|
|
|
if (!empty($gh_data)) |
1461
|
|
|
{ |
1462
|
|
|
$now = new JDate; |
1463
|
|
|
$now = $now->toSQL(); |
1464
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
1465
|
|
|
$client_to_update = 'gh_' . $gh_data['github_client'] . '_last_update'; |
1466
|
|
|
$last_stored_update = $params->get($client_to_update, ''); |
1467
|
|
|
$ref_tag = $params->get('reference', 'en-GB'); |
1468
|
|
|
$allow_develop = $params->get('gh_allow_develop', 0); |
1469
|
|
|
|
1470
|
|
|
if ($allow_develop == 0) |
1471
|
|
|
{ |
1472
|
|
|
return false; |
1473
|
|
|
} |
1474
|
|
|
|
1475
|
|
|
if ($ref_tag != 'en-GB') |
1476
|
|
|
{ |
1477
|
|
|
JFactory::getApplication()->enqueueMessage( |
1478
|
|
|
JText::_('COM_LOCALISE_ERROR_GETTING_ALLOWED_REFERENCE_TAG'), |
1479
|
|
|
'warning'); |
1480
|
|
|
|
1481
|
|
|
return false; |
1482
|
|
|
} |
1483
|
|
|
|
1484
|
|
|
$develop_client_path = JPATH_ROOT |
1485
|
|
|
. '/media/com_localise/develop/github/joomla-cms/en-GB/' |
1486
|
|
|
. $gh_data['github_client']; |
1487
|
|
|
|
1488
|
|
|
$develop_client_path = JFolder::makeSafe($develop_client_path); |
1489
|
|
|
$xml_file = $develop_client_path . '/en-GB.xml'; |
1490
|
|
|
|
1491
|
|
|
if (!JFile::exists($xml_file)) |
1492
|
|
|
{ |
1493
|
|
|
$get_files = 1; |
1494
|
|
|
} |
1495
|
|
|
elseif (!empty($last_stored_update)) |
1496
|
|
|
{ |
1497
|
|
|
$last_update = new JDate($last_stored_update); |
1498
|
|
|
$last_update = $last_update->toSQL(); |
1499
|
|
|
$interval = $params->get('gh_updates_interval', '1') == '1' ? 24 : 1; |
1500
|
|
|
$interval = $last_update . " +" . $interval . " hours"; |
1501
|
|
|
$next_update = new JDate($interval); |
1502
|
|
|
$next_update = $next_update->toSQL(); |
1503
|
|
|
|
1504
|
|
|
if ($now >= $next_update) |
1505
|
|
|
{ |
1506
|
|
|
$get_files = 1; |
1507
|
|
|
} |
1508
|
|
|
else |
1509
|
|
|
{ |
1510
|
|
|
$get_files = 0; |
1511
|
|
|
} |
1512
|
|
|
} |
1513
|
|
|
else |
1514
|
|
|
{ |
1515
|
|
|
$get_files = 1; |
1516
|
|
|
} |
1517
|
|
|
|
1518
|
|
|
if ($get_files == 0) |
1519
|
|
|
{ |
1520
|
|
|
return false; |
1521
|
|
|
} |
1522
|
|
|
|
1523
|
|
|
$gh_paths = array(); |
1524
|
|
|
$gh_client = $gh_data['github_client']; |
1525
|
|
|
$gh_user = 'joomla'; |
1526
|
|
|
$gh_project = 'joomla-cms'; |
1527
|
|
|
$gh_branch = $params->get('gh_branch', 'master'); |
1528
|
|
|
$gh_token = $params->get('gh_token', ''); |
1529
|
|
|
$gh_paths['administrator'] = 'administrator/language/en-GB'; |
1530
|
|
|
$gh_paths['site'] = 'language/en-GB'; |
1531
|
|
|
$gh_paths['installation'] = 'installation/language/en-GB'; |
1532
|
|
|
|
1533
|
|
|
$reference_client_path = JPATH_ROOT . '/' . $gh_paths[$gh_client]; |
1534
|
|
|
$reference_client_path = JFolder::makeSafe($reference_client_path); |
1535
|
|
|
|
1536
|
|
|
$options = new JRegistry; |
1537
|
|
|
|
1538
|
|
View Code Duplication |
if (!empty($gh_token)) |
|
|
|
|
1539
|
|
|
{ |
1540
|
|
|
$options->set('gh.token', $gh_token); |
1541
|
|
|
$github = new Github($options); |
1542
|
|
|
} |
1543
|
|
|
else |
1544
|
|
|
{ |
1545
|
|
|
// Without a token runs fatal. |
1546
|
|
|
// $github = new JGithub; |
1547
|
|
|
|
1548
|
|
|
// Trying with a 'read only' public repositories token |
1549
|
|
|
// But base 64 encoded to avoid Github alarms sharing it. |
1550
|
|
|
$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA=='); |
1551
|
|
|
$options->set('gh.token', $gh_token); |
1552
|
|
|
$github = new Github($options); |
1553
|
|
|
} |
1554
|
|
|
|
1555
|
|
|
try |
1556
|
|
|
{ |
1557
|
|
|
$repostoryfiles = $github->repositories->contents->get( |
1558
|
|
|
$gh_user, |
1559
|
|
|
$gh_project, |
1560
|
|
|
$gh_paths[$gh_client], |
1561
|
|
|
$gh_branch |
1562
|
|
|
); |
1563
|
|
|
} |
1564
|
|
|
catch (Exception $e) |
1565
|
|
|
{ |
1566
|
|
|
JFactory::getApplication()->enqueueMessage( |
1567
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_REPOSITORY_FILES'), |
1568
|
|
|
'warning'); |
1569
|
|
|
|
1570
|
|
|
return false; |
1571
|
|
|
} |
1572
|
|
|
|
1573
|
|
|
$all_files_list = self::getLanguagefileslist($develop_client_path); |
1574
|
|
|
$ini_files_list = self::getInifileslist($develop_client_path); |
|
|
|
|
1575
|
|
|
$sha_files_list = self::getShafileslist($gh_data); |
1576
|
|
|
|
1577
|
|
|
$sha = ''; |
1578
|
|
|
$files_to_include = array(); |
1579
|
|
|
|
1580
|
|
|
foreach ($repostoryfiles as $repostoryfile) |
1581
|
|
|
{ |
1582
|
|
|
$file_to_include = $repostoryfile->name; |
1583
|
|
|
$file_path = JFolder::makeSafe($develop_client_path . '/' . $file_to_include); |
1584
|
|
|
$reference_file_path = JFolder::makeSafe($reference_client_path . '/' . $file_to_include); |
1585
|
|
|
|
1586
|
|
|
if ( (array_key_exists($file_to_include, $sha_files_list) |
1587
|
|
|
&& ($sha_files_list[$file_to_include] != $repostoryfile->sha)) |
1588
|
|
|
|| empty($sha_files_list) |
1589
|
|
|
|| !array_key_exists($file_to_include, $sha_files_list) |
1590
|
|
|
|| !JFile::exists($file_path)) |
1591
|
|
|
{ |
1592
|
|
|
$in_dev_file = $github->repositories->contents->get( |
1593
|
|
|
$gh_user, |
1594
|
|
|
$gh_project, |
1595
|
|
|
$repostoryfile->path, |
1596
|
|
|
$gh_branch |
1597
|
|
|
); |
1598
|
|
|
} |
1599
|
|
|
else |
1600
|
|
|
{ |
1601
|
|
|
$in_dev_file = ''; |
1602
|
|
|
} |
1603
|
|
|
|
1604
|
|
|
$files_to_include[] = $file_to_include; |
1605
|
|
|
$sha_path = JPATH_COMPONENT_ADMINISTRATOR . '/develop/gh_joomla_' . $gh_client . '_files.txt'; |
1606
|
|
|
$sha_path = JFolder::makeSafe($sha_path); |
1607
|
|
|
|
1608
|
|
|
if (!empty($in_dev_file) && isset($in_dev_file->content)) |
1609
|
|
|
{ |
1610
|
|
|
$file_to_include = $repostoryfile->name; |
1611
|
|
|
$file_contents = base64_decode($in_dev_file->content); |
1612
|
|
|
JFile::write($file_path, $file_contents); |
1613
|
|
|
|
1614
|
|
|
if (!JFile::exists($file_path)) |
1615
|
|
|
{ |
1616
|
|
|
JFactory::getApplication()->enqueueMessage( |
1617
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_DEV_FILE'), |
1618
|
|
|
'warning'); |
1619
|
|
|
|
1620
|
|
|
return false; |
1621
|
|
|
} |
1622
|
|
|
|
1623
|
|
|
if (!JFile::exists($reference_file_path) |
1624
|
|
|
&& ($gh_client == 'administrator' || $gh_client == 'site')) |
1625
|
|
|
{ |
1626
|
|
|
// Adding files only present in develop to core reference location. |
1627
|
|
|
JFile::write($reference_file_path, $file_contents); |
1628
|
|
|
|
1629
|
|
|
if (!JFile::exists($reference_file_path)) |
1630
|
|
|
{ |
1631
|
|
|
JFactory::getApplication()->enqueueMessage( |
1632
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_ADD_NEW_FILES'), |
1633
|
|
|
'warning'); |
1634
|
|
|
|
1635
|
|
|
return false; |
1636
|
|
|
} |
1637
|
|
|
|
1638
|
|
|
JFactory::getApplication()->enqueueMessage( |
1639
|
|
|
JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED', $file_to_include, $gh_branch, $gh_client), |
1640
|
|
|
'notice'); |
1641
|
|
|
} |
1642
|
|
|
} |
1643
|
|
|
|
1644
|
|
|
// Saved for each time due few times get all the github files at same time can crash. |
1645
|
|
|
// This one can help to remember the last one saved correctly and next time continue from there. |
1646
|
|
|
$sha .= $repostoryfile->name . "::" . $repostoryfile->sha . "\n"; |
1647
|
|
|
JFile::write($sha_path, $sha); |
1648
|
|
|
|
1649
|
|
|
if (!JFile::exists($sha_path)) |
1650
|
|
|
{ |
1651
|
|
|
JFactory::getApplication()->enqueueMessage( |
1652
|
|
|
JText::_('COM_LOCALISE_ERROR_GITHUB_NO_SHA_FILE_PRESENT'), |
1653
|
|
|
'warning'); |
1654
|
|
|
|
1655
|
|
|
return false; |
1656
|
|
|
} |
1657
|
|
|
} |
1658
|
|
|
|
1659
|
|
|
if (!empty($all_files_list) && !empty($files_to_include)) |
1660
|
|
|
{ |
1661
|
|
|
// For files not present in dev yet. |
1662
|
|
|
$files_to_delete = array_diff($all_files_list, $files_to_include); |
1663
|
|
|
|
1664
|
|
|
if (!empty($files_to_delete)) |
1665
|
|
|
{ |
1666
|
|
|
foreach ($files_to_delete as $file_to_delete) |
1667
|
|
|
{ |
1668
|
|
|
if ($file_to_delete != 'index.html') |
1669
|
|
|
{ |
1670
|
|
|
$file_path = JFolder::makeSafe($develop_client_path . "/" . $file_to_delete); |
1671
|
|
|
JFile::delete($file_path); |
1672
|
|
|
|
1673
|
|
|
if (JFile::exists($file_path)) |
1674
|
|
|
{ |
1675
|
|
|
JFactory::getApplication()->enqueueMessage( |
1676
|
|
|
JText::sprintf('COM_LOCALISE_ERROR_GITHUB_FILE_TO_DELETE_IS_PRESENT', $file_to_delete), |
1677
|
|
|
'warning'); |
1678
|
|
|
|
1679
|
|
|
return false; |
1680
|
|
|
} |
1681
|
|
|
|
1682
|
|
|
JFactory::getApplication()->enqueueMessage( |
1683
|
|
|
JText::sprintf('COM_LOCALISE_GITHUB_FILE_NOT_PRESENT_IN_DEV_YET', $file_to_delete), |
1684
|
|
|
'notice'); |
1685
|
|
|
} |
1686
|
|
|
} |
1687
|
|
|
} |
1688
|
|
|
} |
1689
|
|
|
|
1690
|
|
|
if (!JFile::exists($xml_file)) |
1691
|
|
|
{ |
1692
|
|
|
JFactory::getApplication()->enqueueMessage( |
1693
|
|
|
JText::sprintf('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_GET_A_FULL_SET', $gh_branch), |
1694
|
|
|
'warning'); |
1695
|
|
|
|
1696
|
|
|
return false; |
1697
|
|
|
} |
1698
|
|
|
|
1699
|
|
|
self::saveLastupdate($client_to_update); |
1700
|
|
|
|
1701
|
|
|
JFactory::getApplication()->enqueueMessage( |
1702
|
|
|
JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_GETS_A_TARGET_FULL_SET', $gh_branch), |
1703
|
|
|
'notice'); |
1704
|
|
|
|
1705
|
|
|
return true; |
1706
|
|
|
} |
1707
|
|
|
|
1708
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_NO_DATA_PRESENT'), 'warning'); |
1709
|
|
|
|
1710
|
|
|
return false; |
1711
|
|
|
} |
1712
|
|
|
|
1713
|
|
|
/** |
1714
|
|
|
* Gets the changes between language files versions |
1715
|
|
|
* |
1716
|
|
|
* @param array $info The data to catch grammar cases |
1717
|
|
|
* @param array $refsections The released reference data |
1718
|
|
|
* @param array $develop_sections The developed reference data |
1719
|
|
|
* |
1720
|
|
|
* @return array |
1721
|
|
|
* |
1722
|
|
|
* @since 4.11 |
1723
|
|
|
*/ |
1724
|
|
|
public static function getDevelopchanges($info = array(), $refsections = array(), $develop_sections = array()) |
1725
|
|
|
{ |
1726
|
|
|
if (isset($refsections['keys']) && isset($develop_sections['keys'])) |
1727
|
|
|
{ |
1728
|
|
|
$istranslation = $info['istranslation']; |
1729
|
|
|
$keys_in_reference = array_keys($refsections['keys']); |
1730
|
|
|
$keys_in_develop = array_keys($develop_sections['keys']); |
1731
|
|
|
|
1732
|
|
|
// Catching new keys in develop |
1733
|
|
|
$developdata['extra_keys']['amount'] = 0; |
|
|
|
|
1734
|
|
|
$developdata['extra_keys']['keys'] = array(); |
1735
|
|
|
$developdata['extra_keys']['strings'] = array(); |
1736
|
|
|
|
1737
|
|
|
$extras_in_develop = array_diff($keys_in_develop, $keys_in_reference); |
1738
|
|
|
|
1739
|
|
|
if (!empty($extras_in_develop)) |
1740
|
|
|
{ |
1741
|
|
|
foreach ($extras_in_develop as $extra_key) |
1742
|
|
|
{ |
1743
|
|
|
$developdata['extra_keys']['amount']++; |
1744
|
|
|
$developdata['extra_keys']['keys'][] = $extra_key; |
1745
|
|
|
$developdata['extra_keys']['strings'][$extra_key] = $develop_sections['keys'][$extra_key]; |
1746
|
|
|
} |
1747
|
|
|
} |
1748
|
|
|
|
1749
|
|
|
// Catching text changes in develop |
1750
|
|
|
$developdata['text_changes']['amount'] = 0; |
1751
|
|
|
$developdata['text_changes']['revised'] = 0; |
1752
|
|
|
$developdata['text_changes']['unrevised'] = 0; |
1753
|
|
|
$developdata['text_changes']['keys'] = array(); |
1754
|
|
|
$developdata['text_changes']['ref_in_dev'] = array(); |
1755
|
|
|
$developdata['text_changes']['ref'] = array(); |
1756
|
|
|
$developdata['text_changes']['diff'] = array(); |
1757
|
|
|
|
1758
|
|
|
foreach ($refsections['keys'] as $key => $string) |
1759
|
|
|
{ |
1760
|
|
|
if (array_key_exists($key, $develop_sections['keys'])) |
1761
|
|
|
{ |
1762
|
|
|
$string_in_develop = $develop_sections['keys'][$key]; |
1763
|
|
|
$text_changes = self::htmlgetTextchanges($string, $string_in_develop); |
1764
|
|
|
|
1765
|
|
|
if (!empty($text_changes)) |
1766
|
|
|
{ |
1767
|
|
|
if ($istranslation == 1) |
1768
|
|
|
{ |
1769
|
|
|
$info['key'] = $key; |
1770
|
|
|
$info['source_text'] = $string; |
1771
|
|
|
$info['target_text'] = $string_in_develop; |
1772
|
|
|
$info['catch_grammar'] = 1; |
1773
|
|
|
$info['revised'] = 0; |
1774
|
|
|
|
1775
|
|
|
$grammar_case = self::searchRevisedvalue($info); |
1776
|
|
|
} |
1777
|
|
|
else |
1778
|
|
|
{ |
1779
|
|
|
$grammar_case = '0'; |
1780
|
|
|
} |
1781
|
|
|
|
1782
|
|
|
if ($grammar_case == '0') |
1783
|
|
|
{ |
1784
|
|
|
$developdata['text_changes']['amount']++; |
1785
|
|
|
$developdata['text_changes']['keys'][] = $key; |
1786
|
|
|
$developdata['text_changes']['ref_in_dev'][$key] = $develop_sections['keys'][$key]; |
1787
|
|
|
$developdata['text_changes']['ref'][$key] = $string; |
1788
|
|
|
$developdata['text_changes']['diff'][$key] = $text_changes; |
1789
|
|
|
} |
1790
|
|
|
} |
1791
|
|
|
} |
1792
|
|
|
} |
1793
|
|
|
|
1794
|
|
|
return $developdata; |
1795
|
|
|
} |
1796
|
|
|
|
1797
|
|
|
return array(); |
1798
|
|
|
} |
1799
|
|
|
|
1800
|
|
|
/** |
1801
|
|
|
* Gets the develop path if exists |
1802
|
|
|
* |
1803
|
|
|
* @param string $client The client |
1804
|
|
|
* @param string $refpath The data to the reference path |
1805
|
|
|
* |
1806
|
|
|
* @return string |
1807
|
|
|
* |
1808
|
|
|
* @since 4.11 |
1809
|
|
|
*/ |
1810
|
|
|
public static function searchDevpath($client = '', $refpath = '') |
1811
|
|
|
{ |
1812
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
1813
|
|
|
$ref_tag = $params->get('reference', 'en-GB'); |
1814
|
|
|
$allow_develop = $params->get('gh_allow_develop', 0); |
1815
|
|
|
|
1816
|
|
|
$develop_client_path = JPATH_ROOT |
1817
|
|
|
. '/media/com_localise/develop/github/joomla-cms/en-GB/' |
1818
|
|
|
. $client; |
1819
|
|
|
|
1820
|
|
|
$ref_file = basename($refpath); |
1821
|
|
|
$develop_file_path = JFolder::makeSafe("$develop_client_path/$ref_file"); |
1822
|
|
|
|
1823
|
|
|
if (JFile::exists($develop_file_path) && $allow_develop == 1 && $ref_tag == 'en-GB') |
1824
|
|
|
{ |
1825
|
|
|
$devpath = $develop_file_path; |
1826
|
|
|
} |
1827
|
|
|
else |
1828
|
|
|
{ |
1829
|
|
|
$devpath = ''; |
1830
|
|
|
} |
1831
|
|
|
|
1832
|
|
|
return $devpath; |
1833
|
|
|
} |
1834
|
|
|
|
1835
|
|
|
/** |
1836
|
|
|
* Gets the customised source path if exists |
1837
|
|
|
* |
1838
|
|
|
* @param string $client The client |
1839
|
|
|
* @param string $refpath The data to the reference path |
1840
|
|
|
* |
1841
|
|
|
* @return string |
1842
|
|
|
* |
1843
|
|
|
* @since 4.11 |
1844
|
|
|
*/ |
1845
|
|
|
public static function searchCustompath($client = '', $refpath = '') |
1846
|
|
|
{ |
1847
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
1848
|
|
|
$ref_tag = $params->get('reference', 'en-GB'); |
1849
|
|
|
$allow_develop = $params->get('gh_allow_develop', 0); |
1850
|
|
|
$customisedref = $params->get('customisedref', '0'); |
1851
|
|
|
$custom_client_path = JPATH_ROOT |
1852
|
|
|
. '/media/com_localise/customisedref/github/' |
1853
|
|
|
. $client |
1854
|
|
|
. '/' |
1855
|
|
|
. $customisedref; |
1856
|
|
|
|
1857
|
|
|
$ref_file = basename($refpath); |
1858
|
|
|
$custom_file_path = JFolder::makeSafe("$custom_client_path/$ref_file"); |
1859
|
|
|
|
1860
|
|
|
if (JFile::exists($custom_file_path) && $allow_develop == 1 && $ref_tag == 'en-GB' && $customisedref != 0) |
1861
|
|
|
{ |
1862
|
|
|
$custom_path = $custom_file_path; |
1863
|
|
|
} |
1864
|
|
|
else |
1865
|
|
|
{ |
1866
|
|
|
$custom_path = ''; |
1867
|
|
|
} |
1868
|
|
|
|
1869
|
|
|
return $custom_path; |
1870
|
|
|
} |
1871
|
|
|
|
1872
|
|
|
/** |
1873
|
|
|
* Allow combine the reference versions to obtain a right result editing in raw mode or saving source reference files |
1874
|
|
|
* When development is enabled. |
1875
|
|
|
* |
1876
|
|
|
* @param string $refpath The data to the reference path |
1877
|
|
|
* |
1878
|
|
|
* @param string $devpath The data to the develop path |
1879
|
|
|
* |
1880
|
|
|
* @return string |
1881
|
|
|
* |
1882
|
|
|
* @since 4.11 |
1883
|
|
|
*/ |
1884
|
|
|
public static function combineReferences($refpath = '', $devpath = '') |
1885
|
|
|
{ |
1886
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
1887
|
|
|
$ref_tag = $params->get('reference', 'en-GB'); |
1888
|
|
|
$allow_develop = $params->get('gh_allow_develop', 0); |
1889
|
|
|
$combined_content = ''; |
1890
|
|
|
|
1891
|
|
|
if (JFile::exists($devpath) && JFile::exists($refpath) && $allow_develop == 1 && $ref_tag == 'en-GB') |
1892
|
|
|
{ |
1893
|
|
|
$ref_sections = self::parseSections($refpath); |
1894
|
|
|
$keys_in_reference = array_keys($ref_sections['keys']); |
1895
|
|
|
|
1896
|
|
|
$stream = new JStream; |
1897
|
|
|
$stream->open($devpath); |
1898
|
|
|
$stream->seek(0); |
1899
|
|
|
|
1900
|
|
|
while (!$stream->eof()) |
1901
|
|
|
{ |
1902
|
|
|
$line = $stream->gets(); |
1903
|
|
|
|
1904
|
|
|
if (preg_match('/^([A-Z][A-Z0-9_\*\-\.]*)\s*=/', $line, $matches)) |
1905
|
|
|
{ |
1906
|
|
|
$key = $matches[1]; |
1907
|
|
|
|
1908
|
|
|
if (in_array($key, $keys_in_reference)) |
1909
|
|
|
{ |
1910
|
|
|
$string = $ref_sections['keys'][$key]; |
1911
|
|
|
$combined_content .= $key . '="' . str_replace('"', '"_QQ_"', $string) . "\"\n"; |
1912
|
|
|
} |
1913
|
|
|
else |
1914
|
|
|
{ |
1915
|
|
|
$combined_content .= $line; |
1916
|
|
|
} |
1917
|
|
|
} |
1918
|
|
|
else |
1919
|
|
|
{ |
1920
|
|
|
$combined_content .= $line; |
1921
|
|
|
} |
1922
|
|
|
} |
1923
|
|
|
|
1924
|
|
|
$stream->close(); |
1925
|
|
|
} |
1926
|
|
|
|
1927
|
|
|
return $combined_content; |
1928
|
|
|
} |
1929
|
|
|
|
1930
|
|
|
/** |
1931
|
|
|
* Gets the list of ini files |
1932
|
|
|
* |
1933
|
|
|
* @param string $client_path The data to the client path |
1934
|
|
|
* |
1935
|
|
|
* @return array |
1936
|
|
|
* |
1937
|
|
|
* @since 4.11 |
1938
|
|
|
*/ |
1939
|
|
|
public static function getInifileslist($client_path = '') |
1940
|
|
|
{ |
1941
|
|
|
if (!empty($client_path)) |
1942
|
|
|
{ |
1943
|
|
|
$files = JFolder::files($client_path, ".ini$"); |
1944
|
|
|
|
1945
|
|
|
return $files; |
1946
|
|
|
} |
1947
|
|
|
|
1948
|
|
|
return array(); |
1949
|
|
|
} |
1950
|
|
|
|
1951
|
|
|
/** |
1952
|
|
|
* Gets the list of all type of files in develop |
1953
|
|
|
* |
1954
|
|
|
* @param string $develop_client_path The data to the client path |
1955
|
|
|
* |
1956
|
|
|
* @return array |
1957
|
|
|
* |
1958
|
|
|
* @since 4.11 |
1959
|
|
|
*/ |
1960
|
|
|
public static function getLanguagefileslist($develop_client_path = '') |
1961
|
|
|
{ |
1962
|
|
|
if (!empty($develop_client_path)) |
1963
|
|
|
{ |
1964
|
|
|
$files = JFolder::files($develop_client_path); |
1965
|
|
|
|
1966
|
|
|
return $files; |
1967
|
|
|
} |
1968
|
|
|
|
1969
|
|
|
return array(); |
1970
|
|
|
} |
1971
|
|
|
|
1972
|
|
|
/** |
1973
|
|
|
* Gets the stored SHA id for the files in develop. |
1974
|
|
|
* |
1975
|
|
|
* @param array $gh_data The required data. |
1976
|
|
|
* |
1977
|
|
|
* @return array |
1978
|
|
|
* |
1979
|
|
|
* @since 4.11 |
1980
|
|
|
*/ |
1981
|
|
|
public static function getShafileslist($gh_data = array()) |
1982
|
|
|
{ |
1983
|
|
|
$sha_files = array(); |
1984
|
|
|
$gh_client = $gh_data['github_client']; |
1985
|
|
|
$sha_path = JFolder::makeSafe(JPATH_COMPONENT_ADMINISTRATOR . '/develop/gh_joomla_' . $gh_client . '_files.txt'); |
1986
|
|
|
|
1987
|
|
|
if (JFile::exists($sha_path)) |
1988
|
|
|
{ |
1989
|
|
|
$file_contents = file_get_contents($sha_path); |
1990
|
|
|
$lines = preg_split("/\\r\\n|\\r|\\n/", $file_contents); |
1991
|
|
|
|
1992
|
|
|
if (!empty($lines)) |
1993
|
|
|
{ |
1994
|
|
|
foreach ($lines as $line) |
1995
|
|
|
{ |
1996
|
|
|
if (!empty($line)) |
1997
|
|
|
{ |
1998
|
|
|
list($filename, $sha) = explode('::', $line, 2); |
1999
|
|
|
|
2000
|
|
|
if (!empty($filename) && !empty($sha)) |
2001
|
|
|
{ |
2002
|
|
|
$sha_files[$filename] = $sha; |
2003
|
|
|
} |
2004
|
|
|
} |
2005
|
|
|
} |
2006
|
|
|
} |
2007
|
|
|
} |
2008
|
|
|
|
2009
|
|
|
return $sha_files; |
2010
|
|
|
} |
2011
|
|
|
|
2012
|
|
|
/** |
2013
|
|
|
* Save the date of the last Github files update by client. |
2014
|
|
|
* |
2015
|
|
|
* @param string $client_to_update The client language files. |
2016
|
|
|
* |
2017
|
|
|
* @return bolean |
2018
|
|
|
* |
2019
|
|
|
* @since 4.11 |
2020
|
|
|
*/ |
2021
|
|
|
public static function saveLastupdate($client_to_update) |
2022
|
|
|
{ |
2023
|
|
|
$now = new JDate; |
2024
|
|
|
$now = $now->toSQL(); |
2025
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
2026
|
|
|
$params->set($client_to_update, $now); |
2027
|
|
|
|
2028
|
|
|
$localise_id = JComponentHelper::getComponent('com_localise')->id; |
2029
|
|
|
|
2030
|
|
|
$table = JTable::getInstance('extension'); |
2031
|
|
|
$table->load($localise_id); |
2032
|
|
|
$table->bind(array('params' => $params->toString())); |
2033
|
|
|
|
2034
|
|
|
if (!$table->check()) |
2035
|
|
|
{ |
2036
|
|
|
JFactory::getApplication()->enqueueMessage($table->getError(), 'warning'); |
2037
|
|
|
|
2038
|
|
|
return false; |
2039
|
|
|
} |
2040
|
|
|
|
2041
|
|
|
if (!$table->store()) |
2042
|
|
|
{ |
2043
|
|
|
JFactory::getApplication()->enqueueMessage($table->getError(), 'warning'); |
2044
|
|
|
|
2045
|
|
|
return false; |
2046
|
|
|
} |
2047
|
|
|
|
2048
|
|
|
return true; |
2049
|
|
|
} |
2050
|
|
|
|
2051
|
|
|
/** |
2052
|
|
|
* Forces to save the customised source version to use. Option '0' returns to local installed instance. |
2053
|
|
|
* |
2054
|
|
|
* @param string $option The option value to save. |
2055
|
|
|
* |
2056
|
|
|
* @return bolean |
2057
|
|
|
* |
2058
|
|
|
* @since 4.11 |
2059
|
|
|
*/ |
2060
|
|
|
public static function setCustomisedsource($option = '0') |
2061
|
|
|
{ |
2062
|
|
|
$params = JComponentHelper::getParams('com_localise'); |
2063
|
|
|
$params->set('customisedref', $option); |
2064
|
|
|
|
2065
|
|
|
$localise_id = JComponentHelper::getComponent('com_localise')->id; |
2066
|
|
|
|
2067
|
|
|
$table = JTable::getInstance('extension'); |
2068
|
|
|
$table->load($localise_id); |
2069
|
|
|
$table->bind(array('params' => $params->toString())); |
2070
|
|
|
|
2071
|
|
|
if (!$table->check()) |
2072
|
|
|
{ |
2073
|
|
|
JFactory::getApplication()->enqueueMessage($table->getError(), 'warning'); |
2074
|
|
|
|
2075
|
|
|
return false; |
2076
|
|
|
} |
2077
|
|
|
|
2078
|
|
|
if (!$table->store()) |
2079
|
|
|
{ |
2080
|
|
|
JFactory::getApplication()->enqueueMessage($table->getError(), 'warning'); |
2081
|
|
|
|
2082
|
|
|
return false; |
2083
|
|
|
} |
2084
|
|
|
|
2085
|
|
|
return true; |
2086
|
|
|
} |
2087
|
|
|
|
2088
|
|
|
/** |
2089
|
|
|
* Load revised changes |
2090
|
|
|
* |
2091
|
|
|
* @param array $data The required data. |
2092
|
|
|
* |
2093
|
|
|
* @return array |
2094
|
|
|
* |
2095
|
|
|
* @since 4.11 |
2096
|
|
|
*/ |
2097
|
|
|
public static function searchRevisedvalue($data) |
2098
|
|
|
{ |
2099
|
|
|
$client = $data['client']; |
2100
|
|
|
$reftag = $data['reftag']; |
2101
|
|
|
$tag = $data['tag']; |
2102
|
|
|
$filename = $data['filename']; |
2103
|
|
|
$revised = $data['revised']; |
2104
|
|
|
$key = $data['key']; |
2105
|
|
|
$target_text = $data['target_text']; |
2106
|
|
|
$source_text = $data['source_text']; |
2107
|
|
|
$istranslation = $data['istranslation']; |
|
|
|
|
2108
|
|
|
$catch_grammar = $data['catch_grammar']; |
2109
|
|
|
|
2110
|
|
|
if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename)) |
2111
|
|
|
{ |
2112
|
|
|
try |
2113
|
|
|
{ |
2114
|
|
|
$db = JFactory::getDbo(); |
2115
|
|
|
$query = $db->getQuery(true); |
2116
|
|
|
|
2117
|
|
|
$search_client = $db->quote($client); |
2118
|
|
|
$search_reftag = $db->quote($reftag); |
2119
|
|
|
$search_tag = $db->quote($tag); |
2120
|
|
|
$search_filename = $db->quote($filename); |
2121
|
|
|
$search_key = $db->quote($key); |
2122
|
|
|
$search_target_text = $db->quote($target_text); |
2123
|
|
|
$search_source_text = $db->quote($source_text); |
2124
|
|
|
|
2125
|
|
|
$query->select( |
2126
|
|
|
array ( |
2127
|
|
|
$db->quoteName('revised') |
2128
|
|
|
) |
2129
|
|
|
); |
2130
|
|
|
$query->from( |
2131
|
|
|
$db->quoteName('#__localise_revised_values') |
2132
|
|
|
); |
2133
|
|
|
$query->where( |
2134
|
|
|
$db->quoteName('client') . '= ' . $search_client |
2135
|
|
|
); |
2136
|
|
|
$query->where( |
2137
|
|
|
$db->quoteName('reftag') . '= ' . $search_reftag |
2138
|
|
|
|
2139
|
|
|
); |
2140
|
|
|
$query->where( |
2141
|
|
|
$db->quoteName('tag') . '= ' . $search_tag |
2142
|
|
|
|
2143
|
|
|
); |
2144
|
|
|
$query->where( |
2145
|
|
|
$db->quoteName('filename') . '= ' . $search_filename |
2146
|
|
|
); |
2147
|
|
|
$query->where( |
2148
|
|
|
$db->quoteName('key') . '= ' . $search_key |
2149
|
|
|
); |
2150
|
|
|
$query->where( |
2151
|
|
|
$db->quoteName('target_text') . '= ' . $search_target_text |
2152
|
|
|
); |
2153
|
|
|
$query->where( |
2154
|
|
|
$db->quoteName('source_text') . '= ' . $search_source_text |
2155
|
|
|
); |
2156
|
|
|
|
2157
|
|
|
$db->setQuery($query); |
2158
|
|
|
|
2159
|
|
|
if (!$db->query()) |
2160
|
|
|
{ |
2161
|
|
|
throw new Exception($db->getErrorMsg()); |
2162
|
|
|
} |
2163
|
|
|
} |
2164
|
|
|
|
2165
|
|
|
catch (JException $e) |
|
|
|
|
2166
|
|
|
{ |
2167
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_SEARCHING_REVISED_VALUES'), 'warning'); |
2168
|
|
|
|
2169
|
|
|
return null; |
2170
|
|
|
} |
2171
|
|
|
|
2172
|
|
|
$result = $db->loadResult(); |
2173
|
|
|
|
2174
|
|
|
if (!is_null($result)) |
2175
|
|
|
{ |
2176
|
|
|
return (int) $result; |
2177
|
|
|
} |
2178
|
|
|
elseif ($catch_grammar == '1') |
2179
|
|
|
{ |
2180
|
|
|
return '0'; |
2181
|
|
|
} |
2182
|
|
|
else |
2183
|
|
|
{ |
2184
|
|
|
if (self::saveRevisedvalue($data)) |
2185
|
|
|
{ |
2186
|
|
|
return (int) $revised; |
2187
|
|
|
} |
2188
|
|
|
else |
2189
|
|
|
{ |
2190
|
|
|
return null; |
2191
|
|
|
} |
2192
|
|
|
} |
2193
|
|
|
} |
2194
|
|
|
|
2195
|
|
|
return null; |
2196
|
|
|
} |
2197
|
|
|
|
2198
|
|
|
/** |
2199
|
|
|
* Update revised changes |
2200
|
|
|
* |
2201
|
|
|
* @param array $data The required data. |
2202
|
|
|
* |
2203
|
|
|
* @return array |
2204
|
|
|
* |
2205
|
|
|
* @since 4.11 |
2206
|
|
|
*/ |
2207
|
|
|
public static function updateRevisedvalue($data) |
2208
|
|
|
{ |
2209
|
|
|
$client = $data['client']; |
2210
|
|
|
$reftag = $data['reftag']; |
2211
|
|
|
$tag = $data['tag']; |
2212
|
|
|
$filename = $data['filename']; |
2213
|
|
|
$revised = $data['revised']; |
2214
|
|
|
$key = $data['key']; |
2215
|
|
|
$target_text = $data['target_text']; |
2216
|
|
|
$source_text = $data['source_text']; |
2217
|
|
|
|
2218
|
|
|
if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename)) |
2219
|
|
|
{ |
2220
|
|
|
try |
2221
|
|
|
{ |
2222
|
|
|
$db = JFactory::getDbo(); |
2223
|
|
|
|
2224
|
|
|
$updated_client = $db->quote($client); |
2225
|
|
|
$updated_reftag = $db->quote($reftag); |
2226
|
|
|
$updated_tag = $db->quote($tag); |
2227
|
|
|
$updated_filename = $db->quote($filename); |
2228
|
|
|
$updated_revised = $db->quote($revised); |
2229
|
|
|
$updated_key = $db->quote($key); |
2230
|
|
|
$updated_target_text = $db->quote($target_text); |
2231
|
|
|
$updated_source_text = $db->quote($source_text); |
2232
|
|
|
|
2233
|
|
|
$query = $db->getQuery(true); |
2234
|
|
|
|
2235
|
|
|
$fields = array( |
2236
|
|
|
$db->quoteName('revised') . ' = ' . $updated_revised |
2237
|
|
|
); |
2238
|
|
|
|
2239
|
|
|
$conditions = array( |
2240
|
|
|
$db->quoteName('client') . ' = ' . $updated_client, |
2241
|
|
|
$db->quoteName('reftag') . ' = ' . $updated_reftag, |
2242
|
|
|
$db->quoteName('tag') . ' = ' . $updated_tag, |
2243
|
|
|
$db->quoteName('filename') . ' = ' . $updated_filename, |
2244
|
|
|
$db->quoteName('key') . ' = ' . $updated_key, |
2245
|
|
|
$db->quoteName('target_text') . ' = ' . $updated_target_text, |
2246
|
|
|
$db->quoteName('source_text') . ' = ' . $updated_source_text |
2247
|
|
|
); |
2248
|
|
|
|
2249
|
|
|
$query->update($db->quoteName('#__localise_revised_values'))->set($fields)->where($conditions); |
2250
|
|
|
|
2251
|
|
|
$db->setQuery($query); |
2252
|
|
|
$db->execute(); |
2253
|
|
|
} |
2254
|
|
|
|
2255
|
|
|
catch (JException $e) |
|
|
|
|
2256
|
|
|
{ |
2257
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_UPDATING_REVISED_VALUES'), 'warning'); |
2258
|
|
|
|
2259
|
|
|
return false; |
2260
|
|
|
} |
2261
|
|
|
|
2262
|
|
|
return true; |
2263
|
|
|
} |
2264
|
|
|
|
2265
|
|
|
return false; |
2266
|
|
|
} |
2267
|
|
|
|
2268
|
|
|
/** |
2269
|
|
|
* Save revised changes |
2270
|
|
|
* |
2271
|
|
|
* @param array $data The required data. |
2272
|
|
|
* |
2273
|
|
|
* @return array |
2274
|
|
|
* |
2275
|
|
|
* @since 4.11 |
2276
|
|
|
*/ |
2277
|
|
|
public static function saveRevisedvalue($data) |
2278
|
|
|
{ |
2279
|
|
|
$client = $data['client']; |
2280
|
|
|
$reftag = $data['reftag']; |
2281
|
|
|
$tag = $data['tag']; |
2282
|
|
|
$filename = $data['filename']; |
2283
|
|
|
$revised = $data['revised']; |
2284
|
|
|
$key = $data['key']; |
2285
|
|
|
$target_text = $data['target_text']; |
2286
|
|
|
$source_text = $data['source_text']; |
2287
|
|
|
|
2288
|
|
|
if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename)) |
2289
|
|
|
{ |
2290
|
|
|
try |
2291
|
|
|
{ |
2292
|
|
|
$db = JFactory::getDbo(); |
2293
|
|
|
|
2294
|
|
|
$saved_client = $db->quote($client); |
2295
|
|
|
$saved_reftag = $db->quote($reftag); |
2296
|
|
|
$saved_tag = $db->quote($tag); |
2297
|
|
|
$saved_filename = $db->quote($filename); |
2298
|
|
|
$saved_revised = $db->quote($revised); |
2299
|
|
|
$saved_key = $db->quote($key); |
2300
|
|
|
$saved_target_text = $db->quote($target_text); |
2301
|
|
|
$saved_source_text = $db->quote($source_text); |
2302
|
|
|
|
2303
|
|
|
$query = $db->getQuery(true); |
2304
|
|
|
|
2305
|
|
|
$columns = array('client', 'reftag', 'tag', 'filename', 'revised', 'key', 'target_text', 'source_text'); |
2306
|
|
|
|
2307
|
|
|
$values = array($saved_client, $saved_reftag, $saved_tag, $saved_filename, $saved_revised, $saved_key, $saved_target_text, $saved_source_text); |
2308
|
|
|
|
2309
|
|
|
$query |
2310
|
|
|
->insert($db->quoteName('#__localise_revised_values')) |
2311
|
|
|
->columns($db->quoteName($columns)) |
2312
|
|
|
->values(implode(',', $values)); |
2313
|
|
|
|
2314
|
|
|
$db->setQuery($query); |
2315
|
|
|
$db->execute(); |
2316
|
|
|
} |
2317
|
|
|
|
2318
|
|
|
catch (JException $e) |
|
|
|
|
2319
|
|
|
{ |
2320
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_SAVING_REVISED_VALUES'), 'warning'); |
2321
|
|
|
|
2322
|
|
|
return false; |
2323
|
|
|
} |
2324
|
|
|
|
2325
|
|
|
return true; |
2326
|
|
|
} |
2327
|
|
|
|
2328
|
|
|
return false; |
2329
|
|
|
} |
2330
|
|
|
|
2331
|
|
|
/** |
2332
|
|
|
* Create the required folders for develop |
2333
|
|
|
* |
2334
|
|
|
* @param array $gh_data Array with the data |
2335
|
|
|
* @param string $index If true, allow to create an index.html file |
2336
|
|
|
* |
2337
|
|
|
* @return bolean |
2338
|
|
|
* |
2339
|
|
|
* @since 4.11 |
2340
|
|
|
*/ |
2341
|
|
|
public static function createFolder($gh_data = array(), $index = 'true') |
2342
|
|
|
{ |
2343
|
|
|
$source_ref = $gh_data['customisedref']; |
2344
|
|
|
|
2345
|
|
|
if (!empty($gh_data) && isset($source_ref)) |
2346
|
|
|
{ |
2347
|
|
|
$full_path = JPATH_ROOT . '/media/com_localise/customisedref/github/' |
2348
|
|
|
. $gh_data['github_client'] |
2349
|
|
|
. '/' |
2350
|
|
|
. $source_ref; |
2351
|
|
|
|
2352
|
|
|
$full_path = JFolder::makeSafe($full_path); |
2353
|
|
|
|
2354
|
|
|
if (!JFolder::create($full_path)) |
2355
|
|
|
{ |
2356
|
|
|
} |
2357
|
|
|
|
2358
|
|
|
if (JFolder::exists($full_path)) |
2359
|
|
|
{ |
2360
|
|
|
if ($index == 'true') |
2361
|
|
|
{ |
2362
|
|
|
$cretate_index = self::createIndex($full_path); |
2363
|
|
|
|
2364
|
|
|
if ($cretate_index == 1) |
2365
|
|
|
{ |
2366
|
|
|
return true; |
2367
|
|
|
} |
2368
|
|
|
|
2369
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_INDEX_FILE'), 'warning'); |
2370
|
|
|
|
2371
|
|
|
return false; |
2372
|
|
|
} |
2373
|
|
|
|
2374
|
|
|
return true; |
2375
|
|
|
} |
2376
|
|
|
else |
2377
|
|
|
{ |
2378
|
|
|
JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_FOLDERS'), 'warning'); |
2379
|
|
|
|
2380
|
|
|
return false; |
2381
|
|
|
} |
2382
|
|
|
} |
2383
|
|
|
|
2384
|
|
|
return false; |
2385
|
|
|
} |
2386
|
|
|
|
2387
|
|
|
/** |
2388
|
|
|
* Creates an index.html file within folders for develop |
2389
|
|
|
* |
2390
|
|
|
* @param string $full_path The full path. |
2391
|
|
|
* |
2392
|
|
|
* @return bolean |
2393
|
|
|
* |
2394
|
|
|
* @since 4.11 |
2395
|
|
|
*/ |
2396
|
|
|
public static function createIndex($full_path = '') |
2397
|
|
|
{ |
2398
|
|
|
if (!empty($full_path)) |
2399
|
|
|
{ |
2400
|
|
|
$path = JFolder::makeSafe($full_path . '/index.html'); |
2401
|
|
|
|
2402
|
|
|
$index_content = '<!DOCTYPE html><title></title>'; |
2403
|
|
|
|
2404
|
|
|
if (!JFile::exists($path)) |
2405
|
|
|
{ |
2406
|
|
|
JFile::write($path, $index_content); |
2407
|
|
|
} |
2408
|
|
|
|
2409
|
|
|
if (!JFile::exists($path)) |
2410
|
|
|
{ |
2411
|
|
|
return false; |
2412
|
|
|
} |
2413
|
|
|
else |
2414
|
|
|
{ |
2415
|
|
|
return true; |
2416
|
|
|
} |
2417
|
|
|
} |
2418
|
|
|
|
2419
|
|
|
return false; |
2420
|
|
|
} |
2421
|
|
|
|
2422
|
|
|
/** |
2423
|
|
|
* Gets the text changes. |
2424
|
|
|
* |
2425
|
|
|
* @param array $old The string parts in reference. |
2426
|
|
|
* @param array $new The string parts in develop. |
2427
|
|
|
* |
2428
|
|
|
* @return array |
2429
|
|
|
* |
2430
|
|
|
* @since 4.11 |
2431
|
|
|
*/ |
2432
|
|
|
public static function getTextchanges($old, $new) |
2433
|
|
|
{ |
2434
|
|
|
$maxlen = 0; |
2435
|
|
|
|
2436
|
|
|
foreach ($old as $oindex => $ovalue) |
2437
|
|
|
{ |
2438
|
|
|
$nkeys = array_keys($new, $ovalue); |
2439
|
|
|
|
2440
|
|
|
foreach ($nkeys as $nindex) |
2441
|
|
|
{ |
2442
|
|
|
$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1; |
|
|
|
|
2443
|
|
|
|
2444
|
|
|
if ($matrix[$oindex][$nindex] > $maxlen) |
2445
|
|
|
{ |
2446
|
|
|
$maxlen = $matrix[$oindex][$nindex]; |
2447
|
|
|
$omax = $oindex + 1 - $maxlen; |
2448
|
|
|
$nmax = $nindex + 1 - $maxlen; |
2449
|
|
|
} |
2450
|
|
|
|
2451
|
|
|
unset ($nkeys, $nindex); |
2452
|
|
|
} |
2453
|
|
|
|
2454
|
|
|
unset ($oindex, $ovalue); |
2455
|
|
|
} |
2456
|
|
|
|
2457
|
|
|
if ($maxlen == 0) |
2458
|
|
|
{ |
2459
|
|
|
return array(array ('d' => $old, 'i' => $new)); |
2460
|
|
|
} |
2461
|
|
|
|
2462
|
|
|
return array_merge( |
2463
|
|
|
self::getTextchanges( |
2464
|
|
|
array_slice($old, 0, $omax), |
|
|
|
|
2465
|
|
|
array_slice($new, 0, $nmax) |
|
|
|
|
2466
|
|
|
), |
2467
|
|
|
array_slice($new, $nmax, $maxlen), |
2468
|
|
|
self::getTextchanges( |
2469
|
|
|
array_slice($old, $omax + $maxlen), |
2470
|
|
|
array_slice($new, $nmax + $maxlen) |
2471
|
|
|
) |
2472
|
|
|
); |
2473
|
|
|
} |
2474
|
|
|
|
2475
|
|
|
/** |
2476
|
|
|
* Gets the html text changes. |
2477
|
|
|
* |
2478
|
|
|
* @param string $old The string in reference. |
2479
|
|
|
* @param string $new The string in develop. |
2480
|
|
|
* |
2481
|
|
|
* @return string |
2482
|
|
|
* |
2483
|
|
|
* @since 4.11 |
2484
|
|
|
*/ |
2485
|
|
|
public static function htmlgetTextchanges($old, $new) |
2486
|
|
|
{ |
2487
|
|
|
$text_changes = ''; |
2488
|
|
|
|
2489
|
|
|
if ($old == $new) |
2490
|
|
|
{ |
2491
|
|
|
return $text_changes; |
2492
|
|
|
} |
2493
|
|
|
|
2494
|
|
|
$old = str_replace(' ', 'LOCALISEDOUBLESPACES', $old); |
2495
|
|
|
$new = str_replace(' ', 'LOCALISEDOUBLESPACES', $new); |
2496
|
|
|
|
2497
|
|
|
$diff = self::getTextchanges(explode(' ', $old), explode(' ', $new)); |
2498
|
|
|
|
2499
|
|
|
foreach ($diff as $k) |
2500
|
|
|
{ |
2501
|
|
|
if (is_array($k)) |
2502
|
|
|
{ |
2503
|
|
|
$text_changes .= (!empty ($k['d'])?"LOCALISEDELSTART" |
2504
|
|
|
. implode(' ', $k['d']) . "LOCALISEDELSTOP ":'') |
2505
|
|
|
. (!empty($k['i']) ? "LOCALISEINSSTART" |
2506
|
|
|
. implode(' ', $k['i']) |
2507
|
|
|
. "LOCALISEINSSTOP " : ''); |
2508
|
|
|
} |
2509
|
|
|
else |
2510
|
|
|
{ |
2511
|
|
|
$text_changes .= $k . ' '; |
2512
|
|
|
} |
2513
|
|
|
|
2514
|
|
|
unset ($k); |
2515
|
|
|
} |
2516
|
|
|
|
2517
|
|
|
$text_changes = htmlspecialchars($text_changes); |
2518
|
|
|
$text_changes = preg_replace('/LOCALISEINSSTART/', "<ins class='diff_ins'>", $text_changes); |
2519
|
|
|
$text_changes = preg_replace('/LOCALISEINSSTOP/', "</ins>", $text_changes); |
2520
|
|
|
$text_changes = preg_replace('/LOCALISEDELSTART/', "<del class='diff_del'>", $text_changes); |
2521
|
|
|
$text_changes = preg_replace('/LOCALISEDELSTOP/', "</del>", $text_changes); |
2522
|
|
|
$double_spaces = '<span class="red-space"><font color="red">XX</font></span>'; |
2523
|
|
|
$text_changes = str_replace('LOCALISEDOUBLESPACES', $double_spaces, $text_changes); |
2524
|
|
|
|
2525
|
|
|
return $text_changes; |
2526
|
|
|
} |
2527
|
|
|
} |
2528
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.