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

editer_objet.php ➔ objet_inserer()   F

Complexity

Conditions 28
Paths 3602

Size

Total Lines 104
Code Lines 63

Duplication

Lines 6
Ratio 5.77 %

Importance

Changes 0
Metric Value
cc 28
eloc 63
c 0
b 0
f 0
nc 3602
nop 3
dl 6
loc 104
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
/**
16
 * Point d'entree d'edition d'un objet
17
 * on ne peut entrer que par un appel en fournissant $id et $objet
18
 * mais pas pas une url
19
 *
20
 * @param int $id
0 ignored issues
show
Documentation introduced by
Should the type for parameter $id not be integer|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...
21
 * @param string $objet
0 ignored issues
show
Documentation introduced by
Should the type for parameter $objet 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...
22
 * @param array $set
0 ignored issues
show
Documentation introduced by
Should the type for parameter $set 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...
23
 * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

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...
24
 */
25
function action_editer_objet_dist($id=null, $objet=null, $set=null) {
26
27
	// appel direct depuis une url interdit
28
	if (is_null($id) OR is_null($objet)){
29
		include_spip('inc/minipres');
30
		echo minipres(_T('info_acces_interdit'));
31
		die();
0 ignored issues
show
Coding Style Compatibility introduced by
The function action_editer_objet_dist() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
32
	}
33
34
	// si id n'est pas un nombre, c'est une creation
35
	// mais on verifie qu'on a toutes les donnees qu'il faut.
36
	if (!$id = intval($id)) {
37
		// on ne sait pas si un parent existe mais on essaye
38
		$id_parent = _request('id_parent');
39
		$id = objet_inserer($objet, $id_parent);
40
	}
41
42
	if (!($id = intval($id))>0)
43
		return array($id,_L('echec enregistrement en base'));
44
45
	// Enregistre l'envoi dans la BD
46
	$err = objet_modifier($objet, $id, $set);
47
48
	return array($id,$err);
49
}
50
51
/**
52
 * Appelle toutes les fonctions de modification d'un objet
53
 * $err est un message d'erreur eventuelle
54
 *
55
 * @param string $objet
56
 * @param int $id
57
 * @param array|null $set
58
 * @return mixed|string
59
 */
60
function objet_modifier($objet, $id, $set=null) {
61
	if (include_spip('action/editer_'.$objet)
62
	  AND function_exists($modifier = $objet."_modifier"))
63
		return $modifier($id,$set);
64
65
	$table_sql = table_objet_sql($objet);
66
	$trouver_table = charger_fonction('trouver_table','base');
67
	$desc = $trouver_table($table_sql);
68 View Code Duplication
	if (!$desc OR !isset($desc['field'])) {
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...
69
		spip_log("Objet $objet inconnu dans objet_modifier",_LOG_ERREUR);
70
		return _L("Erreur objet $objet inconnu");
71
	}
72
	include_spip('inc/modifier');
73
74
	$champ_date = '';
75 View Code Duplication
	if (isset($desc['date']) AND $desc['date'])
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...
76
		$champ_date = $desc['date'];
77
	elseif (isset($desc['field']['date']))
78
		$champ_date = 'date';
79
80
	$white = array_keys($desc['field']);
81
	// on ne traite pas la cle primaire par defaut, notamment car
82
	// sur une creation, id_x vaut 'oui', et serait enregistre en id_x=0 dans la base
83
	$white = array_diff($white, array($desc['key']['PRIMARY KEY']));
84
85
	if (isset($desc['champs_editables']) AND is_array($desc['champs_editables'])) {
86
		$white = $desc['champs_editables'];
87
	}
88
	$c = collecter_requests(
89
		// white list
90
		$white,
91
		// black list
92
		array($champ_date,'statut','id_parent','id_secteur'),
93
		// donnees eventuellement fournies
94
		$set
95
	);
96
97
	// Si l'objet est publie, invalider les caches et demander sa reindexation
98
	if (objet_test_si_publie($objet,$id)){
99
		$invalideur = "id='$objet/$id'";
100
		$indexation = true;
101
	}
102
	else {
103
		$invalideur = "";
104
		$indexation = false;
105
	}
106
107
	if ($err = objet_modifier_champs($objet, $id,
108
		array(
109
			'data' => $set,
110
			'nonvide' => '',
111
			'invalideur' => $invalideur,
112
			'indexation' => $indexation,
113
			 // champ a mettre a date('Y-m-d H:i:s') s'il y a modif
114
			'date_modif' => (isset($desc['field']['date_modif'])?'date_modif':'')
115
		),
116
		$c))
117
		return $err;
118
119
	// Modification de statut, changement de rubrique ?
120
	// FIXME: Ici lorsqu'un $set est passé, la fonction collecter_requests() retourne tout
121
	//         le tableau $set hors black liste, mais du coup on a possiblement des champs en trop. 
122
	$c = collecter_requests(array($champ_date, 'statut', 'id_parent'),array(),$set);
123
	$err = objet_instituer($objet, $id, $c);
124
125
	return $err;
126
}
127
128
/**
129
 * Inserer en base un objet generique
130
 * @param string $objet
131
 * @param int $id_parent
0 ignored issues
show
Documentation introduced by
Should the type for parameter $id_parent not be integer|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...
132
 * @param array|null $set
133
 * @return bool|int
134
 */
