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 ( 5dc3f5...f843d8 )
by
unknown
08:37
created

component/admin/helpers/localise.php (49 issues)

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
jimport('joomla.filesystem.folder');
13
jimport('joomla.filesystem.path');
14
jimport("joomla.utilities.date");
15
16
/**
17
 * Localise Helper class
18
 *
19
 * @package     Extensions.Components
20
 * @subpackage  Localise
21
 * @since       4.0
22
 */
23
abstract class LocaliseHelper
24
{
25
	/**
26
	 * Array containing the origin information
27
	 *
28
	 * @var    array
29
	 * @since  4.0
30
	 */
31
	protected static $origins = array('site' => null, 'administrator' => null, 'installation' => null);
32
33
	/**
34
	 * Array containing the package information
35
	 *
36
	 * @var    array
37
	 * @since  4.0
38
	 */
39
	protected static $packages = array();
40
41
	/**
42
	 * Prepares the component submenu
43
	 *
44
	 * @param   string  $vName  Name of the active view
45
	 *
46
	 * @return  void
47
	 *
48
	 * @since   4.0
49
	 */
50
	public static function addSubmenu($vName)
51
	{
52
		JHtmlSidebar::addEntry(
53
			JText::_('COM_LOCALISE_SUBMENU_LANGUAGES'),
54
			'index.php?option=com_localise&view=languages',
55
			$vName == 'languages'
56
		);
57
58
		JHtmlSidebar::addEntry(
59
			JText::_('COM_LOCALISE_SUBMENU_TRANSLATIONS'),
60
			'index.php?option=com_localise&view=translations',
61
			$vName == 'translations'
62
		);
63
64
		JHtmlSidebar::addEntry(
65
			JText::_('COM_LOCALISE_SUBMENU_PACKAGES'),
66
			'index.php?option=com_localise&view=packages',
67
			$vName == 'packages'
68
		);
69
	}
70
71
	/**
72
	 * Determines if a given path is writable in the current environment
73
	 *
74
	 * @param   string  $path  Path to check
75
	 *
76
	 * @return  boolean  True if writable
77
	 *
78
	 * @since   4.0
79
	 */
80
	public static function isWritable($path)
81
	{
82
		if (JFactory::getConfig()->get('config.ftp_enable'))
83
		{
84
			return true;
85
		}
86
		else
87
		{
88
			while (!file_exists($path))
89
			{
90
				$path = dirname($path);
91
			}
92
93
			return is_writable($path) || JPath::isOwner($path) || JPath::canChmod($path);
94
		}
95
	}
96
97
	/**
98
	 * Check if the installation path exists
99
	 *
100
	 * @return  boolean  True if the installation path exists
101
	 *
102
	 * @since   4.0
103
	 */
104
	public static function hasInstallation()
105
	{
106
		return is_dir(LOCALISEPATH_INSTALLATION);
107
	}
108
109
	/**
110
	 * Retrieve the packages array
111
	 *
112
	 * @return  array
113
	 *
114
	 * @since   4.0
115
	 */
116
	public static function getPackages()
117
	{
118
		if (empty(static::$packages))
119
		{
120
			static::scanPackages();
121
		}
122
123
		return static::$packages;
124
	}
125
126
	/**
127
	 * Scans the filesystem for language files in each package
128
	 *
129
	 * @return  void
130
	 *
131
	 * @since   4.0
132
	 */
133
	protected static function scanPackages()
134
	{
135
		$model         = JModelLegacy::getInstance('Packages', 'LocaliseModel', array('ignore_request' => true));
136
		$model->setState('list.start', 0);
137
		$model->setState('list.limit', 0);
138
		$packages       = $model->getItems();
139
140
		foreach ($packages as $package)
141
		{
142
			static::$packages[$package->name] = $package;
143
144
			foreach ($package->administrator as $file)
145
			{
146
				static::$origins['administrator'][$file] = $package->name;
147
			}
148
149
			foreach ($package->site as $file)
150
			{
151
				static::$origins['site'][$file] = $package->name;
152
			}
153
		}
154
	}
155
156
	/**
157
	 * Retrieves the origin information
158
	 *
159
	 * @param   string  $filename  The filename to check
160
	 * @param   string  $client    The client to check
161
	 *
162
	 * @return  string  Origin data
163
	 *
164
	 * @since   4.0
165
	 */
166
	public static function getOrigin($filename, $client)
167
	{
168
		if ($filename == 'override')
169
		{
170
			return '_override';
171
		}
172
173
		// If the $origins array doesn't contain data, fill it
174
		if (empty(static::$origins['site']))
175
		{
176
			static::scanPackages();
177
		}
178
179
		if (isset(static::$origins[$client][$filename]))
180
		{
181
			return static::$origins[$client][$filename];
182
		}
183
		else
184
		{
185
			return '_thirdparty';
186
		}
187
	}
188
189
	/**
190
	 * Scans the filesystem
191
	 *
192
	 * @param   string  $client  The client to scan
193
	 * @param   string  $type    The extension type to scan
194
	 *
195
	 * @return  array
196
	 *
197
	 * @since   4.0
198
	 */
199
	public static function getScans($client = '', $type = '')
200
	{
201
		$params   = JComponentHelper::getParams('com_localise');
202
		$suffixes = explode(',', $params->get('suffixes', '.sys'));
203
204
		$filter_type   = $type ? $type : '.';
205
		$filter_client = $client ? $client : '.';
206
		$scans         = array();
207
208
		// Scan installation folders
209
		if (preg_match("/$filter_client/", 'installation'))
210
		{
211
			// TODO ;-)
212
		}
213
214
		// Scan administrator folders
215
		if (preg_match("/$filter_client/", 'administrator'))
216
		{
217
			// Scan administrator components folders
218 View Code Duplication
			if (preg_match("/$filter_type/", 'component'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
219
			{
220
				$scans[] = array(
221
					'prefix' => '',
222
					'suffix' => '',
223
					'type'   => 'component',
224
					'client' => 'administrator',
225
					'path'   => LOCALISEPATH_ADMINISTRATOR . '/components/',
226
					'folder' => ''
227
				);
228
229
				foreach ($suffixes as $suffix)
230
				{
231
					$scans[] = array(
232
						'prefix' => '',
233
						'suffix' => $suffix,
234
						'type'   => 'component',
235
						'client' => 'administrator',
236
						'path'   => LOCALISEPATH_ADMINISTRATOR . '/components/',
237
						'folder' => ''
238
					);
239
				}
240
			}
241
242
			// Scan administrator modules folders
243 View Code Duplication
			if (preg_match("/$filter_type/", 'module'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
244
			{
245
				$scans[] = array(
246
					'prefix' => '',
247
					'suffix' => '',
248
					'type'   => 'module',
249
					'client' => 'administrator',
250
					'path'   => LOCALISEPATH_ADMINISTRATOR . '/modules/',
251
					'folder' => ''
252
				);
253
254
				foreach ($suffixes as $suffix)
255
				{
256
					$scans[] = array(
257
						'prefix' => '',
258
						'suffix' => $suffix,
259
						'type'   => 'module',
260
						'client' => 'administrator',
261
						'path'   => LOCALISEPATH_ADMINISTRATOR . '/modules/',
262
						'folder' => ''
263
					);
264
				}
265
			}
266
267
			// Scan administrator templates folders
268 View Code Duplication
			if (preg_match("/$filter_type/", 'template'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
269
			{
270
				$scans[] = array(
271
					'prefix' => 'tpl_',
272
					'suffix' => '',
273
					'type'   => 'template',
274
					'client' => 'administrator',
275
					'path'   => LOCALISEPATH_ADMINISTRATOR . '/templates/',
276
					'folder' => ''
277
				);
278
279
				foreach ($suffixes as $suffix)
280
				{
281
					$scans[] = array(
282
						'prefix' => 'tpl_',
283
						'suffix' => $suffix,
284
						'type'   => 'template',
285
						'client' => 'administrator',
286
						'path'   => LOCALISEPATH_ADMINISTRATOR . '/templates/',
287
						'folder' => ''
288
					);
289
				}
290
			}
291
292
			// Scan plugins folders
293
			if (preg_match("/$filter_type/", 'plugin'))
294
			{
295
				$plugin_types = JFolder::folders(JPATH_PLUGINS);
296
297
				foreach ($plugin_types as $plugin_type)
298
				{
299
					// Scan administrator language folders as this is where plugin languages are installed
300
					$scans[] = array(
301
						'prefix' => 'plg_' . $plugin_type . '_',
302
						'suffix' => '',
303
						'type'   => 'plugin',
304
						'client' => 'administrator',
305
						'path'   => JPATH_PLUGINS . "/$plugin_type/",
306
						'folder' => ''
307
					);
308
309
					foreach ($suffixes as $suffix)
310
					{
311
						$scans[] = array(
312
							'prefix' => 'plg_' . $plugin_type . '_',
313
							'suffix' => $suffix,
314
							'type'   => 'plugin',
315
							'client' => 'administrator',
316
							'path'   => JPATH_PLUGINS . "/$plugin_type/",
317
							'folder' => ''
318
						);
319
					}
320
				}
321
			}
322
		}
323
324
		// Scan site folders
325
		if (preg_match("/$filter_client/", 'site'))
326
		{
327
			// Scan site components folders
328 View Code Duplication
			if (preg_match("/$filter_type/", 'component'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
329
			{
330
				$scans[] = array(
331
					'prefix' => '',
332
					'suffix' => '',
333
					'type'   => 'component',
334
					'client' => 'site',
335
					'path'   => LOCALISEPATH_SITE . '/components/',
336
					'folder' => ''
337
				);
338
339
				foreach ($suffixes as $suffix)
340
				{
341
					$scans[] = array(
342
						'prefix' => '',
343
						'suffix' => $suffix,
344
						'type'   => 'component',
345
						'client' => 'site',
346
						'path'   => LOCALISEPATH_SITE . '/components/',
347
						'folder' => ''
348
					);
349
				}
350
			}
351
352
			// Scan site modules folders
353 View Code Duplication
			if (preg_match("/$filter_type/", 'module'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
354
			{
355
				$scans[] = array(
356
					'prefix' => '',
357
					'suffix' => '',
358
					'type'   => 'module',
359
					'client' => 'site',
360
					'path'   => LOCALISEPATH_SITE . '/modules/',
361
					'folder' => ''
362
				);
363
364
				foreach ($suffixes as $suffix)
365
				{
366
					$scans[] = array(
367
						'prefix' => '',
368
						'suffix' => $suffix,
369
						'type'   => 'module',
370
						'client' => 'site',
371
						'path'   => LOCALISEPATH_SITE . '/modules/',
372
						'folder' => ''
373
					);
374
				}
375
			}
376
377
			// Scan site templates folders
378 View Code Duplication
			if (preg_match("/$filter_type/", 'template'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
379
			{
380
				$scans[] = array(
381
					'prefix' => 'tpl_',
382
					'suffix' => '',
383
					'type'   => 'template',
384
					'client' => 'site',
385
					'path'   => LOCALISEPATH_SITE . '/templates/',
386
					'folder' => ''
387
				);
388
389
				foreach ($suffixes as $suffix)
390
				{
391
					$scans[] = array(
392
						'prefix' => 'tpl_',
393
						'suffix' => $suffix,
394
						'type'   => 'template',
395
						'client' => 'site',
396
						'path'   => LOCALISEPATH_SITE . '/templates/',
397
						'folder' => ''
398
					);
399
				}
400
			}
401
		}
402
403
		return $scans;
404
	}
405
406
	/**
407
	 * Get file ID in the database for the given file path
408
	 *
409
	 * @param   string  $path  Path to lookup
410
	 *
411
	 * @return  integer  File ID
412
	 *
413
	 * @since   4.0
414
	 */
415
	public static function getFileId($path)
416
	{
417
		static $fileIds = null;
418
419 View Code Duplication
		if (!isset($fileIds))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
420
		{
421
			$db = JFactory::getDbo();
422
423
			$db->setQuery(
424
				$db->getQuery(true)
425
					->select($db->quoteName(array('id', 'path')))
426
					->from($db->quoteName('#__localise'))
427
			);
428
429
			$fileIds = $db->loadObjectList('path');
430
		}
431
432
		if (is_file($path) || preg_match('/.ini$/', $path))
433
		{
434
			if (!array_key_exists($path, $fileIds))
435
			{
436
				JTable::addIncludePath(JPATH_COMPONENT . '/tables');
437
438
				/* @type  LocaliseTableLocalise  $table */
439
				$table       = JTable::getInstance('Localise', 'LocaliseTable');
440
				$table->path = $path;
441
				$table->store();
442
443
				$fileIds[$path] = new stdClass;
444
				$fileIds[$path]->id = $table->id;
445
			}
446
447
			return $fileIds[$path]->id;
448
		}
449
		else
450
		{
451
			$id = 0;
452
		}
453
454
		return $id;
455
	}
456
457
	/**
458
	 * Get file path in the database for the given file id
459
	 *
460
	 * @param   integer  $id  Id to lookup
461
	 *
462
	 * @return  string   File Path
463
	 *
464
	 * @since   4.0
465
	 */
466
	public static function getFilePath($id)
467
	{
468
		static $filePaths = null;
469
470 View Code Duplication
		if (!isset($filePaths))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
471
		{
472
			$db = JFactory::getDbo();
473
474
			$db->setQuery(
475
				$db->getQuery(true)
476
					->select($db->quoteName(array('id', 'path')))
477
					->from($db->quoteName('#__localise'))
478
			);
479
480
			$filePaths = $db->loadObjectList('id');
481
		}
482
483
		return array_key_exists("$id", $filePaths) ?
484
		$filePaths["$id"]->path : '';
485
	}
486
487
	/**
488
	 * Determine if a package at given path is core or not.
489
	 *
490
	 * @param   string  $path  Path to lookup
491
	 *
492
	 * @return  mixed  null if file is invalid | True if core else false.
493
	 *
494
	 * @since   4.0
495
	 */
496
	public static function isCorePackage($path)
497
	{
498
		if (is_file($path) || preg_match('/.ini$/', $path))
499
		{
500
			$xml = simplexml_load_file($path);
501
502
			return ((string) $xml->attributes()->core) == 'true';
503
		}
504
	}
505
506
	/**
507
	 * Find a translation file
508
	 *
509
	 * @param   string  $client    Client to lookup
510
	 * @param   string  $tag       Language tag to lookup
511
	 * @param   string  $filename  Filename to lookup
512
	 *
513
	 * @return  string  Path to the requested file
514
	 *
515
	 * @since   4.0
516
	 */
517
	public static function findTranslationPath($client, $tag, $filename)
518
	{
519
		$params = JComponentHelper::getParams('com_localise');
520
		$priority = $params->get('priority', '0') == '0' ? 'global' : 'local';
521
		$path = static::getTranslationPath($client, $tag, $filename, $priority);
522
523
		if (!is_file($path))
524
		{
525
			$priority = $params->get('priority', '0') == '0' ? 'local' : 'global';
526
			$path = static::getTranslationPath($client, $tag, $filename, $priority);
527
		}
528
529
		return $path;
530
	}
531
532
	/**
533
	 * Get a translation path
534
	 *
535
	 * @param   string  $client    Client to lookup
536
	 * @param   string  $tag       Language tag to lookup
537
	 * @param   string  $filename  Filename to lookup
538
	 * @param   string  $storage   Storage location to check
539
	 *
540
	 * @return  string  Path to the requested file
541
	 *
542
	 * @since   4.0
543
	 */
544
	public static function getTranslationPath($client, $tag, $filename, $storage)
545
	{
546
		if ($filename == 'override')
547
		{
548
			$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/overrides/$tag.override.ini";
549
		}
550
		elseif ($filename == 'joomla')
551
		{
552
			$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/$tag/$tag.ini";
553
		}
554
		elseif ($storage == 'global')
555
		{
556
			$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/$tag/$tag.$filename.ini";
557
		}
558
		else
559
		{
560
			$parts     = explode('.', $filename);
561
			$extension = $parts[0];
562
563
			switch (substr($extension, 0, 3))
564
			{
565 View Code Duplication
				case 'com':
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
566
					$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/components/$extension/language/$tag/$tag.$filename.ini";
567
568
					break;
569
570 View Code Duplication
				case 'mod':
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
571
					$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/modules/$extension/language/$tag/$tag.$filename.ini";
572
573
					break;
574
575
				case 'plg':
576
					$parts  = explode('_', $extension);
577
					$group  = $parts[1];
578
					$parts	= explode('.', $filename);
579
					$pluginname = $parts[0];
580
					$plugin = substr($pluginname, 5 + strlen($group));
581
					$path   = JPATH_PLUGINS . "/$group/$plugin/language/$tag/$tag.$filename.ini";
582
583
					break;
584
585 View Code Duplication
				case 'tpl':
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
586
					$template = substr($extension, 4);
587
					$path     = constant('LOCALISEPATH_' . strtoupper($client)) . "/templates/$template/language/$tag/$tag.$filename.ini";
588
589
					break;
590
591
				case 'lib':
592
					$path = constant('LOCALISEPATH_' . strtoupper($client)) . "/language/$tag/$tag.$filename.ini";
593
594
					if (!is_file($path))
595
					{
596
						$path = $client == 'administrator' ? 'LOCALISEPATH_' . 'SITE' : 'LOCALISEPATH_' . 'ADMINISTRATOR' . "/language/$tag/$tag.$filename.ini";
597
					}
598
599
					break;
600
601
				default   :
602
					$path = '';
603
604
					break;
605
			}
606
		}
607
608
		return $path;
609
	}
610
611
	/**
612
	 * Load a language file for translating the package name
613
	 *
614
	 * @param   string  $extension  The extension to load
615
	 * @param   string  $client     The client from where to load the file
616
	 *
617
	 * @return  void
618
	 *
619
	 * @since   4.0
620
	 */
621
	public static function loadLanguage($extension, $client)
622
	{
623
		$extension = strtolower($extension);
624
		$lang      = JFactory::getLanguage();
625
		$prefix    = substr($extension, 0, 3);
626
627
		switch ($prefix)
628
		{
629 View Code Duplication
			case 'com':
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
630
				$lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)), null, false, true)
631
					|| $lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)) . "/components/$extension/", null, false, true);
632
633
				break;
634
635 View Code Duplication
			case 'mod':
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
636
				$lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)), null, false, true)
637
					|| $lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)) . "/modules/$extension/", null, false, true);
638
639
				break;
640
641
			case 'plg':
642
				$lang->load($extension, 'LOCALISEPATH_' . 'ADMINISTRATOR', null, false, true)
643
					|| $lang->load($extension, LOCALISEPATH_ADMINISTRATOR . "/components/$extension/", null, false, true);
644
645
				break;
646
647 View Code Duplication
			case 'tpl':
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
648
				$template = substr($extension, 4);
649
				$lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)), null, false, true)
