source: spip-zone/_plugins_/etiquettes/trunk/inc/tag-machine.php

Last change on this file was 106679, checked in by marcimat@…, 19 months ago

Compatible 3.2 + Compatible PHP 7 + Notices PHP en moins (ce plugin semble un peu vieux !)

  • Property svn:executable set to *
File size: 14.3 KB
Line 
1<?php
2/**
3 * Plugin  : Étiquettes
4 * Auteur  : RastaPopoulos
5 * Licence : GPL
6 *
7 * Documentation : https://contrib.spip.net/Plugin-Etiquettes
8 *
9 */
10
11if (!defined("_ECRIRE_INC_VERSION")) return;
12
13//        inc_tag-machine.php
14//
15//    Librairies pour ajouter des mots clefs sur les objets spip à partir
16//    d'un simple champ texte.
17//    Distribué sans garantie sous licence GPL.
18//
19//    Authors  BoOz, Pierre ANDREWS, RastaPopoulos (réécriture nouvelle API)
20//
21//    This program is free software; you can redistribute it and/or modify
22//    it under the terms of the GNU General Public License as published by
23//    the Free Software Foundation; either version 2 of the License, or any later version.
24//
25//    This program is distributed in the hope that it will be useful,
26//    but WITHOUT ANY WARRANTY; without even the implied warranty of
27//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28//    GNU General Public License for more details.
29//
30//    You should have received a copy of the GNU General Public License
31//    along with this program; if not, write to the Free Software
32//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
33
34
35function entableau($tag) {
36        return array('groupe' => $tag->type, 'tag' => $tag->titre);
37}
38
39
40/*
41        Ajoute les mots clefs dans la liste passée en paramètre au bon objet.
42        Si le mot clef n'existe pas, on le crée
43        Si le groupe n'existe pas, on le crée
44       
45        Paramètres :
46        $tags: tableau de tag ('groupe' => groupe, 'tag' => tag)
47        $id: id de l'objet sur lequel ajouter les mots clefs
48        [$groupe_defaut]: groupe par défaut pour les mots qui n'ont pas de groupe dans la chaîne
49        [$table_objet]: type d'objet sur lequel ajouter les mots clefs (une table: spip_mots_$table_objet doit exister)
50        [$id_table_objet]: colonne de la table de cet objet qui contient les ids
51       
52        Retourne:
53        rien
54*/
55function ajouter_liste_mots($tags,
56                                                        $id,
57                                                        $groupe_defaut='',
58                                                        $table_objet='documents',
59                                                        $id_table_objet='id_document',
60                                                        $clear = false) {
61        $tags = new ListeTags($tags,$groupe_defaut);
62        $tags->ajouter($id, $table_objet, $id_table_objet,$clear);
63}
64function ajouter_mots($liste_tags,
65                                          $id,
66                                          $groupe_defaut='',
67                                          $table_objet='documents',
68                                          $id_table_objet='id_document',
69                                          $clear = false) {
70        $tags = new ListeTags($liste_tags,$groupe_defaut);
71        $tags->ajouter($id, $table_objet, $id_table_objet,$clear);
72}
73
74
75/**
76        Enleve les mots clefs passé en paramètre
77       
78        Paramètres :
79        $tags: tableau de tag ('groupe' => groupe, 'tag' => tag)
80        $id: id de l'objet sur lequel supprimer les mots clefs
81        [groupe_defaut]: groupe par défaut pour les mots qui n'ont pas de groupe dans la chaîne
82        [$table_objet]: type d'objet sur lequel supprimer les mots clefs (une table: spip_mots_$table_objet doit exister)
83        [$id_table_objet]: colonne de la table de cet objet qui contient les ids
84       
85        Retourne:
86        rien
87*/
88function retirer_liste_mots($tags,
89                                                        $id,
90                                                        $groupe_defaut='',
91                                                        $table_objet='documents',
92                                                        $id_table_objet='id_document') {
93        $tags = new ListeTags($tags,$groupe_defaut);
94        $tags->retirer($id, $table_objet, $id_table_objet);
95}
96function retirer_mots($liste_tags,
97                                          $id,
98                                          $groupe_defaut='',
99                                          $table_objet='documents',
100                                          $id_table_objet='id_document') {
101        $tags = new ListeTags($liste_tags,$groupe_defaut);
102        $tags->retirer($id, $table_objet, $id_table_objet);
103}
104
105
106function parser_liste($liste_tags) {
107        $tags = new ListeTags($liste_tags,'');
108        return array_map('entableau',$tags->getTags());
109}
110
111
112// Objet Tag
113class Tag {
114       
115        // Propriétés
116        var $titre;
117        var $type;
118        var $id_mot;
119        var $id_groupe;
120       
121        // Constructeur
122        function __construct($titre, $type='', $id_groupe='') {
123                $this->titre = $titre;
124                $this->id_groupe = $id_groupe;
125                $this->type = $type;
126        }
127       
128        // Accesseurs
129        function getID() {return $this->id_mot;} // public
130        function getIDGroupe() {return $this->id_groupe;} // public
131        function getTitre() {return $this->titre;} // public
132        function getType() {return $this->type;} // public
133        function getTitreEchappe() { // public
134                return (strpos($this->titre,' ') || strpos($this->titre,':') || strpos($this->titre,',')) ? '"'.$this->titre.'"' : $this->titre;
135        }
136        function getTypeEchappe() { // public
137                return (strpos($this->type,' ') || strpos($this->type,':') || strpos($this->type,',')) ? '"'.$this->type.'"' : $this->type;
138        }
139       
140        // Renvoie une chaîne 'groupe:titre'
141        function echapper() { // public
142                $cgroupe = $this->type;
143                $ctag = $this->titre;
144               
145                $cgroupe = (strpos($cgroupe,' ') || strpos($cgroupe,':') || strpos($cgroupe,','))?'"'.$cgroupe.'"':$cgroupe;
146                $ctag = (strpos($ctag,' ') || strpos($ctag,':') || strpos($ctag,','))?'"'.$ctag.'"':$ctag;
147               
148                return (($cgroupe)? ($cgroupe.':'):'').$ctag;
149        }
150       
151       
152        /* Fonctions de vérification */
153        /* ------------------------- */
154       
155       
156        // Vérifie le groupe
157        // Renvoie un tableau avec les infos : (id_groupe,unseul,titre_du_groupe)
158        function verifier_groupe() { // private
159               
160                include_spip ('base/abstract_sql');
161               
162                // On va garder en mémoire les groupes vérifiés
163                static $groupes_verifie;
164                static $groupes_verifie_id;
165               
166                if($this->type) {
167                       
168                        if(!isset($groupes_verifie[$this->type])) {
169                                $select_groupe = sql_select(
170                                        array('id_groupe','unseul'),
171                                        'spip_groupes_mots',
172                                        array(array('=', 'titre', _q($this->type)))
173                                );
174                               
175                                if($groupe_ligne = sql_fetch($select_groupe)) {
176                                        $id = $groupe_ligne['id_groupe']; 
177                                        $unseul = $groupe_ligne['unseul'];
178                                        $groupes_verifie[$this->type] = array($id,$unseul,$this->type);
179                                }
180                                if ($select_groupe) sql_free($select_groupe);
181                        }
182                        return $groupes_verifie[$this->type];
183                       
184                }
185                else if($this->id_groupe) {
186                       
187                        if(!isset($groupes_verifie_id[$this->id_groupe])) {
188                               
189                                $select_groupe = sql_select(
190                                        array('titre','unseul'), 
191                                        'spip_groupes_mots', 
192                                        array(array('=', 'id_groupe', $this->id_groupe))
193                                );
194                               
195                                if($groupe_ligne = sql_fetch($select_groupe)) {
196                                        $type = $groupe_ligne['titre']; 
197                                        $unseul = $groupe_ligne['unseul'];
198                                        $groupes_verifie_id[$this->id_groupe] = array($this->id_groupe,$unseul,$type);
199                                }
200                                if ($select_groupe) sql_free($select_groupe);
201                        }
202                        return $groupes_verifie_id[$this->id_groupe];
203                       
204                }
205               
206                // si pas de groupe
207                return array(0,'');
208               
209        }
210       
211        // Vérifie si on peut bien ajouter un mot de ce groupe
212        // Crée le groupe du mot s'il n'existe pas
213        // Retourne l'id_groupe si c'est ok, false sinon
214        function verifier($table_objet) { // private
215       
216                include_spip('base/abstract_sql');
217                $type = objet_type($table_objet);
218
219                list($id_groupe,$unseul,$titre) = $this->verifier_groupe();
220               
221                if($id_groupe > 0) {
222                       
223                        // si le groupe n'accepte qu'un mot actif
224                        if ($unseul == 'oui') {
225                                // on verifie qu'il y a pas déjà un mot associé
226                                $celcount = sql_select(
227                                        'count(id_mot) as tot', 
228                                        array(
229                                                'spip_mots as mots',
230                                                "spip_mots_liens as liens"
231                                        ), 
232                                        array(
233                                                "mots.id_groupe = ".intval($id_groupe),
234                                                "mots.id_mot = liens.id_mot",
235                                                "liens.objet = ".sql_quote($type)
236                                        ),
237                                        'mots.id_groupe'
238                                );
239                                // mot déjà utilisé, on arrête
240                                if($numrow = sql_fetch($celcount)
241                                        AND $numrow['tot'] > 0)
242                                        return false;
243                                if ($celcount) sql_free($celcount);
244                        }
245                       
246                }
247                else if($this->type) {
248                       
249                        spip_log("création du groupe ".$this->type);
250                       
251                        // on rajoute une option pour le type d'objet dans spip_groupes_mots
252                        if(!lire_meta("tag-machine:colonne_.$table_objet")) {
253                                ecrire_meta("tag-machine:colonne_.$table_objet",1);
254                        }
255                       
256                        $id_groupe = sql_insertq(
257                                "spip_groupes_mots",
258                                array(
259                                        'titre' => $this->type,
260                                        'tables_liees' => $table_objet,
261                                        'minirezo' => 'oui'
262                                )
263                        );
264                       
265                }
266                return $id_groupe;
267        }
268       
269       
270        /* Fonctions de modification */
271        /* ------------------------- */
272       
273       
274        // Teste si le mot existe sinon crée le mot
275        // Renvoie l'id_mot
276        function creer($table_objet) { // private
277               
278                include_spip ('base/abstract_sql');
279               
280                if(!$this->id_mot && ($this->id_groupe = $this->verifier($table_objet)) > 0) {
281                       
282                        $where = array(array('=', 'titre', _q($this->titre)));
283                       
284                        if($this->type)
285                                $where[] = array('=', 'type', _q($this->type));
286                        else if($this->id_groupe)
287                                $where[] = array('=', 'id_groupe', $this->id_groupe);
288                       
289                        $result = sql_select('id_mot', 'spip_mots', $where);
290                       
291                        if ($row = sql_fetch($result))
292                                $this->id_mot = $row['id_mot'];
293                        else if($this->id_groupe) {
294                                spip_log("Creer le mot $this->type:$this->titre ($this->id_mot)");
295                               
296                                $this->id_mot = sql_insertq(
297                                        'spip_mots',
298                                        array(
299                                                'id_groupe' => $this->id_groupe,
300                                                'type' => $this->type,
301                                                'titre' => $this->titre
302                                        )
303                                );
304                        }
305                        if ($result) sql_free($result); 
306                         
307                }
308                return $this->id_mot;
309               
310        }
311       
312        // Ajoute le mot à un objet quelconque
313        // Sauf s'il est déjà associé
314        function ajouter($id, $table_objet, $id_table_objet) { // public
315               
316                include_spip ('base/abstract_sql');
317                $type = objet_type($table_objet);
318
319                if($id) {
320                        // on vérifie que le mot est bien créé
321                        if(!$this->id_mot) {
322                                $this->creer($table_objet);
323                        }
324
325                        include_spip('action/editer_liens');
326                        if (!count(objet_trouver_liens(array('mot'=>$this->id_mot),array($type=>$id))))
327                                objet_associer(array('mot'=>$this->id_mot),array($type=>$id));
328                }
329                else spip_log("Tag-machine : id_objet non défini", _LOG_ERREUR);
330               
331        }
332       
333        // Retire le mot d'un objet quelconque
334        function retirer($id, $table_objet, $id_table_objet) { // public
335               
336                $type = objet_type($table_objet);
337                include_spip('action/editer_liens');
338                objet_dissocier(array('mot'=>$this->id_mot),array($type=>$id));
339        }
340       
341}
342
343
344// Objet composé d'une liste d'objet Tag
345class ListeTags {
346       
347        // Propriétés
348        var $tags = array(); // private, la liste des mots
349        var $groupe_defaut; // le groupe par défaut si les mots n'ont pas la forme groupe:titre
350        var $id_groupe;
351        var $id_table_objet; // clé primaire de l'objet auquel on veut lier la liste
352       
353        // Constructeur
354        function __construct($liste_tags,       $groupe_defaut='', $id_groupe='') { // public
355               
356                if(!$groupe_defaut && !$id_groupe)
357                        $groupe_defaut = $this->creer_groupe_defaut();
358               
359                $this->groupe_defaut = $groupe_defaut;
360                $this->id_groupe = $id_groupe;
361               
362                // si la liste est une chaîne, il faut extraire
363                if(!is_array($liste_tags))
364                        $this->tags = $this->parser_liste($liste_tags);
365                else
366                        $this->tags = $liste_tags;
367               
368        }
369       
370        // Accesseurs
371        function getTags() {return $this->tags;} // public
372       
373        // Retourne les id_mot des mots reconnus sans les créer
374        // (ne retourne que ce qui existe déjà dans la base)
375        function getTagsIDs() {
376               
377                //?? Aller chercher les tags dans la boite
378                //?? pour faire plus generique : se baser sur id_$objet et/ou url_propre
379                //?? car " dans l'url arrive ici sous la forme &quot; (#ENV{tags} et non #ENV*{tags})
380               
381                include_spip ('base/abstract_sql');
382                $ids_mot = array();
383               
384                foreach ($this->tags as $mot) {
385                        if (strlen($mot->titre)) {
386                                $where = array(array('=', 'titre', _q($mot->titre)));
387                               
388                                if(strlen($mot->type))
389                                        $where[] = array('=', 'type', _q($mot->type));
390                               
391                                $results = sql_select('id_mot', 'spip_mots', $where); //+ url_propre ? id_objet ?
392                               
393                                list($id) = sql_fetch($results,SPIP_NUM);
394                                if ($id) $ids_mot[] = $id;
395                                if ($results) sql_free($results);
396                        }
397                }
398                return $ids_mot;
399               
400        }
401       
402        // Retourne un tableau de chaînes groupe:titre pour chaque mot
403        function toStringArray() {
404               
405                $retour = array();
406                foreach($this->tags as $tag) {
407                        $retour[] = $tag->echapper();
408                }
409                return $retour;
410               
411        }
412       
413       
414        /* Fonctions de modification */
415        /* ------------------------- */
416       
417       
418        // Ajouter tous les mots de la liste à un objet quelconque, et supprimer les anciens si ya l'option clear
419        function ajouter($id, $table_objet='documents', $id_table_objet='id_document', $clear=false) { // public
420               
421                include_spip ('base/abstract_sql');
422               
423                if($id) {
424                       
425                        // si il y a l'option clear, on efface les anciennes liaisons avant
426                        if ($clear) {
427                                $mots_a_effacer = sql_allfetsel(
428                                        'id_mot',
429                                        'spip_mots as mots',
430                                        "mots.type = "._q($this->groupe_defaut)." OR mots.id_groupe = "._q($this->id_groupe)
431                                );
432
433                                $mots_a_effacer = array_map('reset',$mots_a_effacer);
434
435                                spip_log("Enleve les mots: (".join(',',$mots_a_effacer).") à (".$id_table_objet.", ".intval($id).")");
436                                include_spip('action/editer_liens');
437                                objet_dissocier(array('mot'=>$mots_a_effacer),array($table_objet=>$id));
438
439                        }
440                       
441                        // ensuite on ajoute chaque mot
442                        foreach($this->tags as $mot) {
443                                if (trim($mot->titre) != "")
444                                $mot->ajouter($id,$table_objet,$id_table_objet);
445                        }
446                       
447                }
448               
449        }
450       
451        // Retirer les mots de la liste d'un objet quelconque
452        function retirer($id, $table_objet='documents', $id_table_objet='id_document') {
453               
454                include_spip ('base/abstract_sql');
455               
456                if($id) {
457                        foreach($this->tags as $mot) {
458                                $mot->retirer($id,$table_objet,$id_table_objet);
459                        }
460                }
461               
462        }
463       
464       
465        /* Fonctions statiques */
466        /* ------------------- */
467       
468        // Prend un chaîne et fabrique un tableau d'objets Tag
469        function parser_liste($liste_tags) { // private static
470               
471                $liste_tags = trim($liste_tags);
472               
473                // supprimer les tab (notre separateur final)
474                $liste_tags = strtr($liste_tags, "\t", " ");
475               
476                // doubler les caracteres qui peuvent faire office de separateur
477                $liste_tags = ','.str_replace(',', ',,', $liste_tags).',';
478               
479                // trouver les tags et les separer par \t
480                $liste_tags = preg_replace('/\s*,\s*("?)(.*?)\\1\s*,\s*/', "\t\\2", $liste_tags);
481               
482                // remettre les caracteres doubles en simple
483                $liste_tags = str_replace(',,', ',', $liste_tags);
484               
485                // exploser selon les tab
486                $tags = explode("\t", substr($liste_tags,1));
487               
488                // recuperer les groupes sous la forme  <groupe:mot>
489                foreach ($tags as $i => $tag) {
490                        $tag = str_replace('"', '', $tag);
491                        preg_match('/((.*):)?(.*)/', $tag, $regs);
492                        $groupe = $regs[2];
493                        if(!$groupe)
494                                $groupe = $this->groupe_defaut;
495                        $tags[$i] = new Tag($regs[3], $groupe, $this->id_groupe);
496                }
497               
498                return $tags;
499               
500        }
501       
502        function containsSeparateur($char) {
503                return (strpos($char,' ') || strpos($char,':') || strpos($char,','));
504        }
505       
506        // Crée le groupe de mots "tags"
507        function creer_groupe_defaut() {
508               
509                include_spip('base/abstract_sql');
510               
511                $s = sql_select(
512                        array('id_groupe', 'titre'),
513                        'spip_groupes_mots',
514                        array(array('=', 'titre', 'tags'))
515                );
516               
517                if ($t=sql_fetch($s))
518                        return $this->id_groupe = $t['id_groupe'];
519                else {
520                        return $this->id_groupe =  sql_insertq(
521                                'spip_groupes_mots',
522                                array(
523                                        'titre' => 'tags'
524                                )
525                        );
526                }
527               
528        }
529       
530}
531
532?>
Note: See TracBrowser for help on using the repository browser.