source: spip-zone/_plugins_/pages/trunk/pages_pipelines.php @ 84174

Last change on this file since 84174 was 84174, checked in by eric@…, 6 years ago

Evolutions du plugin dont certaines peuvent être considérées comme des corrections:

  • la page pages_tous devient pages ce qui est plus cohérent avec les autres objets.
  • ajout et utilisation des autorisations classiques pour un obet 'page' : creer, modifier et voir. Ces autorisations et les suivantes sont par défaut positionnées à admin complet. Une fonction surchargeable permet de toutes les modifier d'un coup.
  • ajout de l'autorisation pages_voir pour afficher la liste des pages uniques (exec=pages)
  • ajout des autorisations d'affichage des menus pages et pagecreer. Ces autorisations font appel respectivement à pages_voir et page_creer.
  • utilisation du pipeline pre_boucle sur la boucle ARTICLES afin de clairement séparer les listes de pages uniques et celles d'articles éditoriaux. Par exemple, les listes d'articles de la page d'acceuil et de la page articles sont exemptes de pages uniques.

Tout n'est pas parfait en particulier pour les autorisations car il est toujours possible d'accéder à une page unique en saisissant l'url même si on est pas autorisé. C'est en effet l'autorisation de l'article qui se déroule. Pour combler ce manque il faudrait surcharger l'autorisation de l'article en testant l'id de rubrique mais cela produirait des effets de bords avec d'autres plugins comme accès restreint.
En fait, spécialiser un objet pour en créer un autre n'est pas une opération prévue dans l'api SPIP actuelle.

Autre remarque : lors de la désinstallation du plugin on supprime la colonne 'page' de la table spip_articles. On se retrouve avec des articles possédant un id_rubrique à -1. Est-ce bien de laisser cela ainsi ? Ne faudrait-il pas soit les supprimer soit les transférer dans une rubrique existante ?