135
function objet_inserer($objet, $id_parent=null, $set=null) {
136
	if (include_spip('action/editer_'.$objet)
137
	  AND function_exists($inserer = $objet."_inserer"))
138
		return $inserer($id_parent);
139
140
	$table_sql = table_objet_sql($objet);
141
	$trouver_table = charger_fonction('trouver_table','base');
142
	$desc = $trouver_table($table_sql);
143
	if (!$desc OR !isset($desc['field']))
144
		return 0;
145
146
	$lang_rub = "";
147
	$champs = array();
148
	if (isset($desc['field']['id_rubrique'])){
149
		// Si id_rubrique vaut 0 ou n'est pas definie, creer l'objet
150
		// dans la premiere rubrique racine
151 View Code Duplication
		if (!$id_rubrique = intval($id_parent)) {
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...
152
			$row = sql_fetsel("id_rubrique, id_secteur, lang", "spip_rubriques", "id_parent=0",'', '0+titre,titre', "1");
153
			$id_rubrique = $row['id_rubrique'];
154
		}
155
		else
156
			$row = sql_fetsel("lang, id_secteur", "spip_rubriques", "id_rubrique=".intval($id_rubrique));
157
158
		$champs['id_rubrique'] = $id_rubrique;
159
		if (isset($desc['field']['id_secteur']))
160
			$champs['id_secteur'] = $row['id_secteur'];
161
		$lang_rub = $row['lang'];
162
	}
163
164
	// La langue a la creation : si les liens de traduction sont autorises
165
	// dans les rubriques, on essaie avec la langue de l'auteur,
166
	// ou a defaut celle de la rubrique
167
	// Sinon c'est la langue de la rubrique qui est choisie + heritee
168
	if (isset($desc['field']['lang']) AND $GLOBALS['meta']['multi_objets'] AND in_array($table_sql, explode(',', $GLOBALS['meta']['multi_objets']))) {
169
		lang_select($GLOBALS['visiteur_session']['lang']);
170
		if (in_array($GLOBALS['spip_lang'],
171
		explode(',', $GLOBALS['meta']['langues_multilingue']))) {
172
			$champs['lang'] = $GLOBALS['spip_lang'];
173
			if (isset($desc['field']['langue_choisie']))
174
				$champs['langue_choisie'] = 'oui';
175
		}
176
	}
177
	elseif (isset($desc['field']['lang']) AND isset($desc['field']['langue_choisie'])) {
178
		$champs['lang'] = ($lang_rub ? $lang_rub : $GLOBALS['meta']['langue_site']);
179
		$champs['langue_choisie'] = 'non';
180
	}
181
182
	if (isset($desc['field']['statut'])){
183
		if (isset($desc['statut_textes_instituer'])){
184
			$cles_statut = array_keys($desc['statut_textes_instituer']); 
185
			$champs['statut'] = reset($cles_statut);
186
		}
187
		else
188
			$champs['statut'] = 'prepa';
189
	}
190
191
192
	if ((isset($desc['date']) AND $d=$desc['date']) OR isset($desc['field'][$d='date']))
193
		$champs[$d] = date('Y-m-d H:i:s');
194
195
	if ($set)
196
		$champs = array_merge($champs, $set);
197
198
	// Envoyer aux plugins
199
	$champs = pipeline('pre_insertion',
200
		array(
201
			'args' => array(
202
				'table' => $table_sql,
203
			),
204
			'data' => $champs
205
		)
206
	);
207
208
	$id = sql_insertq($table_sql, $champs);
209
210
	if ($id){
211
		pipeline('post_insertion',
212
			array(
213
				'args' => array(
214
					'table' => $table_sql,
215
					'id_objet' => $id,
216
				),
217
				'data' => $champs
218
			)
219
		);
220
221
		// controler si le serveur n'a pas renvoye une erreur
222
		// et associer l'auteur sinon
223
		// si la table n'a pas deja un champ id_auteur
224
		// et si le form n'a pas poste un id_auteur (meme vide, ce qui sert a annuler cette auto association)
225
		if ($id > 0
226
		  AND !isset($desc['field']['id_auteur'])){
227
			$id_auteur = ((is_null(_request('id_auteur')) AND isset($GLOBALS['visiteur_session']['id_auteur']))?
228
				$GLOBALS['visiteur_session']['id_auteur']
229
				:_request('id_auteur'));
230
		  if ($id_auteur) {
231
				include_spip('action/editer_auteur');
232
				auteur_associer($id_auteur, array($objet=>$id));
233
		  }
234
		}
235
	}
236
237
	return $id;
238
}
239
240
241
/**
242
 * $c est un array ('statut', 'id_parent' = changement de rubrique)
243
 * statut et rubrique sont lies, car un admin restreint peut deplacer
244
 * un objet publie vers une rubrique qu'il n'administre pas
245
 *
246
 * @param string $objet
247
 * @param int $id
248
 * @param array $c
249
 * @param bool $calcul_rub
250
 * @return mixed|string
251
 */
