Completed
Push — master ( 6512a2...eeb9ca )
by cam
06:16 queued 01:49
created

editer_auteur.php ➔ insert_auteur()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 3
rs 10
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
 * Gestion de l'action editer_auteur et de l'API d'édition d'un auteur
15
 *
16
 * @package SPIP\Core\Auteurs\Edition
17
 */
18
19
if (!defined('_ECRIRE_INC_VERSION')) {
20
	return;
21
}
22
23
/**
24
 * Éditer ou créer un auteur
25
 *
26
 * Si aucun identifiant d'auteur n'est donné, on crée alors un nouvel auteur.
27
 *
28
 * @global array visiteur_session
29
 * @uses auteur_inserer()
30
 * @uses auteur_modifier()
31
 *
32
 * @param array|null $arg
33
 *     Identifiant de l'auteur. En absence utilise l'argument
34
 *     de l'action sécurisée.
35
 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<boolean|string|integer>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
36
 *     Liste (identifiant de l'auteur, Texte d'erreur éventuel)
37
 */
38
function action_editer_auteur_dist($arg = null) {
39
40
	if (is_null($arg)) {
41
		$securiser_action = charger_fonction('securiser_action', 'inc');
42
		$arg = $securiser_action();
43
	}
44
45
46
	// si id_auteur n'est pas un nombre, c'est une creation
47
	if (!$id_auteur = intval($arg)) {
48
49
		if (($id_auteur = auteur_inserer()) > 0) {
50
51
			# cf. GROS HACK
52
			# recuperer l'eventuel logo charge avant la creation
53
			# ils ont un id = 0-id_auteur de la session
54
			$id_hack = 0 - $GLOBALS['visiteur_session']['id_auteur'];
55
			$chercher_logo = charger_fonction('chercher_logo', 'inc');
56
			foreach (array('on', 'off') as $type) {
57
				if ($logo = $chercher_logo($id_hack, 'id_auteur', $type)) {
58
					if ($logo = reset($logo)) {
59
						rename($logo, str_replace($id_hack, $id_auteur, $logo));
60
					}
61
				}
62
			}
63
		}
64
	}
65
66
	// Enregistre l'envoi dans la BD
67
	$err = "";
68
	if ($id_auteur > 0) {
69
		$err = auteur_modifier($id_auteur);
70
	}
71
72
	if ($err) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $err of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
73
		spip_log("echec editeur auteur: $err", _LOG_ERREUR);
74
	}
75
76
	return array($id_auteur, $err);
77
}
78
79
/**
80
 * Insérer un auteur en base
81
 *
82
 * @pipeline_appel pre_insertion
83
 * @pipeline_appel post_insertion
84
 *
85
 * @param string|null $source
86
 *     D'où provient l'auteur créé ? par défaut 'spip', mais peut être 'ldap' ou autre.
87
 * @param array|null $set
88
 * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|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.

Loading history...
89
 *     Identifiant de l'auteur créé
90
 */
