source: spip-zone/_plugins_/csv2auteurs/trunk/formulaires/csv2auteurs_importation.php @ 81148

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

ne pas oublier de supprimer les auteurs sans articles à la poubelle

  • Property svn:executable set to *
File size: 20.9 KB
Line 
1<?php
2if (!defined('_ECRIRE_INC_VERSION')) return;
3
4function formulaires_csv2auteurs_importation_charger_dist(){
5    $annee=date("Y");
6    $valeurs = array(
7        "fichier_csv"                => "",
8        "maj_utilisateur"            => "",
9        "type_maj"                   => "ajouter",
10        "abs_redac"                  => "",
11        "abs_admin"                  => "",
12        "abs_poubelle"               => "supprimer",
13        "abs_visiteur"               => "",
14        "traitement_article_efface"  => "rien_faire",
15        "transfere_article"          => "",
16        "id_rubrique_parent_archive"    => "0",
17        "nom_rubrique_archive"       => "archive_$annee",
18        "id_rubrique_parent"            => "0",
19    );
20       
21return $valeurs;
22}
23
24function formulaires_csv2auteurs_importation_verifier_dist(){
25    $erreurs = array();
26    // seuls les webmestres ont le droit d'utiliser cet outil!
27    if ($GLOBALS['visiteur_session']['webmestre'] != 'oui') {
28        $erreurs['message_erreur'] = _T('csv2auteurs:non_autorise');
29        return $erreurs;
30    }
31       
32    //champs obligatoire
33    if (!($_FILES['fichier_csv']['name'])) {
34        $erreurs['fichier_csv'] = _T('csv2auteurs:obligatoire');
35    } else {
36    //Transfert réussi
37        if ($_FILES['fichier_csv']['error'] > 0) $erreurs['fichier_csv'] = _T('csv2auteurs:transfert');
38    //Taille max du fichier csv < 2Mo
39        $maxsize=1000000;
40        if ($_FILES['fichier_csv']['size'] > $maxsize) $erreurs['fichier_csv'] =_T('csv2auteurs:taille');
41    //Extension csv
42        $extensions_valides = array( 'csv','txt' );
43        $extension_upload = strtolower(  substr(  strrchr($_FILES['fichier_csv']['name'], '.')  ,1)  );
44        if (!in_array($extension_upload,$extensions_valides)) $erreurs['fichier_csv'] = _T('csv2auteurs:extension');
45    }
46    //Il y a des erreurs
47    if (count($erreurs)) 
48        $erreurs['message_erreur'] = _T('csv2auteurs:erreurs');
49
50    return $erreurs;
51}
52
53function formulaires_csv2auteurs_importation_traiter_dist(){
54    $maj_utilisateur = _request('maj_utilisateur');
55    $abs_redacs = _request('abs_redac');
56    $abs_admins = _request('abs_admin');
57    $abs_visiteurs = _request('abs_visiteur');
58    $abs_poubelle = _request('abs_poubelle');
59    $suppression_article_efface = _request('suppression_article_efface');
60    $traitement_article_efface = _request('traitement_article_efface');
61    $nom_rubrique_archive = _request('nom_rubrique_archive');
62    $type_maj=_request('type_maj');
63
64    // recuperation de l'id de la rubrique parent des rubriques admins
65    $id_rubrique_parent_admin = _request('rubrique_parent');
66    $id_rubrique_parent_admin = explode('|',$id_rubrique_parent_admin[0]);
67    $id_rubrique_parent_admin = $id_rubrique_parent_admin[1];
68
69    //récupération de l'id de la rubrique parent archive
70    $id_rubrique_parent_archive = _request('rubrique_parent_archive');
71    $id_rubrique_parent_archive = explode('|',$id_rubrique_parent_archive[0]);
72    $id_rubrique_parent_archive = $id_rubrique_parent_archive[1];
73   
74    $retour = array();
75
76    include_spip('action/editer_rubrique');
77    if (test_plugin_actif("accesrestreint"))
78        include_spip('action/editer_zone');
79    include_spip('action/editer_auteur');
80   
81    if ($abs_redacs OR $abs_admins OR $abs_visiteurs OR $abs_poubelle == 'supprimer'){
82        include_spip('action/editer_objet');
83        include_spip('action/editer_liens');
84        include_spip('action/editer_zone');
85    }
86
87    // récupération du fichier csv
88    include_spip('inc/config');
89    $separateur  = lire_config("csv2auteurs_separateur");
90    $tmp_name    = $_FILES['fichier_csv']['tmp_name'];
91    $destination = _DIR_TMP.basename($tmp_name);
92    $resultat    = move_uploaded_file($tmp_name,$destination);
93    if (!$resultat) {
94        $retour['message_erreur'] = _T('csv2auteurs:transfert');
95    } else{
96        $retour['message_ok'] = _T('csv2auteurs:bravo');
97    }
98
99    // transformation du fichier csv en 4 array :
100    // $en_tete = ligne entete
101    // pour les 3 tableaux suivant, la cle est soit le login et s'il n'existe pas on prend le mail
102    // $tableau_csv_visiteurs
103    // $tableau_csv_redacs
104    // $tableau_csv_admins
105    $tableau_csv_visiteurs = $tableau_csv_redacs = $tableau_csv_admins = array();
106    $tableau_csv_rubriques_admins = array();
107    $fichiercsv= fopen($destination, "r");
108    $i=0;
109   
110    // correspondance statut spip / statut csv
111    $Tcorrespondances = array('administrateur'=>'0minirezo', 'redacteur'=>'1comite', 'visiteur'=>'6forum', 'poubelle' => '5poubelle');
112       
113    // tableau de tous les admins
114    $result = sql_select(array('login'), 'spip_auteurs', array('statut = "0minirezo"'));
115    while ($r = sql_fetch($result)) {
116        $Tadmin_tous[] = $r['login'];
117    }
118    // tableau des admins restreints
119    $Tadmin_restreint=array();
120    $from = array( 
121        "spip_auteurs AS auteurs",
122        "spip_auteurs_liens AS liens");
123    $where = array(
124        "auteurs.statut = '0minirezo'",
125        "liens.objet = 'rubrique'",
126        "liens.id_auteur = auteurs.id_auteur",
127        'login!=""');
128    $result = sql_select(array('login'),$from, $where);
129    while ($r = sql_fetch($result)) {
130        $Tadmin_restreint[] = $r['login'];
131    }
132    // tableau admins complets
133    $Tadmin_complet = array_diff($Tadmin_tous, $Tadmin_restreint);
134    // traiter fichier CSV
135    $num_statut = $num_login = -1;
136    while (($data= fgetcsv($fichiercsv,"$separateur")) !== FALSE){
137       // petit hack car fgetcsv ne reconnait pas le ~ comme séparateur !!!
138       $data           = implode("$separateur",$data);
139       $data           = explode("$separateur",$data);
140       $nombre_elements = count($data);
141        if ($i==0) {
142            for ($j = 0; $j < $nombre_elements; $j++) {
143                $en_tete[$j] = strtolower($data[$j]);    //Récupération de la ligne d'entete
144                if ($en_tete[$j] == 'statut')
145                    $num_statut = $j;
146                if ($en_tete[$j] == 'login')
147                    $num_login = $j;
148           }
149            if ($num_statut < 0 OR $num_login < 0){
150                $retour['message_erreur'] = _T('csv2auteurs:champ_manquant').' login:'.$num_login.' statut'.$num_statut;
151                return  $retour;
152            }
153       } 
154       else {
155            for ($j = 0; $j < $nombre_elements; $j++) {
156                // on ne veut pas les auteurs du CSV ayant login égal à celui d'un admin complet
157                if (($data[$num_login] AND !in_array($data[$num_login], $Tadmin_complet))) {
158                    // creation du tableau contenant l'ensemble des données à importer
159                   if ($Tcorrespondances[strtolower($data[$num_statut])] == '6forum')
160                        $tableau_csv_visiteurs[$data[$num_login]][$en_tete[$j]] = $en_tete[$j] == "statut" ? "6forum" : $data[$j];
161                   if ($Tcorrespondances[strtolower($data[$num_statut])] == '1comite')
162                        $tableau_csv_redacs[$data[$num_login]][$en_tete[$j]] = $en_tete[$j] == "statut" ? "1comite" : $data[$j];
163                   if ($Tcorrespondances[strtolower($data[$num_statut])] == '0minirezo') {
164                        $tableau_csv_admins[$data[$num_login]][$en_tete[$j]] = $en_tete[$j] == "statut" ? "0minirezo" : $data[$j];
165                        if ($en_tete[$j] == 'ss_groupe' AND $data[$j]) {
166                            $Trub = explode('|', $data[$j]);
167                            foreach($Trub as $rub)
168                                if (!in_array($rub, $tableau_csv_rubriques_admins))
169                                    $tableau_csv_rubriques_admins[] = $rub;
170                        }
171                    }
172                }
173            }
174        }
175        $i++;
176    }
177    fclose($fichiercsv);
178    unlink($destination);
179
180    // tableau CSV total
181    $tableau_csv_total = $tableau_csv_visiteurs + $tableau_csv_redacs + $tableau_csv_admins;
182//    echo "<pre>";
183//    print_r($tableau_csv_visiteurs);
184//    echo "admi";
185//    print_r($tableau_csv_admins);
186//    echo "red";
187//    print_r($tableau_csv_redacs);
188//    print_r($tableau_csv_total);die;
189
190//spip_log("tableau csv total","csvspip");
191//spip_log($tableau_csv_total,"csvspip");
192
193    //récupération des auteurs de la bdd en 4 array
194    // on ne prend pas les auteurs sans login
195    // $poubelle_bdd = les auteurs à la poubelle
196    // $visiteur_bdd = les visiteurs
197    // $redacteur_bdd
198    // $admin_restreint_bdd
199    // la cle de chaque tableau est le login
200    $poubelle_bdd=$visiteur_bdd=$redacteur_bdd=$admin_restreint_bdd=array();
201/*    $poubelle_bdd_req        = sql_allfetsel('*', 'spip_auteurs',array('statut="5poubelle"','(login!="")'));
202    foreach ($poubelle_bdd_req as $key) {
203        $poubelle_bdd[$key['login']]=$key;
204    }   
205*/
206    $visiteur_bdd_req        = sql_allfetsel('*', 'spip_auteurs',array('statut="6forum"','(login!="")'));
207    foreach ($visiteur_bdd_req as $key) {
208        $visiteur_bdd[$key['login']]=$key;
209    }
210    $redacteur_bdd_req       = sql_allfetsel('*', 'spip_auteurs', array('statut="1comite"','(login!="")'));
211    foreach ($redacteur_bdd_req as $key) {
212        $redacteur_bdd[$key['login']]=$key;
213    }
214    //on récupère seulement les admins restreints !!!
215    $from = array( 
216        "spip_auteurs AS auteurs",
217        "spip_auteurs_liens AS liens");
218    $where = array(
219        "auteurs.statut = '0minirezo'",
220        "liens.objet = 'rubrique'",
221        "liens.id_auteur = auteurs.id_auteur",
222        '(login!="")');
223    $admin_restreint_bdd_req       = sql_allfetsel("DISTINCT auteurs.*" ,$from, $where);
224    foreach ($admin_restreint_bdd_req as $key) {
225        $admin_restreint_bdd[$key['login']]=$key;
226    }
227
228    // tableau BDD total
229    $tableau_bdd_total = $poubelle_bdd + $visiteur_bdd +  $redacteur_bdd + $admin_restreint_bdd;
230
231    // traitement rubriques admin
232    // construction du tableau de correspondance nom_rubrique avec leur id
233    // création des rubriques n'existant pas
234    $tableau_bdd_rubriques_admins = array();
235    $result = sql_select(array('id_rubrique', 'titre'), 'spip_rubriques');
236    while ($row = sql_fetch($result)){
237        $tableau_bdd_rubriques_admins[$row['id_rubrique']] = strtolower($row['titre']);
238    }
239
240    // traitement zones
241    // construction du tableau de correspondance nom_zone avec leur id
242    $tableau_bdd_zones_admins = array();
243    if (test_plugin_actif("accesrestreint")){
244        $result = sql_select(array('id_zone', 'titre'), 'spip_zones');
245        while ($row = sql_fetch($result)){
246            $tableau_bdd_zones_admins[$row['id_zone']] = strtolower($row['titre']);
247        }
248    }
249    spip_log($tableau_bdd_zones_admins,"csvspip");
250    // créer les rubriques admins du csv n'existant pas et les indexer
251    foreach($tableau_csv_rubriques_admins as $id_rub=>$rub){
252        if (!in_array(strtolower($rub), $tableau_bdd_rubriques_admins)) {
253            $set = array('titre'=>$rub);
254            $id_rub = rubrique_inserer($id_rubrique_parent_admin);
255            rubrique_modifier($id_rub, $set);
256            $tableau_bdd_rubriques_admins[$id_rub] = strtolower($rub);
257        }
258    }
259
260    //Récuperer les champs de la table auteurs
261    $Tnom_champs_bdd=array();
262    $desc = sql_showtable('spip_auteurs',true);
263    foreach ($desc['field'] as $cle => $valeur)
264        $Tnom_champs_bdd[] = $cle;
265
266   
267    // PARTIE I : maj ou ajout des auteurs
268    $tableau_nouveaux_auteurs = array_diff_key($tableau_csv_total, $tableau_bdd_total);
269    // si maj demandée
270    if ($maj_utilisateur) {
271        // construire le tableau des utilisateurs à mettre à jour, indexé sur le login
272        $tableau_maj_auteurs = array_diff_key($tableau_csv_total, $tableau_nouveaux_auteurs);
273       
274        // construire le tableau de correspondance login csv => id_auteur bdd
275        $tableau_maj_auteurs_id = array();
276        $Tlogins = array_keys($tableau_maj_auteurs);
277        $chaine_in = implode('","', $Tlogins);
278        $chaine_in = '"'.$chaine_in.'"';
279        $res = sql_select('id_auteur, login', 'spip_auteurs', array('login IN ('.$chaine_in.')'));
280        while ($row = sql_fetch($res)) {
281            $tableau_maj_auteurs_id[$row['login']] = $row['id_auteur'];
282        }
283
284        // si remplacer les données zones et rubriques administrées: supprimer les liens existant
285        if ($type_maj == 'remplacer' AND test_plugin_actif("accesrestreint")) {
286            // suppression des liens des rubriques administrées
287            objet_dissocier(array("auteur"=>array_values($tableau_maj_auteurs_id)), array("rubrique"=>"*"));   
288            // suppression des zones des auteurs
289            zone_lier('',"auteur",array_values($tableau_maj_auteurs_id),'del');
290        }
291//spip_log("table zone admin","csvspip");
292
293//spip_log($tableau_bdd_zones_admins,"csvspip");
294
295        // maj des données des auteurs
296        foreach($tableau_maj_auteurs as $login => $Tauteur)
297            csv2auteurs_ajout_utilisateur($login, $Tauteur, $Tnom_champs_bdd, $Tcorrespondances, $tableau_bdd_rubriques_admins, $tableau_bdd_zones_admins, $tableau_maj_auteurs_id[$login]);
298
299/*     
300echo '<br><pre>';
301var_dump($tableau_maj_auteurs_id);
302*/
303       
304    }
305   
306   
307    // dans tous les cas ajout des nouveaux
308    foreach($tableau_nouveaux_auteurs as $login => $Tauteur)
309        csv2auteurs_ajout_utilisateur($login,$Tauteur,$Tnom_champs_bdd,$Tcorrespondances, $tableau_bdd_rubriques_admins, $tableau_bdd_zones_admins);
310
311       
312   
313
314
315
316    // PARTIE II : Suppressions des absents (changer le statut des auteurs en 5.poubelle)  avec 3 choix pour la gestion des articles associés
317    // 1. ras
318    // 2. supprimer les articles
319    // 3. transferer les articles dans une rubrique d'archivage
320
321    // Si choix3 : transferer les articles , création de la rubrique d'archive (en tenant compte d'une rubrique parent)
322    if($traitement_article_efface == "transferer_articles"){
323        if(!$id_rubrique_archive = sql_fetsel('id_rubrique','spip_rubriques',array('titre ="'.$nom_rubrique_archive.'"',"id_parent=$id_rubrique_parent_archive"))){
324            $objet = 'rubrique';
325            $set = array('titre'=>$nom_rubrique_archive);
326            $id_rubrique_archive = objet_inserer($objet,$id_rubrique_parent_archive);
327            objet_modifier($objet, $id_rubrique_archive, $set);
328        }
329    }   
330   
331    // si l'option auteurs sans articles = suppression complète
332    // alors on supprime aussi tous les auteurs à la poubelle (sans articles)
333    if ($abs_poubelle == 'supprimer') {
334                // récupérer les auteurs à la poubelle avec articles
335                $not_in = sql_allfetsel('auteurs.id_auteur', 
336                        array('spip_auteurs_liens AS liens','spip_auteurs AS auteurs'), 
337                        array('liens.id_auteur = auteurs.id_auteur', 'liens.objet="article"', 'auteurs.statut="5poubelle"'),
338                        array('liens.id_auteur'));             
339                $Tnot_in =      array();
340                foreach ($not_in as $index => $Tid_auteur) 
341                        $Tnot_in[] = $Tid_auteur['id_auteur'];
342                $not_in = sql_in('id_auteur', $Tnot_in, 'NOT');
343                // récupérer les auteurs à la poubelle sans articles
344                $Tabs_poubelle = sql_allfetsel('id_auteur', 'spip_auteurs',array('statut="5poubelle"', $not_in));
345                $Ta_suppr = array();
346                foreach ($Tabs_poubelle as $index => $Tid_auteur) 
347                        $Ta_suppr[] = $Tid_auteur['id_auteur'];
348                // effacer définitevement ces auteurs
349                $in = sql_in('id_auteur', $Ta_suppr);
350                sql_delete('spip_auteurs', $in);
351        }               
352//        $Tid_poubelle = csv2auteurs_diff_absents($poubelle_bdd);
353//        csv2auteurs_supprimer_auteurs($Tid_poubelle, '5poubelle', $traitement_article_efface,$id_rubrique_parent_archive);
354
355    if ($abs_visiteurs) {
356        $Tid_visiteurs = csv2auteurs_diff_absents($visiteur_bdd, $tableau_csv_visiteurs);
357        csv2auteurs_supprimer_auteurs($Tid_visiteurs, '6forum', $traitement_article_efface,$id_rubrique_parent_archive);
358    }
359    if ($abs_redacs) {
360        $Tid_redacs = csv2auteurs_diff_absents($redacteur_bdd, $tableau_csv_redacs);
361        csv2auteurs_supprimer_auteurs($Tid_redacs, '1comite',$traitement_article_efface,$id_rubrique_parent_archive);
362    }
363    if ($abs_admins) {
364        $Tid_admins = csv2auteurs_diff_absents($admin_restreint_bdd, $tableau_csv_admins);
365        csv2auteurs_supprimer_auteurs($Tid_admins, '0minirezo',$traitement_article_efface,$id_rubrique_parent_archive);
366    }
367
368    // PARTIE III : maj des existants
369    // 1. ras
370    // 2. supprimer les articles
371    // 3. transferer les articles dans une rubrique d'archivage
372
373   
374/*
375echo '<pre>$visiteur_bdd';
376var_dump($visiteur_bdd);
377echo '<br>$redacteur_bdd:';
378var_dump($redacteur_bdd);
379echo '<br>$admin_restreint';
380var_dump($admin_restreint);
381echo '</pre>';
382die;
383*/
384
385
386//  $retour['redirect'] = 'index.php?exec=csv2auteurs';
387    return $retour;
388}
389
390/*
391 * générer l"array des id auteurs absents à supprimer
392 * @param $Tbdd: l'array indexé login/mail extrait de la base
393 * @param $Tcsv: l'array indexé login/mail extrait du csv
394 * @return l'array des id_auteurs
395 */
396function csv2auteurs_diff_absents($Tbdd, $Tcsv=array()){
397    $Tid = array();
398    $T = array_diff_key($Tbdd, $Tcsv);
399    foreach ($T as $val)
400        $Tid[] = $val['id_auteur'];
401
402    return $Tid;
403}
404
405
406/*
407 * ajout d'un utilisateur
408 * @param login de l'auteur
409 * @param array associatif CSV: Tauteur_csv  nom_champ : valeur
410 */
411function csv2auteurs_ajout_utilisateur($login,$Tauteur_csv,$Tnom_champs_bdd,$Tcorrespondances, $tableau_bdd_rubriques_admins, $tableau_bdd_zones_admins, $id_auteur=0){
412    $set = $Tzones = $Trubadmin = array();
413    foreach($Tauteur_csv as $champ => $valeur){
414        if($champ == "ss_groupe"){
415            $T = explode('|',$valeur);
416            foreach($T as $rub){
417                $Trubadmin[] = array_search(strtolower($rub),$tableau_bdd_rubriques_admins);
418            }
419        }
420        if($champ == "zone"){
421            $T = explode('|',$valeur);
422            foreach($T as $zone){
423                $Tzones[] = array_search(trim(rtrim(strtolower($zone))),$tableau_bdd_zones_admins);
424            }
425//spip_log("tzone de id_auteur $id_auteur","csvspip");
426//spip_log($Tzones,"csvspip");
427
428        }
429        if(in_array($champ,$Tnom_champs_bdd)){
430            $set[$champ] = ($champ == "statut" AND array_key_exists($valeur,$Tcorrespondances)) ? $Tcorrespondances[$valeur] : $valeur;
431        }
432    }
433
434    //inserer l'auteur si il n'y a pas d'id_auteur transmis
435    if (!$id_auteur)
436        $id_auteur = auteur_inserer();
437   
438    // remplir les champs ou les maj
439    auteur_modifier($id_auteur,$set);
440
441    //liaison des rubriques
442    if(count($Trubadmin) AND $set["statut"] == "0minirezo")
443        objet_associer(array("auteur"=>$id_auteur),array("rubrique"=>$Trubadmin));
444       
445    //liaison des zones
446    if(count($Tzones) AND test_plugin_actif("accesrestreint") AND test_plugin_actif("accesrestreint"))
447        zone_lier($Tzones, 'auteur', $id_auteur, 'add');
448
449}
450
451
452/*
453 * Suppression propre des auteurs
454 * changement de statut à la poubelle + traitement des liaisons spip_auteurs_liens et spip_zones_liens
455 * gestion des articles des auteurs supprimés
456 * @param $Tid array des id_auteurs à traiter
457 * @param $statut des auteurs passent dans $Tid
458 * $param $traitement : choix 2 (suppresion) ou 3 (transfere)
459 * $param $id_rubrique_archive
460 *
461 */
462function csv2auteurs_supprimer_auteurs($Tid, $statut,$traitement="supprimer_articles",$id_rubrique_archive=1) {
463    // passage à la poubelle
464    $objet = 'auteur';
465    $set = array('statut'=>'5poubelle');
466    foreach ($Tid as $id){
467        $Tarticles = sql_allfetsel('id_objet', 'spip_auteurs_liens', array('id_auteur='.$id, 'objet="article"'));
468
469        // auteur sans article et demande de suppression: suppression complète
470        if (count($Tarticles) == 0 AND _request('abs_poubelle') == 'supprimer')
471            sql_delete('spip_auteurs', "id_auteur=$id");
472        // passage à la poubelle
473        else
474            objet_modifier($objet, $id, $set);
475
476        // traitement des articles de l'auteur
477        if (count($Tarticles) != 0) {
478
479            // supprimer les articles
480            $table_idarticle = array();
481            if ($traitement == 'supprimer_articles'){
482                objet_dissocier(array('id_auteur'=>$id), array('article'=>$Tarticles));
483                foreach ($Tarticles as $idarticle) {
484                    $table_idarticle[]=$idarticle['id_objet'];
485                }
486                $inarticle = join(',',$table_idarticle);
487                sql_delete('spip_articles', "id_article IN ($inarticle)");
488            }
489            // deplacer les articles dans la rubrique d'archivage
490            if ($traitement == 'transferer_articles'){
491                foreach($Tarticles as $idarticle)
492                    objet_modifier('article', $idarticle['id_objet'], array('id_parent'=>$id_rubrique_archive));
493            }
494        }
495           
496        if (test_plugin_actif("accesrestreint")){
497            // suppression des zones de l'auteur
498            $Tzones = sql_allfetsel('id_zone', 'spip_zones_liens', array('id_objet='.$id, 'objet="auteur"'));
499            foreach ($Tzones as $id_zone)
500                zone_lier($id_zone, 'auteur', $id, 'del');
501        }   
502        // suppression des rubriques des admins restreints
503        if ($statut == '0minirezo') {
504            $Trubriques = sql_allfetsel('id_objet', 'spip_auteurs_liens', array('id_auteur='.$id, 'objet="rubrique"'));
505            objet_dissocier(array('id_auteur'=>$id), array('rubrique'=>$Trubriques));
506        }
507    }
508}
509
510?>
Note: See TracBrowser for help on using the repository browser.