650
					|| $lang->load($extension, constant('LOCALISEPATH_' . strtoupper($client)) . "/templates/$template/", null, false, true);
651
652
				break;
653
654
			case 'lib':
655
			case 'fil':
656
			case 'pkg':
657
				$lang->load($extension, JPATH_ROOT, null, false, true);
658
659
				break;
660
		}
661
	}
662
663
	/**
664
	 * Parses the sections of a language file
665
	 *
666
	 * @param   string  $filename  The filename to parse
667
	 *
668
	 * @return  array  Array containing the file data
669
	 *
670
	 * @since   4.0
671
	 */
672
	public static function parseSections($filename)
673
	{
674
		static $sections = array();
675
676
		if (!array_key_exists($filename, $sections))
677
		{
678
			if (file_exists($filename))
679
			{
680
				$error = '';
681
682
				if (!defined('_QQ_'))
683
				{
684
					define('_QQ_', '"');
685
				}
686
687
				ini_set('track_errors', '1');
688
689
				$contents = file_get_contents($filename);
690
				$contents = str_replace('_QQ_', '"\""', $contents);
691
				$strings  = @parse_ini_string($contents, true);
692
693
				if (!empty($php_errormsg))
694
				{
695
					$error = "Error parsing " . basename($filename) . ": $php_errormsg";
696
				}
697
698
				ini_restore('track_errors');
699
700
				if ($strings !== false)
701
				{
702
					$default = array();
703
704
					foreach ($strings as $key => $value)
705
					{
706
						if (is_string($value))
707
						{
708
							$default[$key] = $value;
709
710
							unset($strings[$key]);
711
						}
712
						else
713
						{
714
							break;
715
						}
716
					}
717
718
					if (!empty($default))
719
					{
720
						$strings = array_merge(array('Default' => $default), $strings);
721
					}
722
723
					$keys = array();
724
725
					foreach ($strings as $section => $value)
726
					{
727
						foreach ($value as $key => $string)
728
						{
729
							$keys[$key] = $strings[$section][$key];
730
						}
731
					}
732
				}
733
				else
734
				{
735
					$keys = false;
736
				}
737
738
				$sections[$filename] = array('sections' => $strings, 'keys' => $keys, 'error' => $error);
739
			}
740
			else
741
			{
742
				$sections[$filename] = array('sections' => array(), 'keys' => array(), 'error' => '');
743
			}
744
		}
745
746
		if (!empty($sections[$filename]['error']))
747
		{
748
			$model = JModelLegacy::getInstance('Translation', 'LocaliseModel');
749
			$model->setError($sections[$filename]['error']);
750
		}
751
752
		return $sections[$filename];
753
	}
