Completed
Push — master ( b32f18...cfbd44 )
by cam
04:53
created

fonctions.php ➔ appliquer_filtre_sinon()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 4
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
/***************************************************************************\
4
 *  SPIP, Système de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright © avec tendresse depuis 2001                                 *
7
 *  Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James  *
8
 *                                                                         *
9
 *  Ce programme est un logiciel libre distribué sous licence GNU/GPL.     *
10
 *  Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne.   *
11
\***************************************************************************/
12
13
/**
14
 * Des fonctions diverses utilisees lors du calcul d'une page ; ces fonctions
15
 * bien pratiques n'ont guere de logique organisationnelle ; elles sont
16
 * appelees par certaines balises ou criteres au moment du calcul des pages. (Peut-on
17
 * trouver un modele de donnees qui les associe physiquement au fichier
18
 * definissant leur balise ???)
19
 *
20
 * Ce ne sont pas des filtres à part entière, il n'est donc pas logique de les retrouver dans inc/filtres
21
 *
22
 * @package SPIP\Core\Compilateur\Composer
23
 **/
24
25
if (!defined('_ECRIRE_INC_VERSION')) {
26
	return;
27
}
28
29
30
/**
31
 * Calcul d'une introduction
32
 *
33
 * L'introduction est prise dans le descriptif s'il est renseigné,
34
 * sinon elle est calculée depuis le texte : à ce moment là,
35
 * l'introduction est prise dans le contenu entre les balises
36
 * `<intro>` et `</intro>` si présentes, sinon en coupant le
37
 * texte à la taille indiquée.
38
 *
39
 * Cette fonction est utilisée par la balise #INTRODUCTION
40
 *
41
 * @param string $descriptif
42
 *     Descriptif de l'introduction
43
 * @param string $texte
44
 *     Texte à utiliser en absence de descriptif
45
 * @param string $longueur
46
 *     Longueur de l'introduction
47
 * @param string $connect
48
 *     Nom du connecteur à la base de données
49
 * @param string $suite
0 ignored issues
show
Documentation introduced by
Should the type for parameter $suite not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
50
 *     points de suite si on coupe (par defaut _INTRODUCTION_SUITE et sinon &nbsp;(...)
51
 * @return string
52
 *     Introduction calculée
53
 **/
54
function filtre_introduction_dist($descriptif, $texte, $longueur, $connect, $suite = null) {
55
	// Si un descriptif est envoye, on l'utilise directement
56
	if (strlen($descriptif)) {
57
		return appliquer_traitement_champ($descriptif, 'introduction', '', array(), $connect);
58
	}
59
60
	// De preference ce qui est marque <intro>...</intro>
61
	$intro = '';
62
	$texte = preg_replace(",(</?)intro>,i", "\\1intro>", $texte); // minuscules
63
	while ($fin = strpos($texte, "</intro>")) {
64
		$zone = substr($texte, 0, $fin);
65
		$texte = substr($texte, $fin + strlen("</intro>"));
66
		if ($deb = strpos($zone, "<intro>") or substr($zone, 0, 7) == "<intro>") {
67
			$zone = substr($zone, $deb + 7);
68
		}
69
		$intro .= $zone;
70
	}
71
72
	// [12025] On ne *PEUT* pas couper simplement ici car c'est du texte brut,
73
	// qui inclus raccourcis et modeles
74
	// un simple <articlexx> peut etre ensuite transforme en 1000 lignes ...
75
	// par ailleurs le nettoyage des raccourcis ne tient pas compte
76
	// des surcharges et enrichissement de propre
77
	// couper doit se faire apres propre
78
	//$texte = nettoyer_raccourcis_typo($intro ? $intro : $texte, $connect);
79
80
	// Cependant pour des questions de perfs on coupe quand meme, en prenant
81
	// large et en se mefiant des tableaux #1323
82
83
	if (strlen($intro)) {
84
		$texte = $intro;
85
	} else {
86
		if (strpos("\n" . $texte, "\n|") === false
87
			and strlen($texte) > 2.5 * $longueur
88
		) {
89
			if (strpos($texte, "<multi") !== false) {
90
				$texte = extraire_multi($texte);
91
			}
92
			$texte = couper($texte, 2 * $longueur);
93
		}
94
	}
95
96
	// ne pas tenir compte des notes
97
	if ($notes = charger_fonction('notes', 'inc', true)) {
98
		$notes('', 'empiler');
99
	}
100
	// Supprimer les modèles avant le propre afin d'éviter qu'ils n'ajoutent du texte indésirable
101
	// dans l'introduction.
102
	$texte = supprime_img($texte, '');
103
	$texte = appliquer_traitement_champ($texte, 'introduction', '', array(), $connect);
104
105
	if ($notes) {
106
		$notes('', 'depiler');
107
	}
108
109
	if (is_null($suite) and defined('_INTRODUCTION_SUITE')) {
110
		$suite = _INTRODUCTION_SUITE;
111
	}
112
	$texte = couper($texte, $longueur, $suite);
113
	// comme on a coupe il faut repasser la typo (on a perdu les insecables)
114
	$texte = typo($texte, true, $connect, array());
115
116
	// et reparagrapher si necessaire (coherence avec le cas descriptif)
117
	// une introduction a tojours un <p>
118
	if ($GLOBALS['toujours_paragrapher']) // Fermer les paragraphes
119
	{
120
		$texte = paragrapher($texte, $GLOBALS['toujours_paragrapher']);
121
	}
122
123
	return $texte;
124
}
125
126
127
/**
128
 * Filtre calculant une pagination, utilisé par la balise `#PAGINATION`
129
 *
130
 * Le filtre cherche le modèle `pagination.html` par défaut, mais peut
131
 * chercher un modèle de pagination particulier avec l'argument `$modele`.
132
 * S'il `$modele='prive'`, le filtre cherchera le modèle `pagination_prive.html`.
133
 *
134
 * @filtre
135
 * @see balise_PAGINATION_dist()
136
 *
137
 * @param int $total
138
 *     Nombre total d'éléments
139
 * @param string $nom
140
 *     Nom identifiant la pagination
141
 * @param int $position
142
 *     Page à afficher (tel que la 3è page)
143
 * @param int $pas
144
 *     Nombre d'éléments par page
145
 * @param bool $liste
146
 *     - True pour afficher toute la liste des éléments,
147
 *     - False pour n'afficher que l'ancre
148
 * @param string $modele
149
 *     Nom spécifique du modèle de pagination
150
 * @param string $connect
151
 *     Nom du connecteur à la base de données
152
 * @param array $env
153
 *     Environnement à transmettre au modèle
154
 * @return string
155
 *     Code HTML de la pagination
156
 **/
