root/_plugins_/_test_/etiquettes/inc/tag-machine.php

Revision 20112, 14.4 kB (checked in by vincent@…, 7 months ago)

ajout de la balise #CHAMP_ETIQUETTES et du mode "liste"

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