GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( ed0aa8...5ababc )
by
unknown
12:37
created

component/admin/helpers/localise.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
			// Allowed tricks.
1103
			// Configured to 0 the 2.5.x series are not allowed. Configured to 1 it is allowed.
1104
			$allow_25x = 1;
0 ignored issues
show
$allow_25x is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1105
1106 View Code Duplication
			foreach ($releases as $release)
1107
			{
1108
				$tag_name = $release->tag_name;
1109
				$tag_part = explode(".", $tag_name);
1110
				$undoted  = str_replace('.', '', $tag_name);
1111
				$excluded = 0;
1112
1113
				if (version_compare(JVERSION, '2', 'eq'))
1114
				{
1115
					$excluded = 1;
1116
				}
1117
				elseif (version_compare(JVERSION, '3', 'eq'))
1118
				{
1119
					if ($tag_part[0] != '3')
1120
					{
1121
						$excluded = 1;
1122
					}
1123
				}
1124
				elseif (version_compare(JVERSION, '4', 'ge'))
1125
				{
1126
					if ($tag_part[0] == '4' || $tag_part[0] == '3')
1127
					{
1128
						$excluded = 0;
1129
					}
1130
					else
1131
					{
1132
						$excluded = 1;
1133
					}
1134
				}
1135
1136
				// Filtering by "is_numeric" disable betas or similar releases.
1137
				if ($params->get('pre_stable', '0') == '0')
1138
				{
1139
					if (!in_array($tag_name, $versions) && is_numeric($undoted) && $excluded == 0)
1140
					{
1141
						$versions[] = $tag_name;
1142
						JFactory::getApplication()->enqueueMessage(
1143
							JText::sprintf('COM_LOCALISE_NOTICE_NEW_VERSION_DETECTED', $tag_name),
1144
							'notice');
1145
					}
1146
				}
1147
				else
1148
				{
1149
					if (!in_array($tag_name, $versions) && $excluded == 0)
1150
					{
1151
						$versions[] = $tag_name;
1152
						JFactory::getApplication()->enqueueMessage(
1153
							JText::sprintf('COM_LOCALISE_NOTICE_NEW_VERSION_DETECTED', $tag_name),
1154
							'notice');
1155
					}
1156
				}
1157
			}
1158
		}
1159
		catch (Exception $e)
1160
		{
1161
			JFactory::getApplication()->enqueueMessage(
1162
				JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_RELEASES'),
1163
				'warning');
1164
		}
1165
1166
		arsort($versions);
1167
1168
		$versions_file = '';
1169
1170
		foreach ($versions as $id => $version)
1171
		{
1172
			if (!empty($version))
1173
			{
1174
				$versions_file .= $version . "\n";
1175
			}
1176
		}
1177
1178
		JFile::write($versions_path, $versions_file);
1179
1180
		return $versions;
1181
	}
1182
1183
	/**
1184
	 * Save the last en-GB source version used as reference.
1185
	 *
1186
	 * @param   string  $client         The client
1187
	 *
1188
	 * @param   string  $customisedref  The version number
1189
	 *
1190
	 * @return  boolean
1191
	 *
1192
	 * @since   4.11
1193
	 */
1194
	public static function saveLastsourcereference($client = '', $customisedref = '')
1195
	{
1196
		$last_reference_file = JPATH_COMPONENT_ADMINISTRATOR
1197
					. '/customisedref/'
1198
					. $client
1199
					. '_last_source_ref.txt';
1200
1201
		$file_contents = $customisedref . "\n";
1202
1203
		if (!JFile::write($last_reference_file, $file_contents))
1204
		{
1205
			return false;
1206
		}
1207
1208
		return true;
1209
	}
1210
1211
	/**
1212
	 * Gets the last en-GB source reference version moved to the core folders.
1213
	 *
1214
	 * @return  array
1215
	 *
1216
	 * @since   4.11
1217
	 */
1218
	public static function getLastsourcereference()
1219
	{
1220
		$last_source_reference = array();
1221
		$last_source_reference['administrator'] = '';
1222
		$last_source_reference['site'] = '';
1223
		$last_source_reference['installation'] = '';
1224
1225
		$clients = array('administrator', 'site', 'installation');
1226
1227
		foreach ($clients as $client)
1228
		{
1229
			$last_reference_file = JPATH_COMPONENT_ADMINISTRATOR
1230
							. '/customisedref/'
1231
							. $client
1232
							. '_last_source_ref.txt';
1233
1234
			if (JFile::exists($last_reference_file))
1235
			{
1236
				$file_contents = file_get_contents($last_reference_file);
1237
				$lines = preg_split("/\\r\\n|\\r|\\n/", $file_contents);
1238
1239
				foreach ($lines as $line)
1240
				{
1241
					if (!empty($line))
1242
					{
1243
						$last_source_reference[$client] = $line;
1244
					}
1245
				}
1246
			}
1247
		}
1248
1249
		return $last_source_reference;
1250
	}
1251
1252
	/**
1253
	 * Gets the reference name to use at Github
1254
	 *
1255
	 * @param   array  $gh_data  Array with the required data
1256
	 *
1257
	 * @return  array
1258
	 *
1259
	 * @since   4.11
1260
	 */
1261
	public static function getCustomisedsource($gh_data = array())
1262
	{
1263
		$source_ref        = $gh_data['customisedref'];
1264
		$allow_develop     = $gh_data['allow_develop'];
1265
1266
		$sources = array();
1267
1268
		// Detailing it we can handle exceptions and add other Github users or projects.
1269
		// To get the language files for a determined Joomla's version that is not present from main Github repository.
1270
		$sources['3.4.1']['user']    = 'joomla';
1271
		$sources['3.4.1']['project'] = 'joomla-cms';
1272
		$sources['3.4.1']['branch']  = '3.4.1';
1273
1274
		if (array_key_exists($source_ref, $sources))
1275
		{
1276
			return ($sources[$source_ref]);
1277
		}
1278
1279
		// For undefined REF 0 or unlisted cases due Joomla releases at Github are following a version name patern.
1280
		$sources[$source_ref]['user']    = 'joomla';
1281
		$sources[$source_ref]['project'] = 'joomla-cms';
1282
		$sources[$source_ref]['branch']  = $source_ref;
1283
1284
	return ($sources[$source_ref]);
1285
	}