157
function filtre_pagination_dist(
158
	$total,
159
	$nom,
160
	$position,
161
	$pas,
162
	$liste = true,
163
	$modele = '',
164
	$connect = '',
165
	$env = array()
166
) {
167
	static $ancres = array();
168
	if ($pas < 1) {
169
		return '';
170
	}
171
	$ancre = 'pagination' . $nom; // #pagination_articles
172
	$debut = 'debut' . $nom; // 'debut_articles'
173
174
	// n'afficher l'ancre qu'une fois
175
	if (!isset($ancres[$ancre])) {
176
		$bloc_ancre = $ancres[$ancre] = "<a id='" . $ancre . "' class='pagination_ancre'></a>";
177
	} else {
178
		$bloc_ancre = '';
179
	}
180
	// liste = false : on ne veut que l'ancre
181
	if (!$liste) {
182
		return $ancres[$ancre];
183
	}
184
185
	$self = (empty($env['self']) ? self() : $env['self']);
186
	$pagination = array(
187
		'debut' => $debut,
188
		'url' => parametre_url($self, 'fragment', ''), // nettoyer l'id ahah eventuel
189
		'total' => $total,
190
		'position' => intval($position),
191
		'pas' => $pas,
192
		'nombre_pages' => floor(($total - 1) / $pas) + 1,
193
		'page_courante' => floor(intval($position) / $pas) + 1,
194
		'ancre' => $ancre,
195
		'bloc_ancre' => $bloc_ancre
196
	);
197
	if (is_array($env)) {
198
		$pagination = array_merge($env, $pagination);
199
	}
200
201
	// Pas de pagination
202
	if ($pagination['nombre_pages'] <= 1) {
203
		return '';
204
	}
205
206
	if ($modele) {
207
		$modele = '_' . $modele;
208
	}
209
210
	return recuperer_fond("modeles/pagination$modele", $pagination, array('trim' => true), $connect);
211
}
212
213
214
/**
215
 * Retourne pour une clé primaire d'objet donnée les identifiants ayant un logo
216
 *
217
 * @param string $type
218
 *     Nom de la clé primaire de l'objet
219
 * @return string
220
 *     Liste des identifiants ayant un logo (séparés par une virgule)
221
 **/
222
function lister_objets_avec_logos($type) {
223
224
	$objet = objet_type($type);
225
	$ids = sql_allfetsel("L.id_objet", "spip_documents AS D JOIN spip_documents_liens AS L ON L.id_document=D.id_document", "D.mode=".sql_quote('logoon')." AND L.objet=".sql_quote($objet));
226
	if ($ids) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ids 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...
227
		$ids = array_column($ids, 'id_objet');
228
		return implode(',', $ids);
229
	}