754
755
	/**
756
	 * Gets the files to use as source reference from Github
757
	 *
758
	 * @param   array  $gh_data  Array with the required data
759
	 *
760
	 * @return  array
761
	 *
762
	 * @since   4.11
763
	 */
764
	public static function getSourceGithubfiles($gh_data = array())
765
	{
766
		if (!empty($gh_data))
767
		{
768
			$params        = JComponentHelper::getParams('com_localise');
769
			$ref_tag       = $params->get('reference', 'en-GB');
770
			$saved_ref     = $params->get('customisedref', '0');
771
			$allow_develop = $params->get('gh_allow_develop', 0);
772
			$gh_client     = $gh_data['github_client'];
773
			$customisedref = $saved_ref;
774
			$last_sources  = self::getLastsourcereference();
775
			$last_source   = $last_sources[$gh_client];
776
777
			$versions_path = JPATH_ROOT
778
					. '/administrator/components/com_localise/customisedref/stable_joomla_releases.txt';
779
780
			$versions_file = file_get_contents($versions_path);
781
			$versions      = preg_split("/\\r\\n|\\r|\\n/", $versions_file);
782
783
			if ($saved_ref != '0' && !in_array($customisedref, $versions))
784
			{
785
				// Ensure from translations view that we have updated the last one released only when no maches.
786
				$search_releases = self::getReleases();
0 ignored issues
show
$search_releases 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...
787
				$versions_file   = file_get_contents($versions_path);
788
				$versions        = preg_split("/\\r\\n|\\r|\\n/", $versions_file);
789
			}
790
791
			$installed_version = new JVersion;
792
			$installed_version = $installed_version->getShortVersion();
793
794
			$core_paths['administrator'] = 'administrator/language/en-GB';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$core_paths was never initialized. Although not strictly required by PHP, it is generally a good practice to add $core_paths = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
795
			$core_paths['site']          = 'language/en-GB';
796
			$core_paths['installation']  = 'installation/language/en-GB';
797
798
			if ($saved_ref == '0')
799
			{
800
				// It will use core language folders.
801
				$customisedref = "Local installed instance ($installed_version??)";
802
			}
803
			else
804
			{
805
				// It will use language folders with other stored versions.
806
				$custom_client_path = JPATH_ROOT . '/media/com_localise/customisedref/github/'
807
						. $gh_data['github_client']
808
						. '/'
809
						. $customisedref;
810
				$custom_client_path = JFolder::makeSafe($custom_client_path);
811
			}
812
813
			// If reference tag is not en-GB is not required try it
814
			if ($ref_tag != 'en-GB' && $allow_develop == 1)
815
			{
816
				JFactory::getApplication()->enqueueMessage(
817
					JText::_('COM_LOCALISE_ERROR_GETTING_UNALLOWED_CONFIGURATION'),
818
					'warning');
819
820
				return false;
821
			}
822
823
			// If not knowed Joomla version is not required try it
824
			if ($saved_ref != '0' && !in_array($customisedref, $versions) && $allow_develop == 1)
825
			{
826
				JFactory::getApplication()->enqueueMessage(
827
					JText::sprintf('COM_LOCALISE_ERROR_GITHUB_GETTING_LOCAL_INSTALLED_FILES', $customisedref),
828
					'warning');
829
830
				$option    = '0';
831
				$revert    = self::setCustomisedsource($option);
0 ignored issues
show
$revert 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...
832
				$save_last = self::saveLastsourcereference($gh_data['github_client'], '');
0 ignored issues
show
$save_last 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...
833
834
				return false;
835
			}
836
837
			// If feature is disabled but last used files are disctinct to default ones
838
			// Is required make notice that we are coming back to local installed instance version.
839
			if ($saved_ref != '0' && !empty($last_source) && $last_source != '0' && $allow_develop == 0)
840
			{
841
				$customisedref = $installed_version;
0 ignored issues
show
$customisedref 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...
842
843
				JFactory::getApplication()->enqueueMessage(
844
					JText::sprintf('COM_LOCALISE_NOTICE_DISABLED_ALLOW_DEVELOP_WITHOUT_LOCAL_SET',
845
						$last_source,
846
						$installed_version,
847
						$gh_client
848
						),
849
						'notice'
850
						);
851
852
				$option    = '0';
853
				$revert    = self::setCustomisedsource($option);
0 ignored issues
show
$revert 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...
854
				$save_last = self::saveLastsourcereference($gh_data['github_client'], '');
0 ignored issues
show
$save_last 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...
855
856
				return true;
857
			}
858
859
			// If not knowed Joomla version and feature is disabled is not required try it
860
			if ($saved_ref != '0' && !in_array($customisedref, $versions) && $allow_develop == 0)
861
			{
862
				return false;
863
			}
864
865
			// If configured to local installed instance there is nothing to get from Github
866
			if ($saved_ref == '0')
867
			{
868
				$save_last = self::saveLastsourcereference($gh_data['github_client'], '');
0 ignored issues
show
$save_last 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...
869
870
				return true;
871
			}
872
873
			$xml_file = $custom_client_path . '/en-GB.xml';
0 ignored issues
show
The variable $custom_client_path does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
874
875
			// Unrequired move or update files again
876
			if ($saved_ref != '0' && $installed_version == $last_source && JFile::exists($xml_file))
877
			{
878
				return false;
879
			}
880
881
			$gh_data['allow_develop']  = $allow_develop;
882
			$gh_data['customisedref']  = $customisedref;
883
			$gh_target                 = self::getCustomisedsource($gh_data);
884
			$gh_paths                  = array();
885
			$gh_user                   = $gh_target['user'];
886
			$gh_project                = $gh_target['project'];
887
			$gh_branch                 = $gh_target['branch'];
888
			$gh_token                  = $params->get('gh_token', '');
889
			$gh_paths['administrator'] = 'administrator/language/en-GB';
890
			$gh_paths['site']          = 'language/en-GB';
891
			$gh_paths['installation']  = 'installation/language/en-GB';
892
893
			$reference_client_path = JPATH_ROOT . '/' . $gh_paths[$gh_client];
894
			$reference_client_path = JFolder::makeSafe($reference_client_path);
895
896
			if (JFile::exists($xml_file))
897
			{
898
				// We have done this trunk and is not required get the files from Github again.
899
				$update_files = self::updateSourcereference($gh_client, $custom_client_path);
900
901
				if ($update_files == false)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
902
				{
903
					return false;
904
				}
905
906
				$save_last = self::saveLastsourcereference($gh_data['github_client'], $customisedref);
0 ignored issues
show
$save_last 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...
907
908
				return true;
909
			}
910
911
			$options = new JRegistry;
912
913 View Code Duplication
			if (!empty($gh_token))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
914
			{
915
				$options->set('gh.token', $gh_token);
916
				$github = new JGithub($options);
917
			}
918
			else
919
			{
920
				// Without a token runs fatal.
921
				// $github = new JGithub;
922
923
				// Trying with a 'read only' public repositories token
924
				// But base 64 encoded to avoid Github alarms sharing it.
925
				$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA==');
926
				$options->set('gh.token', $gh_token);
927
				$github = new JGithub($options);
928
			}
929
930
			try
931
			{
932
				$repostoryfiles = $github->repositories->contents->get(
933
					$gh_user,
934
					$gh_project,
935
					$gh_paths[$gh_client],
936
					$gh_branch
937
					);
938
			}
939
			catch (Exception $e)
940
			{
941
				JFactory::getApplication()->enqueueMessage(
942
					JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_REPOSITORY_FILES'),
943
					'warning');
944
945
				return false;
946
			}
947
948
			if (!JFolder::exists($custom_client_path))
949
			{
950
				$create_folder = self::createFolder($gh_data, $index = 'true');
951
952
				if ($create_folder == false)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
953
				{
954
					return false;
955
				}
956
			}
957
958
			$all_files_list = self::getLanguagefileslist($custom_client_path);
959
			$ini_files_list = self::getInifileslist($custom_client_path);
0 ignored issues
show
$ini_files_list 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...
960
961
			$files_to_include = array();
962
963
			foreach ($repostoryfiles as $repostoryfile)
964
			{
965
				$file_to_include = $repostoryfile->name;
966
				$file_path = JFolder::makeSafe($custom_client_path . '/' . $file_to_include);
967
				$reference_file_path = JFolder::makeSafe($reference_client_path . '/' . $file_to_include);
0 ignored issues
show
$reference_file_path 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...
968
969
				$custom_file = $github->repositories->contents->get(
970
						$gh_user,
971
						$gh_project,
972
						$repostoryfile->path,
973
						$gh_branch
974
						);
975
976
				$files_to_include[] = $file_to_include;
977
978
				if (!empty($custom_file) && isset($custom_file->content))
979
				{
980
					$file_to_include = $repostoryfile->name;
0 ignored issues
show
$file_to_include 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...
981
					$file_contents   = base64_decode($custom_file->content);
982
					JFile::write($file_path, $file_contents);
983
984
					if (!JFile::exists($file_path))
985
					{
986
						JFactory::getApplication()->enqueueMessage(
987
							JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_DEV_FILE'),
988
							'warning');
989
990
						return false;
991
					}
992
				}
993
			}
994
995
			if (!empty($all_files_list) && !empty($files_to_include))
996
			{
997
				// For files not present yet.
998
				$files_to_delete = array_diff($all_files_list, $files_to_include);
999
1000
				if (!empty($files_to_delete))
1001
				{
1002
					foreach ($files_to_delete as $file_to_delete)
1003
					{
1004
						if ($file_to_delete != 'index.html')
1005
						{
1006
							$file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete);
1007
							JFile::delete($file_path);
1008
1009
							if (JFile::exists($file_path))
1010
							{
1011
								JFactory::getApplication()->enqueueMessage(
1012
									JText::_('COM_LOCALISE_ERROR_GITHUB_FILE_TO_DELETE_IS_PRESENT'),
1013
									'warning');
1014
1015
								return false;
1016
							}
1017
						}
1018
					}
1019
				}
1020
			}
1021
1022
			if (JFile::exists($xml_file))
1023
			{
1024
				// We have done this trunk.
1025
1026
				// So we can move the customised source reference files to core client folder
1027
				$update_files = self::updateSourcereference($gh_client, $custom_client_path);
1028
1029
				if ($update_files == false)
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1030
				{
1031
					return false;
1032
				}
1033
1034
				$save_last = self::saveLastsourcereference($gh_data['github_client'], $customisedref);
0 ignored issues
show
$save_last 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...
1035
1036
				JFactory::getApplication()->enqueueMessage(
1037
					JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_GETS_A_SOURCE_FULL_SET', $customisedref),
1038
					'notice');
1039
1040
				return true;
1041
			}
1042
1043
			JFactory::getApplication()->enqueueMessage(
1044
				JText::sprintf('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_GET_A_FULL_SOURCE_SET', $customisedref),
1045
				'warning');
1046
1047
			return false;
1048
		}
