Completed
Push — master ( dd48fb...2d67f7 )
by cam
05:52
created

filtres_ecrire.php ➔ calculer_rang_smart()   C

Complexity

Conditions 17
Paths 3

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
nc 3
nop 4
dl 0
loc 19
rs 5.2166
c 0
b 0
f 0

How to fix   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-2019                                                *
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
 * Fonctions utilisées au calcul des squelette du privé.
15
 *
16
 * @package SPIP\Core\Filtres
17
 */
18
if (!defined('_ECRIRE_INC_VERSION')) {
19
	return;
20
}
21
22
include_spip('inc/filtres_boites');
23
include_spip('inc/boutons');
24
include_spip('inc/pipelines_ecrire');
25
26
27
/**
28
 * Retourne les paramètres de personnalisation css de l'espace privé
29
 *
30
 * Ces paramètres sont (ltr et couleurs) ce qui permet une écriture comme :
31
 * generer_url_public('style_prive', parametres_css_prive())
32
 * qu'il est alors possible de récuperer dans le squelette style_prive.html avec
33
 *
34
 * #SET{claire,##ENV{couleur_claire,edf3fe}}
35
 * #SET{foncee,##ENV{couleur_foncee,3874b0}}
36
 * #SET{left,#ENV{ltr}|choixsiegal{left,left,right}}
37
 * #SET{right,#ENV{ltr}|choixsiegal{left,right,left}}
38
 *
39
 * @return string
40
 */
41
function parametres_css_prive() {
42
43
	$args = array();
44
	$args['v'] = $GLOBALS['spip_version_code'];
45
	$args['p'] = substr(md5($GLOBALS['meta']['plugin']), 0, 4);
46
	$args['themes'] = implode(',', lister_themes_prives());
47
	$args['ltr'] = $GLOBALS['spip_lang_left'];
48
	// un md5 des menus : si un menu change il faut maj la css
49
	$args['md5b'] = (function_exists('md5_boutons_plugins') ? md5_boutons_plugins() : '');
50
51
	$c = isset($GLOBALS['visiteur_session']['prefs']['couleur'])
52
		? $GLOBALS['visiteur_session']['prefs']['couleur']
53
		: 9;
54
55
	$couleurs = charger_fonction('couleurs', 'inc');
56
	parse_str($couleurs($c), $c);
57
	$args = array_merge($args, $c);
58
59
	if (_request('var_mode') == 'recalcul' or (defined('_VAR_MODE') and _VAR_MODE == 'recalcul')) {
60
		$args['var_mode'] = 'recalcul';
61
	}
62
63
	return http_build_query($args);
64
}
65
66
67
/**
68
 * Afficher le sélecteur de rubrique
69
 *
70
 * Il permet de placer un objet dans la hiérarchie des rubriques de SPIP
71
 *
72
 * @uses inc_chercher_rubrique_dist()
73
 *
74
 * @param string $titre
75
 * @param int $id_objet
76
 * @param int $id_parent
77
 * @param string $objet
78
 * @param int $id_secteur
79
 * @param bool $restreint
80
 * @param bool $actionable
81
 *   true : fournit le selecteur dans un form directement postable
82
 * @param bool $retour_sans_cadre
83
 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
84
 */
