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

modifier.php ➔ objet_modifier_champs()   F

Complexity

Conditions 37
Paths 6128

Size

Total Lines 179
Code Lines 98

Duplication

Lines 17
Ratio 9.5 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 37
eloc 98
c 3
b 1
f 0
nc 6128
nop 5
dl 17
loc 179
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
/**
14
 * Fonctions d'aides pour les fonctions d'objets de modification de contenus
15
 *
16
 * @package SPIP\Objets\Modifications
17
**/
18
19
if (!defined('_ECRIRE_INC_VERSION')) return;
20
21
/**
22
 * Collecte des champs postés
23
 * 
24
 * Fonction générique pour la collecte des posts
25
 * dans action/editer_xxx
26
 *
27
 * @param array $white_list
28
 *     Les champs à récupérer
29
 * @param array $black_list
30
 *     Les champs à ignorer
31
 * @param array|null $set
32
 *     array : Tableau des champs postés
33
 *     null  : Les champs sont obtenus par des _request() sur les noms de la white liste
34
 * @param bool $tous
35
 *     true : Recupère tous les champs de white_list meme ceux n'ayant pas ete postés
36
 * @return array
37
 *     Tableau des champs et valeurs collectées 
38
 */
39
function collecter_requests($white_list, $black_list, $set=null, $tous=false){
40
	$c = $set;
41
	if (!$c){
42
		$c = array();
43
		foreach($white_list as $champ) {
44
			// on ne collecte que les champs reellement envoyes par defaut.
45
			// le cas d'un envoi de valeur NULL peut du coup poser probleme.
46
			$val = _request($champ);
47
			if ($tous OR $val !== NULL) {
48
				$c[$champ] = $val;
49
			}
50
		}
51
		// on ajoute toujours la lang en saisie possible
52
		// meme si pas prevu au depart pour l'objet concerne
53
		if ($l = _request('changer_lang')){
54
			$c['lang'] = $l;
55
		}
56
	}
57
	foreach($black_list as $champ) {
58
		unset($c[$champ]);
59
	}
60
	
61
	return $c;
62
}
63
64
/**
65
 * Modifie le contenu d'un objet
66
 * 
67
 * Fonction generique pour l'API de modification de contenu, qui se
68
 * charge entre autres choses d'appeler les pipelines pre_edition
69
 * et post_edition
70
 *
71
 * Attention, pour éviter des hacks on interdit des champs
72
 * (statut, id_secteur, id_rubrique, id_parent),
73
 * mais la securite doit étre assurée en amont
74
 *
75
 * @api
76
 * @param string $objet
77
 *     Type d'objet
78
 * @param int $id_objet
79
 *     Identifiant de l'objet
80
 * @param array $options
81
 *     array data : tableau des donnees sources utilisees pour la detection de conflit ($_POST sinon fourni ou si nul)
82
 *     array nonvide : valeur par defaut des champs que l'on ne veut pas vide
83
 *     string date_modif : champ a mettre a date('Y-m-d H:i:s') s'il y a modif
84
 *     string invalideur : id de l'invalideur eventuel
85
 *     array champs : non documente (utilise seulement par inc/rechercher ?)
86
 *     string action : action realisee, passee aux pipelines pre/post edition (par defaut 'modifier')
87
 *     bool indexation : deprecie
88
 * @param array|null $c
89
 *     Couples champ/valeur à modifier
90
 * @param string $serveur
91
 *     Nom du connecteur à la base de données
92
 * @return bool|string
93
 *     - false  : Aucune modification, aucun champ n'est à modifier
94
 *     - chaîne vide : Vide si tout s'est bien passé
95
 *     - chaîne : Texte d'un message d'erreur
96
 */