1049
1050
		JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_NO_DATA_PRESENT'), 'warning');
1051
1052
		return false;
1053
	}
1054
1055
	/**
1056
	 * Gets the stable Joomla releases list.
1057
	 *
1058
	 * @return  array
1059
	 *
1060
	 * @since   4.11
1061
	 */
1062
	public static function getReleases()
1063
	{
1064
		$params        = JComponentHelper::getParams('com_localise');
1065
		$versions_path = JPATH_ROOT
1066
				. '/administrator/components/com_localise/customisedref/stable_joomla_releases.txt';
1067
		$versions_file = file_get_contents($versions_path);
1068
		$versions      = preg_split("/\\r\\n|\\r|\\n/", $versions_file);
1069
1070
		$gh_user       = 'joomla';
1071
		$gh_project    = 'joomla-cms';
1072
		$gh_token      = $params->get('gh_token', '');
1073
1074
		$options = new JRegistry;
1075
1076 View Code Duplication
		if (!empty($gh_token))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
1077
		{
1078
			$options->set('gh.token', $gh_token);
1079
			$github = new JGithub($options);
1080
		}
1081
		else
1082
		{
1083
			// Without a token runs fatal.
1084
			// $github = new JGithub;
1085
1086
			// Trying with a 'read only' public repositories token
1087
			// But base 64 encoded to avoid Github alarms sharing it.
1088
			$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA==');
1089
			$options->set('gh.token', $gh_token);
1090
			$github = new JGithub($options);
1091
		}
1092
1093
		try
1094
		{
1095
			$releases = $github->repositories->get(
1096
					$gh_user,
1097
					$gh_project . '/releases'
1098
					);
1099
1100
			// Allowed tricks.
1101
			// Configured to 0 the 2.5.x series are not allowed. Configured to 1 it is allowed.
1102
			$allow_25x = 1;
1103
1104 View Code Duplication
			foreach ($releases as $release)
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
1105
			{
1106
				$tag_name = $release->tag_name;
1107
				$tag_part = explode(".", $tag_name);
1108
				$undoted  = str_replace('.', '', $tag_name);
1109
				$excluded = 0;
1110
1111
				if ($tag_part[0] == '2' && $allow_25x == '0')
1112
				{
1113
					$excluded = 1;
1114
				}
1115
				elseif ($tag_part[0] != '3' && $tag_part[0] != '2')
1116
				{
1117
					// Exclude platforms or similar stuff.
1118
					$excluded = 1;
1119
				}
1120
1121
				// Filtering also by "is_numeric" disable betas or similar releases.
1122
				if (!in_array($tag_name, $versions) && is_numeric($undoted) && $excluded == 0)
1123
				{
1124
					$versions[] = $tag_name;
1125
					JFactory::getApplication()->enqueueMessage(
1126
						JText::sprintf('COM_LOCALISE_NOTICE_NEW_VERSION_DETECTED', $tag_name),
1127
						'notice');
1128
				}
1129
			}
1130
		}
1131
		catch (Exception $e)
1132
		{
1133
			JFactory::getApplication()->enqueueMessage(
1134
				JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_RELEASES'),
1135
				'warning');
1136
		}
1137
1138
		arsort($versions);
1139
1140
		$versions_file = '';
1141
1142
		foreach ($versions as $id => $version)
1143
		{
1144
			if (!empty($version))
1145
			{
1146
				$versions_file .= $version . "\n";
1147
			}
1148
		}
1149
1150
		JFile::write($versions_path, $versions_file);
1151
1152
		return $versions;
1153
	}
1154
1155
	/**
1156
	 * Save the last en-GB source version used as reference.
1157
	 *
1158
	 * @param   string  $client         The client
1159
	 *
1160
	 * @param   string  $customisedref  The version number
1161
	 *
1162
	 * @return  boolean
1163
	 *
1164
	 * @since   4.11
1165
	 */
1166
	public static function saveLastsourcereference($client = '', $customisedref = '')
1167
	{
1168
		$last_reference_file = JPATH_COMPONENT_ADMINISTRATOR
1169
					. '/customisedref/'
1170
					. $client
1171
					. '_last_source_ref.txt';
1172
1173
		$file_contents = $customisedref . "\n";
1174
1175
		if (!JFile::write($last_reference_file, $file_contents))
1176
		{
1177
			return false;
1178
		}
1179
1180
		return true;
1181
	}
1182
1183
	/**
1184
	 * Gets the last en-GB source reference version moved to the core folders.
1185
	 *
1186
	 * @return  array
1187
	 *
1188
	 * @since   4.11
1189
	 */
1190
	public static function getLastsourcereference()
1191
	{
1192
		$last_source_reference = array();
1193
		$last_source_reference['administrator'] = '';
1194
		$last_source_reference['site'] = '';
1195
		$last_source_reference['installation'] = '';
1196
1197
		$clients = array('administrator', 'site', 'installation');
1198
1199
		foreach ($clients as $client)
1200
		{
1201
			$last_reference_file = JPATH_COMPONENT_ADMINISTRATOR
1202
							. '/customisedref/'
1203
							. $client
1204
							. '_last_source_ref.txt';
1205
1206
			if (JFile::exists($last_reference_file))
1207
			{
1208
				$file_contents = file_get_contents($last_reference_file);
1209
				$lines = preg_split("/\\r\\n|\\r|\\n/", $file_contents);
1210
1211
				foreach ($lines as $line)
1212
				{
1213
					if (!empty($line))
1214
					{
1215
						$last_source_reference[$client] = $line;
1216
					}
1217
				}
1218
			}
1219
		}
1220
1221
		return $last_source_reference;
1222
	}
1223
1224
	/**
1225
	 * Gets the reference name to use at Github
1226
	 *
1227
	 * @param   array  $gh_data  Array with the required data
1228
	 *
1229
	 * @return  array
1230
	 *
1231
	 * @since   4.11
1232
	 */
1233
	public static function getCustomisedsource($gh_data = array())
1234
	{
1235
		$source_ref        = $gh_data['customisedref'];
1236
		$allow_develop     = $gh_data['allow_develop'];
0 ignored issues
show
$allow_develop 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...
1237
1238
		$sources = array();
1239
1240
		// Detailing it we can handle exceptions and add other Github users or projects.
1241
		// To get the language files for a determined Joomla's version that is not present from main Github repository.
1242
		$sources['3.4.1']['user']    = 'joomla';
1243
		$sources['3.4.1']['project'] = 'joomla-cms';
1244
		$sources['3.4.1']['branch']  = '3.4.1';
1245
1246
		if (array_key_exists($source_ref, $sources))
1247
		{
1248
			return ($sources[$source_ref]);
1249
		}
1250
1251
		// For undefined REF 0 or unlisted cases due Joomla releases at Github are following a version name patern.
1252
		$sources[$source_ref]['user']    = 'joomla';
1253
		$sources[$source_ref]['project'] = 'joomla-cms';
1254
		$sources[$source_ref]['branch']  = $source_ref;
1255
1256
	return ($sources[$source_ref]);
1257
	}
1258
1259
	/**
1260
	 * Keep updated the customised client path including only the common files present in develop.
1261
	 *
1262
	 * @param   string  $client              The client
1263
	 *
1264
	 * @param   string  $custom_client_path  The path where the new source reference is stored
1265
	 *
1266
	 * @return  boolean
1267
	 *
1268
	 * @since   4.11
1269
	 */
1270
	public static function updateSourcereference($client, $custom_client_path)