85
function chercher_rubrique(
86
	$titre,
87
	$id_objet,
88
	$id_parent,
89
	$objet,
90
	$id_secteur,
91
	$restreint,
92
	$actionable = false,
93
	$retour_sans_cadre = false
94
) {
95
96
	include_spip('inc/autoriser');
97
	if (intval($id_objet) && !autoriser('modifier', $objet, $id_objet)) {
98
		return "";
99
	}
100
	if (!sql_countsel('spip_rubriques')) {
101
		return "";
102
	}
103
	$chercher_rubrique = charger_fonction('chercher_rubrique', 'inc');
104
	$form = $chercher_rubrique($id_parent, $objet, $restreint, ($objet == 'rubrique') ? $id_objet : 0);
105
106
	if ($id_parent == 0) {
107
		$logo = "racine-24.png";
108
	} elseif ($id_secteur == $id_parent) {
109
		$logo = "secteur-24.png";
110
	} else {
111
		$logo = "rubrique-24.png";
112
	}
113
114
	$confirm = "";
115
	if ($objet == 'rubrique') {
116
		// si c'est une rubrique-secteur contenant des breves, demander la
117
		// confirmation du deplacement
118
		$contient_breves = sql_countsel('spip_breves', "id_rubrique=" . intval($id_objet));
119
120
		if ($contient_breves > 0) {
121
			$scb = ($contient_breves > 1 ? 's' : '');
122
			$scb = _T('avis_deplacement_rubrique',
123
				array(
124
					'contient_breves' => $contient_breves,
125
					'scb' => $scb
126
				));
127
			$confirm .= "\n<div class='confirmer_deplacement verdana2'>"
128
				. "<div class='choix'><input type='checkbox' name='confirme_deplace' value='oui' id='confirme-deplace' /><label for='confirme-deplace'>"
129
				. $scb .
130
				"</label></div></div>\n";
131
		} else {
132
			$confirm .= "<input type='hidden' name='confirme_deplace' value='oui' />\n";
133
		}
134
	}
135
	$form .= $confirm;
136
	if ($actionable) {
137
		if (strpos($form, '<select') !== false) {
138
			$form .= "<div style='text-align: " . $GLOBALS['spip_lang_right'] . ";'>"
139
				. '<input class="fondo" type="submit" value="' . _T('bouton_choisir') . '"/>'
140
				. "</div>";
141
		}
142
		$form = "<input type='hidden' name='editer_$objet' value='oui' />\n" . $form;
143
		if ($action = charger_fonction("editer_$objet", "action", true)) {
0 ignored issues
show
Unused Code introduced by
$action 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...
144
			$form = generer_action_auteur("editer_$objet", $id_objet, self(), $form,
145
				" method='post' class='submit_plongeur'");
146
		} else {
147
			$form = generer_action_auteur("editer_objet", "$objet/$id_objet", self(), $form,
148
				" method='post' class='submit_plongeur'");
149
		}
150
	}
151
152
	if ($retour_sans_cadre) {
153
		return $form;
154
	}
155
156
	include_spip('inc/presentation');
157
158
	return debut_cadre_couleur($logo, true, "", $titre) . $form . fin_cadre_couleur(true);
0 ignored issues
show
Unused Code introduced by
The call to fin_cadre_couleur() has too many arguments starting with true.

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...
159
160
}
161
162
163
/**
164
 * Tester si le site peut avoir des visiteurs
165
 *
166
 * @param bool $past
167
 *   si true, prendre en compte le fait que le site a *deja* des visiteurs
168
 *   comme le droit d'en avoir de nouveaux
169
 * @param bool $accepter
170
 * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
171
 */
