Completed
Push — spip-3.0 ( 5d8b58 )
by cam
53:01 queued 42:30
created

assembler.php ➔ assembler()   F

Complexity

Conditions 32
Paths 5234

Size

Total Lines 129
Code Lines 66

Duplication

Lines 7
Ratio 5.43 %

Importance

Changes 0
Metric Value
cc 32
eloc 66
c 0
b 0
f 0
nc 5234
nop 2
dl 7
loc 129
rs 2

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
if (!defined('_ECRIRE_INC_VERSION')) return;
14
15
if (!defined('_CONTEXTE_IGNORE_VARIABLES')) define('_CONTEXTE_IGNORE_VARIABLES', "/(^var_|^PHPSESSID$)/");
16
//
17
// calcule la page et les entetes
18
// determine le contexte donne par l'URL (en tenant compte des reecritures) 
19
// grace a la fonction de passage d'URL a id (reciproque dans urls/*php)
20
//
21
22
// http://doc.spip.org/@assembler
23
function assembler($fond, $connect='') {
24
25
	// flag_preserver est modifie ici, et utilise en globale
26
	// use_cache sert a informer le bouton d'admin pr savoir s'il met un *
27
	// contexte est utilise en globale dans le formulaire d'admin
28
	global $flag_preserver, $use_cache, $contexte;
29
30
	$contexte = calculer_contexte();
31
	$page = array('contexte_implicite'=>calculer_contexte_implicite());
32
	$page['contexte_implicite']['cache'] = $fond . preg_replace(',\.[a-zA-Z0-9]*$,', '', preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI']));
33
	// Cette fonction est utilisee deux fois
34
	$cacher = charger_fonction('cacher', 'public', true);
35
	// Les quatre derniers parametres sont modifies par la fonction:
36
	// emplacement, validite, et, s'il est valide, contenu & age
37
	if ($cacher)
38
		$res = $cacher($GLOBALS['contexte'], $use_cache, $chemin_cache, $page, $lastmodified);
0 ignored issues
show
Bug introduced by
The variable $chemin_cache does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $lastmodified seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
39
	else
40
		$use_cache = -1;
41
	// Si un resultat est retourne, c'est un message d'impossibilite
42
	if ($res) {return array('texte' => $res);}
0 ignored issues
show
Bug introduced by
The variable $res 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...
43
44
	if (!$chemin_cache || !$lastmodified) $lastmodified = time();
0 ignored issues
show
Bug introduced by
The variable $lastmodified seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
45
46
	$headers_only = ($_SERVER['REQUEST_METHOD'] == 'HEAD');
47
	$calculer_page = true;
48
49
	// Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client})
50
	// une perennite valide a meme reponse qu'une requete HEAD (par defaut les
51
	// pages sont dynamiques)
52
	if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
53
	AND (!defined('_VAR_MODE') OR !_VAR_MODE)
54
	AND $chemin_cache
55
	AND isset($page['entetes'])
56
	AND isset($page['entetes']['Cache-Control'])
57
	AND strstr($page['entetes']['Cache-Control'],'max-age=')
58
	AND !strstr($_SERVER['SERVER_SOFTWARE'],'IIS/')
59
	) {
60
		$since = preg_replace('/;.*/', '',
61
			$_SERVER['HTTP_IF_MODIFIED_SINCE']);
62
		$since = str_replace('GMT', '', $since);
63
		if (trim($since) == gmdate("D, d M Y H:i:s", $lastmodified)) {
0 ignored issues
show
Bug introduced by
The variable $lastmodified 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...
64
			$page['status'] = 304;
65
			$headers_only = true;
66
			$calculer_page = false;
67
		}
68
	}
69
70
	// Si requete HEAD ou Last-modified compatible, ignorer le texte
71
	// et pas de content-type (pour contrer le bouton admin de inc-public)
72
	if (!$calculer_page) {
73
		$page['texte'] = "";
74
	} else {
75
		// si la page est prise dans le cache
76
		if (!$use_cache)  {
77
			// Informer les boutons d'admin du contexte
78
			// (fourni par urls_decoder_url ci-dessous lors de la mise en cache)
79
			$contexte = $page['contexte'];
80
81
			// vider les globales url propres qui ne doivent plus etre utilisees en cas
82
			// d'inversion url => objet
83
			// plus necessaire si on utilise bien la fonction urls_decoder_url
84
			#unset($_SERVER['REDIRECT_url_propre']);
85
			#unset($_ENV['url_propre']);
86
		}
87
		else {
88
			// Compat ascendante :
89
			// 1. $contexte est global
90
			// (a evacuer car urls_decoder_url gere ce probleme ?)
91
			// et calculer la page
92
			if (!test_espace_prive()) {
93
				include_spip('inc/urls');
94
				list($fond,$contexte,$url_redirect) = urls_decoder_url(nettoyer_uri(),$fond,$contexte,true);
0 ignored issues
show
Unused Code introduced by
The assignment to $url_redirect is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
95
			}
96
			// squelette par defaut
97
			if (!strlen($fond))
98
				$fond = 'sommaire';
99
100
			// produire la page : peut mettre a jour $lastmodified
101
			$produire_page = charger_fonction('produire_page','public');
102
			$page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, NULL, $page, $lastmodified, $connect);
103
			if ($page === '') {
104
				$erreur = _T('info_erreur_squelette2',
105
					array('fichier'=>spip_htmlspecialchars($fond).'.'._EXTENSION_SQUELETTES));
106
				erreur_squelette($erreur);
107
				// eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4
108
				$page = array('texte' => '', 'erreur' => $erreur);
109
			}
110
		}
111
112
		if ($page AND $chemin_cache) $page['cache'] = $chemin_cache;
113
114
		auto_content_type($page);
115
116
		$flag_preserver |=  headers_sent();
117
118
		// Definir les entetes si ce n'est fait 
119
		if (!$flag_preserver) {
120
			if ($GLOBALS['flag_ob']) {
121
				// Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions
122 View Code Duplication
				if (trim($page['texte']) === ''
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...
123
				AND _VAR_MODE != 'debug'
124
				AND !isset($page['entetes']['Location']) // cette page realise une redirection, donc pas d'erreur
125
				) {
126
					$contexte['fond_erreur'] = $fond;
127
				  $page = message_page_indisponible($page, $contexte);
128
				}
129
				// pas de cache client en mode 'observation'
130
				if (defined('_VAR_MODE') AND _VAR_MODE) {
131
					$page['entetes']["Cache-Control"]= "no-cache,must-revalidate";
132
					$page['entetes']["Pragma"] = "no-cache";
133
				}
134
			}
135
		}
136
	}