1286
1287
	/**
1288
	 * Keep updated the customised client path including only the common files present in develop.
1289
	 *
1290
	 * @param   string  $client              The client
1291
	 *
1292
	 * @param   string  $custom_client_path  The path where the new source reference is stored
1293
	 *
1294
	 * @return  boolean
1295
	 *
1296
	 * @since   4.11
1297
	 */
1298
	public static function updateSourcereference($client, $custom_client_path)
1299
	{
1300
		$develop_client_path   = JPATH_ROOT . '/media/com_localise/develop/github/joomla-cms/en-GB/' . $client;
1301
		$develop_client_path   = JFolder::makeSafe($develop_client_path);
1302
1303
		$custom_ini_files_list = self::getInifileslist($custom_client_path);
1304
		$last_ini_files_list   = self::getInifileslist($develop_client_path);
1305
1306
		$files_to_exclude = array();
1307
1308 View Code Duplication
		if (!JFile::exists($develop_client_path . '/en-GB.xml'))
1309
		{
1310
			JFactory::getApplication()->enqueueMessage(
1311
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_TARGET_FILES'),
1312
				'warning');
1313
1314
			return false;
1315
		}
1316
		elseif (!JFile::exists($custom_client_path . '/en-GB.xml'))
1317
		{
1318
			JFactory::getApplication()->enqueueMessage(
1319
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_SOURCE_FILES'),
1320
				'warning');
1321
1322
			return false;
1323
		}
1324
1325
		// This one is for files not present within last in dev yet.
1326
		// Due have no sense add old language files to translate or revise for the comming soon package.
1327
1328
		$files_to_exclude = array_diff($custom_ini_files_list, $last_ini_files_list);
1329
1330
		if (!empty($files_to_exclude))
1331
		{
1332
			$errors = 0;
1333
1334
			foreach ($files_to_exclude as $file_to_delete)
1335
			{
1336
				$custom_file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete);
1337
1338
				if (!JFile::delete($custom_file_path))
1339
				{
1340
					$errors++;
1341
				}
1342
			}
1343
1344
			if ($errors > 0)
1345
			{
1346
				JFactory::getApplication()->enqueueMessage(
1347
					JText::sprintf('COM_LOCALISE_ERROR_DELETING_EXTRA_SOURCE_FILES', $errors),
1348
					'warning');
1349
1350
				return false;
1351
			}
1352
		}
1353
1354
		return true;
1355
	}
1356
1357
	/**
1358
	 * Keep updated the core path with the selected source files as reference (used at previous working mode).
1359
	 *
1360
	 * @param   string  $client                 The client
1361
	 *
1362
	 * @param   string  $custom_client_path     The path where the new source reference is stored
1363
	 *
1364
	 * @param   string  $reference_client_path  The path where the old source reference is stored
1365
	 *
1366
	 * @return  boolean
1367
	 *
1368
	 * @since   4.11
1369
	 */
1370
	public static function updateSourcereferencedirectly($client, $custom_client_path, $reference_client_path)
1371
	{
1372
		$develop_client_path   = JPATH_ROOT . '/media/com_localise/develop/github/joomla-cms/en-GB/' . $client;
1373
		$develop_client_path   = JFolder::makeSafe($develop_client_path);
1374
1375
		$custom_ini_files_list = self::getInifileslist($custom_client_path);
1376
		$last_ini_files_list   = self::getInifileslist($develop_client_path);
1377
1378
		$files_to_exclude = array();
1379
1380 View Code Duplication
		if (!JFile::exists($develop_client_path . '/en-GB.xml'))
1381
		{
1382
			JFactory::getApplication()->enqueueMessage(
1383
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_TARGET_FILES'),
1384
				'warning');
1385
1386
			return false;
1387
		}
1388
		elseif (!JFile::exists($custom_client_path . '/en-GB.xml'))
1389
		{
1390
			JFactory::getApplication()->enqueueMessage(
1391
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_SOURCE_FILES'),
1392
				'warning');
1393
1394
			return false;
1395
		}
1396
1397
		// This one is for core files not present within last in dev yet.
1398
		// Due have no sense add old language files to translate for the comming soon package.
1399
1400
		$files_to_exclude = array_diff($custom_ini_files_list, $last_ini_files_list);
1401
1402
		if (!empty($files_to_exclude))
1403
		{
1404
			foreach ($files_to_exclude as $file_to_delete)
1405
			{
1406
				$custom_file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete);
1407
				$actual_file_path = JFolder::makeSafe($reference_client_path . "/" . $file_to_delete);
1408
1409
				JFile::delete($custom_file_path);
1410
1411
				// Also verify if the same file is also present in core language folder.
1412
1413
				if (JFile::exists($actual_file_path))
1414
				{
1415
					JFile::delete($actual_file_path);
1416
1417
					JFactory::getApplication()->enqueueMessage(
1418
					JText::sprintf('COM_LOCALISE_OLD_FILE_DELETED', $file_to_delete),
1419
					'notice');
1420
				}
1421
			}
1422
1423
			// Getting the new list again
1424
			$custom_ini_files_list = self::getInifileslist($custom_client_path);
1425
		}
1426
1427
		$errors = 0;
1428
1429
		foreach ($custom_ini_files_list as $customised_source_file)
1430
		{
1431
			$source_path = $custom_client_path . '/' . $customised_source_file;
1432
			$file_contents = file_get_contents($source_path);
1433
			$target_path = $reference_client_path . '/' . $customised_source_file;
1434
1435
			if (!JFile::write($target_path, $file_contents))
1436
			{
1437
				$errors++;
1438
			}
1439
		}
1440
1441
		if ($errors > 0)
