Completed
Push — spip-2.1 ( b6b097 )
by cam
42:28 queued 30:44
created

charger_plugin.php ➔ action_charger_plugin_dist()   F

Complexity

Conditions 38
Paths > 20000

Size

Total Lines 279
Code Lines 158

Duplication

Lines 8
Ratio 2.87 %

Importance

Changes 0
Metric Value
cc 38
eloc 158
nc 207841
nop 0
dl 8
loc 279
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2016                                                *
7
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8
 *                                                                         *
9
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11
\***************************************************************************/
12
13
14
/*
15
 * Ce fichier est extrait du plugin charge : action charger decompresser
16
 *
17
 * Auteur : [email protected]
18
 * © 2007 - Distribue sous licence LGPL
19
 *
20
 */
21
22
if (!defined('_ECRIRE_INC_VERSION')) return;
23
24
// http://doc.spip.org/@action_charger_plugin_dist
25
function action_charger_plugin_dist() {
26
	global $spip_lang_left;
27
28
	$securiser_action = charger_fonction('securiser_action', 'inc');
29
	$arg = $securiser_action();
30
31
	include_spip('inc/minipres');
32
	include_spip('inc/charger_plugin');
33
34
	// droits : il faut avoir le droit de choisir les plugins,
35
	// mais aussi d'en ajouter -- a voir
36
	include_spip('inc/autoriser');
37
	if (!autoriser('configurer', 'plugins')) {
38
		echo minipres();
39
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function action_charger_plugin_dist() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
40
	}
41
42
	if ($arg == 'update_flux') {
43
		if (is_array($syndic_plug = @unserialize($GLOBALS['meta']['syndic_plug'])))
44
			foreach ($syndic_plug as $url => $c)
45
				essaie_ajouter_liste_plugins($url);
46
	} 
47
	elseif ($arg == 'supprimer_flux' AND $url = _request('supprimer_flux')) {
48
		$syndic_plug = @unserialize($GLOBALS['meta']['syndic_plug']);
49
		unset($syndic_plug[$url]);
50
		ecrire_meta('syndic_plug', serialize($syndic_plug));
51
	}
52
	elseif (in_array($arg,array('charger_zip','lib','plugins'))) {
53
		// la verification que c'est bien un zip sera faite apres
54
		$zip = _request('url_zip_plugin');
55
	}
56
	elseif (strlen($arg)) {
57
		// la verification que c'est bien un zip sera faite apres
58
		$zip = $arg;
59
	}
60
	else {
61
		// indetermine : c'est un zip ou une liste
62
		$arg = 'charger_liste_ou_zip';
63
		$zip = _request('url_zip_plugin2');
64
	}
65
66
	# si premiere lecture, destination temporaire des fichiers
67
	$tmp = sous_repertoire(_DIR_CACHE, 'chargeur');
68
	# on ne se contenten pas du basename qui peut etre un simple v1
69
	# exemple de l'url http://nodeload.github.com/kbjr/Git.php/zipball/v0.1.1-rc
70
71
	$fichier = (_request('fichier')?
72
		_request('fichier')
73
		:"h".substr(md5($zip),0,8)."-".basename($zip)
0 ignored issues
show
Bug introduced by
The variable $zip 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...
74
		);
75
	# basename par securite notamment dans le cas ou $fichier viens de l'exterieur
76
	$fichier = $tmp.basename($fichier);
77
	$extension = ""; // a verifier
78
79
	# au second tour, le zip designe directement le fichier au lieu de l'url
80
	# initiale
81
	if (!file_exists($fichier)) {
82
		# si on ne dispose pas encore du fichier
83
		# verifier que le zip en est bien un (sans se fier a son extension)
84
		#	en chargeant son entete car l'url initiale peut etre une simple
85
		# redirection et ne pas comporter d'extension .zip
86
		include_spip('inc/distant');
87
		$head = recuperer_page($zip, false, true, 0);
88
89
		if (preg_match(",^Content-Type:\s*application/zip$,Uims",$head))
90
			$extension = "zip";
91
		elseif (preg_match(',^Content-Disposition:\s*attachment;\s*filename="?([^"]+)"?$,Uims',$head,$m)){
92
			$f = $m[1];
93
			if (pathinfo($f, PATHINFO_EXTENSION)=="zip"){
94
				$fichier = (_request('fichier')?
95
					_request('fichier')
96
					:"h".substr(md5($zip),0,8)."-".basename($f)
97
					);
98
				$fichier = $tmp.basename($fichier);
99
				$extension = "zip";
100
			}
101
		}
102
		// au cas ou, si le content-type n'est pas la
103
		// mais que l'extension est explicite
104
		elseif(pathinfo($zip, PATHINFO_EXTENSION)=="zip")
105
			$extension = "zip";
106
107
		# si ce n'est pas un zip dans un format connu,
108
		# c'est sans doute une liste de plugins
109
		# si on est dans le bon scenario
110
		if (!$extension) {
111
			if ($arg == 'charger_liste_ou_zip') {
112
				essaie_ajouter_liste_plugins($zip);
113
			}
114
		}
115
	}
116
	else {
117
		$extension = pathinfo($fichier, PATHINFO_EXTENSION);
118
		if (!$extension)
119
			$extension = pathinfo($zip, PATHINFO_EXTENSION);
120
	}
121
	# format de fichier inconnu
122
	if (!$extension) {
123
		spip_log("Extension inconnue pour le paquet $fichier venant de $zip");
124
		include_spip('inc/headers');
125
		redirige_url_ecrire('charger_plugin');
126
	}
127
128
	# Si definie a '', le chargeur est interdit ; mais on n'aurait de toutes
129
	# facons jamais pu venir ici avec toutes les securisations faites :^)
130
	if (!_DIR_PLUGINS_AUTO) die('jamais');
0 ignored issues
show
Coding Style Compatibility introduced by
The function action_charger_plugin_dist() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
131
132
	# dispose-t-on du fichier ?
133
	$status = null;
134
	# forcer l'extension du fichier par securite
135
	$fichier = $tmp.basename($fichier,".$extension").".$extension";
136 View Code Duplication
	if (!@file_exists($fichier)) {
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...
137
		include_spip('inc/distant');
138
		$contenu = recuperer_page($zip, $fichier, false,_COPIE_LOCALE_MAX_SIZE);
139
		if (!$contenu) {
140
			spip_log('charger_decompresser impossible de charger '.$zip);
141
			$status = -1;
142
		}
143
	}
144
145
	if ($status === null) {
146
		$status = chargeur_charger_zip(
147
			array(
148
				'zip' => $zip,
149
				'arg' => $arg,
150
				'fichier' => $fichier,
151
				'tmp' => $tmp,
152
				'extract' => _request('extract')
153
			)
154
		);
155
		if (_request('extract')) {
156
			spip_unlink($fichier);
157
		}
158
	}
159
160
	// Vers quoi pointe le bouton "suite"
161
	$suite = '';
162
163
	// le fichier .zip est la et bien forme
164
	if (is_array($status)) {
165
166
		// Reconnaitre un plugin par son fichier xml
167
		$get_infos = charger_fonction('get_infos','plugins');
168
		$infos = $get_infos($status['tmpname'], true, '');
169
		if ($infos) {
170
			$nom = $infos['nom'];
171
			$image = $infos['icon'];
172
			$description = $infos['description'];
173
			$type = 'plugin';
174
			$dest = _DIR_PLUGINS_AUTO;
175
		} else {
176
			$type = 'lib';
177
			$dest = _DIR_RACINE.'lib/';
178
		}
179
180
		// Fixer son emplacement final
181
		$status['dirname'] = $dest
182
			. basename($status['tmpname']) . '/';
183
184
		// repertoire parent accessible en ecriture ?
185
		if (!@is_dir($dest)
186
		OR !@is_writeable($dest)) {
187
			$retour = _T("erreur");
188
			$texte = "<p>"._T('plugin_erreur_droit1',array('dest'=>$dest))."</p>"
189
			  . "<p>"._T('plugin_erreur_droit2').aide('install0')."</p>";
190
		}
191
		else
192
193
		// C'est un plugin ?
194
		if ($type == 'plugin') {
195
196
			$retour = typo($nom);
0 ignored issues
show
Bug introduced by
The variable $nom 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...
197
198
			// l'icone ne peut pas etre dans tmp/ (lecture http oblige)
199
			// on la copie donc dans local/chargeur/
200
			if ($image) {
201
				$dir = sous_repertoire(_DIR_VAR,'chargeur');
202
				@copy($status['tmpname'].'/'.$image, $image2 = $dir.basename($image));
0 ignored issues
show
Bug introduced by
The variable $image 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...
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
203
				$retour = "<img src='".$image2."' style='float:right;' />"
204
					. $retour;
205
			} else 
206
				$retour = "<img src='".find_in_path('images/plugin-24.gif')."' style='float:right;' />"
207
					. $retour;
208
209
			if (_request('extract')) {
210
				$afficher = charger_fonction('afficher_plugin','plugins'); // pour plugin_propre
0 ignored issues
show
Unused Code introduced by
$afficher 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...
211
				$texte = plugin_propre($description)
0 ignored issues
show
Bug introduced by
The variable $description 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...
212
				. '<p>'._T('plugin_zip_installe_finie',array('zip'=>$zip)).'</p>'
213
				. "<h2 style='text-align:center;'>"._T('plugin_zip_active')."</h2>";
214
			} else {
215
                $texte = '<p>'._T('plugin_zip_telecharge',array('zip'=>$zip)).'</p>';
216
				$texte .= liste_fichiers_pclzip($status);
217
				$texte .= "<h2 style='text-align:center;'>"._T('plugin_zip_installer')."</h2>";
218
				$suite = 'plugins';
219
			}
220
		}
221
222
		// C'est un paquet quelconque
223
		else {
224
		  $retour = _T('plugin_charge_paquet',array('name' => basename($status['tmpname'])));
225
226
			if (_request('extract')) {
227
			  $texte = '<p>'._T('plugin_zip_installe_rep_finie', array('zip'=>$zip, 'rep'=>$status['dirname'])).'</p>';
228
			} else {
229
                $texte = "<p>"._T('plugin_zip_telecharge',array('zip'=>$zip))."</p>\n";
230
				$texte .= liste_fichiers_pclzip($status);
231
				$suite = 'lib';
232
			}
233
		}
234
	}
235
236
	// fichier absent
237
	else if ($status == -1) {
238
		$retour = _T('erreur');
239
		$texte = _T('plugin_erreur_charger', array('zip'=>$zip));
240
	}
241
242
	// fichier la mais pas bien dezippe
243
	else {
244
		$retour = _T('erreur');
245
		$texte = _T('plugin_erreur_zip',array('status'=>$status));
246
	}
247
248
249
	include_spip('inc/install'); // pour bouton_suivant()
250
251
	$texte = "<div style='text-align:$spip_lang_left;'>$texte</div>\n";
252
253
	$redirect = rawurldecode(_request('redirect'));
254
	// par defaut on revient sur la page admin_plugin
255
	if($redirect == _DIR_RESTREINT OR $redirect == "./"){
256
		$redirect_annul = generer_url_ecrire('admin_plugin');
257
		$redirect_form = 'admin_plugin&voir=recents&'.$type.'='.preg_replace(',^[^/]+/|/$,', '', $status['dirname']);
0 ignored issues
show
Bug introduced by
The variable $type 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...
258
		$redirect_action = '';
259
	}
260
	else{
261
		$redirect_annul = $redirect;
262
		$redirect_form = preg_replace(',^.*exec\=,', '', $redirect);
263
		if (!$suite)
264
			$texte .= form_hidden(parametre_url(generer_url_ecrire($redirect_form), $type,preg_replace(',^[^/]+/|/$,', '', $status['dirname'])));
265
		$redirect_action = $redirect_form;
266
	}
267
	echo minipres($retour." ",
268
		$suite
269
			? redirige_action_post(_request('action'),
270
				$suite,
271
				$redirect_action,
272
				'',
273
					form_hidden('?url_zip_plugin='.urlencode($zip).'&extract=oui&fichier='.urlencode($fichier))
274
					.$texte
275
					."<a class='suivant' href='"
276
						.$redirect_annul
277
					."'>"._T('bouton_annuler')."</a>"
278
				.bouton_suivant())
279
			: generer_form_ecrire($redirect_form, $texte . bouton_suivant())
280
	);
281
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function action_charger_plugin_dist() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
282
283
	// 0 = rien, pas charge
284
	// liste de fichiers = retour gagnant
285
	// < 0 = erreur pclzip 
286
	// ----- Error codes
287
	//   -1 : Unable to open file in binary write mode
288
	//   -2 : Unable to open file in binary read mode
289
	//   -3 : Invalid parameters
290
	//   -4 : File does not exist
291
	//   -5 : Filename is too long (max. 255)
292
	//   -6 : Not a valid zip file
293
	//   -7 : Invalid extracted file size
294
	//   -8 : Unable to create directory
295
	//   -9 : Invalid archive extension
296
	//  -10 : Invalid archive format
297
	//  -11 : Unable to delete file (unlink)
298
	//  -12 : Unable to rename file (rename)
299
	//  -13 : Invalid header checksum
300
	//  -14 : Invalid archive size
301
302
#	redirige_par_entete($url_retour);
303
}
304
305
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
306