137
138
	// Entete Last-Modified:
139
	// eviter d'etre incoherent en envoyant un lastmodified identique
140
	// a celui qu'on a refuse d'honorer plus haut (cf. #655)
141
	if ($lastmodified
142
	AND !isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
143
	AND !isset($page['entetes']["Last-Modified"]))
144
		$page['entetes']["Last-Modified"]=gmdate("D, d M Y H:i:s", $lastmodified)." GMT";
145
146
	// fermer la connexion apres les headers si requete HEAD
147
	if ($headers_only)
148
		$page['entetes']["Connection"] = "close";
149
150
	return $page;
151
}
152
153
//
154
// Contexte : lors du calcul d'une page spip etablit le contexte a partir
155
// des variables $_GET et $_POST, purgees des fausses variables var_*
156
// Note : pour hacker le contexte depuis le fichier d'appel (page.php),
157
// il est recommande de modifier $_GET['toto'] (meme si la page est
158
// appelee avec la methode POST).
159
//
160
// http://doc.spip.org/@calculer_contexte
161
function calculer_contexte() {
162
163
	$contexte = array();
164 View Code Duplication
	foreach($_GET as $var => $val) {
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...
165
		if (!preg_match(_CONTEXTE_IGNORE_VARIABLES,$var))
166
			$contexte[$var] = $val;
167
	}
168 View Code Duplication
	foreach($_POST as $var => $val) {
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...
169
		if (!preg_match(_CONTEXTE_IGNORE_VARIABLES,$var))
170
			$contexte[$var] = $val;
171
	}
172
173
	return $contexte;
174
}
175
176
/**
177
 * Calculer le contexte implicite, qui n'apparait pas dans le ENV d'un cache
178
 * mais est utilise pour distinguer deux caches differents
179
 *
180
 * @staticvar string $notes
181
 * @return array
182
 */