172
function avoir_visiteurs($past = false, $accepter = true) {
173
	if ($GLOBALS['meta']["forums_publics"] == 'abo') {
174
		return true;
175
	}
176
	if ($accepter and $GLOBALS['meta']["accepter_visiteurs"] <> 'non') {
177
		return true;
178
	}
179
	if (sql_countsel('spip_articles', "accepter_forum='abo'")) {
180
		return true;
181
	}
182
	if (!$past) {
183
		return false;
184
	}
185
186
	return sql_countsel('spip_auteurs',
187
		"statut NOT IN ('0minirezo','1comite', '5poubelle')
188
	                    AND (statut<>'nouveau' OR prefs NOT IN ('0minirezo','1comite', '5poubelle'))");
189
}
190
191
/**
192
 * Lister les status d'article visibles dans l'espace prive
193
 * en fonction du statut de l'auteur
194
 *
195
 * Pour l'extensibilie de SPIP, on se repose sur autoriser('voir','article')
196
 * en testant un à un les status présents en base
197
 *
198
 * On mémorise en static pour éviter de refaire plusieurs fois.
199
 *
200
 * @param string $statut_auteur
201
 * @return array
202
 */
203
function statuts_articles_visibles($statut_auteur) {
204
	static $auth = array();
205
	if (!isset($auth[$statut_auteur])) {
206
		$auth[$statut_auteur] = array();
207
		$statuts = array_column(sql_allfetsel('distinct statut', 'spip_articles'), 'statut');
208
		foreach ($statuts as $s) {
0 ignored issues
show
Bug introduced by
The expression $statuts of type null|false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
209
			if (autoriser('voir', 'article', 0, array('statut' => $statut_auteur), array('statut' => $s))) {
210
				$auth[$statut_auteur][] = $s;
211
			}
212
		}
213
	}
214
215
	return $auth[$statut_auteur];
216
}
217
218
/**
219
 * Traduire le statut technique de l'auteur en langage compréhensible
220
 *
221
 * Si $statut=='nouveau' et que le statut en attente est fourni,
222
 * le prendre en compte en affichant que l'auteur est en attente
223
 *
224
 * @param string $statut
225
 * @param string $attente
226
 * @return string
227
 */
228
function traduire_statut_auteur($statut, $attente = "") {
229
	$plus = "";
230
	if ($statut == 'nouveau') {
231
		if ($attente) {
232
			$statut = $attente;
233
			$plus = " (" . _T('info_statut_auteur_a_confirmer') . ")";
234
		} else {
235
			return _T('info_statut_auteur_a_confirmer');
236
		}
237
	}
238
239
	$recom = array(
240
		"info_administrateurs" => _T('item_administrateur_2'),
241
		"info_redacteurs" => _T('intem_redacteur'),
242
		"info_visiteurs" => _T('item_visiteur'),
243
		'5poubelle' => _T('texte_statut_poubelle'), // bouh
244
	);
245
	if (isset($recom[$statut])) {
246
		return $recom[$statut] . $plus;
247
	}
248
249
	// retrouver directement par le statut sinon
250
	if ($t = array_search($statut, $GLOBALS['liste_des_statuts'])) {
251
		if (isset($recom[$t])) {
252
			return $recom[$t] . $plus;
253
		}
254
255
		return _T($t) . $plus;
256
	}
257
258
	// si on a pas reussi a le traduire, retournons la chaine telle quelle
259
	// c'est toujours plus informatif que rien du tout
260
	return $statut;
261
}
262
263
/**
264
 * Afficher la mention des autres auteurs ayant modifié un objet
265
 *
266
 * @param int $id_objet
267
 * @param string $objet
268
 * @return string
269
 */
270
function afficher_qui_edite($id_objet, $objet) {
271
	static $qui = array();
272
	if (isset($qui[$objet][$id_objet])) {
273
		return $qui[$objet][$id_objet];
274
	}
275
276
	if ($GLOBALS['meta']['articles_modif'] == 'non') {
277
		return $qui[$objet][$id_objet] = '';
278
	}
279
280
	include_spip('inc/drapeau_edition');
281
	$modif = mention_qui_edite($id_objet, $objet);
282
	if (!$modif) {
283
		return $qui[$objet][$id_objet] = '';
284
	}
285
286
	include_spip('base/objets');
287
	$infos = lister_tables_objets_sql(table_objet_sql($objet));
288
	if (isset($infos['texte_signale_edition'])) {
289
		return $qui[$objet][$id_objet] = _T($infos['texte_signale_edition'], $modif);
290
	}
291
292
	return $qui[$objet][$id_objet] = _T('info_qui_edite', $modif);
293
}
294
295
/**
296
 * Lister les statuts des auteurs
297
 *
298
 * @param string $quoi
299
 *   - redacteurs : retourne les statuts des auteurs au moins redacteur,
300
 *     tels que defini par AUTEURS_MIN_REDAC
301
 *   - visiteurs : retourne les statuts des autres auteurs, cad les visiteurs
302
 *     et autres statuts perso
303
 *   - tous : retourne tous les statuts connus
304
 * @param bool $en_base
305
 *   si true, ne retourne strictement que les status existants en base
306
 *   dans tous les cas, les statuts existants en base sont inclus
307
 * @return array
308
 */
309
function auteurs_lister_statuts($quoi = 'tous', $en_base = true) {
310
	if (!defined('AUTEURS_MIN_REDAC')) {
311
		define('AUTEURS_MIN_REDAC', "0minirezo,1comite,5poubelle");
312
	}
313
314
	switch ($quoi) {
315
		case "redacteurs":
316
			$statut = AUTEURS_MIN_REDAC;
317
			$statut = explode(',', $statut);
318 View Code Duplication
			if ($en_base) {
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...
319
				$check = array_column(sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $statut)), 'statut');
320
				$retire = array_diff($statut, $check);
321
				$statut = array_diff($statut, $retire);
322
			}
323
324
			return array_unique($statut);
325
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
326
		case "visiteurs":
327
			$statut = array();
328
			$exclus = AUTEURS_MIN_REDAC;
329
			$exclus = explode(',', $exclus);
330
			if (!$en_base) {
331
				// prendre aussi les statuts de la table des status qui ne sont pas dans le define
332
				$statut = array_diff(array_values($GLOBALS['liste_des_statuts']), $exclus);
333
			}
334
			$s_complement = array_column(
335
				sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $exclus, 'NOT')),
