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.

LocaliseModelPackage   F
last analyzed

Complexity

Total Complexity 131

Size/Duplication

Total Lines 1184
Duplicated Lines 35.14 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 416
loc 1184
rs 0.864
c 0
b 0
f 0
wmc 131
lcom 1
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A populateState() 0 12 1
A getTable() 0 4 1
A getForm() 24 24 3
A loadFormData() 16 16 2
A getFormFtp() 20 20 3
C getItem() 36 128 13
F save() 110 300 29
F download() 210 488 66
A uploadFile() 0 36 3
C uploadOtherFile() 0 65 10

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like LocaliseModelPackage often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LocaliseModelPackage, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package     Com_Localise
4
 * @subpackage  model
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.file');
14
jimport('joomla.client.helper');
15
16
/**
17
 * Package Model class for the Localise component
18
 *
19
 * @package     Extensions.Components
20
 * @subpackage  Localise
21
 *
22
 * @since       1.0
23
 */
24
class LocaliseModelPackage extends JModelAdmin
25
{
26
	/**
27
	 * Method to auto-populate the model state.
28
	 *
29
	 * Note. Calling getState in this method will result in recursion.
30
	 *
31
	 * @param   string  $ordering   An optional ordering field.
32
	 * @param   string  $direction  An optional direction (asc|desc).
33
	 *
34
	 * @return  void
35
	 *
36
	 * @since   1.6
37
	 */
38
	protected function populateState($ordering = null, $direction = null)
39
	{
40
		// Get the application
41
		$app = JFactory::getApplication('administrator');
42
43
		// Load the User state.
44
		$name = $app->getUserState('com_localise.package.name');
45
		$this->setState('package.name', $name);
46
47
		$id = $app->getUserState('com_localise.edit.package.id');
48
		$this->setState('package.id', $id);
49
	}
50
51
	/**
52
	 * Returns a Table object, always creating it.
53
	 *
54
	 * @param   string  $type    The table type to instantiate
55
	 * @param   string  $prefix  A prefix for the table class name. Optional.
56
	 * @param   array   $config  Configuration array for model. Optional.
57
	 *
58
	 * @return  JTable  A database object
59
	 */
60
	public function getTable($type = 'Localise', $prefix = 'LocaliseTable', $config = array())
61
	{
62
		return JTable::getInstance($type, $prefix, $config);
63
	}
64
65
	/**
66
	 * Method to get the record form.
67
	 *
68
	 * @param   array    $data      Data for the form.
69
	 * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
70
	 *
71
	 * @return  mixed  A JForm object on success, false on failure
72
	 */
73 View Code Duplication
	public function getForm($data = array(), $loadData = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
74
	{
75
		// Get the form.
76
		$id   = $this->getState('package.id');
0 ignored issues
show
Unused Code introduced by
$id 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...
77
		$name = $this->getState('package.name');
78
		$form = $this->loadForm('com_localise.package', 'package', array('control' => 'jform', 'load_data' => $loadData));
79
80
		if (empty($form))
81
		{
82
			return false;
83
		}
84
85
		$form->setFieldAttribute('translations', 'package', $name, 'translations');
86
87
		// Check for an error.
88
		if (JError::isError($form))
89
		{
90
			$this->setError($form->getMessage());
91
92
			return false;
93
		}
94
95
		return $form;
96
	}
97
98
	/**
99
	 * Method to get the data that should be injected in the form.
100
	 *
101
	 * @return   mixed  The data for the form.
102
	 */
103 View Code Duplication
	protected function loadFormData()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
104
	{
105
		// Initialise variables.
106
		$app = JFactory::getApplication();
107
108
		// Check the session for previously entered form data.
109
		$data = $app->getUserState('com_localise.edit.package.data', array());
110
111
		// Get the package data.
112
		if (empty($data))
113
		{
114
			$data = $this->getItem();
115
		}
116
117
		return $data;
118
	}
119
120
	/**
121
	 * Method to get the ftp form.
122
	 *
123
	 * @return  mixed  A JForm object on success, false on failure or not ftp
124
	 */
125 View Code Duplication
	public function getFormFtp()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
126
	{
127
		// Get the form.
128
		$form = $this->loadForm('com_localise.ftp', 'ftp');
129
130
		if (empty($form))
131
		{
132
			return false;
133
		}
134
135
		// Check for an error.
136
		if (JError::isError($form))
137
		{
138
			$this->setError($form->getMessage());
139
140
			return false;
141
		}
142
143
		return $form;
144
	}
145
146
	/**
147
	 * Method to get the package.
148
	 *
149
	 * @param   integer  $pk  The ID of the primary key.
150
	 *
151
	 * @return JObject the package
152
	 */
153
	public function getItem($pk = null)
154
	{
155
		$id = $this->getState('package.id');
156
		$id = is_array($id) ? (count($id) > 0 ? $id[0] : 0) : $id;
157
		$package = new JObject;
158
		$package->checked_out = 0;
159
		$package->standalone  = true;
160
		$package->manifest    = null;
161
		$package->title       = null;
162
		$package->description = null;
163
		$package->id          = $id;
164
165
		if (!empty($id))
166
		{
167
			// If the package exists get it
168
			$table = $this->getTable();
169
170
			if (is_array($id))
171
			{
172
				$id = $id[0];
173
			}
174
175
			$table->load($id);
176
			$package->setProperties($table->getProperties());
177
178
			// Get the manifest
179
			$xml = simplexml_load_file($table->path);
180
181
			if ($xml)
182
			{
183
				$manifest = (string) $xml->manifest;
184
185
				// $client   = (string) $xml->manifest->attributes()->client;
186
				// LocaliseHelper::loadLanguage($manifest, $client);
187
188
				// Set up basic information
189
				$name = basename($table->path);
190
				$name = substr($name, 0, strlen($name) - 4);
191
192
				$package->id          = $id;
193
				$package->name        = $name;
194
				$package->manifest    = $manifest;
195
196
				// $package->client      = $client;
197
				// $package->standalone  = substr($manifest, 0, 4) == 'fil_';
198
199
				$package->core           = ((string) $xml->attributes()->core) == 'true';
200
				$package->title          = (string) $xml->title;
201
				$package->version        = (string) $xml->version;
202
				$package->packversion    = (string) $xml->packversion;
203
				$package->description    = (string) $xml->description;
204
				$package->language       = (string) $xml->language;
205
				$package->blockuninstall = (string) $xml->blockuninstall;
206
				$package->license        = (string) $xml->license;
207
				$package->copyright      = (string) $xml->copyright;
208
				$package->author         = (string) $xml->author;
209
				$package->authoremail    = (string) $xml->authoremail;
210
				$package->authorurl      = (string) $xml->authorurl;
211
				$package->url            = (string) $xml->url;
212
				$package->packager       = (string) $xml->packager;
213
				$package->packagerurl    = (string) $xml->packagerurl;
214
				$package->servername     = (string) $xml->servername;
215
				$package->serverurl      = (string) $xml->serverurl;
216
				$package->writable       = LocaliseHelper::isWritable($package->path);
217
218
				$user = JFactory::getUser($table->checked_out);
219
				$package->setProperties($table->getProperties());
220
221
				if ($package->checked_out == JFactory::getUser()->id)
222
				{
223
					$package->checked_out = 0;
224
				}
225
226
				$package->editor = JText::sprintf('COM_LOCALISE_TEXT_PACKAGE_EDITOR', $user->name, $user->username);
227
228
				// Get the translations
229
				$package->translations  = array();
230
				$package->administrator = array();
231
232 View Code Duplication
				if ($xml->administrator)
0 ignored issues
show
Duplication introduced by
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...
233
				{
234
					foreach ($xml->administrator->children() as $file)
235
					{
236
						$data = (string) $file;
237
238
						if ($data)
239
						{
240
							$package->translations[] = "administrator_$data";
241
						}
242
						else
243
						{
244
							$package->translations[] = "administrator_joomla";
245
						}
246
247
						$package->administrator[] = $data;
248
					}
249
				}
250
251
				$package->site = array();
252
253 View Code Duplication
				if ($xml->site)
0 ignored issues
show
Duplication introduced by
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...
254
				{
255
					foreach ($xml->site->children() as $file)
256
					{
257
						$data = (string) $file;
258
259
						if ($data)
260
						{
261
							$package->translations[] = "site_$data";
262
						}
263
						else
264
						{
265
							$package->translations[] = "site_joomla";
266
						}
267
268
						$package->site[] = $data;
269
					}
270
				}
271
			}
272
			else
273
			{
274
				$package = null;
275
				$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_FILEEDIT'), $table->path);
276
			}
277
		}
278
279
		return $package;
280
	}
281
282
	/**
283
	 * Method to save data
284
	 *
285
	 * @param   array  $data  the data to save
286
	 *
287
	 * @return  boolean  success or failure
288
	 */
289
	public function save($data)
290
	{
291
		// When editing a package, find the original path
292
		$app = JFactory::getApplication('administrator');
293
		$originalId = $app->getUserState('com_localise.edit.package.id');
294
		$oldpath = null;
295
296
		$originalId = is_array($originalId) && count($originalId) > 0 ?
297
						$originalId[0] : $originalId;
298
299 View Code Duplication
		if (!empty($originalId))
0 ignored issues
show
Duplication introduced by
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...
300
		{
301
			$db = JFactory::getDbo();
302
			$query = $db->getQuery(true)
303
				->select($db->quoteName('path'))
304
				->from($db->quoteName('#__localise'))
305
				->where($db->quoteName('id') . ' = ' . $originalId);
306
			$db->setQuery($query);
307
308
			$oldpath = $db->loadResult('path');
309
		}
310
311
		// Get the package name
312
		$name = $data['name'];
313
314
		// Get the package
315
		$package  = $this->getItem();
316
		$path     = JPATH_COMPONENT_ADMINISTRATOR . "/packages/$name.xml";
317
		$manifest = $name;
318
319
		// $client   = $package->client ? $package->client : 'site';
320
321
		if ($package->standalone)
322
		{
323
			$title = $name;
324
			$description = $data['description'];
325
326
			$dom = new DOMDocument('1.0', 'utf-8');
327
328
			// Create simple XML element and base package tag
329
			$packageXml = $dom->createElement('package');
330
331
			// Add main package information
332
			$titleElement = $dom->createElement('title', $title);
333
			$descriptionElement = $dom->createElement('description', $description);
334
			$manifestElement = $dom->createElement('manifest', $manifest);
335
			$versionElement = $dom->createElement('version', $data['version']);
336
			$packversionElement = $dom->createElement('packversion', $data['packversion']);
337
			$blockUninstallElement = $dom->createElement('blockuninstall', $data['blockuninstall']);
338
			$authorElement = $dom->createElement('author', $data['author']);
339
			$licenseElement = $dom->createElement('license', $data['license']);
340
			$authorEmailElement = $dom->createElement('authoremail', $data['authoremail']);
341
			$authorUrlElement = $dom->createElement('authorurl', $data['authorurl']);
342
			$languageElement = $dom->createElement('language', $data['language']);
343
			$copyrightElement = $dom->createElement('copyright', $data['copyright']);
344
			$urlElement = $dom->createElement('url', $data['url']);
345
			$packagerElement = $dom->createElement('packager', $data['packager']);
346
			$packagerUrlElement = $dom->createElement('packagerurl', $data['packagerurl']);
347
			$servernameElement = $dom->createElement('servername', $data['servername']);
348
			$serverurlElement = $dom->createElement('serverurl', $data['serverurl']);
349
350
			// Set the client attribute on the manifest element
351
352
			// $clientAttribute = $dom->createAttribute('client');
353
354
			// $clientAttribute->value = $client;
355
			// $manifestElement->appendChild($clientAttribute);
356
357
			// Set the core attribute as we only make packages for Core
358
			$coreAttribute = $dom->createAttribute('core');
359
			$coreAttribute->value = "true";
360
			$packageXml->appendChild($coreAttribute);
361
362
			// Add all the elements to the parent <package> tag
363
			$packageXml->appendChild($titleElement);
364
			$packageXml->appendChild($descriptionElement);
365
			$packageXml->appendChild($manifestElement);
366
			$packageXml->appendChild($versionElement);
367
			$packageXml->appendChild($packversionElement);
368
			$packageXml->appendChild($blockUninstallElement);
369
			$packageXml->appendChild($authorElement);
370
			$packageXml->appendChild($copyrightElement);
371
			$packageXml->appendChild($licenseElement);
372
			$packageXml->appendChild($authorEmailElement);
373
			$packageXml->appendChild($authorUrlElement);
374
			$packageXml->appendChild($languageElement);
375
			$packageXml->appendChild($copyrightElement);
376
			$packageXml->appendChild($urlElement);
377
			$packageXml->appendChild($packagerElement);
378
			$packageXml->appendChild($packagerUrlElement);
379
			$packageXml->appendChild($servernameElement);
380
			$packageXml->appendChild($serverurlElement);
381
382
			$administrator = array();
383
			$site          = array();
384
385 View Code Duplication
			foreach ($data['translations'] as $translation)
0 ignored issues
show
Duplication introduced by
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...
386
			{
387
				if (preg_match('/^site_(.*)$/', $translation, $matches))
388
				{
389
					$site[] = $matches[1];
390
				}
391
392
				if (preg_match('/^administrator_(.*)$/', $translation, $matches))
393
				{
394
					$administrator[] = $matches[1];
395
				}
396
			}
397
398
			// Add the site language files
399 View Code Duplication
			if (count($site))
0 ignored issues
show
Duplication introduced by
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...
400
			{
401
				$siteXml = $dom->createElement('site');
402
403
				foreach ($site as $translation)
404
				{
405
					$fileElement = $dom->createElement('filename', $translation . '.ini');
406
					$siteXml->appendChild($fileElement);
407
				}
408
409
				$packageXml->appendChild($siteXml);
410
			}
411
412
			// Add the administrator language files
413 View Code Duplication
			if (count($administrator))
0 ignored issues
show
Duplication introduced by
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...
414
			{
415
				$adminXml = $dom->createElement('administrator');
416
417
				foreach ($administrator as $translation)
418
				{
419
					$fileElement = $dom->createElement('filename', $translation . '.ini');
420
					$adminXml->appendChild($fileElement);
421
				}
422
423
				$packageXml->appendChild($adminXml);
424
			}
425
426
			$dom->appendChild($packageXml);
427
428
			// Set FTP credentials, if given.
429
			JClientHelper::setCredentialsFromRequest('ftp');
430
			$ftp = JClientHelper::getCredentials('ftp');
431
432
			// Try to make the file writeable.
433 View Code Duplication
			if (JFile::exists($path) && !$ftp['enabled'] && JPath::isOwner($path) && !JPath::setPermissions($path, '0644'))
0 ignored issues
show
Duplication introduced by
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...
434
			{
435
				$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_WRITABLE', $path));
436
437
				return false;
438
			}
439
440
			// Make the XML look pretty
441
			$dom->formatOutput = true;
442
			$formattedXML = $dom->saveXML();
443
444
			$return = JFile::write($path, $formattedXML);
445
446
			// Try to make the file unwriteable.
447 View Code Duplication
			if (!$ftp['enabled'] && JPath::isOwner($path) && !JPath::setPermissions($path, '0444'))
0 ignored issues
show
Duplication introduced by
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...
448
			{
449
				$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_UNWRITABLE', $path));
450
451
				return false;
452
			}
453
			elseif (!$return)
454
			{
455
				$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_FILESAVE', $path));
456
457
				return false;
458
			}
459
		}
460
461
		// Save the title and the description in the language file
462
463
		/* @TODO Check ftp part
464
		$translation_path  = LocaliseHelper::findTranslationPath($client, JFactory::getLanguage()->getTag(), $manifest);
465
		$translation_id    = LocaliseHelper::getFileId($translation_path);
466
		$translation_model = JModelLegacy::getInstance('Translation', 'LocaliseModel', array('ignore_request' => true));
467
468
		if ($translation_model->checkout($translation_id))
469
		{
470
			$translation_model->setState('translation.path', $translation_path);
471
			$translation_model->setState('translation.client', $client);
472
			$translation = $translation_model->getItem();
473
			$sections    = LocaliseHelper::parseSections($translation_path);
474
		}
475
		else
476
		{
477
		}
478
479
		$text = '';
480
		$text .= strtoupper($title) . '="' . str_replace('"', '"_QQ_"', $data['title']) . "\"\n";
481
		$text .= strtoupper($description) . '="' . str_replace('"', '"_QQ_"', $data['description']) . "\"\n";
482
		$tag  = JFactory::getLanguage()->getTag();
483
		$languagePath = JPATH_SITE . "/language/$tag/$tag.$manifest.ini";
484
		 */
485
486
		// Try to make the file writeable.
487
488
		/*
489
		if (!$ftp['enabled'] && JPath::isOwner($languagePath) && !JPath::setPermissions($languagePath, '0644'))
490
		{
491
			$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_WRITABLE', $languagePath));
492
493
			return false;
494
		}
495
496
		$return = JFile::write($languagePath, $text);
497
		*/
498
499
		// Try to make the file unwriteable.
500
501
		/*
502
		if (!$ftp['enabled'] && JPath::isOwner($languagePath) && !JPath::setPermissions($languagePath, '0444'))
503
		{
504
			$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_UNWRITABLE', $languagePath));
505
506
			return false;
507
		}
508
		elseif (!$return)
509
		{
510
			$this->setError(JText::sprintf('COM_LOCALISE_ERROR_PACKAGE_FILESAVE', $languagePath));
511
512
			return false;
513
		}
514
		*/
515 View Code Duplication
		if ($path == $oldpath)
0 ignored issues
show
Duplication introduced by
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...
516
		{
517
			$id = LocaliseHelper::getFileId($path);
518
			$this->setState('package.id', $id);
519
520
			// Bind the rules.
521
			$table = $this->getTable();
522
			$table->load($id);
523
		}
524
		else
525
		{
526
			$table = $this->getTable();
527
528
			if (!$table->delete((int) $originalId))
529
			{
530
				$this->setError($table->getError());
531
532
				return false;
533
			}
534
535
			$table->store();
536
537
			$id = LocaliseHelper::getFileId($path);
538
			$this->setState('package.id', $id);
539
			$app->setUserState('com_localise.edit.package.id', $id);
540
		}
541
542
		if (isset($data['rules']))
543
		{
544
			$rules = new JAccessRules($data['rules']);
545
			$table->setRules($rules);
546
		}
547
548
		// Check the data.
549
		if (!$table->check())
550
		{
551
			$this->setError($table->getError());
552
553
			return false;
554
		}
555
556
		// Store the data.
557
		if (!$table->store())
558
		{
559
			$this->setError($table->getError());
560
561
			return false;
562
		}
563
564
		// Delete the older file and redirect
565 View Code Duplication
		if ($path !== $oldpath && file_exists($oldpath))
0 ignored issues
show
Duplication introduced by
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
		{
567
			if (!JFile::delete($oldpath))
568
			{
569
				$app->enqueueMessage(JText::_('COM_LOCALISE_ERROR_OLDFILE_REMOVE'), 'notice');
570
			}
571
572
			$task = JFactory::getApplication()->input->get('task');
573
574
			if ($task == 'save')
575
			{
576
				$app->redirect(JRoute::_('index.php?option=com_localise&view=packages', false));
577
			}
578
			else
579
			{
580
				// Redirect to the new $id as name has changed
581
				$app->redirect(JRoute::_('index.php?option=com_localise&view=package&layout=edit&id=' . $this->getState('package.id'), false));
582
			}
583
		}
584
585
		$this->cleanCache();
586
587
		return true;
588
	}
589
590
	/**
591
	 * Method to generate and download a package
592
	 *
593
	 * @param   array  $data  the data to generate the package
594
	 *
595
	 * @return  boolean  success or failure
596
	 */
597
	public function download($data)
598
	{
599
		// The data could potentially be loaded from the file with $this->getItem() instead of using directly the data from the post
600
		$app = JFactory::getApplication();
601
602
		// Prevent generating and downloading Master package
603 View Code Duplication
		if (strpos($data['name'], 'master_') !== false)
0 ignored issues
show
Duplication introduced by
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...
604
		{
605
			$app->enqueueMessage(JText::sprintf('COM_LOCALISE_ERROR_MASTER_PACKAGE_DOWNLOAD_FORBIDDEN', $data['name']), 'warning');
606
			$app->redirect(JRoute::_('index.php?option=com_localise&view=package&layout=edit&id=' . $this->getState('package.id'), false));
607
608
			return false;
609
		}
610
611
		// Necessary variables if xx-XX.localise.php is not present in target language
612
		$params			= JComponentHelper::getParams('com_localise');
613
		$reftag			= $params->get('reference');
614
		$refclassname	= str_replace('-', '_', $reftag);
615
		$refclassname	= ucfirst($refclassname);
616
		$langclassname	= str_replace('-', '_', $data['language']);
617
		$langclassname	= ucfirst($langclassname);
618
		$msg = null;
619
620
		$administrator = array();
621
		$site          = array();
622
		$main_package_files = array();
623
624
		// Delete old files
625
		$delete = JFolder::files(JPATH_ROOT . '/tmp/', 'com_localise_', false, true);
626
627 View Code Duplication
		if (!empty($delete))
0 ignored issues
show
Duplication introduced by
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...
628
		{
629
			if (!JFile::delete($delete))
630
			{
631
				// JFile::delete throws an error
632
				$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ZIPDELETE'));
633
634
				return false;
635
			}
636
		}
637
638 View Code Duplication
		foreach ($data['translations'] as $translation)
0 ignored issues
show
Duplication introduced by
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...
639
		{
640
			if (preg_match('/^site_(.*)$/', $translation, $matches))
641
			{
642
				$site[] = $matches[1];
643
			}
644
645
			if (preg_match('/^administrator_(.*)$/', $translation, $matches))
646
			{
647
				$administrator[] = $matches[1];
648
			}
649
		}
650
651
		$parts = explode('.', $data['version']);
652
		$small_version = implode('.', array($parts[0],$parts[1]));
653
654
		// Prepare text to save for the xml package description
655
		$text = '';
656
		$text .= '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
657
		$text .= '<extension type="package" version="' . $small_version . '" method="upgrade">' . "\n";
658
		$text .= "\t" . '<name>' . $data['name'] . '</name>' . "\n";
659
		$text .= "\t" . '<packagename>' . $data['language'] . '</packagename>' . "\n";
660
		$text .= "\t" . '<version>' . $data['version'] . '.' . $data['packversion'] . '</version>' . "\n";
661
		$text .= "\t" . '<creationDate>' . date('d/m/Y') . '</creationDate>' . "\n";
662
		$text .= "\t" . '<author>' . $data['author'] . '</author>' . "\n";
663
		$text .= "\t" . '<authorEmail>' . $data['authoremail'] . '</authorEmail>' . "\n";
664
		$text .= "\t" . '<authorUrl>' . $data['authorurl'] . '</authorUrl>' . "\n";
665
		$text .= "\t" . '<copyright>' . $data['copyright'] . '</copyright>' . "\n";
666
		$text .= "\t" . '<license>' . $data['license'] . '</license>' . "\n";
667
		$text .= "\t" . '<url>' . $data['url'] . '</url>' . "\n";
668
		$text .= "\t" . '<packager>' . $data['packager'] . '</packager>' . "\n";
669
		$text .= "\t" . '<packagerurl>' . $data['packagerurl'] . '</packagerurl>' . "\n";
670
		$text .= "\t" . '<description><![CDATA[' . $data['description'] . ']]></description>' . "\n";
671
		$text .= "\t" . '<blockChildUninstall>' . $data['blockuninstall'] . '</blockChildUninstall>' . "\n";
672
		$text .= "\t" . '<files>' . "\n";
673
674
		if (count($site))
675
		{
676
			$text .= "\t\t" . '<file type="language" client="site" id="' . $data['language'] . '">site_' . $data['language'] . '.zip</file>' . "\n";
677
678
			$path = JPATH_ROOT . '/language/' . $data['language'] . '/' . $data['language'] . '.xml';
679
680
			if (JFile::exists($path))
681
			{
682
				$xmldata = file_get_contents($path);
683
684
				// Fetch the language name for the install.xml
685
				if (!empty($xmldata))
686
				{
687
					$xml         = simplexml_load_file($path);
688
					$installName = (string) $xml->name;
689
				}
690
			}
691
692 View Code Duplication
			if (!JFile::exists($path) || empty($xmldata))
0 ignored issues
show
Duplication introduced by
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...
693
			{
694
				$app->enqueueMessage(JText::sprintf('COM_LOCALISE_ERROR_NO_XML', JText::_('JSITE'), $data['language'] . '.xml', 'error'));
695
				$app->redirect(JRoute::_('index.php?option=com_localise&view=package&layout=edit&id=' . $this->getState('package.id'), false));
696
697
				return false;
698
			}
699
700
			// Generate site package
701
			$site_package_files = array();
702
703
			$site_txt = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
704
			$site_txt .= '<extension version="' . $small_version . '" client="site" type="language" method="upgrade">' . "\n";
705
			$site_txt .= "\t" . '<name>' . $installName . '</name>' . "\n";
0 ignored issues
show
Bug introduced by
The variable $installName 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...
706
			$site_txt .= "\t" . '<tag>' . $data['language'] . '</tag>' . "\n";
707
			$site_txt .= "\t" . '<version>' . $data['version'] . '.' . $data['packversion'] . '</version>' . "\n";
708
			$site_txt .= "\t" . '<creationDate>' . date('d/m/Y') . '</creationDate>' . "\n";
709
			$site_txt .= "\t" . '<author>' . $data['author'] . '</author>' . "\n";
710
			$site_txt .= "\t" . '<authorEmail>' . $data['authoremail'] . '</authorEmail>' . "\n";
711
			$site_txt .= "\t" . '<authorUrl>' . $data['authorurl'] . '</authorUrl>' . "\n";
712
			$site_txt .= "\t" . '<copyright>' . $data['copyright'] . '</copyright>' . "\n";
713
			$site_txt .= "\t" . '<license>' . $data['license'] . '</license>' . "\n";
714
			$site_txt .= "\t" . '<description>' . $data['language'] . ' - Site language</description>' . "\n";
715
			$site_txt .= "\t" . '<files>' . "\n";
716
717
			// As this is a core package, the main joomla file xx-XX.ini should be in the package
718
			$path = JPATH_ROOT . '/language/' . $data['language'] . '/' . $data['language'] . '.ini';
719
720
			if (JFile::exists($path))
721
			{
722
				$file_data = file_get_contents($path);
723
			}
724
725 View Code Duplication
			if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
726
			{
727
				$site = array_diff($site, array("joomla"));
728
				$site_txt .= "\t\t" . '<filename>' . $data['language'] . '.ini</filename>' . "\n";
729
				$site_package_files[] = array('name' => $data['language'] . '.ini','data' => $file_data);
730
			}
731
			else
732
			{
733
				$msg .= JText::sprintf('COM_LOCALISE_MAINFILE_NOT_TRANSLATED', $data['language'] . '.ini', JText::_('JSITE'));
734
			}
735
736 View Code Duplication
			foreach ($site as $translation)
0 ignored issues
show
Duplication introduced by
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...
737
			{
738
				$path = JPATH_ROOT . '/language/' . $data['language'] . '/' . $data['language'] . '.' . $translation . '.ini';
739
740
				if (JFile::exists($path))
741
				{
742
					$file_data = file_get_contents($path);
743
				}
744
745
				if (JFile::exists($path) && !empty($file_data))
746
				{
747
					$site_txt .= "\t\t" . '<filename>' . $data['language'] . '.' . $translation . '.ini</filename>' . "\n";
748
					$site_package_files[] = array('name' => $data['language'] . '.' . $translation . '.ini', 'data' => $file_data);
749
				}
750
				elseif ($translation != 'joomla')
751
				{
752
					$msg .= JText::sprintf('COM_LOCALISE_FILE_NOT_TRANSLATED', $data['language'] . '.' . $translation . '.ini', JText::_('JSITE'));
753
				}
754
			}
755
756
			$path = JPATH_ROOT . '/language/' . $data['language'] . '/' . $data['language'] . '.localise.php';
757
758 View Code Duplication
			if (JFile::exists($path))
0 ignored issues
show
Duplication introduced by
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...
759
			{
760
				$language_data = file_get_contents($path);
761
			}
762
763
			// Create a basic xx-XX.localise.php if not present in target language
764
			elseif (!JFile::exists($path) || empty($languagedata))
0 ignored issues
show
Bug introduced by
The variable $languagedata seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
765
			{
766
				$language_data = file_get_contents(JPATH_ROOT . '/language/' . $reftag . '/' . $reftag . '.localise.php');
767
				$language_data = str_replace($reftag, $data['language'], $language_data);
768
				$language_data = str_replace($refclassname, $langclassname, $language_data);
769
			}
770
771
			$site_txt .= "\t\t" . '<filename>' . $data['language'] . '.localise.php</filename>' . "\n";
772
			$site_package_files[] = array('name' => $data['language'] . '.localise.php','data' => $language_data);
0 ignored issues
show
Bug introduced by
The variable $language_data 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...
773
774
			if ($msg)
0 ignored issues
show
Bug Best Practice introduced by
The expression $msg of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
775
			{
776
				$msg .= '<p>...</p>';
777
			}
778
779
			$site_txt .= "\t\t" . '<filename file="meta">install.xml</filename>' . "\n";
780
			$site_txt .= "\t\t" . '<filename file="meta">' . $data['language'] . '.xml</filename>' . "\n";
781
			$site_txt .= "\t\t" . '<filename>index.html</filename>' . "\n";
782
			$site_txt .= "\t" . '</files>' . "\n";
783
784
			// Check if language has a custom calendar. The folder xx-XX should be present in the media folder
785
			if (JFolder::exists(JPATH_ROOT . '/media/' . $data['language']))
786
			{
787
				$site_txt .= "\n";
788
				$site_txt .= "\t" . '<media destination="' . $data['language'] . '">' . "\n";
789
				$site_txt .= "\t\t" . '<filename>index.html</filename>' . "\n";
790
				$path = JPATH_ROOT . '/media/' . $data['language'] . '/js/calendar-setup.js';
791
792
				if (JFile::exists($path))
793
				{
794
					$file_data = file_get_contents($path);
795
				}
796
797 View Code Duplication
				if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
798
				{
799
					$site_package_files[] = array('name' => 'js/calendar-setup.js','data' => $file_data);
800
					$site_txt .= "\t\t" . '<filename>js/calendar-setup.js</filename>' . "\n";
801
				}
802
803
				$path = JPATH_ROOT . '/media/' . $data['language'] . '/js/calendar-setup-uncompressed.js';
804
805
				if (JFile::exists($path))
806
				{
807
					$file_data = file_get_contents($path);
808
				}
809
810 View Code Duplication
				if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
811
				{
812
					$site_package_files[] = array('name' => 'js/calendar-setup-uncompressed.js','data' => $file_data);
813
					$site_txt .= "\t\t" . '<filename>js/calendar-setup-uncompressed</filename>' . "\n";
814
				}
815
816
				$path = JPATH_ROOT . '/media/' . $data['language'] . '/js/index.html';
817
818
				if (JFile::exists($path))
819
				{
820
					$file_data = file_get_contents($path);
821
				}
822
823 View Code Duplication
				if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
824
				{
825
					$site_package_files[] = array('name' => 'js/index.html','data' => $file_data);
826
					$site_txt .= "\t\t" . '<filename>js/index.html</filename>' . "\n";
827
				}
828
829
				$path = JPATH_ROOT . '/media/' . $data['language'] . '/js/calendar.js';
830
831
				if (JFile::exists($path))
832
				{
833
					$file_data = file_get_contents($path);
834
				}
835
836 View Code Duplication
				if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
837
				{
838
					$site_package_files[] = array('name' => 'js/calendar.js','data' => $file_data);
839
					$site_txt .= "\t\t" . '<filename>js/calendar.js</filename>' . "\n";
840
				}
841
842
				$path = JPATH_ROOT . '/media/' . $data['language'] . '/js/calendar-uncompressed.js';
843
844
				if (JFile::exists($path))
845
				{
846
					$file_data = file_get_contents($path);
847
				}
848
849 View Code Duplication
				if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
850
				{
851
					$site_package_files[] = array('name' => 'js/calendar-uncompressed.js','data' => $file_data);
852
					$site_txt .= "\t\t" . '<filename>js/calendar-uncompressed.js</filename>' . "\n";
853
				}
854
855
				$site_txt .= "\t" . '</media>' . "\n";
856
			}
857
858
			$site_txt .= "\t" . '<params />' . "\n";
859
			$site_txt .= '</extension>' . "\n";
860
			$site_package_files[] = array('name' => 'install.xml','data' => $site_txt);
861
			$language_data = file_get_contents(JPATH_ROOT . '/language/' . $data['language'] . '/' . $data['language'] . '.xml');
862
			$site_package_files[] = array('name' => $data['language'] . '.xml','data' => $language_data);
863
864
			$language_data = file_get_contents(JPATH_ROOT . '/administrator/components/com_localise/models/index.html');
865
			$site_package_files[] = array('name' => 'index.html','data' => $language_data);
866
867
			$site_zip_path = JPATH_ROOT . '/tmp/' . uniqid('com_localise_') . '.zip';
868
869 View Code Duplication
			if (!$packager = JArchive::getAdapter('zip'))
0 ignored issues
show
Duplication introduced by
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...
870
			{
871
				$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ADAPTER'));
872
873
				return false;
874
			}
875
			else
876
			{
877
				if (!$packager->create($site_zip_path, $site_package_files))
878
				{
879
					$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ZIPCREATE'));
880
881
					return false;
882
				}
883
			}
884
885
			$main_package_files[] = array('name' => 'site_' . $data['language'] . '.zip','data' => file_get_contents($site_zip_path));
886
		}
887
888
		if (count($administrator))
889
		{
890
			$text .= "\t\t" . '<file type="language" client="administrator" id="' . $data['language'] . '">admin_' . $data['language'] . '.zip</file>' . "\n";
891
892
			$path = JPATH_ROOT . '/administrator/language/' . $data['language'] . '/' . $data['language'] . '.xml';
893
894
			if (JFile::exists($path))
895
			{
896
				$xmldata = file_get_contents($path);
897
			}
898
899 View Code Duplication
			if (!JFile::exists($path) || empty($xmldata))
0 ignored issues
show
Duplication introduced by
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...
900
			{
901
				$app->enqueueMessage(JText::sprintf('COM_LOCALISE_ERROR_NO_XML', JText::_('JADMINISTRATOR'), $data['language'] . '.xml', 'error'));
902
				$app->redirect(JRoute::_('index.php?option=com_localise&view=package&layout=edit&id=' . $this->getState('package.id'), false));
903
904
				return false;
905
			}
906
907
			// Generate administrator package
908
			$admin_package_files = array();
909
910
			$admin_txt = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
911
			$admin_txt .= '<extension version="' . $small_version . '" client="administrator" type="language" method="upgrade">' . "\n";
912
			$admin_txt .= "\t" . '<name>' . $installName . '</name>' . "\n";
913
			$admin_txt .= "\t" . '<tag>' . $data['language'] . '</tag>' . "\n";
914
			$admin_txt .= "\t" . '<version>' . $data['version'] . '.' . $data['packversion'] . '</version>' . "\n";
915
			$admin_txt .= "\t" . '<creationDate>' . date('d/m/Y') . '</creationDate>' . "\n";
916
			$admin_txt .= "\t" . '<author>' . $data['author'] . '</author>' . "\n";
917
			$admin_txt .= "\t" . '<authorEmail>' . $data['authoremail'] . '</authorEmail>' . "\n";
918
			$admin_txt .= "\t" . '<authorUrl>' . $data['authorurl'] . '</authorUrl>' . "\n";
919
			$admin_txt .= "\t" . '<copyright>' . $data['copyright'] . '</copyright>' . "\n";
920
			$admin_txt .= "\t" . '<license>' . $data['license'] . '</license>' . "\n";
921
			$admin_txt .= "\t" . '<description>' . $data['language'] . ' - Administration language</description>' . "\n";
922
			$admin_txt .= "\t" . '<files>' . "\n";
923
924
			// As this is a core package, the main joomla file xx-XX.ini should be in the package
925
			$path = JPATH_ROOT . '/administrator/language/' . $data['language'] . '/' . $data['language'] . '.ini';
926
927
			if (JFile::exists($path))
928
			{
929
				$file_data = file_get_contents($path);
930
			}
931
932 View Code Duplication
			if (JFile::exists($path) && !empty($file_data))
0 ignored issues
show
Duplication introduced by
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...
933
			{
934
				$administrator = array_diff($administrator, array("joomla"));
935
				$admin_txt .= "\t\t" . '<filename>' . $data['language'] . '.ini</filename>' . "\n";
936
				$admin_package_files[] = array('name' => $data['language'] . '.ini','data' => $file_data);
937
			}
938
			else
939
			{
940
				$msg .= JText::sprintf('COM_LOCALISE_MAINFILE_NOT_TRANSLATED', $data['language'] . '.ini', JText::_('JADMINISTRATOR'));
941
			}
942
943 View Code Duplication
			foreach ($administrator as $translation)
0 ignored issues
show
Duplication introduced by
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...
944
			{
945
				$path = JPATH_ROOT . '/administrator/language/' . $data['language'] . '/' . $data['language'] . '.' . $translation . '.ini';
946
947
				if (JFile::exists($path))
948
				{
949
					$file_data = file_get_contents($path);
950
				}
951
952
				if (JFile::exists($path) && !empty($file_data))
953
				{
954
					$admin_txt .= "\t\t" . '<filename>' . $data['language'] . '.' . $translation . '.ini</filename>' . "\n";
955
					$admin_package_files[] = array('name' => $data['language'] . '.' . $translation . '.ini','data' => $file_data);
956
				}
957
				elseif ($translation != 'joomla')
958
				{
959
					$msg .= JText::sprintf('COM_LOCALISE_FILE_NOT_TRANSLATED', $data['language'] . '.' . $translation . '.ini', JText::_('JADMINISTRATOR'));
960
				}
961
			}
962
963
			$path = JPATH_ROOT . '/administrator/language/' . $data['language'] . '/' . $data['language'] . '.localise.php';
964
965 View Code Duplication
			if (JFile::exists($path))
0 ignored issues
show
Duplication introduced by
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...
966
			{
967
				$language_data = file_get_contents($path);
968
			}
969
970
			// Create a basic xx-XX.localise.php if not present in target language
971
			elseif (!JFile::exists($path) || empty($languagedata))
972
			{
973
				$language_data = file_get_contents(JPATH_ROOT . '/administrator/language/' . $reftag . '/' . $reftag . '.localise.php');
974
				$language_data = str_replace($reftag, $data['language'], $language_data);
975
				$language_data = str_replace($refclassname, $langclassname, $language_data);
976
			}
977
978
			$admin_txt .= "\t\t" . '<filename>' . $data['language'] . '.localise.php</filename>' . "\n";
979
			$admin_package_files[] = array('name' => $data['language'] . '.localise.php','data' => $language_data);
980
981
			// Add the css file if present
982
			$path = JPATH_ROOT . '/administrator/language/' . $data['language'] . '/' . $data['language'] . '.css';
983
984
			if (JFile::exists($path))
985
			{
986
				$css_data = file_get_contents($path);
987
			}
988
989
			if (JFile::exists($path) && !empty($css_data))
990
			{
991
				$admin_txt .= "\t\t" . '<filename>' . $data['language'] . '.css</filename>' . "\n";
992
				$admin_package_files[] = array('name' => $data['language'] . '.css','data' => $css_data);
993
			}
994
995 View Code Duplication
			if ($msg)
0 ignored issues
show
Duplication introduced by
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...
Bug Best Practice introduced by
The expression $msg of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
996
			{
997
				$msg .= '<p>...</p>';
998
				$msg .= JText::_('COM_LOCALISE_UNTRANSLATED');
999
				$app->enqueueMessage($msg, 'error');
1000
				$app->redirect(JRoute::_('index.php?option=com_localise&view=package&layout=edit&id=' . $this->getState('package.id'), false));
1001
1002
				return false;
1003
			}
1004
1005
			$admin_txt .= "\t\t" . '<filename file="meta">install.xml</filename>' . "\n";
1006
			$admin_txt .= "\t\t" . '<filename file="meta">' . $data['language'] . '.xml</filename>' . "\n";
1007
			$admin_txt .= "\t\t" . '<filename>index.html</filename>' . "\n";
1008
			$admin_txt .= "\t" . '</files>' . "\n";
1009
			$admin_txt .= "\t" . '<params />' . "\n";
1010
			$admin_txt .= '</extension>' . "\n";
1011
			$admin_package_files[] = array('name' => 'install.xml','data' => $admin_txt);
1012
			$language_data = file_get_contents(JPATH_ROOT . '/administrator/language/' . $data['language'] . '/' . $data['language'] . '.xml');
1013
			$admin_package_files[] = array('name' => $data['language'] . '.xml','data' => $language_data);
1014
			$language_data = file_get_contents(JPATH_ROOT . '/administrator/components/com_localise/models/index.html');
1015
			$admin_package_files[] = array('name' => 'index.html','data' => $language_data);
1016
1017
			$admin_zip_path = JPATH_ROOT . '/tmp/' . uniqid('com_localise_') . '.zip';
1018
1019 View Code Duplication
			if (!$packager = JArchive::getAdapter('zip'))
0 ignored issues
show
Duplication introduced by
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...
1020
			{
1021
				$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ADAPTER'));
1022
1023
				return false;
1024
			}
1025
			else
1026
			{
1027
				if (!$packager->create($admin_zip_path, $admin_package_files))
1028
				{
1029
					$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ZIPCREATE'));
1030
1031
					return false;
1032
				}
1033
			}
1034
1035
			$main_package_files[] = array('name' => 'admin_' . $data['language'] . '.zip','data' => file_get_contents($admin_zip_path));
1036
		}
1037
1038
		$text .= "\t" . '</files>' . "\n";
1039
1040 View Code Duplication
		if (!empty($data['serverurl']))
0 ignored issues
show
Duplication introduced by
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...
1041
		{
1042
			$text .= "\t" . '<updateservers>' . "\n";
1043
			$text .= "\t\t" . '<server type="collection" priority="1" name="' . $data['servername'] . '">' . $data['serverurl'] . '</server>' . "\n";
1044
			$text .= "\t" . '</updateservers>' . "\n";
1045
		}
1046
1047
		$text .= '</extension>' . "\n";
1048
1049
		$main_package_files[] = array('name' => 'pkg_' . $data['language'] . '.xml', 'data' => $text);
1050
1051
		$ziproot = JPATH_ROOT . '/tmp/' . uniqid('com_localise_main_') . '.zip';
1052
1053
		// Run the packager
1054 View Code Duplication
		if (!$packager = JArchive::getAdapter('zip'))
0 ignored issues
show
Duplication introduced by
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...
1055
		{
1056
			$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ADAPTER'));
1057
1058
			return false;
1059
		}
1060
		else
1061
		{
1062
			if (!$packager->create($ziproot, $main_package_files))
1063
			{
1064
				$this->setError(JText::_('COM_LOCALISE_ERROR_EXPORT_ZIPCREATE'));
1065
1066
				return false;
1067
			}
1068
		}
1069
1070
		ob_clean();
1071
		$zipdata = file_get_contents($ziproot);
1072
		header("Expires: 0");
1073
		header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
1074
		header('Content-Type: application/zip');
1075
		header('Content-Disposition: attachment; filename="'
1076
			. $data['language'] . '_joomla_lang_full_'
1077
			. $data['version'] . 'v' . $data['packversion'] . '.zip"');
1078
		header('Content-Length: ' . strlen($zipdata));
1079
		header("Cache-Control: maxage=1");
1080
		header("Pragma: public");
1081
		header("Content-Transfer-Encoding: binary");
1082
		echo $zipdata;
1083
		exit;
1084
	}
1085
1086
	/**
1087
	 * Upload new file.
1088
	 *
1089
	 * @param   string  $file  The name of the file.
1090
	 *
1091
	 * @return  boolean  True if file uploaded successfully, false otherwise
1092
	 *
1093
	 * @since   3.0
1094
	 */
1095
	public function uploadFile($file)
1096
	{
1097
		jimport('joomla.filesystem.folder');
1098
1099
			$app      = JFactory::getApplication();
1100
			$fileName = JFile::makeSafe($file['name']);
1101
1102
			try
1103
			{
1104
				$xmltree = new SimpleXMLElement(file_get_contents($file['tmp_name']));
0 ignored issues
show
Unused Code introduced by
$xmltree is not used, you could remove the assignment.

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

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

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

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

Loading history...
1105
			}
1106
			catch (Exception $e)
1107
			{
1108
				$app->enqueueMessage(JText::_('COM_LOCALISE_ERROR_PACKAGE_XML'), 'error');
1109
1110
				return false;
1111
			}
1112
1113
			/* @TODO: get this in the js confirmation alert in views/packages/tmpl/defaul.php
1114
			if (file_exists(JPath::clean(JPATH_COMPONENT_ADMINISTRATOR . '/packages/' . $file['name'])))
1115
			{
1116
				$app->enqueueMessage(JText::sprintf('COM_LOCALISE_FILE_EXISTS', $file['name']), 'error');
1117
1118
				return false;
1119
			}
1120
			*/
1121
1122
			if (!JFile::upload($file['tmp_name'], JPath::clean(JPATH_COMPONENT_ADMINISTRATOR . '/packages/' . $fileName)))
1123
			{
1124
				$app->enqueueMessage(JText::sprintf('COM_LOCALISE_FILE_UPLOAD_ERROR', $file['name']), 'error');
1125
1126
				return false;
1127
			}
1128
1129
			return true;
1130
	}
1131
1132
	/**
1133
	 * Upload new css or php file in the language folders.
1134
	 *
1135
	 * @param   string  $file      The name of the file.
1136
	 * @param   string  $location  The location for the file.
1137
	 *
1138
	 * @return  boolean  True if file uploaded successfully, false otherwise
1139
	 *
1140
	 * @since   3.0
1141
	 */
1142
	public function uploadOtherFile($file, $location)
1143
	{
1144
		jimport('joomla.filesystem.folder');
1145
1146
		$app	= JFactory::getApplication();
1147
		$id		= $app->getUserState('com_localise.edit.package.id');
1148
1149
		if (is_array($id))
1150
		{
1151
			$id = $id[0];
1152
		}
1153
1154
		$table = $this->getTable();
1155
		$table->load($id);
1156
1157
		$xml = simplexml_load_file($table->path);
1158
1159
		if ($xml)
1160
		{
1161
			$tag = $xml->language;
0 ignored issues
show
Bug introduced by
The property language does not seem to exist in SimpleXMLElement.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1162
		}
1163
1164
		if ($tag == '')
0 ignored issues
show
Bug introduced by
The variable $tag 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...
1165
		{
1166
			$app->enqueueMessage(JText::_('COM_LOCALISE_FILE_TAG_ERROR'), 'error');
1167
1168
			return false;
1169
		}
1170
1171
		$fileName = JFile::makeSafe($file['name']);
1172
		$ext = JFile::getExt($fileName);
1173
1174
		// Prevent uploading some file types
1175
		if (!($ext == "ini" || $fileName == $tag . '.css' || $fileName == $tag . '.localise.php'))
1176
		{
1177
			$app->enqueueMessage(JText::sprintf('COM_LOCALISE_FILE_TYPE_ERROR', $fileName), 'error');
1178
1179
			return false;
1180
		}
1181
1182
		if ($fileName == $tag . '.css' && $location == LOCALISEPATH_SITE)
1183
		{
1184
			$app->enqueueMessage(JText::sprintf('COM_LOCALISE_FILE_CSS_ERROR', $fileName), 'error');
1185
1186
			return false;
1187
		}
1188
1189
		/* @TODO: get this in the js confirmation alert in views/package/tmpl/edit.php
1190
		 if (file_exists(JPath::clean($location . '/language/' . $tag . '/' . $file['name'])))
1191
		 {
1192
		$app->enqueueMessage(JText::sprintf('COM_LOCALISE_FILE_EXISTS', $file['name']), 'error');
1193
1194
		return false;
1195
		}
1196
		*/
1197
1198
		if (!JFile::upload($file['tmp_name'], JPath::clean($location . '/language/' . $tag . '/' . $fileName)))
1199
		{
1200
			$app->enqueueMessage(JText::sprintf('COM_LOCALISE_FILE_UPLOAD_ERROR', $file['name']), 'error');
1201
1202
			return false;
1203
		}
1204
1205
		return true;
1206
	}
1207
}
1208