183
function calculer_contexte_implicite(){
184
	static $notes = null;
185
	if (is_null($notes))
186
		$notes = charger_fonction('notes','inc',true);
187
	$contexte_implicite = array(
188
		'squelettes' => $GLOBALS['dossier_squelettes'], // devrait etre 'chemin' => $GLOBALS['path_sig'], ?
189
		'host' => $_SERVER['HTTP_HOST'],
190
		'https' => (isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : ''),
191
		'espace' => test_espace_prive(),
192
		'marqueur' => (isset($GLOBALS['marqueur']) ?  $GLOBALS['marqueur'] : ''),
193
		'marqueur_skel' => (isset($GLOBALS['marqueur_skel']) ?  $GLOBALS['marqueur_skel'] : ''),
194
		'notes' => $notes?$notes('','contexter_cache'):'',
195
		'spip_version_code' => $GLOBALS['spip_version_code'],
196
	);
197
	return $contexte_implicite;
198
}
199
200
//
201
// fonction pour compatibilite arriere, probablement superflue
202
//
203
204
// http://doc.spip.org/@auto_content_type
205
function auto_content_type($page)
206
{
207
	global $flag_preserver;
208
	if (!isset($flag_preserver))
209
	  {
210
	    $flag_preserver = ($page && preg_match("/header\s*\(\s*.content\-type:/isx",$page['texte']) || (isset($page['entetes']['Content-Type'])));
211
	  }
212
}
213
214
// http://doc.spip.org/@inclure_page
215
function inclure_page($fond, $contexte, $connect='') {
216
	static $cacher, $produire_page;
217
	global $lastmodified;
218
219
	// enlever le fond de contexte inclus car sinon il prend la main
220
	// dans les sous inclusions -> boucle infinie d'inclusion identique
221
	// (cette precaution n'est probablement plus utile)
222
	unset($contexte['fond']);
223
	$page = array('contexte_implicite'=>calculer_contexte_implicite());
224
	$page['contexte_implicite']['cache'] = $fond;
225
	if (is_null($cacher))
226
		$cacher = charger_fonction('cacher', 'public', true);
227
	// Les quatre derniers parametres sont modifies par la fonction:
228
	// emplacement, validite, et, s'il est valide, contenu & age
229
	if ($cacher)
230
		$res = $cacher($contexte, $use_cache, $chemin_cache, $page, $lastinclude);
0 ignored issues
show
Bug introduced by
The variable $use_cache seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
Bug introduced by
The variable $chemin_cache does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $lastinclude does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
231
	else
232
		$use_cache = -1;
233
	// $res = message d'erreur : on sort de la
234
	if ($res) {return array('texte' => $res);}
0 ignored issues
show
Bug introduced by
The variable $res 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...
235
236
	// Si use_cache ne vaut pas 0, la page doit etre calculee
237
	// produire la page : peut mettre a jour $lastinclude
238
	// le contexte_cache envoye a cacher() a ete conserve et est passe a produire
239
	if ($use_cache) {
240
		if (is_null($produire_page))
241
			$produire_page = charger_fonction('produire_page','public');
242
		$page = $produire_page($fond, $contexte, $use_cache, $chemin_cache, $contexte, $page, $lastinclude, $connect);
0 ignored issues
show
Bug introduced by
The variable $use_cache 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...
243
	}
244
	// dans tous les cas, mettre a jour $lastmodified
245
	$lastmodified = max($lastmodified, $lastinclude);
246
247
	return $page;
248
}
249
250
/**
251
 * Produire la page et la mettre en cache
252
 * lorsque c'est necessaire
253
 *
254
 * @param string $fond
255
 * @param array $contexte
256
 * @param int $use_cache
257
 * @param string $chemin_cache
258
 * @param array $contexte_cache
259
 * @param array $page
260
 * @param int $lastinclude
261
 * @param string $connect
262
 * @return array
263
 */