336
				'statut'
337
			);
338
339
			return array_unique(array_merge($statut, $s_complement));
340
			break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
341
		default:
342
		case "tous":
0 ignored issues
show
Unused Code introduced by
case 'tous': $statut...ue($statut); break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
343
			$statut = array_values($GLOBALS['liste_des_statuts']);
344
			$s_complement = array_column(
345
				sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $statut, 'NOT')),
346
				'statut'
347
			);
348
			$statut = array_merge($statut, $s_complement);
349 View Code Duplication
			if ($en_base) {
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...
350
				$check = array_column(sql_allfetsel('DISTINCT statut', 'spip_auteurs', sql_in('statut', $statut)), 'statut');
351
				$retire = array_diff($statut, $check);
352
				$statut = array_diff($statut, $retire);
353
			}
354
355
			return array_unique($statut);
356
			break;
357
	}
358
359
	// on arrive jamais ici
360
	return array_values($GLOBALS['liste_des_statuts']);
361
}
362
363
/**
364
 * Déterminer la rubrique pour la création d'un objet heuristique
365
 *
366
 * Rubrique courante si possible,
367
 * - sinon rubrique administrée pour les admin restreint
368
 * - sinon première rubrique de premier niveau autorisée que l'on trouve
369
 *
370
 * @param int $id_rubrique Identifiant de rubrique (si connu)
371
 * @param string $objet Objet en cours de création
372
 * @return int             Identifiant de la rubrique dans laquelle créer l'objet
373
 */
374
function trouver_rubrique_creer_objet($id_rubrique, $objet) {
375
376
	if (!$id_rubrique and defined('_CHOIX_RUBRIQUE_PAR_DEFAUT') and _CHOIX_RUBRIQUE_PAR_DEFAUT) {
377
		$in = !count($GLOBALS['connect_id_rubrique'])
378
			? ''
379
			: (" AND " . sql_in('id_rubrique', $GLOBALS['connect_id_rubrique']));
380
381
		// on tente d'abord l'ecriture a la racine dans le cas des rubriques uniquement
382
		if ($objet == 'rubrique') {
383
			$id_rubrique = 0;
384
		} else {
385
			$id_rubrique = sql_getfetsel('id_rubrique', 'spip_rubriques', "id_parent=0$in", '', "id_rubrique DESC", 1);
386
		}
387
388
		if (!autoriser("creer{$objet}dans", 'rubrique', $id_rubrique)) {
389
			// manque de chance, la rubrique n'est pas autorisee, on cherche un des secteurs autorises
390
			$res = sql_select("id_rubrique", "spip_rubriques", "id_parent=0");
391
			while (!autoriser("creer{$objet}dans", 'rubrique', $id_rubrique) && $row_rub = sql_fetch($res)) {
392
				$id_rubrique = $row_rub['id_rubrique'];
393
			}
394
		}
395
	}
396
397
	return $id_rubrique;
398
}
399
400
/**
401
 * Afficher le lien de redirection d'un article virtuel si il y a lieu
402
 * (rien si l'article n'est pas redirige)
403
 *
404
 * @param string $virtuel
405
 * @return string
406
 */
407
function lien_article_virtuel($virtuel) {
408
	include_spip('inc/lien');
409
	if (!$virtuel = virtuel_redirige($virtuel)) {
410
		return '';
411
	}
412
413
	return propre("[->" . $virtuel . "]");
414
}
415
416
417
/**
418
 * Filtre pour générer un lien vers un flux RSS privé
419
 *
420
 * Le RSS est protegé par un hash de faible sécurité
421
 *
422
 * @example
423
 *     - `[(#VAL{a_suivre}|bouton_spip_rss)]`
424
 *     - `[(#VAL{signatures}|bouton_spip_rss{#ARRAY{id_article,#ID_ARTICLE}})]`
425
 *
426
 * @filtre
427
 * @uses param_low_sec()
428
 * @param string $op
429
 * @param array $args
430
 * @param string $lang
431
 * @param string $title
432
 * @return string
433
 *     Code HTML du lien
434
 */