91
function auteur_inserer($source = null, $set = null) {
92
93
	// Ce qu'on va demander comme modifications
94
	$champs = array();
95
	$champs['source'] = $source ? $source : 'spip';
96
97
	$champs['login'] = '';
98
	$champs['statut'] = '5poubelle';  // inutilisable tant qu'il n'a pas ete renseigne et institue
99
	$champs['webmestre'] = 'non';
100
	if (empty($champs['imessage'])) {
101
		$champs['imessage'] = 'oui';
102
	}
103
104
	if ($set) {
105
		$champs = array_merge($champs, $set);
106
	}
107
108
	// Envoyer aux plugins
109
	$champs = pipeline('pre_insertion',
110
		array(
111
			'args' => array(
112
				'table' => 'spip_auteurs',
113
			),
114
			'data' => $champs
115
		)
116
	);
117
	$id_auteur = sql_insertq("spip_auteurs", $champs);
118
	pipeline('post_insertion',
119
		array(
120
			'args' => array(
121
				'table' => 'spip_auteurs',
122
				'id_objet' => $id_auteur
123
			),
124
			'data' => $champs
125
		)
126
	);
127
128
	return $id_auteur;
129
}
130
131
132
/**
133
 * Modifier un auteur
134
 *
135
 * Appelle toutes les fonctions de modification d'un auteur
136
 *
137
 * @param int $id_auteur
138
 *     Identifiant de l'auteur
139
 * @param array|null $set
140
 *     Couples (colonne => valeur) de données à modifier.
141
 *     En leur absence, on cherche les données dans les champs éditables
142
 *     qui ont été postés (via collecter_requests())
143
 * @param bool $force_update
144
 *   Permet de forcer la maj en base des champs fournis, sans passer par instancier.
145
 *   Utilise par auth/spip
146
 * @return string|null
0 ignored issues
show
Documentation introduced by
Should the return type not be string|false?

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...
147
 *
148
 *     - Chaîne vide si aucune erreur,
149
 *     - Chaîne contenant un texte d'erreur sinon.
150
 */
151
function auteur_modifier($id_auteur, $set = null, $force_update = false) {
152
153
	include_spip('inc/modifier');
154
	include_spip('inc/filtres');
155
	$c = collecter_requests(
156
	// white list
157
		objet_info('auteur', 'champs_editables'),
0 ignored issues
show
Bug introduced by
It seems like objet_info('auteur', 'champs_editables') targeting objet_info() can also be of type string; however, collecter_requests() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
158
		// black list
159
		$force_update ? array() : array('webmestre', 'pass', 'login'),
160
		// donnees eventuellement fournies
161
		$set
162
	);
163
164
	if ($err = objet_modifier_champs('auteur', $id_auteur,
165
		array(
166
			'data' => $set,
167
			'nonvide' => array('nom' => _T('ecrire:item_nouvel_auteur'))
168
		),
169
		$c)
170
	) {
171
		return $err;
172
	}
173
	$session = $c;
174
175
	$err = '';
176
	if (!$force_update) {
177
		// Modification de statut, changement de rubrique ?
178
		$c = collecter_requests(
179
		// white list
180
			array(
181
				'statut',
182
				'new_login',
183
				'new_pass',
184
				'login',
185
				'pass',
186
				'webmestre',
187
				'restreintes',
188
				'id_parent'
189
			),
190
			// black list
191
			array(),
192
			// donnees eventuellement fournies
193
			$set
194
		);
195
		if (isset($c['new_login']) and !isset($c['login'])) {
196
			$c['login'] = $c['new_login'];
197
		}
198
		if (isset($c['new_pass']) and !isset($c['pass'])) {
199
			$c['pass'] = $c['new_pass'];
200
		}
201
		$err = auteur_instituer($id_auteur, $c);
202
		$session = array_merge($session, $c);
203
	}
204
205
	// .. mettre a jour les sessions de cet auteur
206
	include_spip('inc/session');
207
	$session['id_auteur'] = $id_auteur;
208
	unset($session['new_login']);
209
	unset($session['new_pass']);
210
	actualiser_sessions($session);
211
212
	return $err;
213
}
214
215
/**
216
 * Associer un auteur à des objets listés
217
 *
218
 * @uses objet_associer()
219
 *
220
 * @param int $id_auteur
221
 *     Identifiant de l'auteur
222
 * @param array $objets
223
 *     Liste sous la forme `array($objet=>$id_objets,...)`.
224
 *     `$id_objets` peut lui-même être un scalaire ou un tableau pour une liste
225
 *     d'objets du même type.
226
 * @param array|null $qualif
227
 *     Optionnellement indique une qualification du (des) lien(s) qui sera
228
 *     alors appliquée dans la foulée.
229
 *     En cas de lot de liens, c'est la même qualification qui est appliquée à tous
230
 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer|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...
231
 */