264
function public_produire_page_dist($fond, $contexte, $use_cache, $chemin_cache, $contexte_cache, &$page, &$lastinclude, $connect=''){
265
	static $parametrer,$cacher;
266
	if (!$parametrer)
267
		$parametrer = charger_fonction('parametrer', 'public');
268
	$page = $parametrer($fond, $contexte, $chemin_cache, $connect);
269
	// et on l'enregistre sur le disque
270
	if ($chemin_cache
271
	AND $use_cache>-1
272
	AND is_array($page)
273
	AND count($page)
274
	AND $page['entetes']['X-Spip-Cache'] > 0){
275
		if (is_null($cacher))
276
			$cacher = charger_fonction('cacher', 'public', true);
277
		$lastinclude = time();
278
		if ($cacher)
279
			$cacher($contexte_cache, $use_cache, $chemin_cache, $page, $lastinclude);
280
		else
281
			$use_cache = -1;
0 ignored issues
show
Unused Code introduced by
$use_cache 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...
282
	}
283
	return $page;
284
}
285
286
287
// Fonction inseree par le compilateur dans le code compile.
288
// Elle recoit un contexte pour inclure un squelette, 
289
// et les valeurs du contexte de compil prepare par memoriser_contexte_compil
290
// elle-meme appelee par calculer_balise_dynamique dans references.php:
291
// 0: sourcefile
292
// 1: codefile
293
// 2: id_boucle
294
// 3: ligne
295
// 4: langue
296
297
function inserer_balise_dynamique($contexte_exec, $contexte_compil)
298
{
299
	if (!is_array($contexte_exec))
300
		echo $contexte_exec; // message d'erreur etc
301
	else {
302
		inclure_balise_dynamique($contexte_exec, true, $contexte_compil);
303
	}
304
}
305
306
// Attention, un appel explicite a cette fonction suppose certains include
307
// $echo = faut-il faire echo ou return
308
309
// http://doc.spip.org/@inclure_balise_dynamique
310
function inclure_balise_dynamique($texte, $echo=true, $contexte_compil=array())
311
{
312
	if (is_array($texte)) {
313
314
		list($fond, $delainc, $contexte_inclus) = $texte;
315
316
		// delais a l'ancienne, c'est pratiquement mort
317
		$d = isset($GLOBALS['delais']) ? $GLOBALS['delais'] : NULL;
318
		$GLOBALS['delais'] = $delainc;
319
320
		$page = recuperer_fond($fond,$contexte_inclus,array('trim'=>false, 'raw' => true, 'compil' => $contexte_compil));
321
322
		$texte = $page['texte'];
323
324
		$GLOBALS['delais'] = $d;
325
		// Faire remonter les entetes
326
		if (is_array($page['entetes'])) {
327
			// mais pas toutes
328
			unset($page['entetes']['X-Spip-Cache']);
329
			unset($page['entetes']['Content-Type']);
330
			if (isset($GLOBALS['page']) AND is_array($GLOBALS['page'])) {
331
				if (!is_array($GLOBALS['page']['entetes']))
332
					$GLOBALS['page']['entetes'] = array();
333
				$GLOBALS['page']['entetes'] = 
334
					array_merge($GLOBALS['page']['entetes'],$page['entetes']);
335
			}
336
		}
337
		// _pipelines au pluriel array('nom_pipeline' => $args...) avec une syntaxe permettant plusieurs pipelines
338
		if (isset($page['contexte']['_pipelines'])
339
		  AND is_array($page['contexte']['_pipelines'])
340
			AND count($page['contexte']['_pipelines'])) {
341
			foreach($page['contexte']['_pipelines'] as $pipe=>$args){
342
				$args['contexte'] = $page['contexte'];
343
				unset($args['contexte']['_pipelines']); // par precaution, meme si le risque de boucle infinie est a priori nul
344
				$texte = pipeline(
345
					$pipe,
346
					array(
347
						'data'=>$texte,
348
						'args'=>$args
349
					),
350
					false
0 ignored issues
show
Unused Code introduced by
The call to pipeline() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
351
				);
352
			}
353
		}
354
	}
355
356 View Code Duplication
	if (defined('_VAR_MODE') AND _VAR_MODE == 'debug') {
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...
357
		// compatibilite : avant on donnait le numero de ligne ou rien.
358
		$ligne =  intval(isset($contexte_compil[3]) ? $contexte_compil[3] : $contexte_compil);
359
		$GLOBALS['debug_objets']['resultat'][$ligne] = $texte;
360
	}
361
	if ($echo)
362
		echo $texte;
363
	else
364
		return $texte;
365
366
}
367
368
// http://doc.spip.org/@message_page_indisponible
369
function message_page_indisponible ($page, $contexte) {
370
	static $deja = false;
371
	if ($deja) return "erreur";
372
	$codes = array(
373
		'404' => '404 Not Found',
374
		'503' => '503 Service Unavailable',
375
	);
376
377
	$contexte['status'] = ($page !== false) ? '404' : '503';
378
	$contexte['code'] = $codes[$contexte['status']];
379
	$contexte['fond'] = '404'; // gere les 2 erreurs
380
	if (!isset($contexte['lang']))
381
		$contexte['lang'] = $GLOBALS['spip_lang'];
382
383
	$deja = true;
384
	// passer aux plugins qui peuvent decider d'une page d'erreur plus pertinent
385
	// ex restriction d'acces => 401
386
	$contexte = pipeline('page_indisponible',$contexte);
387
388
	// produire la page d'erreur
389
	$page = inclure_page($contexte['fond'], $contexte);
390
	if (!$page)
391
		$page = inclure_page('404', $contexte);
392
	$page['status'] = $contexte['status'];
393
394
	return $page;
395
}
396
397
// temporairement ici : a mettre dans le futur inc/modeles
398
// creer_contexte_de_modele('left', 'autostart=true', ...) renvoie un array()
399
// http://doc.spip.org/@creer_contexte_de_modele
400
function creer_contexte_de_modele($args) {
401
	$contexte = array();
402
	foreach ($args as $var=>$val) {
403
		if (is_int($var)){ // argument pas formate
404
			if (in_array($val, array('left', 'right', 'center'))) {
405
				$var = 'align';
406
				$contexte[$var] = $val;
407
			} else {
408
				$args = explode('=', $val);
409
				if (count($args)>=2) // Flashvars=arg1=machin&arg2=truc genere plus de deux args
410
					$contexte[trim($args[0])] = substr($val,strlen($args[0])+1);
411
				else // notation abregee
412
					$contexte[trim($val)] = trim($val);
413
			}
414
		}
415
		else
416
			$contexte[$var] = $val;
417
	}
418
419
	return $contexte;
420
}
421
422
// Calcule le modele et retourne la mini-page ainsi calculee
423
// http://doc.spip.org/@inclure_modele
424
function inclure_modele($type, $id, $params, $lien, $connect='', $env=array()) {
425
426
	static $compteur;
427
	if (++$compteur>10) return ''; # ne pas boucler indefiniment
428
429
	$type = strtolower($type);
430
431
	$fond = $class = '';
432
433
	$params = array_filter(explode('|', $params));
434
	if ($params) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $params of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
435
		list(,$soustype) = each($params);
436
		$soustype = strtolower(trim($soustype));
437
		if (in_array($soustype,
438
		array('left', 'right', 'center', 'ajax'))) {
439
			list(,$soustype) = each($params);
440
			$soustype = strtolower($soustype);
441
		}
442
443
		if (preg_match(',^[a-z0-9_]+$,', $soustype)) {
444
			if (!trouve_modele($fond = ($type.'_'.$soustype))) {
445
				$fond = '';
446
				$class = $soustype;
447
			}
448
			// enlever le sous type des params
449
			$params = array_diff($params,array($soustype));
450
		}
451
	}
