Merge branch 'fusionax' of /home/git/platal into fusionax
[platal.git] / include / userset.inc.php
index a76b7c1..4c4e38e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2007 Polytechnique.org                              *
+ *  Copyright (C) 2003-2008 Polytechnique.org                              *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
@@ -19,7 +19,6 @@
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-require_once('xorg.misc.inc.php');
 require_once('user.func.inc.php');
 
 global $globals;
 require_once('user.func.inc.php');
 
 global $globals;
@@ -32,7 +31,9 @@ global $globals;
     LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id)
     LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
     LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
     LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id)
     LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
     LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
-    LEFT JOIN  geoloc_pays    AS n   ON (u.nationalite = n.a2)
+    LEFT JOIN  geoloc_pays    AS n1  ON (u.nationalite = n1.a2)
+    LEFT JOIN  geoloc_pays    AS n2  ON (u.nationalite2 = n2.a2)
+    LEFT JOIN  geoloc_pays    AS n3  ON (u.nationalite2 = n3.a2)
     LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut))
     LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
     LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
     LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut))
     LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
     LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
@@ -44,11 +45,11 @@ class UserSet extends PlSet
     {
         global $globals;
         parent::__construct('auth_user_md5 AS u',
     {
         global $globals;
         parent::__construct('auth_user_md5 AS u',
-                            (!empty($GLOBALS['IS_XNET_SITE']) ? 
-                                'INNER JOIN groupex.membres AS gxm ON (u.user_id = gxm.uid 
+                            (!empty($GLOBALS['IS_XNET_SITE']) ?
+                                'INNER JOIN groupex.membres AS gxm ON (u.user_id = gxm.uid
                                                                        AND gxm.asso_id = ' . $globals->asso('id') . ') ' : '')
                                                                        AND gxm.asso_id = ' . $globals->asso('id') . ') ' : '')
-                           . 'LEFT JOIN auth_user_quick AS q USING (user_id) 
-                              LEFT JOIN aliases         AS a ON (a.id = u.user_id AND type = \'a_vie\')
+                           . 'LEFT JOIN auth_user_quick AS q USING (user_id)
+                              LEFT JOIN aliases         AS a ON (a.id = u.user_id AND a.type = \'a_vie\')
                               ' . $joins,
                             $where,
                             'u.user_id');
                               ' . $joins,
                             $where,
                             'u.user_id');
@@ -62,7 +63,7 @@ class SearchSet extends UserSet
     private $order = null;
     private $quick = false;
 
     private $order = null;
     private $quick = false;
 
-    public function __construct($quick = false, $no_search = false)
+    public function __construct($quick = false, $no_search = false, $join = '', $where = '')
     {
         require_once dirname(__FILE__).'/../modules/search/search.inc.php';
 
     {
         require_once dirname(__FILE__).'/../modules/search/search.inc.php';
 
@@ -72,13 +73,13 @@ class SearchSet extends UserSet
 
         $this->quick = $quick;
         if ($quick) {
 
         $this->quick = $quick;
         if ($quick) {
-            $this->getQuick();
+            $this->getQuick($join, $where);
         } else {
         } else {
-            $this->getAdvanced();
+            $this->getAdvanced($join, $where);
         }
     }
 
         }
     }
 
-    private function getQuick()
+    private function getQuick($join, $where)
     {
         require_once dirname(__FILE__).'/../modules/search/search.inc.php';
         global $globals;
     {
         require_once dirname(__FILE__).'/../modules/search/search.inc.php';
         global $globals;
@@ -88,18 +89,29 @@ class SearchSet extends UserSet
         $qSearch = new QuickSearch('quick');
         $fields  = new SFieldGroup(true, array($qSearch));
         if ($qSearch->isEmpty()) {
         $qSearch = new QuickSearch('quick');
         $fields  = new SFieldGroup(true, array($qSearch));
         if ($qSearch->isEmpty()) {
-            new ThrowError('Recherche trop générale.');
+            new ThrowError('Aucun critère de recherche n\'est spécifié.');
         }
         $this->score = $qSearch->get_score_statement();
         }
         $this->score = $qSearch->get_score_statement();
-        parent::__construct("{$fields->get_select_statement()}",
-                            $fields->get_where_statement() .
-                            (S::logged() && Env::has('nonins') ? ' AND u.perms="pending" AND u.deces=0' : ''));
+        $pwhere = $fields->get_where_statement();
+        if (trim($pwhere)) {
+            if (trim($where)) {
+                $where .= ' AND ';
+            }
+            $where .= $pwhere;
+        }
+        if (S::logged() && Env::has('nonins')) {
+            if (trim($where)) {
+                $where .= ' AND ';
+            }
+            $where .= 'u.perms="pending" AND u.deces=0';
+        }
+        parent::__construct($join . ' ' . $fields->get_select_statement(), $where);
 
         $this->order = implode(',',array_filter(array($fields->get_order_statement(),
                                                       'u.promo DESC, NomSortKey, prenom')));
     }
 
 
         $this->order = implode(',',array_filter(array($fields->get_order_statement(),
                                                       'u.promo DESC, NomSortKey, prenom')));
     }
 
-    private function getAdvanced()
+    private function getAdvanced($join, $where)
     {
         global $globals;
         $this->advanced = true;
     {
         global $globals;
         $this->advanced = true;
@@ -107,8 +119,8 @@ class SearchSet extends UserSet
         if ($fields->too_large()) {
             new ThrowError('Recherche trop générale.');
         }
         if ($fields->too_large()) {
             new ThrowError('Recherche trop générale.');
         }
-        parent::__construct($fields->get_select_statement(),
-                            $fields->get_where_statement());
+        parent::__construct(@$join . ' ' . $fields->get_select_statement(),
+                            @$where . ' ' . $fields->get_where_statement());
         $this->order = implode(',',array_filter(array($fields->get_order_statement(),
                                                       'promo DESC, NomSortKey, prenom')));
     }
         $this->order = implode(',',array_filter(array($fields->get_order_statement(),
                                                       'promo DESC, NomSortKey, prenom')));
     }
@@ -153,11 +165,11 @@ class MinificheView extends MultipageView
         global $globals;
         $this->entriesPerPage = $globals->search->per_page;
         if (@$params['with_score']) {
         global $globals;
         $this->entriesPerPage = $globals->search->per_page;
         if (@$params['with_score']) {
-            $this->addSortKey('score', array('-score', '-watch_last', '-promo', 'nom', 'prenom'), 'pertinence');
+            $this->addSortKey('score', array('-score', '-date', '-promo', 'name_sort'), 'pertinence');
         }
         }
-        $this->addSortKey('name', array('nom', 'prenom'), 'nom');
-        $this->addSortKey('promo', array('-promo', 'nom', 'prenom'), 'promotion');
-        $this->addSortKey('date', array('-watch_last', '-promo', 'nom', 'prenom'), 'dernière modification');
+        $this->addSortKey('name', array('name_sort'), 'nom');
+        $this->addSortKey('promo', array('-promo', 'name_sort'), 'promotion');
+        $this->addSortKey('date_mod', array('-date', '-promo', 'name_sort'), 'dernière modification');
         parent::__construct($set, $data, $params);
     }
 
         parent::__construct($set, $data, $params);
     }
 
@@ -170,34 +182,57 @@ class MinificheView extends MultipageView
                 u.deces != 0 AS dcd, u.deces, u.matricule_ax,
                 FIND_IN_SET('femme', u.flags) AS sexe,
                 e.entreprise, es.label AS secteur, ef.fonction_fr AS fonction,
                 u.deces != 0 AS dcd, u.deces, u.matricule_ax,
                 FIND_IN_SET('femme', u.flags) AS sexe,
                 e.entreprise, es.label AS secteur, ef.fonction_fr AS fonction,
-                IF(n.nat='',n.pays,n.nat) AS nat, n.a2 AS iso3166,
+                IF(n1.nat='',n1.pays,n1.nat) AS nat1, n1.a2 AS iso3166_1,
+                IF(n2.nat='',n2.pays,n2.nat) AS nat2, n2.a2 AS iso3166_2,
+                IF(n3.nat='',n3.pays,n3.nat) AS nat3, n3.a2 AS iso3166_3,
                 ad0.text AS app0text, ad0.url AS app0url, ai0.type AS app0type,
                 ad1.text AS app1text, ad1.url AS app1url, ai1.type AS app1type,
                 adr.city, gp.a2, gp.pays AS countrytxt, gr.name AS region,
                 ad0.text AS app0text, ad0.url AS app0url, ai0.type AS app0type,
                 ad1.text AS app1text, ad1.url AS app1url, ai1.type AS app1type,
                 adr.city, gp.a2, gp.pays AS countrytxt, gr.name AS region,
-                IF(u.nom_usage<>'',u.nom_usage,u.nom) AS sortkey,
-                COUNT(em.email) > 0 AS actif" . (S::logged() ? ", c.contact AS contact" : '');
+                (COUNT(em.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif,
+                nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort" .
+                (S::logged() ? ", c.contact AS contact" : '');
     }
 
     public function joins()
     {
     }
 
     public function joins()
     {
-        return  "LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id)
+        return  "LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id".(S::logged() ? "" : " AND e.pub = 'public'").")
                  LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
                  LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
                  LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
                  LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
-                 LEFT JOIN  geoloc_pays    AS n   ON (u.nationalite = n.a2)
+                 LEFT JOIN  geoloc_pays    AS n1  ON (u.nationalite = n1.a2)
+                 LEFT JOIN  geoloc_pays    AS n2  ON (u.nationalite2 = n2.a2)
+                 LEFT JOIN  geoloc_pays    AS n3  ON (u.nationalite3 = n3.a2)
                  LEFT JOIN  applis_ins     AS ai0 ON (u.user_id = ai0.uid AND ai0.ordre = 0)
                  LEFT JOIN  applis_def     AS ad0 ON (ad0.id = ai0.aid)
                  LEFT JOIN  applis_ins     AS ai1 ON (u.user_id = ai1.uid AND ai1.ordre = 1)
                  LEFT JOIN  applis_def     AS ad1 ON (ad1.id = ai1.aid)
                  LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid
                  LEFT JOIN  applis_ins     AS ai0 ON (u.user_id = ai0.uid AND ai0.ordre = 0)
                  LEFT JOIN  applis_def     AS ad0 ON (ad0.id = ai0.aid)
                  LEFT JOIN  applis_ins     AS ai1 ON (u.user_id = ai1.uid AND ai1.ordre = 1)
                  LEFT JOIN  applis_def     AS ad1 ON (ad1.id = ai1.aid)
                  LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid
-                                                      AND FIND_IN_SET('active', adr.statut))
+                                                      AND FIND_IN_SET('active', adr.statut)".(S::logged() ? "" : " AND adr.pub = 'public'").")
                  LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
                  LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
                  LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
                  LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
-                 LEFT JOIN  emails         AS em  ON (em.uid = u.user_id AND em.flags = 'active')" .
-                (S::logged() ? 
+                 LEFT JOIN  emails         AS em  ON (em.uid = u.user_id AND em.flags = 'active')
+                INNER JOIN  profile_names_display AS nd  ON (nd.user_id = u.user_id)" .
+                (S::logged() ?
                  "LEFT JOIN  contacts       AS c   On (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
                  : "");
     }
 
                  "LEFT JOIN  contacts       AS c   On (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
                  : "");
     }
 