1442
		{
1443
			JFactory::getApplication()->enqueueMessage(
1444
				JText::sprintf('COM_LOCALISE_ERROR_SAVING_FILES_AT_CORE_FOLDER', $errors),
1445
				'warning');
1446
1447
			return false;
1448
		}
1449
1450
		return true;
1451
	}
1452
1453
	/**
1454
	 * Gets from zero or keept updated the files in develop to use as target reference from Github
1455
	 *
1456
	 * @param   array  $gh_data  Array with the required data
1457
	 *
1458
	 * @return  array
1459
	 *
1460
	 * @since   4.11
1461
	 */
1462
	public static function getTargetgithubfiles($gh_data = array())
1463
	{
1464
		if (!empty($gh_data))
1465
		{
1466
			$now                = new JDate;
1467
			$now                = $now->toSQL();
1468
			$params             = JComponentHelper::getParams('com_localise');
1469
			$client_to_update   = 'gh_' . $gh_data['github_client'] . '_last_update';
1470
			$last_stored_update = $params->get($client_to_update, '');
1471
			$ref_tag            = $params->get('reference', 'en-GB');
1472
			$allow_develop      = $params->get('gh_allow_develop', 0);
1473
1474
			if ($allow_develop == 0)
1475
			{
1476
				return false;
1477
			}
1478
1479
			if ($ref_tag != 'en-GB')
1480
			{
1481
				JFactory::getApplication()->enqueueMessage(
1482
					JText::_('COM_LOCALISE_ERROR_GETTING_ALLOWED_REFERENCE_TAG'),
1483
					'warning');
1484
1485
				return false;
1486
			}
1487
1488
			$develop_client_path = JPATH_ROOT
1489
						. '/media/com_localise/develop/github/joomla-cms/en-GB/'
1490
						. $gh_data['github_client'];
1491
1492
			$develop_client_path = JFolder::makeSafe($develop_client_path);
1493
			$xml_file            = $develop_client_path . '/en-GB.xml';
1494
1495
			if (!JFile::exists($xml_file))
1496
			{
1497
				$get_files = 1;
1498
			}
1499
			elseif (!empty($last_stored_update))
1500
			{
1501
				$last_update = new JDate($last_stored_update);
1502
				$last_update = $last_update->toSQL();
1503
				$interval    = $params->get('gh_updates_interval', '1') == '1' ? 24 : 1;
1504
				$interval    = $last_update . " +" . $interval . " hours";
1505
				$next_update = new JDate($interval);
1506
				$next_update = $next_update->toSQL();
1507
1508
				if ($now >= $next_update)
1509
				{
1510
					$get_files = 1;
1511
				}
1512
				else
1513
				{
1514
					$get_files = 0;
1515
				}
1516
			}
1517
			else
1518
			{
1519
				$get_files = 1;
1520
			}
1521
1522
			if ($get_files == 0)
1523
			{
1524
				return false;
1525
			}
1526
1527
			$gh_paths                  = array();
1528
			$gh_client                 = $gh_data['github_client'];
1529
			$gh_user                   = 'joomla';
1530
			$gh_project                = 'joomla-cms';
1531
			$gh_branch                 = $params->get('gh_branch', 'master');
1532
			$gh_token                  = $params->get('gh_token', '');
1533
			$gh_paths['administrator'] = 'administrator/language/en-GB';
1534
			$gh_paths['site']          = 'language/en-GB';
1535
			$gh_paths['installation']  = 'installation/language/en-GB';
1536
1537
			$reference_client_path = JPATH_ROOT . '/' . $gh_paths[$gh_client];
1538
			$reference_client_path = JFolder::makeSafe($reference_client_path);
1539
1540
			$options = new JRegistry;
1541
1542 View Code Duplication
			if (!empty($gh_token))
1543
			{
1544
				$options->set('gh.token', $gh_token);
1545
				$github = new Github($options);
1546
			}
1547
			else
1548
			{
1549
				// Without a token runs fatal.
1550
				// $github = new JGithub;
1551
1552
				// Trying with a 'read only' public repositories token
1553
				// But base 64 encoded to avoid Github alarms sharing it.
1554
				$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA==');
1555
				$options->set('gh.token', $gh_token);
1556
				$github = new Github($options);
1557
			}
1558
1559
			try
1560
			{
1561
				$repostoryfiles = $github->repositories->contents->get(
1562
					$gh_user,
1563
					$gh_project,
1564
					$gh_paths[$gh_client],
1565
					$gh_branch
1566
					);
1567
			}
1568
			catch (Exception $e)
1569
			{
1570
				JFactory::getApplication()->enqueueMessage(
1571
					JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_REPOSITORY_FILES'),
1572
					'warning');
1573
1574
				return false;
1575
			}
1576
1577
			$all_files_list = self::getLanguagefileslist($develop_client_path);
1578
			$ini_files_list = self::getInifileslist($develop_client_path);
1579
			$sha_files_list = self::getShafileslist($gh_data);
1580
1581
			$sha = '';
1582
			$files_to_include = array();
1583
1584
			foreach ($repostoryfiles as $repostoryfile)
1585
			{
1586
				$file_to_include     = $repostoryfile->name;
1587
				$file_path           = JFolder::makeSafe($develop_client_path . '/' . $file_to_include);
1588
				$reference_file_path = JFolder::makeSafe($reference_client_path . '/' . $file_to_include);
1589
1590
				if (	(array_key_exists($file_to_include, $sha_files_list)
1591
					&& ($sha_files_list[$file_to_include] != $repostoryfile->sha))
1592
					|| empty($sha_files_list)
1593
					|| !array_key_exists($file_to_include, $sha_files_list)
1594
					|| !JFile::exists($file_path))
1595
				{
1596
					$in_dev_file = $github->repositories->contents->get(
1597
							$gh_user,
1598
							$gh_project,
1599
							$repostoryfile->path,
1600
							$gh_branch
1601
							);
1602
				}
1603
				else
1604
				{
1605
					$in_dev_file = '';
1606
				}
1607
1608
				$files_to_include[] = $file_to_include;
1609
				$sha_path  = JPATH_COMPONENT_ADMINISTRATOR . '/develop/gh_joomla_' . $gh_client . '_files.txt';
1610
				$sha_path  = JFolder::makeSafe($sha_path);
1611
1612
				if (!empty($in_dev_file) && isset($in_dev_file->content))
1613
				{
1614
					$file_to_include = $repostoryfile->name;
1615
					$file_contents = base64_decode($in_dev_file->content);
1616
					JFile::write($file_path, $file_contents);
1617
1618
					if (!JFile::exists($file_path))
1619
					{
1620
						JFactory::getApplication()->enqueueMessage(
1621
							JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_DEV_FILE'),
1622
							'warning');
1623
1624
						return false;
1625
					}
1626
1627
					if (!JFile::exists($reference_file_path)
1628
						&& ($gh_client == 'administrator' || $gh_client == 'site'))
1629
					{
1630
						// Adding files only present in develop to core reference location.
1631
						JFile::write($reference_file_path, $file_contents);
1632
1633
						if (!JFile::exists($reference_file_path))
1634
						{
1635
							JFactory::getApplication()->enqueueMessage(
1636
								JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_ADD_NEW_FILES'),
1637
								'warning');
1638
1639
							return false;
1640
						}
1641
1642
						JFactory::getApplication()->enqueueMessage(
1643
							JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED', $file_to_include, $gh_branch, $gh_client),
1644
							'notice');
1645
					}
1646
				}
1647
1648
				// Saved for each time due few times get all the github files at same time can crash.
1649
				// This one can help to remember the last one saved correctly and next time continue from there.
1650
				$sha .= $repostoryfile->name . "::" . $repostoryfile->sha . "\n";
1651
				JFile::write($sha_path, $sha);
1652
1653
				if (!JFile::exists($sha_path))
1654
				{
1655
					JFactory::getApplication()->enqueueMessage(
1656
						JText::_('COM_LOCALISE_ERROR_GITHUB_NO_SHA_FILE_PRESENT'),
1657
						'warning');
1658
1659
					return false;
1660
				}
1661
			}
1662
1663
			if (!empty($all_files_list) && !empty($files_to_include))
1664
			{
1665
				// For files not present in dev yet.
1666
				$files_to_delete = array_diff($all_files_list, $files_to_include);
1667
1668
				if (!empty($files_to_delete))
1669
				{
1670
					foreach ($files_to_delete as $file_to_delete)
1671
					{
1672
						if ($file_to_delete != 'index.html')
1673
						{
1674
							$file_path = JFolder::makeSafe($develop_client_path . "/" . $file_to_delete);
1675
							JFile::delete($file_path);
1676
1677
							if (JFile::exists($file_path))
1678
							{
1679
								JFactory::getApplication()->enqueueMessage(
1680
									JText::sprintf('COM_LOCALISE_ERROR_GITHUB_FILE_TO_DELETE_IS_PRESENT', $file_to_delete),
1681
									'warning');
1682
1683
								return false;
1684
							}
1685
1686
							JFactory::getApplication()->enqueueMessage(
1687
								JText::sprintf('COM_LOCALISE_GITHUB_FILE_NOT_PRESENT_IN_DEV_YET', $file_to_delete),
1688
								'notice');
1689
						}
1690
					}
1691
				}
1692
			}
1693
1694
			if (!JFile::exists($xml_file))
1695
			{
1696
				JFactory::getApplication()->enqueueMessage(
1697
					JText::sprintf('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_GET_A_FULL_SET', $gh_branch),
1698
					'warning');
1699
1700
				return false;
1701
			}
1702
1703
			self::saveLastupdate($client_to_update);
1704
1705
			JFactory::getApplication()->enqueueMessage(
1706
				JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_GETS_A_TARGET_FULL_SET', $gh_branch),
1707
				'notice');
1708
1709
			return true;
1710
		}
1711
1712
		JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_NO_DATA_PRESENT'), 'warning');
1713
1714
		return false;
1715
	}