File size: 13.0 KB
Line 
1<?php
2/**
3 * Déclaration des pipelines utilisés par le plugin
4 *
5 * @plugin     Pages
6 * @copyright  2013
7 * @author     RastaPopoulos
8 * @licence    GNU/GPL
9 * @package    SPIP\Pages\Pipelines
10 * @link       http://contrib.spip.net/Pages-uniques
11 */
12
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15// Change l'entête du formulaire des articles pour montrer que c'est une page
16function pages_affiche_milieu_ajouter_page($flux){
17
18        if ($flux['args']['exec'] == 'article_edit'){
19                include_spip('base/abstract_sql');
20                if (
21                        _request('modele') == 'page'
22                        or
23                        (
24                                ($id_article = $flux['args']['id_article']) > 0
25                                and
26                                (sql_getfetsel('page', 'spip_articles', 'id_article='.intval($id_article)))
27                        )
28                )
29                {
30                       
31                        //On force l'id parent à -1
32                        //Par principe une page nouvelle ou existante est dans la rubrique parent -1
33                        $cherche = "/(<input[^>]*name=('|\")id_parent[^>]*>)/is";
34                        if (!preg_match($cherche,$flux['data'])) {
35                                $cherche = "/(<input[^>]*name=('|\")id_rubrique[^>]*>)/is";
36                                $remplace = "$1<input type=\"hidden\" name=\"id_parent\" value=\"-1\" />\n";
37                                $flux['data'] = preg_replace($cherche, $remplace, $flux['data']);
38                        }
39                       
40                        // On cherche et remplace l'entete de la page : "modifier la page"
41                        $cherche = "/(<div[^>]*class=('|\")entete-formulaire.*?<\/span>).*?(<h1>.*?<\/h1>.*?<\/div>)/is";
42                        $surtitre = _T('pages:modifier_page');
43                        $remplace = "$1$surtitre$3";
44                        $flux['data'] = preg_replace($cherche, $remplace, $flux['data']);
45                       
46                        // Si c'est une nouvelle page, on remplace le lien de retour dans l'entete
47                        if (_request('new') == 'oui'){
48                                $cherche = "/(<span[^>]*class=(?:'|\")icone[^'\"]*retour[^'\"]*(?:'|\")>"
49                                                        . "<a[^>]*href=(?:'|\"))[^'\"]*('|\")/is";
50                                $retour = generer_url_ecrire("pages_tous");
51                                $remplace = "$1$retour$2";
52                                $flux['data'] = preg_replace($cherche, $remplace, $flux['data']);
53                        }
54                }
55        }
56
57        return $flux;
58}
59
60
61/**
62 * Saisie de l'identifiant de la page sur la fiche d'une page
63 *
64 * @param array $flux
65 *              Le contexte du pipeline
66 * @return array $flux
67 *              Le contexte du pipeline modifié
68 */
69function pages_affiche_milieu_identifiant($flux){
70        $texte = "";
71        $e = trouver_objet_exec($flux['args']['exec']);
72
73        // Si on est sur la fiche d'un article...
74        if (!$e['edition'] and $e['type']=='article' ) {
75                include_spip('base/abstract_sql');
76                $id_article = isset($flux['args'][$e['id_table_objet']]) ? $flux['args'][$e['id_table_objet']] : false;
77                // ... et s'il s'agit d'une page
78                if (
79                        _request('modele') == 'page'
80                        or
81                        (
82                                intval($id_article) > 0
83                                and
84                                (sql_getfetsel('page', 'spip_articles', 'id_article='.intval($id_article)))
85                        )
86                ) {
87                        $texte .= recuperer_fond('prive/objets/editer/identifiant_page',
88                                array('id_article' => $id_article),
89                                array('ajax'=>true)
90                        );
91                }
92        }
93
94        if ($texte) {
95                if ($p=strpos($flux['data'],"<!--affiche_milieu-->"))
96                        $flux['data'] = substr_replace($flux['data'],$texte,$p,0);
97                else
98                        $flux['data'] .= $texte;
99        }
100
101        return $flux;
102}
103
104
105// Vérifier que la page n'est pas vide
106function pages_formulaire_charger($flux){
107
108        // Si on est dans l'édition d'un article
109        if (is_array($flux) and $flux['args']['form'] == 'editer_article'){
110       
111                // Si on est dans un article de modele page
112                if (_request('modele') == 'page' or ($flux['data']['page'] and _request('modele') != 'article')){
113                        $flux['data']['modele'] = 'page';
114                        $flux['data']['champ_page'] = $flux['data']['page'];
115                }
116                unset($flux['data']['page']);
117        }
118
119        return $flux;
120}
121
122
123/**
124 * Vérifications de l'identifiant d'une page
125 *
126 * @param array $flux
127 *              Le contexte du pipeline
128 * @return array $flux
129 *              Le contexte du pipeline modifié
130 */
131function pages_formulaire_verifier($flux){
132
133        // Si on est dans l'édition d'un article/page ou dans le formulaire d'édition d'un identifiant page
134        if ( 
135                is_array($flux)
136                and (
137                        ( $flux['args']['form'] == 'editer_article' and _request('modele') == 'page' )
138                        or $flux['args']['form'] == 'editer_identifiant_page'
139                )
140        ){
141                $erreur = '';
142                $page = _request('champ_page');
143                $id_page = $flux['args']['args'][0];
144
145                // champ vide
146                if (!$page)
147                        $erreur .= _T('info_obligatoire');
148                // nombre de charactères : 40 max
149                elseif (strlen($page) > 255)
150                         $erreur = _T('pages:erreur_champ_page_taille');
151                // format : charactères alphanumériques en minuscules ou "_"
152                elseif (!preg_match('/^[a-z0-9_]+$/', $page))
153                         $erreur = _T('pages:erreur_champ_page_format');
154                // doublon
155                elseif (sql_countsel(table_objet_sql('article'), "page=".sql_quote($page) . " AND id_article!=".intval($id_page)))
156                        $erreur = _T('pages:erreur_champ_page_doublon');
157
158                if ($erreur)
159                        $flux['data']['champ_page'] .= $erreur;
160        }
161        return $flux;
162
163}
164
165
166/**
167 * Insertion dans le pipeline editer_contenu_objet (SPIP)
168 *
169 * Sur les articles considérés comme pages uniques, on remplace l'élément de choix de rubriques par :
170 * -* un input hidden id_rubrique et id_parent avec pour valeur -1
171 * -* un input hidden modele avec comme valeur "page"
172 * -* un champ d'édition de l'identifiant de la page unique
173 *
174 * @param array $flux
175 *              Le contexte du pipeline
176 * @return array $flux
177 *              Le contexte du pipeline modifié
178 */
179function pages_editer_contenu_objet($flux){
180        $args = $flux['args'];
181        if ($args['type'] == 'article' && isset($args['contexte']['modele']) && $args['contexte']['modele'] == 'page'){
182                $erreurs = $args['contexte']['erreurs'];
183                // On cherche et remplace l'édition de la rubrique
184                $cherche = "/<li[^>]*class=('|\")editer editer_parent.*?<\/li>/is";
185                $remplace = '<li class="editer editer_page obligatoire'.($erreurs['champ_page'] ? ' erreur' : '').'">';
186                $remplace .= '<input type="hidden" name="id_parent" value="-1" />';
187                $remplace .= '<input type="hidden" name="id_rubrique" value="-1" />';
188                $remplace .= '<input type="hidden" name="modele" value="page" />';
189                $remplace .= '<label for="id_page">'._T('pages:titre_page').'</label>';
190                if ($erreurs['champ_page'])
191                        $remplace .= '<span class="erreur_message">'.$erreurs['champ_page'].'</span>';
192                $value = $args['contexte']['champ_page'] ? $args['contexte']['champ_page'] : $args['contexte']['page'];
193                $remplace .= '<input type="text" class="text" name="champ_page" id="id_page" value="'.$value.'" />';
194                $remplace .= '</li>';
195                if (preg_match($cherche,$flux['data'])) {
196                        $flux['data'] = preg_replace($cherche, $remplace, $flux['data'],1);
197                        $flux['data'] = preg_replace($cherche, '', $flux['data']);
198                } else {
199                        $cherche = "/(<li[^>]*class=('|\")editer editer_soustitre.*?<\/li>)/is";
200                        if (preg_match($cherche,$flux['data'])) {
201                                $flux['data'] = preg_replace($cherche,'$1'.$remplace, $flux['data']);
202                        } else {
203                                $cherche = "/(<li[^>]*class=('|\")editer editer_titre.*?<\/li>)/is";
204                                $flux['data'] = preg_replace($cherche,'$1'.$remplace, $flux['data']);
205                        }
206                }
207        }
208        return $flux;
209}
210
211/**
212 * Insertion dans le pipeline pre_edition (SPIP)
213 *
214 * Si on édite un article :
215 * - Si on récupère un champ "champ_page" dans les _request() et qu'il est différent de "article",
216 * on transforme l'article en page unique, id_rubrique devient -1
217 * - Si on ne récupère pas de champ_page et que id_parent est supérieur à 0, on le passe en article et on vide
218 * son champ page pour pouvoir réaliser le processus inverse dans le futur
219 *
220 * @param array $flux Le contexte du pipeline
221 * @return array $flux Le contexte modifié
222 */
223function pages_pre_edition_ajouter_page($flux){
224        if (is_array($flux) and isset($flux['args']['type']) && $flux['args']['type'] == 'article'){
225                if ((($page = _request('champ_page')) != '') AND ($page != 'article')){
226                        /**
227                         * On ajoute le "champ_page" du formulaire qui deviendra "page" dans la table
228                         * On force l'id_rubrique à -1
229                         */
230                        $flux['data']['page'] = $page;
231                        $flux['data']['id_rubrique'] = '-1';
232                        $flux['data']['id_secteur'] = '0';
233                }
234                /**
235                 * si l'id_parent est supérieur à 0 on que l'on ne récupère pas de champ_page,
236                 * on pense à vider le champ "page", pour pouvoir revenir après coup en page
237                 */
238                if (!_request('champ_page') && (_request('id_parent') > 0)){
239                        $flux['data']['page'] = '';
240                }
241        }
242        return $flux;
243}
244
245/**
246 * Insertion dans le pipeline boite_infos (SPIP)
247 *
248 * Ajouter un lien pour transformer un article éditorial en page ou inversement
249 *
250 * @param array $flux
251 *              Le contexte du pipeline
252 * @return array $flux
253 *              Le contexte modifié
254 */
255function pages_boite_infos($flux){
256        if ($flux['args']['type'] == 'article') {
257                include_spip('inc/presentation');
258                if (sql_getfetsel('page', 'spip_articles', 'id_article='. intval($flux['args']['id'])) == '') {
259                        if (autoriser('creer', 'page', $flux['args']['id']))
260                                $flux['data'] .= icone_horizontale(_T('pages:convertir_page'), parametre_url(parametre_url(generer_url_ecrire('article_edit'), 'id_article', $flux['args']['id']), 'modele', 'page'), 'page', $fonction="", $dummy="", $javascript="");
261                }
262                else {
263                        if (autoriser('modifier', 'page', $flux['args']['id']))
264                                $flux['data'] .= icone_horizontale(_T('pages:convertir_article'), parametre_url(parametre_url(generer_url_ecrire('article_edit'), 'id_article', $flux['args']['id']), 'modele', 'article'), 'article', $fonction="", $dummy="", $javascript="");
265                }
266        }
267        return $flux;
268}
269
270
271/**
272 * Insertion dans le pipeline affiche_hierarchie (SPIP)
273 * Pour les pages, faire pointer la racine vers la liste des pages au lieux des rubriques
274 * Pour savoir si on se trouve sur une page, on vérifie que le champ "page" existe, faute de mieux 
275 *
276 * @param array $flux
277 *              Le contexte du pipeline
278 * @return array $flux
279 *              Le contexte modifié
280 */
281function pages_affiche_hierarchie($flux){
282
283        $objet = $flux['args']['objet'];
284        $id_article = $flux['args']['id_objet'];
285        if (
286                $objet == 'article'
287                and sql_getfetsel('page', 'spip_articles', 'id_article='.intval($id_article))
288        ){
289                $cherche = "<a href=\"". generer_url_ecrire('rubriques') . "\">" . _T('info_racine_site') . "</a>";
290                $remplace = "<a href=\"". generer_url_ecrire('pages') . "\">" . _T('pages:pages_uniques') . "</a>";
291                $flux['data'] = str_replace($cherche,$remplace,$flux['data']);
292        }
293        return $flux;
294}
295
296
297/**
298 * Insertion dans le pipeline pre_boucle (SPIP)
299 * Pour les listes d'articles purement éditoriaux, il faut exclure les pages uniques afin d'éviter la confusion des genres
300 * ainsi que les liens vers des pages parfois inaccessibles en fonction de l'autorisation de l'auteur.
301 *
302 * @param array $flux
303 *              Le contexte du pipeline
304 * @return array $flux
305 *              Le contexte modifié
306 */
307function pages_pre_boucle($boucle){
308
309        // On ne s'intéresse qu'à la boucle ARTICLES
310        if ($boucle->type_requete == 'articles') {
311                // On n'insère le filtre {id_rubriques>0} pour exclure les pages uniques que si aucune des conditions
312                // suivantes n'est vérifiée:
313                // - pas de critère page
314                // - pas de critère explicite {id_rubrique=-1} ou {id_rubrique<0}
315                // - pas de critère {id_rubrique?} pour lequel l'environnement renvoie -1 pour l'id de la rubrique
316                $boucle_articles = true;
317                $critere_page = false;
318
319                // On cherche les critères id_rubrique, id_article ou page
320                foreach($boucle->criteres as $_critere){
321                        if (($_critere->op == 'page') // {page} ou {page?}
322                        OR ($_critere->param[0][0]->texte == 'page')) { // {page=x}
323                                // On considère qu'on cherche toujours des pages uniques donc on force le filtre id_rubrique=-1
324                                $boucle_articles = false;
325                                $critere_page = true;
326                                break;
327                        }
328                        elseif (($_critere->op == 'id_article') // {id_article} ou {id_article?}
329                                OR ($_critere->param[0][0]->texte == 'id_article')) { // {id_article=x}
330                                // On pointe sur un article précis, il est donc inutile de rajouter un test sur la rubrique
331                                // Pour le critère {id_article?} on considère que si l'on veut sélectionner des pages uniques
332                                // ou des articles éditoriaux on doit préciser le critère {id_rubrique}
333                                $boucle_articles = false;
334                        }
335                        elseif ((($_critere->param[0][0]->texte == 'id_rubrique') // {id_rubrique=-1}
336                                        AND ($_critere->op == '=')
337                                        AND ($_critere->param[1][0]->texte == '-1'))
338                                OR (($_critere->param[0][0]->texte == 'id_rubrique') // {id_rubrique<0}
339                                        AND ($_critere->op == '<')
340                                        AND ($_critere->param[1][0]->texte == '0'))) {
341                                // On cherche explicitement des pages uniques
342                                $boucle_articles = false;
343                                break;
344                        }
345                        elseif (($_critere->op == 'id_rubrique')) {
346                                // On connait pas à ce stade la valeur de id_rubrique qui est passé dans le env.
347                                // Aussi, on créer une condition where qui se compile différemment suivant la valeur de l'id_rubrique.
348                                // En fait, il suffit de tester si l'id_rubrique est null. Dans ce cas il faut bien rajouter id_rubrique>0
349                                // pour éliminer les pages uniques.
350                                $boucle_articles = false;
351                                $env_id = "\$Pile[0]['id_rubrique']";
352                                $boucle->where[] =
353                                        array("'?'", "(is_array($env_id)?count($env_id):strlen($env_id))", "''", "'articles.id_rubrique>0'");
354                                break;
355                        }
356                }
357
358                // Si on est en présence d'une boucle article purement éditoriale, on ajoute le filtre id_rubrique>0
359                if ($boucle_articles) {
360                        $boucle->where[] = array("'>'", "'articles.id_rubrique'", "'\"0\"'");
361                }
362
363                // Si on est en présence d'un critère {page} quelconque, on force le filtre id_rubrique=-1
364                if ($critere_page) {
365                        $boucle->where[] = array("'='", "'articles.id_rubrique'", "'\"-1\"'");
366                }
367        }
368
369        return $boucle;
370}
371
372?>
Note: See TracBrowser for help on using the repository browser.