+    public function bounds()
+    {
+        $order = Env::v('order', $this->defaultkey);
+        $show_bounds = 0;
+        if (($order == "name") || ($order == "-name")) {
+            $this->bound_field = "nom";
+            $show_bounds = 1;
+        } elseif (($order == "promo") || ($order == "-promo")) {
+            $this->bound_field = "promo";
+            $show_bounds = -1;
+        }
+        if ($order{0} == '-') {
+            $show_bounds = -$show_bounds;
+        }
+        return $show_bounds;
+    }
+
     public function templateName()
     {
         return 'include/plview.minifiche.tpl';
     public function templateName()
     {
         return 'include/plview.minifiche.tpl';
@@ -208,19 +243,42 @@ class MentorView extends MultipageView
 {
     public function __construct(PlSet &$set, $data, array $params)
     {
 {
     public function __construct(PlSet &$set, $data, array $params)
     {
-        $this->entriesPerPage = 10; 
+        $this->entriesPerPage = 10;
         $this->addSortKey('rand', array('RAND(' . S::i('uid') . ')'), 'aléatoirement');
         $this->addSortKey('rand', array('RAND(' . S::i('uid') . ')'), 'aléatoirement');
-        $this->addSortKey('name', array('nom', 'prenom'), 'nom'); 
-        $this->addSortKey('promo', array('-promo', 'nom', 'prenom'), 'promotion'); 
-        $this->addSortKey('date', array('-watch_last', '-promo', 'nom', 'prenom'), 'dernière modification'); 
-        parent::__construct($set, $data, $params); 
+        $this->addSortKey('name', array('name_sort'), 'nom');
+        $this->addSortKey('promo', array('-promo', 'name_sort'), 'promotion');
+        $this->addSortKey('date_mod', array('-date', '-promo', 'name_sort'), 'dernière modification');
+        parent::__construct($set, $data, $params);
     }
 
     public function fields()
     {
     }
 
     public function fields()
     {
-        return "m.uid, u.prenom, u.nom, u.promo,
+        return "m.uid, u.promo,
                 a.alias AS bestalias, m.expertise, mp.pid,
                 a.alias AS bestalias, m.expertise, mp.pid,
-                ms.secteur, ms.ss_secteur";
+                ms.secteur, ms.ss_secteur,
+                nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort";
+    }
+
+    public function joins()
+    {
+        return "INNER JOIN  profile_names_display AS nd ON (nd.user_id = u.user_id)";
+    }
+
+    public function bounds()
+    {
+        $order = Env::v('order', $this->defaultkey);
+        $show_bounds = 0;
+        if (($order == "name") || ($order == "-name")) {
+            $this->bound_field = "nom";
+            $show_bounds = 1;
+        } elseif (($order == "promo") || ($order == "-promo")) {
+            $this->bound_field = "promo";
+            $show_bounds = -1;
+        }
+        if ($order{0} == '-') {
+            $show_bounds = -$show_bounds;
+        }
+        return $show_bounds;
     }
 
     public function templateName()
     }
 
     public function templateName()
@@ -234,23 +292,41 @@ class TrombiView extends MultipageView
     public function __construct(PlSet &$set, $data, array $params)
     {
         $this->entriesPerPage = 24;
     public function __construct(PlSet &$set, $data, array $params)
     {
         $this->entriesPerPage = 24;
-        $this->order = explode(',', Env::v('order', 'nom,prenom,promo'));
+        $this->order = explode(',', Env::v('order', 'name_sort'));
         if (@$params['with_score']) {
         if (@$params['with_score']) {
-            $this->addSortKey('score', array('-score', '-watch_last', '-promo', 'nom', 'prenom'), 'pertinence');
+            $this->addSortKey('score', array('-score', '-watch_last', '-promo', 'name_sort'), 'pertinence');
         }
         }
-        $this->addSortKey('name', array('nom', 'prenom'), 'nom');
-        $this->addSortKey('promo', array('-promo', 'nom', 'prenom'), 'promotion');
+        $this->addSortKey('name', array('name_sort'), 'nom');
+        $this->addSortKey('promo', array('-promo', 'name_sort'), 'promotion');
         parent::__construct($set, $data, $params);
     }
 
     public function fields()
     {
         parent::__construct($set, $data, $params);
     }
 
     public function fields()
     {
-        return "u.user_id, IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom, u.prenom, u.promo, a.alias AS forlife ";
+        return "u.user_id, nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort, u.promo, a.alias AS forlife ";
     }
 
     public function joins()
     {
     }
 
     public function joins()
     {
-        return "INNER JOIN  photo AS p ON (p.uid = u.user_id) ";
+        return "INNER JOIN  photo AS p ON (p.uid = u.user_id)
+                INNER JOIN  profile_names_display AS nd ON (nd.user_id = u.user_id)";
+    }
+
+    public function bounds()
+    {
+        $order = Env::v('order', $this->defaultkey);
+        $show_bounds = 0;
+        if (($order == "name") || ($order == "-name")) {
+            $this->bound_field = "nom";
+            $show_bounds = 1;
+        } elseif (($order == "promo") || ($order == "-promo")) {
+            $this->bound_field = "promo";
+            $show_bounds = -1;
+        }
+        if ($order{0} == '-') {
+            $show_bounds = -$show_bounds;
+        }
+        return $show_bounds;
     }
 
     public function templateName()
     }
 
     public function templateName()
@@ -258,7 +334,7 @@ class TrombiView extends MultipageView
         return 'include/plview.trombi.tpl';
     }
 
         return 'include/plview.trombi.tpl';
     }
 
-    public function apply(PlatalPage &$page)
+    public function apply(PlPage &$page)
     {
         if (!empty($GLOBALS['IS_XNET_SITE'])) {
             global $globals;
     {
         if (!empty($GLOBALS['IS_XNET_SITE'])) {
             global $globals;
@@ -295,7 +371,7 @@ class GeolocView implements PlView
         return $args;
     }
 
         return $args;
     }
 
-    public function apply(PlatalPage &$page)
+    public function apply(PlPage &$page)
     {
         require_once 'geoloc.inc.php';
         require_once '../modules/search/search.inc.php';
     {
         require_once 'geoloc.inc.php';
         require_once '../modules/search/search.inc.php';
@@ -326,11 +402,12 @@ class GeolocView implements PlView
             $page->changeTpl('geoloc/city.tpl', NO_SKIN);
             header('Content-Type: text/xml');
             header('Pragma:');
             $page->changeTpl('geoloc/city.tpl', NO_SKIN);
             header('Content-Type: text/xml');
             header('Pragma:');
+            $only_current = Env::v('only_current', false)? ' AND FIND_IN_SET(\'active\', adrf.statut)' : '';
             $it =& $this->set->get('u.user_id AS id, u.prenom, u.nom, u.promo, al.alias',
             $it =& $this->set->get('u.user_id AS id, u.prenom, u.nom, u.promo, al.alias',
-                                   "INNER JOIN  adresses AS adrf  ON (adrf.uid = u.user_id)
+                                   "INNER JOIN  adresses AS adrf  ON (adrf.uid = u.user_id $only_current)
                                      LEFT JOIN  aliases  AS al   ON (u.user_id = al.id
                                      LEFT JOIN  aliases  AS al   ON (u.user_id = al.id
-                                                                   AND FIND_IN_SET(al.flags, 'bestalias'))
-                                    INNER JOIN  adresses AS av ON (" . getadr_join('av') . ")",
+                                                                   AND FIND_IN_SET('bestalias', al.flags))
+                                    INNER JOIN  adresses AS avg ON (" . getadr_join('avg') . ")",
                                    'adrf.cityid = ' . Env::i('cityid'), null, null, 11);
             $page->assign('users', $it);
             break;
                                    'adrf.cityid = ' . Env::i('cityid'), null, null, 11);
             $page->assign('users', $it);
             break;
@@ -354,9 +431,7 @@ class GeolocView implements PlView
             if (!$this->use_map()) {
                 $page->assign('request_geodesix', true);
             }
             if (!$this->use_map()) {
                 $page->assign('request_geodesix', true);
             }
-            if (!empty($GLOBALS['IS_XNET_SITE'])) {
-                $page->assign('no_annu', true);
-            }
+            $page->assign('annu', @$this->params['with_annu']);
             $page->assign('protocole', @$_SERVER['HTTPS'] ? 'https' : 'http');
             $this->set->get('u.user_id', null, "u.perms != 'pending' AND u.deces = 0", "u.user_id", null);
             return 'include/plview.geoloc.tpl';
             $page->assign('protocole', @$_SERVER['HTTPS'] ? 'https' : 'http');
             $this->set->get('u.user_id', null, "u.perms != 'pending' AND u.deces = 0", "u.user_id", null);
             return 'include/plview.geoloc.tpl';
@@ -364,5 +439,46 @@ class GeolocView implements PlView
     }
 }
 
     }
 }
 
+class GadgetView implements PlView
+{
+    public function __construct(PlSet &$set, $data, array $params)
+    {
+        $this->set =& $set;
+    }
+
+    public function fields()
+    {
+        return "u.user_id AS id,
+                u.*, a.alias AS forlife," .
+               "u.perms != 'pending' AS inscrit,
+                u.perms != 'pending' AS wasinscrit,
+                u.deces != 0 AS dcd, u.deces,
+                FIND_IN_SET('femme', u.flags) AS sexe,
+                adr.city, gp.a2, gp.pays AS countrytxt, gr.name AS region" .
+                (S::logged() ? ", c.contact AS contact" : '');
+    }
+
+    public function joins()
+    {
+        return  "LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid AND FIND_IN_SET('active', adr.statut)".(S::logged() ? "" : " AND adr.pub = 'public'").")
+                 LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
+                 LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)" .
+                (S::logged() ?
+                 "LEFT JOIN  contacts       AS c   On (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
+                 : "");
+    }
+
+    public function apply(PlPage &$page)
+    {
+        $page->assign_by_ref('set',
+          $this->set->get($this->fields(), $this->joins(), null, null, null, 5, 0));
+    }
+
+    public function args()
+    {
+        return null;
+    }
+}
+
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>