97
function objet_modifier_champs($objet, $id_objet, $options, $c=null, $serveur='') {
98
	if (!$id_objet = intval($id_objet)) {
99
		spip_log('Erreur $id_objet non defini', 'warn');
100
		return _T('erreur_technique_enregistrement_impossible');
101
	}
102
103
	include_spip('inc/filtres');
104
105
	$table_objet = table_objet($objet,$serveur);
106
	$spip_table_objet = table_objet_sql($objet,$serveur);
107
	$id_table_objet = id_table_objet($objet,$serveur);
108
	$trouver_table = charger_fonction('trouver_table', 'base');
109
	$desc = $trouver_table($spip_table_objet, $serveur);
110
111
	// Appels incomplets (sans $c)
112
	if (!is_array($c)) {
113
		spip_log('erreur appel objet_modifier_champs('.$objet.'), manque $c');
114
		return _T('erreur_technique_enregistrement_impossible');
115
	}
116
117
	// Securite : certaines variables ne sont jamais acceptees ici
118
	// car elles ne relevent pas de autoriser(xxx, modifier) ;
119
	// il faut passer par instituer_XX()
120
	// TODO: faut-il passer ces variables interdites
121
	// dans un fichier de description separe ?
122
	unset($c['statut']);
123
	unset($c['id_parent']);
124
	unset($c['id_rubrique']);
125
	unset($c['id_secteur']);
126
127
	// Gerer les champs non vides
128 View Code Duplication
	if (isset($options['nonvide']) AND is_array($options['nonvide'])) {
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...
129
		foreach ($options['nonvide'] as $champ => $sinon) {
130
			if ($c[$champ] === '') {
131
				$c[$champ] = $sinon;
132
			}
133
		}
134
	}
135
136
137
	// N'accepter que les champs qui existent
138
	// TODO: ici aussi on peut valider les contenus
139
	// en fonction du type
140
	$champs = array();
141 View Code Duplication
	foreach($desc['field'] as $champ => $ignore)
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...
142
		if (isset($c[$champ]))
143
			$champs[$champ] = $c[$champ];
144
145
	// Nettoyer les valeurs
146
	$champs = array_map('corriger_caracteres', $champs);
147
148
	// Envoyer aux plugins
149
	$champs = pipeline('pre_edition',
150
		array(
151
			'args' => array(
152
				'table' => $spip_table_objet, // compatibilite
153
				'table_objet' => $table_objet,
154
				'spip_table_objet' => $spip_table_objet,
155
				'type' =>$objet,
156
				'id_objet' => $id_objet,
157
				'champs' => isset($options['champs']) ? $options['champs'] : array(), // [doc] c'est quoi ?
158
				'serveur' => $serveur,
159
				'action' => isset($options['action']) ? $options['action'] : 'modifier'
160
			),
161
			'data' => $champs
162
		)
163
	);
164
165
	if (!$champs) return false;
166
167
168
	// marquer le fait que l'objet est travaille par toto a telle date
169
	if ($GLOBALS['meta']['articles_modif'] != 'non') {
170
		include_spip('inc/drapeau_edition');
171
		signale_edition ($id_objet, $GLOBALS['visiteur_session'], $objet);
172
	}
173
174
	// Verifier si les mises a jour sont pertinentes, datees, en conflit etc
175
	include_spip('inc/editer');
176
	if (!isset($options['data']) OR is_null($options['data'])){
177
		$options['data'] = &$_POST;
178
	}
179
	$conflits = controler_md5($champs, $options['data'], $objet, $id_objet, $serveur);
180
	// cas hypothetique : normalement inc/editer verifie en amont le conflit edition
181
	// et gere l'interface
182
	// ici on ne renvoie donc qu'un messsage d'erreur, au cas ou on y arrive quand meme
183
	if ($conflits)
184
		return _T('titre_conflit_edition');
185
186
	if ($champs) {
187
		// cas particulier de la langue : passer par instituer_langue_objet
188
		if (isset($champs['lang'])){
189
			if ($changer_lang=$champs['lang']){
190
				$id_rubrique = 0;
191
				if ($desc['field']['id_rubrique']){
192
					$parent = ($objet=='rubrique')?'id_parent':'id_rubrique';
193
					$id_rubrique = sql_getfetsel($parent, $spip_table_objet, "$id_table_objet=".intval($id_objet));
194
				}
195
				$instituer_langue_objet = charger_fonction('instituer_langue_objet', 'action');
196
				$champs['lang'] = $instituer_langue_objet($objet, $id_objet, $id_rubrique, $changer_lang, $serveur);
197
			}
198
			// on laisse 'lang' dans $champs,
199
			// ca permet de passer dans le pipeline post_edition et de journaliser
200
			// et ca ne gene pas qu'on refasse un sql_updateq dessus apres l'avoir
201
			// deja pris en compte
202
		}
203
204
		// la modif peut avoir lieu
205
206
		// faut-il ajouter date_modif ?
207
		if (isset($options['date_modif']) AND $options['date_modif']
208
		AND !isset($champs[$options['date_modif']]))
209
			$champs[$options['date_modif']] = date('Y-m-d H:i:s');
210
211
		// allez on commit la modif
212
		sql_updateq($spip_table_objet, $champs, "$id_table_objet=".intval($id_objet), $serveur);
213
214
		// on verifie si elle est bien passee
215
		$moof = sql_fetsel(array_keys($champs), $spip_table_objet, "$id_table_objet=".intval($id_objet), array(), array(), '', array(), $serveur);
216
		// si difference entre les champs, reperer les champs mal enregistres
217
		if ($moof != $champs) {
218
			$liste = array();
219
			foreach($moof as $k=>$v)
220
				if ($v !== $champs[$k]
221
					// ne pas alerter si le champ est numerique est que les valeurs sont equivalentes
222
					AND (!is_numeric($v) OR intval($v)!=intval($champs[$k]))
223
					) {
224
					$liste[] = $k;
225
					$conflits[$k]['post'] = $champs[$k];
226
					$conflits[$k]['save'] = $v;
227
				}
228
			// si un champ n'a pas ete correctement enregistre, loger et retourner une erreur
229
			// c'est un cas exceptionnel
230
			if (count($liste)){
231
				spip_log("Erreur enregistrement en base $objet/$id_objet champs :".var_export($conflits,true),'modifier.'._LOG_CRITIQUE);
232
				return _T('erreur_technique_enregistrement_champs',array('champs'=>"<i>'".implode("'</i>,<i>'",$liste)."'</i>"));
233
			}
234
		}
235
236
		// Invalider les caches
237 View Code Duplication
		if (isset($options['invalideur']) and $options['invalideur']) {
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...
238
			include_spip('inc/invalideur');
239
			if (is_array($options['invalideur']))
240
				array_map('suivre_invalideur',$options['invalideur']);
241
			else
242
				suivre_invalideur($options['invalideur']);
243
		}
244
245
		// Notifications, gestion des revisions...
246
		// en standard, appelle |nouvelle_revision ci-dessous
247
		pipeline('post_edition',
248
			array(
249
				'args' => array(
250
					'table' => $spip_table_objet,
251
					'table_objet' => $table_objet,
252
					'spip_table_objet' => $spip_table_objet,
253
					'type' =>$objet,
254
					'id_objet' => $id_objet,
255
					'champs' => isset($options['champs']) ? $options['champs'] : array(), // [doc] kesako ?
256
					'serveur' => $serveur,
257
					'action' => isset($options['action']) ? $options['action'] : 'modifier'
258
				),
259
				'data' => $champs
260
			)
261
		);
262
	}
263
264
	// journaliser l'affaire
265
	// message a affiner :-)
266
	include_spip('inc/filtres_mini');
267
	$qui = ((isset($GLOBALS['visiteur_session']['nom']) AND $GLOBALS['visiteur_session']['nom'])?$GLOBALS['visiteur_session']['nom']:$GLOBALS['ip']);
268
	journal(_L($qui.' a &#233;dit&#233; l&#8217;'.$objet.' '.$id_objet.' ('.join('+',array_diff(array_keys($champs), array('date_modif'))).')'), array(
269
		'faire' => 'modifier',
270
		'quoi' => $objet,
271
		'id' => $id_objet
272
	));
273
274
	return '';
275
}
276
277
/**
278
 * Modifie un contenu
279
 * 
280
 * Dépreciée :
281
 * Fonction générique pour l'API de modification de contenu
282
 *
283
 * @deprecated
284
 * @param string $type
285
 *     Type d'objet
286
 * @param int $id
287
 *     Identifiant de l'objet
288
 * @param array $options
289
 *     Toutes les options
290
 * @param array|null $c
291
 *     Couples champ/valeur à modifier
292
 * @param string $serveur
293
 *     Nom du connecteur à la base de données
294
 * @return bool
295
 *     true si quelque chose est modifié correctement
296
 *     false sinon (erreur ou aucun champ modifié)
297
 */
298
function modifier_contenu($type, $id, $options, $c=null, $serveur='') {
299
	$res = objet_modifier_champs($type, $id, $options, $c, $serveur);
300
	return ($res===''?true:false);
301
}
302
303
/**
304
 * Crée une modification d'un objet
305
 * 
306
 * Wrapper pour remplacer tous les obsoletes revision_xxx
307
 *
308
 * @deprecated
309
 *     Utiliser objet_modifier();
310
 * @see objet_modifier();
311
 * 
312
 * @param string $objet
313
 *     Nom de l'objet
314
 * @param int $id_objet
315
 *     Identifiant de l'objet
316
 * @param array $c
0 ignored issues
show
Documentation introduced by
Should the type for parameter $c 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...
317
 *     Couples des champs/valeurs modifiées
318
 * @return mixed|string
319
 */
320
function revision_objet($objet,$id_objet,$c=null){
321
	$objet = objet_type($objet); // securite
322
	include_spip('action/editer_objet');
323
	return objet_modifier($objet,$id_objet,$c);
324
}
325
326
327
?>
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...
328