1716
1717
	/**
1718
	 * Gets the changes between language files versions
1719
	 *
1720
	 * @param   array  $info              The data to catch grammar cases
1721
	 * @param   array  $refsections       The released reference data
1722
	 * @param   array  $develop_sections  The developed reference data
1723
	 *
1724
	 * @return  array
1725
	 *
1726
	 * @since   4.11
1727
	 */
1728
	public static function getDevelopchanges($info = array(), $refsections = array(), $develop_sections = array())
1729
	{
1730
		if (isset($refsections['keys']) && isset($develop_sections['keys']))
1731
		{
1732
			$istranslation     = $info['istranslation'];
1733
			$keys_in_reference = array_keys($refsections['keys']);
1734
			$keys_in_develop   = array_keys($develop_sections['keys']);
1735
1736
			// Catching new keys in develop
1737
			$developdata['extra_keys']['amount']  = 0;
1738
			$developdata['extra_keys']['keys']    = array();
1739
			$developdata['extra_keys']['strings'] = array();
1740
1741
			$extras_in_develop = array_diff($keys_in_develop, $keys_in_reference);
1742
1743
			if (!empty($extras_in_develop))
1744
			{
1745
				foreach ($extras_in_develop as $extra_key)
1746
				{
1747
					$developdata['extra_keys']['amount']++;
1748
					$developdata['extra_keys']['keys'][]              = $extra_key;
1749
					$developdata['extra_keys']['strings'][$extra_key] = $develop_sections['keys'][$extra_key];
1750
				}
1751
			}
1752
1753
			// Catching text changes in develop
1754
			$developdata['text_changes']['amount']     = 0;
1755
			$developdata['text_changes']['revised']    = 0;
1756
			$developdata['text_changes']['unrevised']  = 0;
1757
			$developdata['text_changes']['keys']       = array();
1758
			$developdata['text_changes']['ref_in_dev'] = array();
1759
			$developdata['text_changes']['ref']        = array();
1760
			$developdata['text_changes']['diff']       = array();
1761
1762
			foreach ($refsections['keys'] as $key => $string)
1763
			{
1764
				if (array_key_exists($key, $develop_sections['keys']))
1765
				{
1766
					$string_in_develop = $develop_sections['keys'][$key];
1767
					$text_changes = self::htmlgetTextchanges($string, $string_in_develop);
1768
1769
					if (!empty($text_changes))
1770
					{
1771
						if ($istranslation == 1)
1772
						{
1773
							$info['key']           = $key;
1774
							$info['source_text']   = $string;
1775
							$info['target_text']   = $string_in_develop;
1776
							$info['catch_grammar'] = 1;
1777
							$info['revised']       = 0;
1778
1779
							$grammar_case = self::searchRevisedvalue($info);
1780
						}
1781
						else
1782
						{
1783
							$grammar_case = '0';
1784
						}
1785
1786
						if ($grammar_case == '0')
1787
						{
1788
							$developdata['text_changes']['amount']++;
1789
							$developdata['text_changes']['keys'][]           = $key;
1790
							$developdata['text_changes']['ref_in_dev'][$key] = $develop_sections['keys'][$key];
1791
							$developdata['text_changes']['ref'][$key]        = $string;
1792
							$developdata['text_changes']['diff'][$key]       = $text_changes;
1793
						}
1794
					}
1795
				}
1796
			}
1797
1798
			return $developdata;
1799
		}
1800
1801
		return array();
1802
	}
