[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / public / criteres.php
index fd7dcf9..6ed1857 100644 (file)
@@ -3,7 +3,7 @@
 /***************************************************************************\
  *  SPIP, Systeme de publication pour l'internet                           *
  *                                                                         *
- *  Copyright (c) 2001-2011                                                *
+ *  Copyright (c) 2001-2014                                                *
  *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
  *                                                                         *
  *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
@@ -60,20 +60,29 @@ function critere_exclus_dist($idb, &$boucles, $crit) {
 function critere_doublons_dist($idb, &$boucles, $crit) {
        $boucle = &$boucles[$idb];
        $primary = $boucle->primary;
+       $type = $boucle->type_requete;
+       // Dans le cas NOT, la table du doublon peut etre indiquee
+       // si la table courante a un champ homonyme de sa cle primaire.
+       // Tres utile pour la table des forums.
+       if (isset($crit->param[1])) {
+         $primary = '';
+         $x = !$crit->not ? '' : calculer_liste($crit->param[1], array(), $boucles, $boucle->id_parent);
+         # attention au commentaire "// x signes" qui precede
+         if (preg_match(",^(?:\s*//[^\n]*\n)?'([^']+)'*$,ms", $x, $m))  {
+           $x = id_table_objet($type = $m[1]);
+           if (isset($boucle->show['field'][$x]))
+             $primary = $x; // sinon erreur declenchee ci-dessous
+         }
+       }
 
        if (!$primary OR strpos($primary,',')) {
                return (array('zbug_doublon_sur_table_sans_cle_primaire'));
        }
-
        $not = ($crit->not ? '' : 'NOT');
-
        $nom = !isset($crit->param[0]) ? "''" : calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
        // mettre un tableau pour que ce ne soit pas vu comme une constante
 
-       $nom = "'" .
-         $boucle->type_requete . 
-         "'" .
-         ($nom == "''" ? '' : " . $nom");
+       $nom = "'" . $type .  "'" .  ($nom == "''" ? '' : " . $nom");
 
        $debutdoub = '$doublons['
        .  (!$not ? '' : ($boucle->doublons . "[]= "));
@@ -93,9 +102,6 @@ function critere_doublons_dist($idb, &$boucles, $crit) {
        }
        $boucle->where[]= array($suitin . $findoub . ", '" . $not . "')");
 
-
-
-
 # la ligne suivante avait l'intention d'eviter une collecte deja faite
 # mais elle fait planter une boucle a 2 critere doublons:
 # {!doublons A}{doublons B}
@@ -530,19 +536,38 @@ function critere_agenda_dist($idb, &$boucles, $crit)
        $params = $crit->param;
 
        if (count($params) < 1)
-               return (array('zbug_critere_inconnu', array('critere' => $crit->op . " ?")));
-
-       $parent = $boucles[$idb]->id_parent;
+               return array('zbug_critere_inconnu', array('critere' => $crit->op . " ?"));
 
-       // les valeurs $date et $type doivent etre connus a la compilation
-       // autrement dit ne pas etre des champs
+       $boucle = &$boucles[$idb];
+       $parent = $boucle->id_parent;
+       $fields = $boucle->show['field'];
 
        $date = array_shift($params);
-       $date = $date[0]->texte;
-
        $type = array_shift($params);
+
+       // la valeur $type doit etre connue a la compilation
+       // donc etre forcement reduite a un litteral unique dans le source
+
        $type = $type[0]->texte;
 
+       // La valeur date doit designer un champ de la table SQL.
+       // Si c'est un litteral unique dans le source, verifier a la compil,
+       // sinon synthetiser le test de verif pour execution ulterieure
+       // On prendra arbitrairement le premier champ si test negatif.
+
+       if ((count($date) == 1)  AND ($date[0]->type == 'texte')) {
+               $date = $date[0]->texte;
+               if (!isset($fields[$date]))
+                 return array('zbug_critere_inconnu', array('critere' => $crit->op . " " . $date));
+       } else  {
+               $a = calculer_liste($date, array(), $boucles, $parent);
+               $noms = array_keys($fields);
+               $defaut = $noms[0];
+               $noms = join(" ", $noms);
+               # bien laisser 2 espaces avant $nom pour que strpos<>0
+               $cond = "(\$a=strval($a))AND\nstrpos(\"  $noms \",\" \$a \")";
+               $date = "'.(($cond)\n?\$a:\"$defaut\").'";
+       }
        $annee = $params ? array_shift($params) : "";
        $annee = "\n" . 'sprintf("%04d", ($x = ' .
                calculer_liste($annee, array(), $boucles, $parent) .
@@ -573,7 +598,6 @@ function critere_agenda_dist($idb, &$boucles, $crit)
                calculer_liste($jour2, array(), $boucles, $parent) .
                ') ? $x : date("d"))';
 
-       $boucle = &$boucles[$idb];
        $date = $boucle->id_table . ".$date";
 
        if ($type == 'jour')