230
	else {
231
		return "0";
232
	}
233
}
234
235
236
/**
237
 * Renvoie l'état courant des notes, le purge et en prépare un nouveau
238
 *
239
 * Fonction appelée par la balise `#NOTES`
240
 *
241
 * @see  balise_NOTES_dist()
242
 * @uses inc_notes_dist()
243
 *
244
 * @return string
245
 *     Code HTML des notes
246
 **/
247
function calculer_notes() {
248
	$r = '';
249
	if ($notes = charger_fonction('notes', 'inc', true)) {
250
		$r = $notes(array());
251
		$notes('', 'depiler');
252
		$notes('', 'empiler');
253
	}
254
255
	return $r;
256
}
257
258
259
/**
260
 * Retrouver le rang du lien entre un objet source et un obet lie
261
 * utilisable en direct dans un formulaire d'edition des liens, mais #RANG doit faire le travail automatiquement
262
 * [(#ENV{objet_source}|rang_lien{#ID_AUTEUR,#ENV{objet},#ENV{id_objet},#ENV{_objet_lien}})]
263
 *
264
 * @param $objet_source
265
 * @param $ids
266
 * @param $objet_lie
267
 * @param $idl
268
 * @param $objet_lien
269
 * @return string
270
 */
271
function retrouver_rang_lien($objet_source, $ids, $objet_lie, $idl, $objet_lien){
272
	$res = lister_objets_liens($objet_source, $objet_lie, $idl, $objet_lien);
273
	$res = array_column($res, 'rang_lien', $objet_source);
274
275
	return (isset($res[$ids]) ? $res[$ids] : '');
276
}
277
278
279
/**
280
 * Lister les liens en le memoizant dans une static
281
 * pour utilisation commune par lister_objets_lies et retrouver_rang_lien dans un formuluaire d'edition de liens
282
 * (evite de multiplier les requetes)
283
 *
284
 * @param $objet_source
285
 * @param $objet
286
 * @param $id_objet
287
 * @param $objet_lien
288
 * @return mixed
289
 * @private
290
 */
291
function lister_objets_liens($objet_source, $objet, $id_objet, $objet_lien) {
292
	static $liens = array();
293
	if (!isset($liens["$objet_source-$objet-$id_objet-$objet_lien"])) {
294
		include_spip('action/editer_liens');
295
		// quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
296 View Code Duplication
		if ($objet_lien == $objet and $objet_lien !== $objet_source) {
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...
297
			$res = objet_trouver_liens(array($objet => $id_objet), array($objet_source => '*'));
298
		} else {
299
			$res = objet_trouver_liens(array($objet_source => '*'), array($objet => $id_objet));
300
		}
301
302
		$liens["$objet_source-$objet-$id_objet-$objet_lien"] = $res;
303
	}
304
	return $liens["$objet_source-$objet-$id_objet-$objet_lien"];
305
}
306
307
/**
308
 * Calculer la balise #RANG
309
 * quand ce n'est pas un champ rang :
310
 * peut etre le num titre, le champ rang_lien ou le rang du lien en edition des liens, a retrouver avec les infos du formulaire
311
 * @param $titre
312
 * @param $objet_source
313
 * @param $id
314
 * @param $env
315
 * @return int|string
316
 */
317
function calculer_rang_smart($titre, $objet_source, $id, $env) {
318
	// Cas du #RANG utilisé dans #FORMULAIRE_EDITER_LIENS -> attraper le rang du lien
319
	// permet de voir le rang du lien si il y en a un en base, meme avant un squelette xxxx-lies.html ne gerant pas les liens
320
	if (isset($env['form']) and $env['form']
321
		and isset($env['_objet_lien']) and $env['_objet_lien']
322
		and (function_exists('lien_triables') or include_spip('action/editer_liens'))
323
		and $r = objet_associable($env['_objet_lien'])
324
		and list($p, $table_lien) = $r
325
	  and lien_triables($table_lien)
326
	  and isset($env['objet']) and $env['objet']
327
		and isset($env['id_objet']) and $env['id_objet']
328
		and $objet_source
329
		and $id = intval($id)
330
	) {
331
		$rang = retrouver_rang_lien($objet_source, $id, $env['objet'], $env['id_objet'], $env['_objet_lien']);
332
		return ($rang ? $rang : '');
333
	}
334
	return recuperer_numero($titre);
335
}
336
337
338
/**
339
 * Proteger les champs passes dans l'url et utiliser dans {tri ...}
340
 * preserver l'espace pour interpreter ensuite num xxx et multi xxx
341
 *
342
 * @param string $t
343
 * @return string
344
 */