1803
1804
	/**
1805
	 * Gets the develop path if exists
1806
	 *
1807
	 * @param   string  $client   The client
1808
	 * @param   string  $refpath  The data to the reference path
1809
	 *
1810
	 * @return  string
1811
	 *
1812
	 * @since   4.11
1813
	 */
1814
	public static function searchDevpath($client = '', $refpath = '')
1815
	{
1816
		$params             = JComponentHelper::getParams('com_localise');
1817
		$ref_tag            = $params->get('reference', 'en-GB');
1818
		$allow_develop      = $params->get('gh_allow_develop', 0);
1819
1820
		$develop_client_path = JPATH_ROOT
1821
					. '/media/com_localise/develop/github/joomla-cms/en-GB/'
1822
					. $client;
1823
1824
		$ref_file            = basename($refpath);
1825
		$develop_file_path   = JFolder::makeSafe("$develop_client_path/$ref_file");
1826
1827
		if (JFile::exists($develop_file_path) && $allow_develop == 1 && $ref_tag == 'en-GB')
1828
		{
1829
			$devpath = $develop_file_path;
1830
		}
1831
		else
1832
		{
1833
			$devpath = '';
1834
		}
1835
1836
		return $devpath;
1837
	}
1838
1839
	/**
1840
	 * Gets the customised source path if exists
1841
	 *
1842
	 * @param   string  $client   The client
1843
	 * @param   string  $refpath  The data to the reference path
1844
	 *
1845
	 * @return  string
1846
	 *
1847
	 * @since   4.11
1848
	 */
1849
	public static function searchCustompath($client = '', $refpath = '')
1850
	{
1851
		$params             = JComponentHelper::getParams('com_localise');
1852
		$ref_tag            = $params->get('reference', 'en-GB');
1853
		$allow_develop      = $params->get('gh_allow_develop', 0);
1854
		$customisedref      = $params->get('customisedref', '0');
1855
		$custom_client_path = JPATH_ROOT
1856
					. '/media/com_localise/customisedref/github/'
1857
					. $client
1858
					. '/'
1859
					. $customisedref;
1860
1861
		$ref_file         = basename($refpath);
1862
		$custom_file_path = JFolder::makeSafe("$custom_client_path/$ref_file");
1863
1864
		if (JFile::exists($custom_file_path) && $allow_develop == 1 && $ref_tag == 'en-GB' && $customisedref != 0)
1865
		{
1866
			$custom_path = $custom_file_path;
1867
		}
1868
		else
1869
		{
1870
			$custom_path = '';
1871
		}
1872
1873
		return $custom_path;
1874
	}
1875
1876
	/**
1877
	 * Allow combine the reference versions to obtain a right result editing in raw mode or saving source reference files
1878
	 * When development is enabled.
1879
	 *
1880
	 * @param   string  $refpath  The data to the reference path
1881
	 *
1882
	 * @param   string  $devpath  The data to the develop path
1883
	 *
1884
	 * @return  string
1885
	 *
1886
	 * @since   4.11
1887
	 */
1888
	public static function combineReferences($refpath = '', $devpath = '')
1889
	{
1890
		$params             = JComponentHelper::getParams('com_localise');
1891
		$ref_tag            = $params->get('reference', 'en-GB');
1892
		$allow_develop      = $params->get('gh_allow_develop', 0);
1893
		$combined_content   = '';
1894
1895
		if (JFile::exists($devpath) && JFile::exists($refpath) && $allow_develop == 1 && $ref_tag == 'en-GB')
1896
		{
1897
			$ref_sections      = self::parseSections($refpath);
1898
			$keys_in_reference = array_keys($ref_sections['keys']);
1899
1900
			$stream = new JStream;
1901
			$stream->open($devpath);
1902
			$stream->seek(0);
1903
1904
			while (!$stream->eof())
1905
			{
1906
				$line = $stream->gets();
1907
1908
				if (preg_match('/^([A-Z][A-Z0-9_\*\-\.]*)\s*=/', $line, $matches))
1909
				{
1910
					$key = $matches[1];
1911
1912
					if (in_array($key, $keys_in_reference))
1913
					{
1914
						$string = $ref_sections['keys'][$key];
1915
						$combined_content .= $key . '="' . str_replace('"', '"_QQ_"', $string) . "\"\n";
1916
					}
1917
					else
1918
					{
1919
						$combined_content .= $line;
1920
					}
1921
				}
1922
				else
1923
				{
1924
					$combined_content .= $line;
1925
				}
1926
			}
1927
1928
			$stream->close();
1929
		}
1930
1931
		return $combined_content;
1932
	}
1933
1934
	/**
1935
	 * Gets the list of ini files
1936
	 *
1937
	 * @param   string  $client_path  The data to the client path
1938
	 *
1939
	 * @return  array
1940
	 *
1941
	 * @since   4.11
1942
	 */