232
function auteur_associer($id_auteur, $objets, $qualif = null) {
233
	include_spip('action/editer_liens');
234
235
	return objet_associer(array('auteur' => $id_auteur), $objets, $qualif);
236
}
237
238
/**
239
 * Dissocier un auteur des objets listés
240
 *
241
 * @uses objet_dissocier()
242
 *
243
 * @param int $id_auteur
244
 *     Identifiant de l'auteur
245
 * @param array $objets
246
 *     Liste sous la forme `array($objet=>$id_objets,...)`.
247
 *     `$id_objets` peut lui-même être un scalaire ou un tableau pour une liste
248
 *     d'objets du même type.
249
 *
250
 *     Un `*` pour $id_auteur,$objet,$id_objet permet de traiter par lot
251
 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer|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...
252
 */
253
function auteur_dissocier($id_auteur, $objets) {
254
	include_spip('action/editer_liens');
255
256
	return objet_dissocier(array('auteur' => $id_auteur), $objets);
257
}
258
259
/**
260
 * Qualifier le lien d'un auteur avec les objets listés
261
 *
262
 * @uses objet_qualifier_liens()
263
 *
264
 * @param int $id_auteur
265
 *     Identifiant de l'auteur
266
 * @param array $objets
267
 *     Liste sous la forme `array($objet=>$id_objets,...)`.
268
 *     `$id_objets` peut lui-même être un scalaire ou un tableau pour une liste
269
 *     d'objets du même type.
270
 *
271
 *     Un `*` pour $id_auteur,$objet,$id_objet permet de traiter par lot
272
 * @param array $qualif
273
 *     Couples (colonne, valeur) tel que `array('vu'=>'oui');`
274
 * @return bool|int
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|integer|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...
275
 */
276
function auteur_qualifier($id_auteur, $objets, $qualif) {
277
	include_spip('action/editer_liens');
278
279
	return objet_qualifier_liens(array('auteur' => $id_auteur), $objets, $qualif);
280
}
281
282
283
/**
284
 * Modifier le statut d'un auteur, ou son login/pass
285
 *
286
 * @pipeline_appel pre_edition
287
 * @pipeline_appel post_edition
288
 *
289
 * @param int $id_auteur
290
 *     Identifiant de l'auteur
291
 * @param array $c
292
 *     Couples (colonne => valeur) des données à instituer
293
 * @param bool $force_webmestre
294
 *     Autoriser un auteur à passer webmestre (force l'autorisation)
295
 * @return bool|string
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
296
 */