1271
	{
1272
		$develop_client_path   = JPATH_ROOT . '/media/com_localise/develop/github/joomla-cms/en-GB/' . $client;
1273
		$develop_client_path   = JFolder::makeSafe($develop_client_path);
1274
1275
		$custom_ini_files_list = self::getInifileslist($custom_client_path);
1276
		$last_ini_files_list   = self::getInifileslist($develop_client_path);
1277
1278
		$files_to_exclude = array();
0 ignored issues
show
$files_to_exclude 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...
1279
1280 View Code Duplication
		if (!JFile::exists($develop_client_path . '/en-GB.xml'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
1281
		{
1282
			JFactory::getApplication()->enqueueMessage(
1283
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_TARGET_FILES'),
1284
				'warning');
1285
1286
			return false;
1287
		}
1288
		elseif (!JFile::exists($custom_client_path . '/en-GB.xml'))
1289
		{
1290
			JFactory::getApplication()->enqueueMessage(
1291
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_SOURCE_FILES'),
1292
				'warning');
1293
1294
			return false;
1295
		}
1296
1297
		// This one is for files not present within last in dev yet.
1298
		// Due have no sense add old language files to translate or revise for the comming soon package.
1299
1300
		$files_to_exclude = array_diff($custom_ini_files_list, $last_ini_files_list);
1301
1302
		if (!empty($files_to_exclude))
1303
		{
1304
			$errors = 0;
1305
1306
			foreach ($files_to_exclude as $file_to_delete)
1307
			{
1308
				$custom_file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete);
1309
1310
				if (!JFile::delete($custom_file_path))
1311
				{
1312
					$errors++;
1313
				}
1314
			}
1315
1316
			if ($errors > 0)
1317
			{
1318
				JFactory::getApplication()->enqueueMessage(
1319
					JText::sprintf('COM_LOCALISE_ERROR_DELETING_EXTRA_SOURCE_FILES', $errors),
1320
					'warning');
1321
1322
				return false;
1323
			}
1324
		}
1325
1326
		return true;
1327
	}
1328
1329
	/**
1330
	 * Keep updated the core path with the selected source files as reference (used at previous working mode).
1331
	 *
1332
	 * @param   string  $client                 The client
1333
	 *
1334
	 * @param   string  $custom_client_path     The path where the new source reference is stored
1335
	 *
1336
	 * @param   string  $reference_client_path  The path where the old source reference is stored
1337
	 *
1338
	 * @return  boolean
1339
	 *
1340
	 * @since   4.11
1341
	 */
1342
	public static function updateSourcereferencedirectly($client, $custom_client_path, $reference_client_path)
1343
	{
1344
		$develop_client_path   = JPATH_ROOT . '/media/com_localise/develop/github/joomla-cms/en-GB/' . $client;
1345
		$develop_client_path   = JFolder::makeSafe($develop_client_path);
1346
1347
		$custom_ini_files_list = self::getInifileslist($custom_client_path);
1348
		$last_ini_files_list   = self::getInifileslist($develop_client_path);
1349
1350
		$files_to_exclude = array();
0 ignored issues
show
$files_to_exclude 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...
1351
1352 View Code Duplication
		if (!JFile::exists($develop_client_path . '/en-GB.xml'))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
1353
		{
1354
			JFactory::getApplication()->enqueueMessage(
1355
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_TARGET_FILES'),
1356
				'warning');
1357
1358
			return false;
1359
		}
1360
		elseif (!JFile::exists($custom_client_path . '/en-GB.xml'))
1361
		{
1362
			JFactory::getApplication()->enqueueMessage(
1363
				JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_UPDATE_SOURCE_FILES'),
1364
				'warning');
1365
1366
			return false;
1367
		}
1368
1369
		// This one is for core files not present within last in dev yet.
1370
		// Due have no sense add old language files to translate for the comming soon package.
1371
1372
		$files_to_exclude = array_diff($custom_ini_files_list, $last_ini_files_list);
1373
1374
		if (!empty($files_to_exclude))
1375
		{
1376
			foreach ($files_to_exclude as $file_to_delete)
1377
			{
1378
				$custom_file_path = JFolder::makeSafe($custom_client_path . "/" . $file_to_delete);
1379
				$actual_file_path = JFolder::makeSafe($reference_client_path . "/" . $file_to_delete);
1380
1381
				JFile::delete($custom_file_path);
1382
1383
				// Also verify if the same file is also present in core language folder.
1384
1385
				if (JFile::exists($actual_file_path))
1386
				{
1387
					JFile::delete($actual_file_path);
1388
1389
					JFactory::getApplication()->enqueueMessage(
1390
					JText::sprintf('COM_LOCALISE_OLD_FILE_DELETED', $file_to_delete),
1391
					'notice');
1392
				}
1393
			}
1394
1395
			// Getting the new list again
1396
			$custom_ini_files_list = self::getInifileslist($custom_client_path);
1397
		}
1398
1399
		$errors = 0;
1400
1401
		foreach ($custom_ini_files_list as $customised_source_file)
1402
		{
1403
			$source_path = $custom_client_path . '/' . $customised_source_file;
1404
			$file_contents = file_get_contents($source_path);
1405
			$target_path = $reference_client_path . '/' . $customised_source_file;
1406
1407
			if (!JFile::write($target_path, $file_contents))
1408
			{
1409
				$errors++;
1410
			}
1411
		}
1412
1413
		if ($errors > 0)
1414
		{
1415
			JFactory::getApplication()->enqueueMessage(
1416
				JText::sprintf('COM_LOCALISE_ERROR_SAVING_FILES_AT_CORE_FOLDER', $errors),
1417
				'warning');
1418
1419
			return false;
1420
		}
1421
1422
		return true;
1423
	}
1424
1425
	/**
1426
	 * Gets from zero or keept updated the files in develop to use as target reference from Github
1427
	 *
1428
	 * @param   array  $gh_data  Array with the required data
1429
	 *
1430
	 * @return  array
1431
	 *
1432
	 * @since   4.11
1433
	 */
1434
	public static function getTargetgithubfiles($gh_data = array())
1435
	{
1436
		if (!empty($gh_data))
1437
		{
1438
			$now                = new JDate;
1439
			$now                = $now->toSQL();
1440
			$params             = JComponentHelper::getParams('com_localise');
1441
			$client_to_update   = 'gh_' . $gh_data['github_client'] . '_last_update';
1442
			$last_stored_update = $params->get($client_to_update, '');
1443
			$ref_tag            = $params->get('reference', 'en-GB');
1444
			$allow_develop      = $params->get('gh_allow_develop', 0);
1445
1446
			if ($allow_develop == 0)
1447
			{
1448
				return false;
1449
			}
1450
1451
			if ($ref_tag != 'en-GB')
1452
			{
1453
				JFactory::getApplication()->enqueueMessage(
1454
					JText::_('COM_LOCALISE_ERROR_GETTING_ALLOWED_REFERENCE_TAG'),
1455
					'warning');
1456
1457
				return false;
1458
			}
1459
1460
			$develop_client_path = JPATH_ROOT
1461
						. '/media/com_localise/develop/github/joomla-cms/en-GB/'
1462
						. $gh_data['github_client'];
1463
1464
			$develop_client_path = JFolder::makeSafe($develop_client_path);
1465
			$xml_file            = $develop_client_path . '/en-GB.xml';
1466
1467
			if (!JFile::exists($xml_file))
1468
			{
1469
				$get_files = 1;
1470
			}
1471
			elseif (!empty($last_stored_update))
1472
			{
1473
				$last_update = new JDate($last_stored_update);
1474
				$last_update = $last_update->toSQL();
1475
				$interval    = $params->get('gh_updates_interval', '1') == '1' ? 24 : 1;
1476
				$interval    = $last_update . " +" . $interval . " hours";
1477
				$next_update = new JDate($interval);
1478
				$next_update = $next_update->toSQL();
1479
1480
				if ($now >= $next_update)
1481
				{
1482
					$get_files = 1;
1483
				}
1484
				else
1485
				{
1486
					$get_files = 0;
1487
				}
1488
			}
1489
			else
1490
			{
1491
				$get_files = 1;
1492
			}
1493
1494
			if ($get_files == 0)
1495
			{
1496
				return false;
1497
			}
1498
1499
			$gh_paths                  = array();
1500
			$gh_client                 = $gh_data['github_client'];
1501
			$gh_user                   = 'joomla';
1502
			$gh_project                = 'joomla-cms';
1503
			$gh_branch                 = $params->get('gh_branch', 'master');
1504
			$gh_token                  = $params->get('gh_token', '');
1505
			$gh_paths['administrator'] = 'administrator/language/en-GB';
1506
			$gh_paths['site']          = 'language/en-GB';
1507
			$gh_paths['installation']  = 'installation/language/en-GB';
1508
1509
			$reference_client_path = JPATH_ROOT . '/' . $gh_paths[$gh_client];
1510
			$reference_client_path = JFolder::makeSafe($reference_client_path);
1511
1512
			$options = new JRegistry;
1513
1514 View Code Duplication
			if (!empty($gh_token))
0 ignored issues
show
This code seems to be duplicated across your project.

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.

Loading history...
1515
			{
1516
				$options->set('gh.token', $gh_token);
1517
				$github = new JGithub($options);
1518
			}
1519
			else
1520
			{
1521
				// Without a token runs fatal.
1522
				// $github = new JGithub;
1523
1524
				// Trying with a 'read only' public repositories token
1525
				// But base 64 encoded to avoid Github alarms sharing it.
1526
				$gh_token = base64_decode('MzY2NzYzM2ZkMzZmMWRkOGU5NmRiMTdjOGVjNTFiZTIyMzk4NzVmOA==');
1527
				$options->set('gh.token', $gh_token);
1528
				$github = new JGithub($options);
1529
			}
1530
1531
			try
1532
			{
1533
				$repostoryfiles = $github->repositories->contents->get(
1534
					$gh_user,
1535
					$gh_project,
1536
					$gh_paths[$gh_client],
1537
					$gh_branch
1538
					);
1539
			}
1540
			catch (Exception $e)
1541
			{
1542
				JFactory::getApplication()->enqueueMessage(
1543
					JText::_('COM_LOCALISE_ERROR_GITHUB_GETTING_REPOSITORY_FILES'),
1544
					'warning');
1545
1546
				return false;
1547
			}
1548
1549
			$all_files_list = self::getLanguagefileslist($develop_client_path);
1550
			$ini_files_list = self::getInifileslist($develop_client_path);
0 ignored issues
show
$ini_files_list 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...
1551
			$sha_files_list = self::getShafileslist($gh_data);
1552
1553
			$sha = '';
1554
			$files_to_include = array();
1555
1556
			foreach ($repostoryfiles as $repostoryfile)
1557
			{
1558
				$file_to_include     = $repostoryfile->name;
1559
				$file_path           = JFolder::makeSafe($develop_client_path . '/' . $file_to_include);
1560
				$reference_file_path = JFolder::makeSafe($reference_client_path . '/' . $file_to_include);
1561
1562
				if (	(array_key_exists($file_to_include, $sha_files_list)
1563
					&& ($sha_files_list[$file_to_include] != $repostoryfile->sha))
1564
					|| empty($sha_files_list)
1565
					|| !array_key_exists($file_to_include, $sha_files_list)
1566
					|| !JFile::exists($file_path))
1567
				{
1568
					$in_dev_file = $github->repositories->contents->get(
1569
							$gh_user,
1570
							$gh_project,
1571
							$repostoryfile->path,
1572
							$gh_branch
1573
							);
1574
				}
1575
				else
1576
				{
1577
					$in_dev_file = '';
1578
				}
1579
1580
				$files_to_include[] = $file_to_include;
1581
				$sha_path  = JPATH_COMPONENT_ADMINISTRATOR . '/develop/gh_joomla_' . $gh_client . '_files.txt';
1582
				$sha_path  = JFolder::makeSafe($sha_path);
1583
1584
				if (!empty($in_dev_file) && isset($in_dev_file->content))
1585
				{
1586
					$file_to_include = $repostoryfile->name;
1587
					$file_contents = base64_decode($in_dev_file->content);
1588
					JFile::write($file_path, $file_contents);
1589
1590
					if (!JFile::exists($file_path))
1591
					{
1592
						JFactory::getApplication()->enqueueMessage(
1593
							JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_DEV_FILE'),
1594
							'warning');
1595
1596
						return false;
1597
					}
1598
1599
					if (!JFile::exists($reference_file_path)
1600
						&& ($gh_client == 'administrator' || $gh_client == 'site'))
1601
					{
1602
						// Adding files only present in develop to core reference location.
1603
						JFile::write($reference_file_path, $file_contents);
1604
1605
						if (!JFile::exists($reference_file_path))
1606
						{
1607
							JFactory::getApplication()->enqueueMessage(
1608
								JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_ADD_NEW_FILES'),
1609
								'warning');
1610
1611
							return false;
1612
						}
1613
1614
						JFactory::getApplication()->enqueueMessage(
1615
							JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_FILE_ADDED', $file_to_include, $gh_branch, $gh_client),
1616
							'notice');
1617
					}
1618
				}
1619
1620
				// Saved for each time due few times get all the github files at same time can crash.
1621
				// This one can help to remember the last one saved correctly and next time continue from there.
1622
				$sha .= $repostoryfile->name . "::" . $repostoryfile->sha . "\n";
1623
				JFile::write($sha_path, $sha);
1624
1625
				if (!JFile::exists($sha_path))
1626
				{
1627
					JFactory::getApplication()->enqueueMessage(
1628
						JText::_('COM_LOCALISE_ERROR_GITHUB_NO_SHA_FILE_PRESENT'),
1629
						'warning');
1630
1631
					return false;
1632
				}
1633
			}
1634
1635
			if (!empty($all_files_list) && !empty($files_to_include))
1636
			{
1637
				// For files not present in dev yet.
1638
				$files_to_delete = array_diff($all_files_list, $files_to_include);
1639
1640
				if (!empty($files_to_delete))
1641
				{
1642
					foreach ($files_to_delete as $file_to_delete)
1643
					{
1644
						if ($file_to_delete != 'index.html')
1645
						{
1646
							$file_path = JFolder::makeSafe($develop_client_path . "/" . $file_to_delete);
1647
							JFile::delete($file_path);
1648
1649
							if (JFile::exists($file_path))
1650
							{
1651
								JFactory::getApplication()->enqueueMessage(
1652
									JText::sprintf('COM_LOCALISE_ERROR_GITHUB_FILE_TO_DELETE_IS_PRESENT', $file_to_delete),
1653
									'warning');
1654
1655
								return false;
1656
							}
1657
1658
							JFactory::getApplication()->enqueueMessage(
1659
								JText::sprintf('COM_LOCALISE_GITHUB_FILE_NOT_PRESENT_IN_DEV_YET', $file_to_delete),
1660
								'notice');
1661
						}
1662
					}
1663
				}
1664
			}
1665
1666
			if (!JFile::exists($xml_file))
1667
			{
1668
				JFactory::getApplication()->enqueueMessage(
1669
					JText::sprintf('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_GET_A_FULL_SET', $gh_branch),
1670
					'warning');
1671
1672
				return false;
1673
			}
1674
1675
			self::saveLastupdate($client_to_update);
1676
1677
			JFactory::getApplication()->enqueueMessage(
1678
				JText::sprintf('COM_LOCALISE_NOTICE_GITHUB_GETS_A_TARGET_FULL_SET', $gh_branch),
1679
				'notice');
1680
1681
			return true;
1682
		}
1683
1684
		JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_NO_DATA_PRESENT'), 'warning');
1685
1686
		return false;
1687
	}
1688
1689
	/**
1690
	 * Gets the changes between language files versions
1691
	 *
1692
	 * @param   array  $info              The data to catch grammar cases
1693
	 * @param   array  $refsections       The released reference data
1694
	 * @param   array  $develop_sections  The developed reference data
1695
	 *
1696
	 * @return  array
1697
	 *
1698
	 * @since   4.11
1699
	 */
1700
	public static function getDevelopchanges($info = array(), $refsections = array(), $develop_sections = array())
1701
	{
1702
		if (isset($refsections['keys']) && isset($develop_sections['keys']))
1703
		{
1704
			$istranslation     = $info['istranslation'];
1705
			$keys_in_reference = array_keys($refsections['keys']);
1706
			$keys_in_develop   = array_keys($develop_sections['keys']);
1707
1708
			// Catching new keys in develop
1709
			$developdata['extra_keys']['amount']  = 0;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$developdata was never initialized. Although not strictly required by PHP, it is generally a good practice to add $developdata = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1710
			$developdata['extra_keys']['keys']    = array();
1711
			$developdata['extra_keys']['strings'] = array();
1712
1713
			$extras_in_develop = array_diff($keys_in_develop, $keys_in_reference);
1714
1715
			if (!empty($extras_in_develop))
1716
			{
1717
				foreach ($extras_in_develop as $extra_key)
1718
				{
1719
					$developdata['extra_keys']['amount']++;
1720
					$developdata['extra_keys']['keys'][]              = $extra_key;
1721
					$developdata['extra_keys']['strings'][$extra_key] = $develop_sections['keys'][$extra_key];
1722
				}
1723
			}
1724
1725
			// Catching text changes in develop
1726
			$developdata['text_changes']['amount']     = 0;
1727
			$developdata['text_changes']['revised']    = 0;
1728
			$developdata['text_changes']['unrevised']  = 0;
1729
			$developdata['text_changes']['keys']       = array();
1730
			$developdata['text_changes']['ref_in_dev'] = array();
1731
			$developdata['text_changes']['ref']        = array();
1732
			$developdata['text_changes']['diff']       = array();
1733
1734
			foreach ($refsections['keys'] as $key => $string)
1735
			{
1736
				if (array_key_exists($key, $develop_sections['keys']))
1737
				{
1738
					$string_in_develop = $develop_sections['keys'][$key];
1739
					$text_changes = self::htmlgetTextchanges($string, $string_in_develop);
1740
1741
					if (!empty($text_changes))
1742
					{
1743
						if ($istranslation == 1)
1744
						{
1745
							$info['key']           = $key;
1746
							$info['source_text']   = $string;
1747
							$info['target_text']   = $string_in_develop;
1748
							$info['catch_grammar'] = 1;
1749
							$info['revised']       = 0;
1750
1751
							$grammar_case = self::searchRevisedvalue($info);
1752
						}
1753
						else
1754
						{
1755
							$grammar_case = '0';
1756
						}
1757
1758
						if ($grammar_case == '0')
1759
						{
1760
							$developdata['text_changes']['amount']++;
1761
							$developdata['text_changes']['keys'][]           = $key;
1762
							$developdata['text_changes']['ref_in_dev'][$key] = $develop_sections['keys'][$key];
1763
							$developdata['text_changes']['ref'][$key]        = $string;
1764
							$developdata['text_changes']['diff'][$key]       = $text_changes;
1765
						}
1766
					}
1767
				}
1768
			}
1769
1770
			return $developdata;
1771
		}
1772
1773
		return array();
1774
	}
1775
1776
	/**
1777
	 * Gets the develop path if exists
1778
	 *
1779
	 * @param   string  $client   The client
1780
	 * @param   string  $refpath  The data to the reference path
1781
	 *
1782
	 * @return  string
1783
	 *
1784
	 * @since   4.11
1785
	 */
1786
	public static function searchDevpath($client = '', $refpath = '')
1787
	{
1788
		$params             = JComponentHelper::getParams('com_localise');
1789
		$ref_tag            = $params->get('reference', 'en-GB');
1790
		$allow_develop      = $params->get('gh_allow_develop', 0);
1791
1792
		$develop_client_path = JPATH_ROOT
1793
					. '/media/com_localise/develop/github/joomla-cms/en-GB/'
1794
					. $client;
1795
1796
		$ref_file            = basename($refpath);
1797
		$develop_file_path   = JFolder::makeSafe("$develop_client_path/$ref_file");
1798
1799
		if (JFile::exists($develop_file_path) && $allow_develop == 1 && $ref_tag == 'en-GB')
1800
		{
1801
			$devpath = $develop_file_path;
1802
		}
1803
		else
1804
		{
1805
			$devpath = '';
1806
		}
1807
1808
		return $devpath;
1809
	}
1810
1811
	/**
1812
	 * Gets the customised source path if exists
1813
	 *
1814
	 * @param   string  $client   The client
1815
	 * @param   string  $refpath  The data to the reference path
1816
	 *
1817
	 * @return  string
1818
	 *
1819
	 * @since   4.11
1820
	 */
1821
	public static function searchCustompath($client = '', $refpath = '')
1822
	{
1823
		$params             = JComponentHelper::getParams('com_localise');
1824
		$ref_tag            = $params->get('reference', 'en-GB');
1825
		$allow_develop      = $params->get('gh_allow_develop', 0);
1826
		$customisedref      = $params->get('customisedref', '0');
1827
		$custom_client_path = JPATH_ROOT
1828
					. '/media/com_localise/customisedref/github/'
1829
					. $client
1830
					. '/'
1831
					. $customisedref;
1832
1833
		$ref_file         = basename($refpath);
1834
		$custom_file_path = JFolder::makeSafe("$custom_client_path/$ref_file");
1835
1836
		if (JFile::exists($custom_file_path) && $allow_develop == 1 && $ref_tag == 'en-GB' && $customisedref != 0)
1837
		{
1838
			$custom_path = $custom_file_path;
1839
		}
1840
		else
1841
		{
1842
			$custom_path = '';
1843
		}
1844
1845
		return $custom_path;
1846
	}
1847
1848
	/**
1849
	 * Allow combine the reference versions to obtain a right result editing in raw mode or saving source reference files
1850
	 * When development is enabled.
1851
	 *
1852
	 * @param   string  $refpath  The data to the reference path
1853
	 *
1854
	 * @param   string  $devpath  The data to the develop path
1855
	 *
1856
	 * @return  string
1857
	 *
1858
	 * @since   4.11
1859
	 */
1860
	public static function combineReferences($refpath = '', $devpath = '')
1861
	{
1862
		$params             = JComponentHelper::getParams('com_localise');
1863
		$ref_tag            = $params->get('reference', 'en-GB');
1864
		$allow_develop      = $params->get('gh_allow_develop', 0);
1865
		$combined_content   = '';
1866
1867
		if (JFile::exists($devpath) && JFile::exists($refpath) && $allow_develop == 1 && $ref_tag == 'en-GB')
1868
		{
1869
			$ref_sections      = self::parseSections($refpath);
1870
			$keys_in_reference = array_keys($ref_sections['keys']);
1871
1872
			$stream = new JStream;
1873
			$stream->open($devpath);
1874
			$stream->seek(0);
1875
1876
			while (!$stream->eof())
1877
			{
1878
				$line = $stream->gets();
1879
1880
				if (preg_match('/^([A-Z][A-Z0-9_\*\-\.]*)\s*=/', $line, $matches))
1881
				{
1882
					$key = $matches[1];
1883
1884
					if (in_array($key, $keys_in_reference))
1885
					{
1886
						$string = $ref_sections['keys'][$key];
1887
						$combined_content .= $key . '="' . str_replace('"', '"_QQ_"', $string) . "\"\n";
1888
					}
1889
					else
1890
					{
1891
						$combined_content .= $line;
1892
					}
1893
				}
1894
				else
1895
				{
1896
					$combined_content .= $line;
1897
				}
1898
			}
1899
1900
			$stream->close();
1901
		}
1902
1903
		return $combined_content;
1904
	}
1905
1906
	/**
1907
	 * Gets the list of ini files
1908
	 *
1909
	 * @param   string  $client_path  The data to the client path
1910
	 *
1911
	 * @return  array
1912
	 *
1913
	 * @since   4.11
1914
	 */
1915
	public static function getInifileslist($client_path = '')
1916
	{
1917
		if (!empty($client_path))
1918
		{
1919
			$files = JFolder::files($client_path, ".ini$");
1920
1921
			return $files;
1922
		}
1923
1924
	return array();
1925
	}
1926
1927
	/**
1928
	 * Gets the list of all type of files in develop
1929
	 *
1930
	 * @param   string  $develop_client_path  The data to the client path
1931
	 *
1932
	 * @return  array
1933
	 *
1934
	 * @since   4.11
1935
	 */
1936
	public static function getLanguagefileslist($develop_client_path = '')
1937
	{
1938
		if (!empty($develop_client_path))
1939
		{
1940
			$files = JFolder::files($develop_client_path);
1941
1942
			return $files;
1943
		}
1944
1945
	return array();
1946
	}
1947
1948
	/**
1949
	 * Gets the stored SHA id for the files in develop.
1950
	 *
1951
	 * @param   array  $gh_data  The required data.
1952
	 *
1953
	 * @return  array
1954
	 *
1955
	 * @since   4.11
1956
	 */
1957
	public static function getShafileslist($gh_data = array())
1958
	{
1959
		$sha_files = array();
1960
		$gh_client = $gh_data['github_client'];
1961
		$sha_path  = JFolder::makeSafe(JPATH_COMPONENT_ADMINISTRATOR . '/develop/gh_joomla_' . $gh_client . '_files.txt');
1962
1963
		if (JFile::exists($sha_path))
1964
		{
1965
			$file_contents = file_get_contents($sha_path);
1966
			$lines = preg_split("/\\r\\n|\\r|\\n/", $file_contents);
1967
1968
			if (!empty($lines))
1969
			{
1970
				foreach ($lines as $line)
1971
				{
1972
					if (!empty($line))
1973
					{
1974
						list($filename, $sha) = explode('::', $line, 2);
1975
1976
						if (!empty($filename) && !empty($sha))
1977
						{
1978
							$sha_files[$filename] = $sha;
1979
						}
1980
					}
1981
				}
1982
			}
1983
		}
1984
1985
	return $sha_files;
1986
	}
1987
1988
	/**
1989
	 * Save the date of the last Github files update by client.
1990
	 *
1991
	 * @param   string  $client_to_update  The client language files.
1992
	 *
1993
	 * @return  bolean
1994
	 *
1995
	 * @since   4.11
1996
	 */
1997
	public static function saveLastupdate($client_to_update)
1998
	{
1999
		$now    = new JDate;
2000
		$now    = $now->toSQL();
2001
		$params = JComponentHelper::getParams('com_localise');
2002
		$params->set($client_to_update, $now);
2003
2004
		$localise_id = JComponentHelper::getComponent('com_localise')->id;
2005
2006
		$table = JTable::getInstance('extension');
2007
		$table->load($localise_id);
2008
		$table->bind(array('params' => $params->toString()));
2009
2010
		if (!$table->check())
2011
		{
2012
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2013
2014
			return false;
2015
		}
2016
2017
		if (!$table->store())
2018
		{
2019
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2020
2021
			return false;
2022
		}
2023
2024
		return true;
2025
	}
2026
2027
	/**
2028
	 * Forces to save the customised source version to use. Option '0' returns to local installed instance.
2029
	 *
2030
	 * @param   string  $option  The option value to save.
2031
	 *
2032
	 * @return  bolean
2033
	 *
2034
	 * @since   4.11
2035
	 */
2036
	public static function setCustomisedsource($option = '0')
2037
	{
2038
		$params = JComponentHelper::getParams('com_localise');
2039
		$params->set('customisedref', $option);
2040
2041
		$localise_id = JComponentHelper::getComponent('com_localise')->id;
2042
2043
		$table = JTable::getInstance('extension');
2044
		$table->load($localise_id);
2045
		$table->bind(array('params' => $params->toString()));
2046
2047
		if (!$table->check())
2048
		{
2049
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2050
2051
			return false;
2052
		}
2053
2054
		if (!$table->store())
2055
		{
2056
			JFactory::getApplication()->enqueueMessage($table->getError(), 'warning');
2057
2058
			return false;
2059
		}
2060
2061
		return true;
2062
	}
2063
2064
	/**
2065
	 * Load revised changes
2066
	 *
2067
	 * @param   array  $data  The required data.
2068
	 *
2069
	 * @return  array
2070
	 *
2071
	 * @since   4.11
2072
	 */
2073
	public static function searchRevisedvalue($data)
2074
	{
2075
		$client        = $data['client'];
2076
		$reftag        = $data['reftag'];
2077
		$tag           = $data['tag'];
2078
		$filename      = $data['filename'];
2079
		$revised       = $data['revised'];
2080
		$key           = $data['key'];
2081
		$target_text   = $data['target_text'];
2082
		$source_text   = $data['source_text'];
2083
		$istranslation = $data['istranslation'];
0 ignored issues
show
$istranslation 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...
2084
		$catch_grammar = $data['catch_grammar'];
2085
2086
		if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename))