1943
	public static function getInifileslist($client_path = '')
1944
	{
1945
		if (!empty($client_path))
1946
		{
1947
			$files = JFolder::files($client_path, ".ini$");
1948
1949
			return $files;
1950
		}
1951
1952
	return array();
1953
	}
1954
1955
	/**
1956
	 * Gets the list of all type of files in develop
1957
	 *
1958
	 * @param   string  $develop_client_path  The data to the client path
1959
	 *
1960
	 * @return  array
1961
	 *
1962
	 * @since   4.11
1963
	 */
1964
	public static function getLanguagefileslist($develop_client_path = '')
1965
	{
1966
		if (!empty($develop_client_path))
1967
		{
1968
			$files = JFolder::files($develop_client_path);
1969
1970
			return $files;
1971
		}
1972
1973
	return array();
1974
	}
1975
1976
	/**
1977
	 * Gets the stored SHA id for the files in develop.
1978
	 *
1979
	 * @param   array  $gh_data  The required data.
1980
	 *
1981
	 * @return  array
1982
	 *
1983
	 * @since   4.11
1984
	 */
1985
	public static function getShafileslist($gh_data = array())
1986
	{
1987
		$sha_files = array();
1988
		$gh_client = $gh_data['github_client'];
1989
		$sha_path  = JFolder::makeSafe(JPATH_COMPONENT_ADMINISTRATOR . '/develop/gh_joomla_' . $gh_client . '_files.txt');
1990
1991
		if (JFile::exists($sha_path))
1992
		{
1993
			$file_contents = file_get_contents($sha_path);
1994
			$lines = preg_split("/\\r\\n|\\r|\\n/", $file_contents);
1995
1996
			if (!empty($lines))
1997
			{
1998
				foreach ($lines as $line)
1999
				{
2000
					if (!empty($line))
2001
					{
2002
						list($filename, $sha) = explode('::', $line, 2);
2003
2004
						if (!empty($filename) && !empty($sha))
2005
						{
2006
							$sha_files[$filename] = $sha;
2007
						}
2008
					}
2009
				}
2010
			}
2011
		}
2012
2013
	return $sha_files;
2014
	}
2015
2016
	/**
2017
	 * Save the date of the last Github files update by client.
2018
	 *
2019
	 * @param   string  $client_to_update  The client language files.
2020
	 *
2021
	 * @return  bolean
2022
	 *
2023
	 * @since   4.11
2024
	 */
2025
	public static function saveLastupdate($client_to_update)
2026
	{
2027
		$now    = new JDate;
2028
		$now    = $now->toSQL();
2029
		$params = JComponentHelper::getParams('com_localise');
2030
		$params->set($client_to_update, $now);
2031
2032
		$localise_id = JComponentHelper::getComponent('com_localise')->id;
2033
2034
		$table = JTable::getInstance('extension');
2035
		$table->load($localise_id);
2036
		$table->bind(array('params' => $params->toString()));
2037
2038
		if (!$table->check())
2039
		{
2040
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2041
2042
			return false;
2043
		}
2044
2045
		if (!$table->store())
2046
		{
2047
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2048
2049
			return false;
2050
		}
2051
2052
		return true;
2053
	}
2054
2055
	/**
2056
	 * Forces to save the customised source version to use. Option '0' returns to local installed instance.
2057
	 *
2058
	 * @param   string  $option  The option value to save.
2059
	 *
2060
	 * @return  bolean
2061
	 *
2062
	 * @since   4.11
2063
	 */
2064
	public static function setCustomisedsource($option = '0')
2065
	{
2066
		$params = JComponentHelper::getParams('com_localise');
2067
		$params->set('customisedref', $option);
2068
2069
		$localise_id = JComponentHelper::getComponent('com_localise')->id;
2070
2071
		$table = JTable::getInstance('extension');
2072
		$table->load($localise_id);
2073
		$table->bind(array('params' => $params->toString()));
2074
2075
		if (!$table->check())
2076
		{
2077
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2078
2079
			return false;
2080
		}
2081
2082
		if (!$table->store())
2083
		{
2084
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2085
2086
			return false;
2087
		}
2088
2089
		return true;
2090
	}
2091
2092
	/**
2093
	 * Load revised changes
2094
	 *
2095
	 * @param   array  $data  The required data.
2096
	 *
2097
	 * @return  array
2098
	 *
2099
	 * @since   4.11
2100
	 */
2101
	public static function searchRevisedvalue($data)
2102
	{
2103
		$client        = $data['client'];
2104
		$reftag        = $data['reftag'];
2105
		$tag           = $data['tag'];
2106
		$filename      = $data['filename'];
2107
		$revised       = $data['revised'];
2108
		$key           = $data['key'];
2109
		$target_text   = $data['target_text'];
2110
		$source_text   = $data['source_text'];
2111
		$istranslation = $data['istranslation'];
2112
		$catch_grammar = $data['catch_grammar'];
2113
2114
		if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename))