252
function objet_instituer($objet, $id, $c, $calcul_rub=true) {
253
	if (include_spip('action/editer_'.$objet)
254
	  AND function_exists($instituer = $objet."_instituer"))
255
		return $instituer($id,$c,$calcul_rub);
256
257
	$table_sql = table_objet_sql($objet);
258
	$trouver_table = charger_fonction('trouver_table','base');
259
	$desc = $trouver_table($table_sql);
260
	if (!$desc OR !isset($desc['field']))
261
		return _L("Impossible d'instituer $objet : non connu en base");
262
263
	include_spip('inc/autoriser');
264
	include_spip('inc/rubriques');
265
	include_spip('inc/modifier');
266
267
	$sel = array();
268
	$sel[] = (isset($desc['field']['statut'])?"statut":"'' as statut");
269
270
	$champ_date = '';
271 View Code Duplication
	if (isset($desc['date']) AND $desc['date'])
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...
272
		$champ_date = $desc['date'];
273
	elseif (isset($desc['field']['date']))
274
		$champ_date = 'date';
275
276
	$sel[] = ($champ_date ? "$champ_date as date" : "'' as date");
277
	$sel[] = (isset($desc['field']['id_rubrique'])?'id_rubrique':"0 as id_rubrique");
278
279
	$row = sql_fetsel($sel, $table_sql, id_table_objet($objet).'='.intval($id));
280
281
	$id_rubrique = $row['id_rubrique'];
282
	$statut_ancien = $statut = $row['statut'];
283
	$date_ancienne = $date = $row['date'];
284
	$champs = array();
285
286
	$d = ($date AND isset($c[$champ_date]))?$c[$champ_date]:null;
287
	$s = (isset($desc['field']['statut']) AND isset($c['statut']))?$c['statut']:$statut;
288
289
	// cf autorisations dans inc/instituer_objet
290
	if ($s != $statut OR ($d AND $d != $date)) {
291
		if ($id_rubrique ?
292
				autoriser('publierdans', 'rubrique', $id_rubrique)
293
			:
294
				autoriser('instituer', $objet, $id, null, array('statut'=>$s))
295
			)
296
			$statut = $champs['statut'] = $s;
297 View Code Duplication
		else if ($s!='publie' AND autoriser('modifier', $objet, $id))
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...
298
			$statut = $champs['statut'] = $s;
299
		else
300
			spip_log("editer_objet $id refus " . join(' ', $c));
301
302
		// En cas de publication, fixer la date a "maintenant"
303
		// sauf si $c commande autre chose
304
		// ou si l'objet est deja date dans le futur
305
		// En cas de proposition d'un objet (mais pas depublication), idem
306
		if ($champ_date) {
307 View Code Duplication
			if ($champs['statut'] == 'publie'
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...
308
			 OR ($champs['statut'] == 'prop' AND !in_array($statut_ancien, array('publie', 'prop')))
309
			 OR $d
310
			) {
311
				if ($d OR strtotime($d=$date)>time())
312
					$champs[$champ_date] = $date = $d;
313
				else
314
					$champs[$champ_date] = $date = date('Y-m-d H:i:s');
315
			}
316
		}
317
	}
318
319
	// Verifier que la rubrique demandee existe et est differente
320
	// de la rubrique actuelle
321 View Code Duplication
	if ($id_rubrique
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...
322
	  AND $id_parent = $c['id_parent']
323
	  AND $id_parent != $id_rubrique
324
	  AND (sql_fetsel('1', "spip_rubriques", "id_rubrique=".intval($id_parent)))) {
325
		$champs['id_rubrique'] = $id_parent;
326
327
		// si l'objet etait publie
328
		// et que le demandeur n'est pas admin de la rubrique
329
		// repasser l'objet en statut 'propose'.
330
		if ($statut == 'publie'
331
		AND !autoriser('publierdans', 'rubrique', $id_rubrique))
332
			$champs['statut'] = 'prop';
333
	}
334
335
336
	// Envoyer aux plugins
337
	$champs = pipeline('pre_edition',
338
		array(
339
			'args' => array(
340
				'table' => $table_sql,
341
				'id_objet' => $id,
342
				'action'=>'instituer',
343
				'statut_ancien' => $statut_ancien,
344
				'date_ancienne' => $date_ancienne,
345
				'id_parent_ancien' => $id_rubrique,
346
			),
347
			'data' => $champs
348
		)
349
	);
350
351
	if (!count($champs)) return '';
352
353
	// Envoyer les modifs.
354
	objet_editer_heritage($objet, $id, $id_rubrique, $statut_ancien, $champs, $calcul_rub);
355
356
	// Invalider les caches
357
	include_spip('inc/invalideur');
358
	suivre_invalideur("id='$objet/$id'");
359
360
	/*
361
	if ($date) {
362
		$t = strtotime($date);
363
		$p = @$GLOBALS['meta']['date_prochain_postdate'];
364
		if ($t > time() AND (!$p OR ($t < $p))) {
365
			ecrire_meta('date_prochain_postdate', $t);
366
		}
367
	}*/
368
369
	// Pipeline
370
	pipeline('post_edition',
371
		array(
372
			'args' => array(
373
				'table' => $table_sql,
374
				'id_objet' => $id,
375
				'action'=>'instituer',
376
				'statut_ancien' => $statut_ancien,
377
				'date_ancienne' => $date_ancienne,
378
				'id_parent_ancien' => $id_rubrique,
379
			),
380
			'data' => $champs
381
		)
382
	);
383
384
	// Notifications
385 View Code Duplication
	if ($notifications = charger_fonction('notifications', 'inc')) {
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...
386
		$notifications("instituer$objet", $id,
387
			array('statut' => $statut, 'statut_ancien' => $statut_ancien, 'date'=>$date, 'date_ancienne' => $date_ancienne)
388
		);
389
	}
390
391
	return ''; // pas d'erreur
392
}
393
394
/**
395
 * fabrique la requete d'institution de l'objet, avec champs herites
396
 *
397
 * @param string $objet
398
 * @param int $id
399
 * @param int $id_rubrique
400
 * @param string $statut
401
 * @param array $champs
402
 * @param bool $cond
403
 * @return 
404
 */