452
453
	// Si ca marche pas en precisant le sous-type, prendre le type
454
	if (!$fond AND !trouve_modele($fond = $type)){
455
		spip_log("Modele $type introuvable",_LOG_INFO_IMPORTANTE);
456
		return false;
457
	}
458
	$fond = 'modeles/'.$fond;
459
	// Creer le contexte
460
	$contexte = $env;
461
	$contexte['dir_racine'] = _DIR_RACINE; # eviter de mixer un cache racine et un cache ecrire (meme si pour l'instant les modeles ne sont pas caches, le resultat etant different il faut que le contexte en tienne compte
462
463
	// Le numero du modele est mis dans l'environnement
464
	// d'une part sous l'identifiant "id"
465
	// et d'autre part sous l'identifiant de la cle primaire
466
	// par la fonction id_table_objet,
467
	// (<article1> =>> article =>> id_article =>> id_article=1)
468
	$_id = id_table_objet($type);
469
	$contexte['id'] = $contexte[$_id] = $id;
470
471
	if (isset($class))
472
		$contexte['class'] = $class;
473
474
	// Si un lien a ete passe en parametre, ex: [<modele1>->url]
475
	if ($lien) {
476
		# un eventuel guillemet (") sera reechappe par #ENV
477
		$contexte['lien'] = str_replace("&quot;",'"', $lien['href']);
478
		$contexte['lien_class'] = $lien['class'];
479
		$contexte['lien_mime'] = $lien['mime'];
480
		$contexte['lien_title'] = $lien['title'];
481
		$contexte['lien_hreflang'] = $lien['hreflang'];
482
	}