2115
		{
2116
			try
2117
			{
2118
				$db                 = JFactory::getDbo();
2119
				$query	            = $db->getQuery(true);
2120
2121
				$search_client      = $db->quote($client);
2122
				$search_reftag      = $db->quote($reftag);
2123
				$search_tag         = $db->quote($tag);
2124
				$search_filename    = $db->quote($filename);
2125
				$search_key         = $db->quote($key);
2126
				$search_target_text = $db->quote($target_text);
2127
				$search_source_text = $db->quote($source_text);
2128
2129
				$query->select(
2130
						array	(
2131
							$db->quoteName('revised')
2132
							)
2133
						);
2134
				$query->from(
2135
						$db->quoteName('#__localise_revised_values')
2136
						);
2137
				$query->where(
2138
						$db->quoteName('client') . '= ' . $search_client
2139
						);
2140
				$query->where(
2141
						$db->quoteName('reftag') . '= ' . $search_reftag
2142
2143
						);
2144
				$query->where(
2145
						$db->quoteName('tag') . '= ' . $search_tag
2146
2147
						);
2148
				$query->where(
2149
						$db->quoteName('filename') . '= ' . $search_filename
2150
						);
2151
				$query->where(
2152
						$db->quoteName('key') . '= ' . $search_key
2153
						);
2154
				$query->where(
2155
						$db->quoteName('target_text') . '= ' . $search_target_text
2156
						);
2157
				$query->where(
2158
						$db->quoteName('source_text') . '= ' . $search_source_text
2159
						);
2160
2161
				$db->setQuery($query);
2162
2163
					if (!$db->query())
2164
					{
2165
						throw new Exception($db->getErrorMsg());
2166
					}
2167
			}
2168
2169
			catch (JException $e)
2170
			{
2171
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_SEARCHING_REVISED_VALUES'), 'warning');
2172
2173
				return null;
2174
			}
2175
2176
			$result = $db->loadResult();
2177
2178
				if (!is_null($result))
2179
				{
2180
					return (int) $result;
2181
				}
2182
				elseif ($catch_grammar == '1')
2183
				{
2184
					return '0';
2185
				}
2186
				else
2187
				{
2188
					if (self::saveRevisedvalue($data))
2189
					{
2190
						return (int) $revised;
2191
					}
2192
					else
2193
					{
2194
						return null;
2195
					}
2196
				}
2197
		}
2198
2199
		return null;
2200
	}
2201
2202
	/**
2203
	 * Update revised changes
2204
	 *
2205
	 * @param   array  $data  The required data.
2206
	 *
2207
	 * @return  array
2208
	 *
2209
	 * @since   4.11
2210
	 */
2211
	public static function updateRevisedvalue($data)
2212
	{
2213
		$client      = $data['client'];
2214
		$reftag      = $data['reftag'];
2215
		$tag         = $data['tag'];
2216
		$filename    = $data['filename'];
2217
		$revised     = $data['revised'];
2218
		$key         = $data['key'];
2219
		$target_text = $data['target_text'];
2220
		$source_text = $data['source_text'];
2221
2222
		if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename))
2223
		{
2224
			try
2225
			{
2226
				$db = JFactory::getDbo();
2227
2228
				$updated_client      = $db->quote($client);
2229
				$updated_reftag      = $db->quote($reftag);
2230
				$updated_tag         = $db->quote($tag);
2231
				$updated_filename    = $db->quote($filename);
2232
				$updated_revised     = $db->quote($revised);
2233
				$updated_key         = $db->quote($key);
2234
				$updated_target_text = $db->quote($target_text);
2235
				$updated_source_text = $db->quote($source_text);
2236
2237
				$query = $db->getQuery(true);
2238
2239
				$fields = array(
2240
					$db->quoteName('revised') . ' = ' . $updated_revised
2241
				);
2242
2243
				$conditions = array(
2244
					$db->quoteName('client') . ' = ' . $updated_client,
2245
					$db->quoteName('reftag') . ' = ' . $updated_reftag,
2246
					$db->quoteName('tag') . ' = ' . $updated_tag,
2247
					$db->quoteName('filename') . ' = ' . $updated_filename,
2248
					$db->quoteName('key') . ' = ' . $updated_key,
2249
					$db->quoteName('target_text') . ' = ' . $updated_target_text,
2250
					$db->quoteName('source_text') . ' = ' . $updated_source_text
2251
				);
2252
2253
				$query->update($db->quoteName('#__localise_revised_values'))->set($fields)->where($conditions);
2254
2255
				$db->setQuery($query);
2256
				$db->execute();
2257
			}
2258
2259
			catch (JException $e)
2260
			{
2261
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_UPDATING_REVISED_VALUES'), 'warning');
2262
2263
				return false;
2264
			}
2265
2266
			return true;
2267
		}
2268
2269
		return false;
2270
	}
2271
2272
	/**
2273
	 * Save revised changes
2274
	 *
2275
	 * @param   array  $data  The required data.
2276
	 *
2277
	 * @return  array
2278
	 *
2279
	 * @since   4.11
2280
	 */
2281
	public static function saveRevisedvalue($data)
2282
	{
2283
		$client      = $data['client'];
2284
		$reftag      = $data['reftag'];
2285
		$tag         = $data['tag'];
2286
		$filename    = $data['filename'];
2287
		$revised     = $data['revised'];
2288
		$key         = $data['key'];
2289
		$target_text = $data['target_text'];
2290
		$source_text = $data['source_text'];
2291
2292
		if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename))
2293
		{
2294
			try
2295
			{
2296
				$db = JFactory::getDbo();
2297
2298
				$saved_client      = $db->quote($client);
2299
				$saved_reftag      = $db->quote($reftag);
2300
				$saved_tag         = $db->quote($tag);
2301
				$saved_filename    = $db->quote($filename);
2302
				$saved_revised     = $db->quote($revised);
2303
				$saved_key         = $db->quote($key);
2304
				$saved_target_text = $db->quote($target_text);
2305
				$saved_source_text = $db->quote($source_text);
2306
2307
				$query = $db->getQuery(true);
2308
2309
				$columns = array('client', 'reftag', 'tag', 'filename', 'revised', 'key', 'target_text', 'source_text');
2310
2311
				$values = array($saved_client, $saved_reftag, $saved_tag, $saved_filename, $saved_revised, $saved_key, $saved_target_text, $saved_source_text);
2312
2313
				$query
2314
					->insert($db->quoteName('#__localise_revised_values'))
2315
					->columns($db->quoteName($columns))
2316
					->values(implode(',', $values));
2317
2318
				$db->setQuery($query);
2319
				$db->execute();
2320
			}
2321
2322
			catch (JException $e)
2323
			{
2324
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_SAVING_REVISED_VALUES'), 'warning');
2325
2326
				return false;
2327
			}
2328
2329
			return true;
2330
		}
2331
2332
		return false;
2333
	}
2334
2335
	/**
2336
	 * Create the required folders for develop
2337
	 *
2338
	 * @param   array   $gh_data  Array with the data
2339
	 * @param   string  $index    If true, allow to create an index.html file
2340
	 *
2341
	 * @return  bolean
2342
	 *
2343
	 * @since   4.11
2344
	 */