405
function objet_editer_heritage($objet, $id, $id_rubrique, $statut, $champs, $cond=true) {
406
	$table_sql = table_objet_sql($objet);
407
	$trouver_table = charger_fonction('trouver_table','base');
408
	$desc = $trouver_table($table_sql);
409
410
	// Si on deplace l'objet
411
	// changer aussi son secteur et sa langue (si heritee)
412
	if (isset($champs['id_rubrique'])) {
413
414
		$row_rub = sql_fetsel("id_secteur, lang", "spip_rubriques", "id_rubrique=".sql_quote($champs['id_rubrique']));
415
		$langue = $row_rub['lang'];
416
417
		if (isset($desc['field']['id_secteur']))
418
			$champs['id_secteur'] = $row_rub['id_secteur'];
419
420
		if (isset($desc['field']['lang']) AND isset($desc['field']['langue_choisie']))
421
			if (sql_fetsel('1', $table_sql, id_table_objet($objet)."=".intval($id)." AND langue_choisie<>'oui' AND lang<>" . sql_quote($langue))) {
422
				$champs['lang'] = $langue;
423
			}
424
	}
425
426
	if (!$champs) return;
0 ignored issues
show
Bug Best Practice introduced by
The expression $champs 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...
427
	sql_updateq($table_sql, $champs, id_table_objet($objet).'='.intval($id));
428
429
	// Changer le statut des rubriques concernees
430
	if ($cond) {
431
		include_spip('inc/rubriques');
432
		//$postdate = ($GLOBALS['meta']["post_dates"] == "non" AND isset($champs['date']) AND (strtotime($champs['date']) < time()))?$champs['date']:false;
433
		$postdate = false;
434
		calculer_rubriques_if($id_rubrique, $champs, $statut, $postdate);
435
	}
436
}
437
438
?>
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...
439