435
function bouton_spip_rss($op, $args = array(), $lang = '', $title = 'RSS') {
436
	include_spip('inc/acces');
437
	$clic = http_img_pack('feed.png', 'RSS', '', $title);
438
	$args = param_low_sec($op, $args, $lang, 'rss');
439
	$url = generer_url_public('rss', $args);
440
441
	return "<a style='float: " . $GLOBALS['spip_lang_right'] . ";' href='$url'>$clic</a>";
442
}
443
444
445
/**
446
 * Vérifier la présence d'alertes pour les auteur
447
 *
448
 * @param int $id_auteur
449
 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
450
 */
451
function alertes_auteur($id_auteur) {
452
453
	$alertes = array();
454
455
	if (isset($GLOBALS['meta']['message_crash_tables'])
456
		and autoriser('detruire', null, null, $id_auteur)
457
	) {
458
		include_spip('genie/maintenance');
459
		if ($msg = message_crash_tables()) {
460
			$alertes[] = $msg;
461
		}
462
	}
463
464
	if (isset($GLOBALS['meta']['message_crash_plugins'])
465
		and $GLOBALS['meta']['message_crash_plugins']
466
		and autoriser('configurer', '_plugins', null, $id_auteur)
467
		and is_array($msg = unserialize($GLOBALS['meta']['message_crash_plugins']))
468
	) {
469
		$msg = implode(', ', array_map('joli_repertoire', array_keys($msg)));
470
		$alertes[] = _T('plugins_erreur', array('plugins' => $msg));
471
	}
472
473
	$a = isset($GLOBALS['meta']['message_alertes_auteurs']) ? $GLOBALS['meta']['message_alertes_auteurs'] : '';
474
	if ($a
475
		and is_array($a = unserialize($a))
476
		and count($a)
477
	) {
478
		$update = false;
479
		if (isset($a[$GLOBALS['visiteur_session']['statut']])) {
480
			$alertes = array_merge($alertes, $a[$GLOBALS['visiteur_session']['statut']]);
481
			unset($a[$GLOBALS['visiteur_session']['statut']]);
482
			$update = true;
483
		}
484
		if (isset($a[''])) {
485
			$alertes = array_merge($alertes, $a['']);
486
			unset($a['']);
487
			$update = true;
488
		}
489
		if ($update) {
490
			ecrire_meta("message_alertes_auteurs", serialize($a));
491
		}
492
	}
493
494
	if (isset($GLOBALS['meta']['plugin_erreur_activation'])
495
		and autoriser('configurer', '_plugins', null, $id_auteur)
496
	) {
497
		include_spip('inc/plugin');
498
		$alertes[] = plugin_donne_erreurs();
499
	}
500
501
	$alertes = pipeline(
502
		'alertes_auteur',
503
		array(
504
			'args' => array(
505
				'id_auteur' => $id_auteur,
506
				'exec' => _request('exec'),
507
			),
508
			'data' => $alertes
509
		)
510
	);
511
512
	if ($alertes = array_filter($alertes)) {
513
		return "<div class='wrap-messages-alertes'><div class='messages-alertes'>" .
514
		join(' | ', $alertes)
515
		. "</div></div>";
516
	}
517
}
518
519
/**
520
 * Filtre pour afficher les rubriques enfants d'une rubrique
521
 *
522
 * @param int $id_rubrique
523
 * @return string
524
 */
525
function filtre_afficher_enfant_rub_dist($id_rubrique) {
526
	include_spip('inc/presenter_enfants');
527
528
	return afficher_enfant_rub(intval($id_rubrique));
529
}
530
531
/**
532
 * Afficher un petit "i" pour lien vers autre page
533
 *
534
 * @param string $lien
535
 *    URL du lien desire
536
 * @param string $titre
537
 *    Titre au survol de l'icone pointant le lien
538
 * @param string $titre_lien
539
 *    Si present, ajoutera en plus apres l'icone
540
 *    un lien simple, vers la meme URL,
541
 *    avec le titre indique
542
 *
543
 * @return string
544
 */
545
function afficher_plus_info($lien, $titre = "+", $titre_lien = "") {
546
	$titre = attribut_html($titre);
547
	$icone = "\n<a href='$lien' title='$titre' class='plus_info'>" .
548
		http_img_pack("information-16.png", $titre) . "</a>";
549
550
	if (!$titre_lien) {
551
		return $icone;
552
	} else {
553
		return $icone . "\n<a href='$lien'>$titre_lien</a>";
554
	}
555
}
556
557
558
559
560
/**
561
 * Lister les id objet_source associés à l'objet id_objet
562
 * via la table de lien objet_lien
563
 *
564
 * Utilisé pour les listes de #FORMULAIRE_EDITER_LIENS
565
 *
566
 * @param string $objet_source
567
 * @param string $objet
568
 * @param int $id_objet
569
 * @param string $objet_lien
570
 * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|false|array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
571
 */