2345
	public static function createFolder($gh_data = array(), $index = 'true')
2346
	{
2347
		$source_ref = $gh_data['customisedref'];
2348
2349
		if (!empty($gh_data) && isset($source_ref))
2350
		{
2351
		$full_path = JPATH_ROOT . '/media/com_localise/customisedref/github/'
2352
					. $gh_data['github_client']
2353
					. '/'
2354
					. $source_ref;
2355
2356
		$full_path = JFolder::makeSafe($full_path);
2357
2358
			if (!JFolder::create($full_path))
2359
			{
2360
			}
2361
2362
			if (JFolder::exists($full_path))
2363
			{
2364
				if ($index == 'true')
2365
				{
2366
				$cretate_index = self::createIndex($full_path);
2367
2368
					if ($cretate_index == 1)
2369
					{
2370
						return true;
2371
					}
2372
2373
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_INDEX_FILE'), 'warning');
2374
2375
				return false;
2376
				}
2377
2378
			return true;
2379
			}
2380
			else
2381
			{
2382
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_FOLDERS'), 'warning');
2383
2384
				return false;
2385
			}
2386
		}
2387
2388
	return false;
2389
	}
2390
2391
	/**
2392
	 * Creates an index.html file within folders for develop
2393
	 *
2394
	 * @param   string  $full_path  The full path.
2395
	 *
2396
	 * @return  bolean
2397
	 *
2398
	 * @since   4.11
2399
	 */
2400
	public static function createIndex($full_path = '')
2401
	{
2402
		if (!empty($full_path))
2403
		{
2404
		$path = JFolder::makeSafe($full_path . '/index.html');
2405
2406
		$index_content = '<!DOCTYPE html><title></title>';
2407
2408
			if (!JFile::exists($path))
2409
			{
2410
				JFile::write($path, $index_content);
2411
			}
2412
2413
			if (!JFile::exists($path))
2414
			{
2415
				return false;
2416
			}
2417
			else
2418
			{
2419
				return true;
2420
			}
2421
		}
2422
2423
	return false;
2424
	}
2425
2426
	/**
2427
	 * Gets the text changes.
2428
	 *
2429
	 * @param   array  $old  The string parts in reference.
2430
	 * @param   array  $new  The string parts in develop.
2431
	 *
2432
	 * @return  array
2433
	 *
2434
	 * @since   4.11
2435
	 */
2436
	public static function getTextchanges($old, $new)
2437
	{
2438
		$maxlen = 0;
2439
2440
		foreach ($old as $oindex => $ovalue)
2441
		{
2442
			$nkeys = array_keys($new, $ovalue);
2443
2444
			foreach ($nkeys as $nindex)
2445
			{
2446
				$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
2447
2448
				if ($matrix[$oindex][$nindex] > $maxlen)
2449
				{
2450
					$maxlen = $matrix[$oindex][$nindex];
2451
					$omax = $oindex + 1 - $maxlen;
2452
					$nmax = $nindex + 1 - $maxlen;
2453
				}
2454
2455
			unset ($nkeys, $nindex);
2456
			}
2457
2458
		unset ($oindex, $ovalue);
2459
		}
2460
2461
		if ($maxlen == 0)
2462
		{
2463
			return array(array ('d' => $old, 'i' => $new));
2464
		}
2465
2466
		return array_merge(
2467
			self::getTextchanges(
2468
			array_slice($old, 0, $omax),
2469
			array_slice($new, 0, $nmax)
2470
			),
2471
			array_slice($new, $nmax, $maxlen),
2472
			self::getTextchanges(
2473
			array_slice($old, $omax + $maxlen),
2474
			array_slice($new, $nmax + $maxlen)
2475
			)
2476
			);
2477
	}
2478
2479
	/**
2480
	 * Gets the html text changes.
2481
	 *
2482
	 * @param   string  $old  The string in reference.
2483
	 * @param   string  $new  The string in develop.
2484
	 *
2485
	 * @return  string
2486
	 *
2487
	 * @since   4.11
2488
	 */
2489
	public static function htmlgetTextchanges($old, $new)
2490
	{
2491
		$text_changes = '';
2492
2493
		if ($old == $new)
2494
		{
2495
			return $text_changes;
2496
		}
2497
2498
		$old = str_replace('  ', 'LOCALISEDOUBLESPACES', $old);
2499
		$new = str_replace('  ', 'LOCALISEDOUBLESPACES', $new);
2500
2501
		$diff = self::getTextchanges(explode(' ', $old), explode(' ', $new));
2502
2503
		foreach ($diff as $k)
2504
		{
2505
			if (is_array($k))
2506
			{
2507
				$text_changes .= (!empty ($k['d'])?"LOCALISEDELSTART"
2508
					. implode(' ', $k['d']) . "LOCALISEDELSTOP ":'')
2509
					. (!empty($k['i']) ? "LOCALISEINSSTART"
2510
					. implode(' ', $k['i'])
2511
					. "LOCALISEINSSTOP " : '');
2512
			}
2513
			else
2514
			{
2515
				$text_changes .= $k . ' ';
2516
			}
2517
2518
		unset ($k);
2519
		}
2520
2521
		$text_changes = htmlspecialchars($text_changes);
2522
		$text_changes = preg_replace('/LOCALISEINSSTART/', "<ins class='diff_ins'>", $text_changes);
2523
		$text_changes = preg_replace('/LOCALISEINSSTOP/', "</ins>", $text_changes);
2524
		$text_changes = preg_replace('/LOCALISEDELSTART/', "<del class='diff_del'>", $text_changes);
2525
		$text_changes = preg_replace('/LOCALISEDELSTOP/', "</del>", $text_changes);
2526
		$double_spaces = '<span class="red-space"><font color="red">XX</font></span>';
2527
		$text_changes = str_replace('LOCALISEDOUBLESPACES', $double_spaces, $text_changes);
2528
2529
	return $text_changes;
2530
	}
2531
}
2532