2087
		{
2088
			try
2089
			{
2090
				$db                 = JFactory::getDbo();
2091
				$query	            = $db->getQuery(true);
2092
2093
				$search_client      = $db->quote($client);
2094
				$search_reftag      = $db->quote($reftag);
2095
				$search_tag         = $db->quote($tag);
2096
				$search_filename    = $db->quote($filename);
2097
				$search_key         = $db->quote($key);
2098
				$search_target_text = $db->quote($target_text);
2099
				$search_source_text = $db->quote($source_text);
2100
2101
				$query->select(
2102
						array	(
2103
							$db->quoteName('revised')
2104
							)
2105
						);
2106
				$query->from(
2107
						$db->quoteName('#__localise_revised_values')
2108
						);
2109
				$query->where(
2110
						$db->quoteName('client') . '= ' . $search_client
2111
						);
2112
				$query->where(
2113
						$db->quoteName('reftag') . '= ' . $search_reftag
2114
2115
						);
2116
				$query->where(
2117
						$db->quoteName('tag') . '= ' . $search_tag
2118
2119
						);
2120
				$query->where(
2121
						$db->quoteName('filename') . '= ' . $search_filename
2122
						);
2123
				$query->where(
2124
						$db->quoteName('key') . '= ' . $search_key
2125
						);
2126
				$query->where(
2127
						$db->quoteName('target_text') . '= ' . $search_target_text
2128
						);
2129
				$query->where(
2130
						$db->quoteName('source_text') . '= ' . $search_source_text
2131
						);
2132
2133
				$db->setQuery($query);
2134
2135
					if (!$db->query())
2136
					{
2137
						throw new Exception($db->getErrorMsg());
2138
					}
2139
			}
2140
2141
			catch (JException $e)
0 ignored issues
show
The class JException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
2142
			{
2143
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_SEARCHING_REVISED_VALUES'), 'warning');
2144
2145
				return null;
2146
			}
2147
2148
			$result = $db->loadResult();
2149
2150
				if (!is_null($result))
2151
				{
2152
					return (int) $result;
2153
				}
2154
				elseif ($catch_grammar == '1')
2155
				{
2156
					return '0';
2157
				}
2158
				else
2159
				{
2160
					if (self::saveRevisedvalue($data))
2161
					{
2162
						return (int) $revised;
2163
					}
2164
					else
2165
					{
2166
						return null;
2167
					}
2168
				}
2169
		}