345
function tri_protege_champ($t) {
346
	return preg_replace(',[^\s\w.+],', '', $t);
347
}
348
349
/**
350
 * Interpreter les multi xxx et num xxx utilise comme tri
351
 * pour la clause order
352
 * 'multi xxx' devient simplement 'multi' qui est calcule dans le select
353
 *
354
 * @param string $t
355
 * @param array $from
0 ignored issues
show
Documentation introduced by
Should the type for parameter $from not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
356
 * @return string
357
 */
358
function tri_champ_order($t, $from = null) {
359
	if (strncmp($t, 'multi ', 6) == 0) {
360
		return "multi";
361
	}
362
363
	$champ = $t;
364
365
	if (strncmp($t, 'num ', 4) == 0) {
366
		$champ = substr($t, 4);
367
	}
368
	// enlever les autres espaces non evacues par tri_protege_champ
369
	$champ = preg_replace(',\s,', '', $champ);
370
371
	if (is_array($from)) {
372
		$trouver_table = charger_fonction('trouver_table', 'base');
373
		foreach ($from as $idt => $table_sql) {
374
			if ($desc = $trouver_table($table_sql)
375
				and isset($desc['field'][$champ])
376
			) {
377
				$champ = "$idt.$champ";
378
				break;
379
			}
380
		}
381
	}
382
	if (strncmp($t, 'num ', 4) == 0) {
383
		return "0+$champ";
384
	} else {
385
		return $champ;
386
	}
387
}
388
389
/**
390
 * Interpreter les multi xxx et num xxx utilise comme tri
391
 * pour la clause select
392
 * 'multi xxx' devient select "...." as multi
393
 * les autres cas ne produisent qu'une chaine vide '' en select
394
 * 'hasard' devient 'rand() AS hasard' dans le select
395
 *
396
 * @param string $t
397
 * @return string
398
 */
399
function tri_champ_select($t) {
400
	if (strncmp($t, 'multi ', 6) == 0) {
401
		$t = substr($t, 6);
402
		$t = preg_replace(',\s,', '', $t);
403
		$t = sql_multi($t, $GLOBALS['spip_lang']);
404
405
		return $t;
406
	}
407
	if (trim($t) == 'hasard') {
408
		return 'rand() AS hasard';
409
	}
410
411
	return "''";
412
}
413
414
/**
415
 * Fonction de mise en forme utilisee par le critere {par_ordre_liste..}
416
 * @see critere_par_ordre_liste_dist()
417
 *
418
 * @param array $valeurs
419
 * @param string $serveur
420
 * @return string
421
 */
422
function formate_liste_critere_par_ordre_liste($valeurs, $serveur = ''){
423
	if (!is_array($valeurs)){
424
		return '';
425
	}
426
	$f = sql_serveur('quote', $serveur, true);
427
	if (!is_string($f) or !$f){
428
		return '';
429
	}
430
	$valeurs = implode(',', array_map($f, array_unique($valeurs)));
431
432
	return $valeurs;
433
}
434
435
/**
436
 * Applique un filtre s'il existe, sinon retourne la valeur par défaut indiquée
437
 *
438
 * @internal
439
 * @uses trouver_filtre_matrice()
440
 * @uses chercher_filtre()
441
 *
442
 * @param mixed $arg
443
 *     Texte (le plus souvent) sur lequel appliquer le filtre
444
 * @param string $filtre
445
 *     Nom du filtre à appliquer
446
 * @param array $args
447
 *     Arguments reçus par la fonction parente (appliquer_filtre ou appliquer_si_filtre).
448
 * @param mixed $defaut
449
 *     Valeur par défaut à retourner en cas d'absence du filtre.
450
 * @return string
451
 *     Texte traité par le filtre si le filtre existe,
452
 *     Valeur $defaut sinon.
453
 **/
454
function appliquer_filtre_sinon($arg, $filtre, $args, $defaut = '') {
455
	// Si c'est un filtre d'image, on utilise image_filtrer()
456
	// Attention : les 2 premiers arguments sont inversés dans ce cas
457
	if (trouver_filtre_matrice($filtre) and substr($filtre, 0, 6) == 'image_') {
458
		$args[1] = $args[0];
459
		$args[0] = $filtre;
460
		return image_graver(image_filtrer($args));
461
	}
462
463
	$f = chercher_filtre($filtre);
464
	if (!$f) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $f of type null|string is loosely compared to false; 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...
465
		return $defaut;
466
	}
467
	array_shift($args); // enlever $arg
468
	array_shift($args); // enlever $filtre
469
	array_unshift($args, $arg); // remettre $arg
470
	return call_user_func_array($f, $args);
471
}
472