297
function auteur_instituer($id_auteur, $c, $force_webmestre = false) {
298
	if (!$id_auteur = intval($id_auteur)) {
299
		return false;
300
	}
301
	$erreurs = array(); // contiendra les differentes erreurs a traduire par _T()
302
	$champs = array();
303
304
	// les memoriser pour les faire passer dans le pipeline pre_edition
305 View Code Duplication
	if (isset($c['login']) and strlen($c['login'])) {
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...
306
		$champs['login'] = $c['login'];
307
	}
308 View Code Duplication
	if (isset($c['pass']) and strlen($c['pass'])) {
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...
309
		$champs['pass'] = $c['pass'];
310
	}
311
312
	$statut = $statut_ancien = sql_getfetsel('statut', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
313
314
	if (isset($c['statut'])
315
		and (autoriser('modifier', 'auteur', $id_auteur, null, array('statut' => $c['statut'])))
316
	) {
317
		$statut = $champs['statut'] = $c['statut'];
318
	}
319
320
	// Restreindre avant de declarer l'auteur
321
	// (section critique sur les droits)
322
	if (isset($c['id_parent']) and $c['id_parent']) {
323
		if (is_array($c['restreintes'])) {
324
			$c['restreintes'][] = $c['id_parent'];
325
		} else {
326
			$c['restreintes'] = array($c['id_parent']);
327
		}
328
	}
329
330
	if (isset($c['webmestre'])
331
		and ($force_webmestre or autoriser('modifier', 'auteur', $id_auteur, null, array('webmestre' => '?')))
332
	) {
333
		$champs['webmestre'] = $c['webmestre'] == 'oui' ? 'oui' : 'non';
334
	}
335
336
	// si statut change et n'est pas 0minirezo, on force webmestre a non
337
	if (isset($c['statut']) and $c['statut'] !== '0minirezo') {
338
		$champs['webmestre'] = $c['webmestre'] = 'non';
339
	}
340
341
	// Envoyer aux plugins
342
	$champs = pipeline('pre_edition',
343
		array(
344
			'args' => array(
345
				'table' => 'spip_auteurs',
346
				'id_objet' => $id_auteur,
347
				'action' => 'instituer',
348
				'statut_ancien' => $statut_ancien,
349
			),
350
			'data' => $champs
351
		)
352
	);
353
354
	if (isset($c['restreintes']) and is_array($c['restreintes'])
355
		and autoriser('modifier', 'auteur', $id_auteur, null, array('restreint' => $c['restreintes']))
356
	) {
357
		$rubriques = array_map('intval', $c['restreintes']);
358
		$rubriques = array_unique($rubriques);
359
		$rubriques = array_diff($rubriques, array(0));
360
		auteur_dissocier($id_auteur, array('rubrique' => '*'));
361
		auteur_associer($id_auteur, array('rubrique' => $rubriques));
362
	}
363
364
	$flag_ecrire_acces = false;
365
	// commencer par traiter les cas particuliers des logins et pass
366
	// avant les autres ecritures en base
367
	if (isset($champs['login']) or isset($champs['pass'])) {
368
		$auth_methode = sql_getfetsel('source', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
369
		include_spip('inc/auth');
370 View Code Duplication
		if (isset($champs['login']) and strlen($champs['login'])) {
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...
371
			if (!auth_modifier_login($auth_methode, $champs['login'], $id_auteur)) {
372
				$erreurs[] = 'ecrire:impossible_modifier_login_auteur';
373
			}
374
		}
375
		if (isset($champs['pass']) and strlen($champs['pass'])) {
376
			$champs['login'] = sql_getfetsel('login', 'spip_auteurs', 'id_auteur=' . intval($id_auteur));
377
			if (!auth_modifier_pass($auth_methode, $champs['login'], $champs['pass'], $id_auteur)) {
378
				$erreurs[] = 'ecrire:impossible_modifier_pass_auteur';
379
			}
380
		}
381
		unset($champs['login']);
382
		unset($champs['pass']);
383
		$flag_ecrire_acces = true;
384
	}
385
386
	if (!count($champs)) {
387
		return implode(' ', array_map('_T', $erreurs));
388
	}
389
	sql_updateq('spip_auteurs', $champs, 'id_auteur=' . $id_auteur);
390
391
	// .. mettre a jour les fichiers .htpasswd et .htpasswd-admin
392
	if ($flag_ecrire_acces
393
		or isset($champs['statut'])
394
	) {
395
		include_spip('inc/acces');
396
		ecrire_acces();
397
	}
398
399
	// Invalider les caches
400
	include_spip('inc/invalideur');
401
	suivre_invalideur("id='auteur/$id_auteur'");
402
403
	// Pipeline
404
	pipeline('post_edition',
405
		array(
406
			'args' => array(
407
				'table' => 'spip_auteurs',
408
				'id_objet' => $id_auteur,
409
				'action' => 'instituer',
410
				'statut_ancien' => $statut_ancien,
411
			),
412
			'data' => $champs
413
		)
414
	);
415
416
417
	// Notifications
418
	if ($notifications = charger_fonction('notifications', 'inc')) {
419
		$notifications('instituerauteur', $id_auteur,
420
			array('statut' => $statut, 'statut_ancien' => $statut_ancien)
421
		);
422
	}
423
424
	return implode(' ', array_map('_T', $erreurs));
425
426
}
427