2170
2171
		return null;
2172
	}
2173
2174
	/**
2175
	 * Update revised changes
2176
	 *
2177
	 * @param   array  $data  The required data.
2178
	 *
2179
	 * @return  array
2180
	 *
2181
	 * @since   4.11
2182
	 */
2183
	public static function updateRevisedvalue($data)
2184
	{
2185
		$client      = $data['client'];
2186
		$reftag      = $data['reftag'];
2187
		$tag         = $data['tag'];
2188
		$filename    = $data['filename'];
2189
		$revised     = $data['revised'];
2190
		$key         = $data['key'];
2191
		$target_text = $data['target_text'];
2192
		$source_text = $data['source_text'];
2193
2194
		if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename))
2195
		{
2196
			try
2197
			{
2198
				$db = JFactory::getDbo();
2199
2200
				$updated_client      = $db->quote($client);
2201
				$updated_reftag      = $db->quote($reftag);
2202
				$updated_tag         = $db->quote($tag);
2203
				$updated_filename    = $db->quote($filename);
2204
				$updated_revised     = $db->quote($revised);
2205
				$updated_key         = $db->quote($key);
2206
				$updated_target_text = $db->quote($target_text);
2207
				$updated_source_text = $db->quote($source_text);
2208
2209
				$query = $db->getQuery(true);
2210
2211
				$fields = array(
2212
					$db->quoteName('revised') . ' = ' . $updated_revised
2213
				);
2214
2215
				$conditions = array(
2216
					$db->quoteName('client') . ' = ' . $updated_client,
2217
					$db->quoteName('reftag') . ' = ' . $updated_reftag,
2218
					$db->quoteName('tag') . ' = ' . $updated_tag,
2219
					$db->quoteName('filename') . ' = ' . $updated_filename,
2220
					$db->quoteName('key') . ' = ' . $updated_key,
2221
					$db->quoteName('target_text') . ' = ' . $updated_target_text,
2222
					$db->quoteName('source_text') . ' = ' . $updated_source_text
2223
				);
2224
2225
				$query->update($db->quoteName('#__localise_revised_values'))->set($fields)->where($conditions);
2226
2227
				$db->setQuery($query);
2228
				$db->execute();
2229
			}
2230
2231
			catch (JException $e)
0 ignored issues
show
The class JException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
2232
			{
2233
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_UPDATING_REVISED_VALUES'), 'warning');
2234
2235
				return false;
2236
			}
2237
2238
			return true;
2239
		}