483
484
	// Traiter les parametres
485
	// par exemple : <img1|center>, <emb12|autostart=true> ou <doc1|lang=en>
486
	$arg_list = creer_contexte_de_modele($params);
487
	$contexte['args'] = $arg_list; // on passe la liste des arguments du modeles dans une variable args
488
	$contexte = array_merge($contexte,$arg_list);
489
490
491
	// Appliquer le modele avec le contexte
492
	$retour = recuperer_fond($fond, $contexte, array(), $connect);
493
494
495
	// Regarder si le modele tient compte des liens (il *doit* alors indiquer
496
	// spip_lien_ok dans les classes de son conteneur de premier niveau ;
497
	// sinon, s'il y a un lien, on l'ajoute classiquement
498
	if (strstr(' ' . ($classes = extraire_attribut($retour, 'class')).' ',
499
	'spip_lien_ok')) {
500
		$retour = inserer_attribut($retour, 'class',
0 ignored issues
show
Bug introduced by
It seems like $retour can also be of type array; however, inserer_attribut() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
501
			trim(str_replace(' spip_lien_ok ', ' ', " $classes ")));
502
	} else if ($lien)
503
		$retour = "<a href='".$lien['href']."' class='".$lien['class']."'>".$retour."</a>";
504
505
	$compteur--;
506
507
	return  (isset($arg_list['ajax'])AND $arg_list['ajax']=='ajax')
508
	? encoder_contexte_ajax($contexte,'',$retour)
0 ignored issues
show
Bug introduced by
It seems like $retour defined by recuperer_fond($fond, $c...xte, array(), $connect) on line 492 can also be of type array; however, encoder_contexte_ajax() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
509
	: $retour; 