572
function lister_objets_lies($objet_source, $objet, $id_objet, $objet_lien) {
573
	$res = lister_objets_liens($objet_source, $objet, $id_objet, $objet_lien);
574
	if (count($res)) {
575
		$r = reset($res);
576
		if (isset($r['rang_lien'])) {
577
			$l = array_column($res, 'rang_lien', $objet_source);
578
			asort($l);
579
			$l = array_keys($l);
580
		}
581
		else {
582
			$l = array_column($res, $objet_source);
583
		}
584
	}
585
	return $l;
0 ignored issues
show
Bug introduced by
The variable $l 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...
586
}
587
588
589
/**
590
 * Retrouver le rang du lien entre un objet source et un obet lie
591
 * utilisable en direct dans un formulaire d'edition des liens, mais #RANG doit faire le travail automatiquement
592
 * [(#ENV{objet_source}|rang_lien{#ID_AUTEUR,#ENV{objet},#ENV{id_objet},#ENV{_objet_lien}})]
593
 *
594
 * @param $objet_source
595
 * @param $ids
596
 * @param $objet_lie
597
 * @param $idl
598
 * @param $objet_lien
599
 * @return string
600
 */
601
function retrouver_rang_lien($objet_source, $ids, $objet_lie, $idl, $objet_lien){
602
	$res = lister_objets_liens($objet_source, $objet_lie, $idl, $objet_lien);
603
	$res = array_column($res, 'rang_lien', $objet_source);
604
605
	return (isset($res[$ids]) ? $res[$ids] : '');
606
}
607
608
609
/**
610
 * Lister les liens en le memoizant dans une static
611
 * pour utilisation commune par lister_objets_lies et retrouver_rang_lien dans un formuluaire d'edition de liens
612
 * (evite de multiplier les requetes)
613
 *
614
 * @param $objet_source
615
 * @param $objet
616
 * @param $id_objet
617
 * @param $objet_lien
618
 * @return mixed
619
 * @private
620
 */
621
function lister_objets_liens($objet_source, $objet, $id_objet, $objet_lien) {
622
	static $liens = array();
623
	if (!isset($liens["$objet_source-$objet-$id_objet-$objet_lien"])) {
624
		include_spip('action/editer_liens');
625
		// quand $objet == $objet_lien == $objet_source on reste sur le cas par defaut de $objet_lien == $objet_source
626 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...
627
			$res = objet_trouver_liens(array($objet => $id_objet), array($objet_source => '*'));
628
		} else {
629
			$res = objet_trouver_liens(array($objet_source => '*'), array($objet => $id_objet));
630
		}
631
632
		$liens["$objet_source-$objet-$id_objet-$objet_lien"] = $res;
633
	}
634
	return $liens["$objet_source-$objet-$id_objet-$objet_lien"];
635
}
636
637
/**
638
 * Calculer la balise #RANG
639
 * quand ce n'est pas un champ rang :
640
 * 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
641
 * @param $titre
642
 * @param $objet_source
643
 * @param $id
644
 * @param $env
645
 * @return int|string
646
 */
647
function calculer_rang_smart($titre, $objet_source, $id, $env) {
648
	// Cas du #RANG utilisé dans #FORMULAIRE_EDITER_LIENS -> attraper le rang du lien
649
	// 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
650
	if (isset($env['form']) and $env['form']
651
		and isset($env['_objet_lien']) and $env['_objet_lien']
652
		and (function_exists('lien_triables') or include_spip('action/editer_liens'))
653
		and $r = objet_associable($env['_objet_lien'])
654
		and list($p, $table_lien) = $r
655
	  and lien_triables($table_lien)
656
	  and isset($env['objet']) and $env['objet']
657
		and isset($env['id_objet']) and $env['id_objet']
658
		and $objet_source
659
		and $id = intval($id)
660
	) {
661
		$rang = retrouver_rang_lien($objet_source, $id, $env['objet'], $env['id_objet'], $env['_objet_lien']);
662
		return ($rang ? $rang : '');
663
	}
664
	return recuperer_numero($titre);
665
}
666