2240
2241
		return false;
2242
	}
2243
2244
	/**
2245
	 * Save revised changes
2246
	 *
2247
	 * @param   array  $data  The required data.
2248
	 *
2249
	 * @return  array
2250
	 *
2251
	 * @since   4.11
2252
	 */
2253
	public static function saveRevisedvalue($data)
2254
	{
2255
		$client      = $data['client'];
2256
		$reftag      = $data['reftag'];
2257
		$tag         = $data['tag'];
2258
		$filename    = $data['filename'];
2259
		$revised     = $data['revised'];
2260
		$key         = $data['key'];
2261
		$target_text = $data['target_text'];
2262
		$source_text = $data['source_text'];
2263
2264
		if (!empty($client) && !empty($reftag) && !empty($tag) && !empty($filename))
2265
		{
2266
			try
2267
			{
2268
				$db = JFactory::getDbo();
2269
2270
				$saved_client      = $db->quote($client);
2271
				$saved_reftag      = $db->quote($reftag);
2272
				$saved_tag         = $db->quote($tag);
2273
				$saved_filename    = $db->quote($filename);
2274
				$saved_revised     = $db->quote($revised);
2275
				$saved_key         = $db->quote($key);
2276
				$saved_target_text = $db->quote($target_text);
2277
				$saved_source_text = $db->quote($source_text);
2278
2279
				$query = $db->getQuery(true);
2280
2281
				$columns = array('client', 'reftag', 'tag', 'filename', 'revised', 'key', 'target_text', 'source_text');
2282
2283
				$values = array($saved_client, $saved_reftag, $saved_tag, $saved_filename, $saved_revised, $saved_key, $saved_target_text, $saved_source_text);
2284
2285
				$query
2286
					->insert($db->quoteName('#__localise_revised_values'))
2287
					->columns($db->quoteName($columns))
2288
					->values(implode(',', $values));
2289
2290
				$db->setQuery($query);
2291
				$db->execute();
2292
			}
2293
2294
			catch (JException $e)
0 ignored issues
show
The class JException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
2295
			{
2296
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_SAVING_REVISED_VALUES'), 'warning');
2297
2298
				return false;
2299
			}
2300
2301
			return true;
2302
		}
2303
2304
		return false;
2305
	}
2306
2307
	/**
2308
	 * Create the required folders for develop
2309
	 *
2310
	 * @param   array   $gh_data  Array with the data
2311
	 * @param   string  $index    If true, allow to create an index.html file
2312
	 *
2313
	 * @return  bolean
2314
	 *
2315
	 * @since   4.11
2316
	 */
2317
	public static function createFolder($gh_data = array(), $index = 'true')
2318
	{
2319
		$source_ref = $gh_data['customisedref'];
2320
2321
		if (!empty($gh_data) && isset($source_ref))
2322
		{
2323
		$full_path = JPATH_ROOT . '/media/com_localise/customisedref/github/'
2324
					. $gh_data['github_client']
2325
					. '/'
2326
					. $source_ref;
2327
2328
		$full_path = JFolder::makeSafe($full_path);
2329
2330
			if (!JFolder::create($full_path))
2331
			{
2332
			}
2333
2334
			if (JFolder::exists($full_path))
2335
			{
2336
				if ($index == 'true')
2337
				{
2338
				$cretate_index = self::createIndex($full_path);
2339
2340
					if ($cretate_index == 1)
2341
					{
2342
						return true;
2343
					}
2344
2345
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_INDEX_FILE'), 'warning');
2346
2347
				return false;
2348
				}
2349
2350
			return true;
2351
			}
2352
			else
2353
			{
2354
				JFactory::getApplication()->enqueueMessage(JText::_('COM_LOCALISE_ERROR_GITHUB_UNABLE_TO_CREATE_FOLDERS'), 'warning');
2355
2356
				return false;
2357
			}
2358
		}
2359
2360
	return false;
2361
	}
2362
2363
	/**
2364
	 * Creates an index.html file within folders for develop
2365
	 *
2366
	 * @param   string  $full_path  The full path.
2367
	 *
2368
	 * @return  bolean
2369
	 *
2370
	 * @since   4.11
2371
	 */
2372
	public static function createIndex($full_path = '')
2373
	{
2374
		if (!empty($full_path))
2375
		{
2376
		$path = JFolder::makeSafe($full_path . '/index.html');
2377
2378
		$index_content = '<!DOCTYPE html><title></title>';
2379
2380
			if (!JFile::exists($path))
2381
			{
2382
				JFile::write($path, $index_content);
2383
			}
2384
2385
			if (!JFile::exists($path))
2386
			{
2387
				return false;
2388
			}
2389
			else
2390
			{
2391
				return true;
2392
			}
2393
		}
2394
2395
	return false;
2396
	}
2397
2398
	/**
2399
	 * Gets the text changes.
2400
	 *
2401
	 * @param   array  $old  The string parts in reference.
2402
	 * @param   array  $new  The string parts in develop.
2403
	 *
2404
	 * @return  array
2405
	 *
2406
	 * @since   4.11
2407
	 */
2408
	public static function getTextchanges($old, $new)
2409
	{
2410
		$maxlen = 0;
2411
2412
		foreach ($old as $oindex => $ovalue)
2413
		{
2414
			$nkeys = array_keys($new, $ovalue);
2415
2416
			foreach ($nkeys as $nindex)
2417
			{
2418
				$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
0 ignored issues
show
The variable $matrix does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2419
2420
				if ($matrix[$oindex][$nindex] > $maxlen)
2421
				{
2422
					$maxlen = $matrix[$oindex][$nindex];
2423
					$omax = $oindex + 1 - $maxlen;
2424
					$nmax = $nindex + 1 - $maxlen;
2425
				}
2426
2427
			unset ($nkeys, $nindex);
2428
			}
2429
2430
		unset ($oindex, $ovalue);
2431
		}
2432
2433
		if ($maxlen == 0)
2434
		{
2435
			return array(array ('d' => $old, 'i' => $new));
2436
		}
2437
2438
		return array_merge(
2439
			self::getTextchanges(
2440
			array_slice($old, 0, $omax),
0 ignored issues
show
The variable $omax does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2441
			array_slice($new, 0, $nmax)
0 ignored issues
show
The variable $nmax does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2442
			),
2443
			array_slice($new, $nmax, $maxlen),
2444
			self::getTextchanges(
2445
			array_slice($old, $omax + $maxlen),
2446
			array_slice($new, $nmax + $maxlen)
2447
			)
2448
			);
2449
	}
2450
2451
	/**
2452
	 * Gets the html text changes.
2453
	 *
2454
	 * @param   string  $old  The string in reference.
2455
	 * @param   string  $new  The string in develop.
2456
	 *
2457
	 * @return  string
2458
	 *
2459
	 * @since   4.11
2460
	 */
2461
	public static function htmlgetTextchanges($old, $new)
2462
	{
2463
		$text_changes = '';
2464
2465
		if ($old == $new)
2466
		{
2467
			return $text_changes;
2468
		}
2469
2470
		$old = str_replace('  ', 'LOCALISEDOUBLESPACES', $old);
2471
		$new = str_replace('  ', 'LOCALISEDOUBLESPACES', $new);
2472
2473
		$diff = self::getTextchanges(explode(' ', $old), explode(' ', $new));
2474
2475
		foreach ($diff as $k)
2476
		{
2477
			if (is_array($k))
2478
			{
2479
				$text_changes .= (!empty ($k['d'])?"LOCALISEDELSTART"
2480
					. implode(' ', $k['d']) . "LOCALISEDELSTOP ":'')
2481
					. (!empty($k['i']) ? "LOCALISEINSSTART"
2482
					. implode(' ', $k['i'])
2483
					. "LOCALISEINSSTOP " : '');
2484
			}
2485
			else
2486
			{
2487
				$text_changes .= $k . ' ';
2488
			}
2489
2490
		unset ($k);
2491
		}
2492
2493
		$text_changes = htmlspecialchars($text_changes);
2494
		$text_changes = preg_replace('/LOCALISEINSSTART/', "<ins class='diff_ins'>", $text_changes);
2495
		$text_changes = preg_replace('/LOCALISEINSSTOP/', "</ins>", $text_changes);
2496
		$text_changes = preg_replace('/LOCALISEDELSTART/', "<del class='diff_del'>", $text_changes);
2497
		$text_changes = preg_replace('/LOCALISEDELSTOP/', "</del>", $text_changes);
2498
		$double_spaces = '<span class="red-space"><font color="red">XX</font></span>';
2499
		$text_changes = str_replace('LOCALISEDOUBLESPACES', $double_spaces, $text_changes);
2500
2501
	return $text_changes;
2502
	}
2503
}
2504