510
}
511
512
// Un inclure_page qui marche aussi pour l'espace prive
513
// fonction interne a spip, ne pas appeler directement
514
// pour recuperer $page complet, utiliser:
515
// 	recuperer_fond($fond,$contexte,array('raw'=>true))
516
// http://doc.spip.org/@evaluer_fond
517
function evaluer_fond ($fond, $contexte=array(), $connect=null) {
518
519
	$page = inclure_page($fond, $contexte, $connect);
520
521
	if (!$page) return $page;
522
	// eval $page et affecte $res
523
	include _ROOT_RESTREINT."public/evaluer_page.php";
524
	
525
	// Lever un drapeau (global) si le fond utilise #SESSION
526
	// a destination de public/parametrer
527
	// pour remonter vers les inclusions appelantes
528
	// il faut bien lever ce drapeau apres avoir evalue le fond
529
	// pour ne pas faire descendre le flag vers les inclusions appelees
530 View Code Duplication
	if (isset($page['invalideurs'])
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...
531
	AND isset($page['invalideurs']['session']))
532
		$GLOBALS['cache_utilise_session'] = $page['invalideurs']['session'];
533
534
	return $page;
535
}
536
537
538
// http://doc.spip.org/@page_base_href
539
function page_base_href(&$texte){
540
	static $set_html_base = null;
541
	if (is_null($set_html_base)){
542
		if (!defined('_SET_HTML_BASE'))
543
			// si la profondeur est superieure a 1
544
			// est que ce n'est pas une url page ni une url action
545
			// activer par defaut
546
			$set_html_base = ((
547
				$GLOBALS['profondeur_url'] >= (_DIR_RESTREINT?1:2)
548
				AND _request(_SPIP_PAGE) !== 'login'
549
				AND !_request('action'))?true:false);
550
		else
551
			$set_html_base = _SET_HTML_BASE;
552
	}
553
554
	if ($set_html_base
555
	  AND isset($GLOBALS['html']) AND $GLOBALS['html']
556
	  AND $GLOBALS['profondeur_url']>0
557
	  AND ($poshead = strpos($texte,'</head>'))!==FALSE){
558
		$head = substr($texte,0,$poshead);
559
		$insert = false;
0 ignored issues
show
Unused Code introduced by
$insert 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...
560
		if (strpos($head, '<base')===false) 
561
			$insert = true;
562
		else {
563
			// si aucun <base ...> n'a de href c'est bon quand meme !
564
			$insert = true;
565
			include_spip('inc/filtres');
566
			$bases = extraire_balises($head,'base');
567
			foreach ($bases as $base)
568
				if (extraire_attribut($base,'href'))
569
					$insert = false;
570
		}
571
		if ($insert) {
572
			include_spip('inc/filtres_mini');
573
			// ajouter un base qui reglera tous les liens relatifs
574
			$base = url_absolue('./');
575
			$bbase = "\n<base href=\"$base\" />";
576
			if (($pos = strpos($head, '<head>')) !== false)
577
				$head = substr_replace($head, $bbase, $pos+6, 0);
578
			elseif(preg_match(",<head[^>]*>,i",$head,$r)){
579
				$head = str_replace($r[0], $r[0].$bbase, $head);
580
			}
581
			$texte = $head . substr($texte,$poshead);
582
			// gerer les ancres
583
			$base = $_SERVER['REQUEST_URI'];
584 View Code Duplication
			if (strpos($texte,"href='#")!==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...
585
				$texte = str_replace("href='#","href='$base#",$texte);
586 View Code Duplication
			if (strpos($texte, "href=\"#")!==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...
587
				$texte = str_replace("href=\"#","href=\"$base#",$texte);
588
		}
589
	}
590
}
591
592
593
// Envoyer les entetes, en retenant ceux qui sont a usage interne
594
// et demarrent par X-Spip-...
595
// http://doc.spip.org/@envoyer_entetes
596
function envoyer_entetes($entetes) {
597
	foreach ($entetes as $k => $v)
598
	#	if (strncmp($k, 'X-Spip-', 7))
599
			@header(strlen($v)?"$k: $v":$k); 
0 ignored issues
show
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...
600
}
601
602
?>
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...
603