/**
 * Analyse les critères de boucle
 *
 * Chaque paramètre de la boucle (tel que {id_article>3}) est analysé
 * pour construire un critère (objet Critere) de boucle.
 *
 * Un critère a une description plus fine que le paramètre original
 * car on en extrait certaines informations tel que la négation et l'opérateur
 * utilisé s'il y a.
 *
 * La fonction en profite pour déclarer des modificateurs de boucles
 * en présence de certains critères (tout, plat) ou initialiser des
 * variables de compilation (doublons)...
 *
 * @param array $params
 *     Tableau de description des paramètres passés à la boucle.
 *     Chaque paramètre deviendra un critère
 * @param Boucle $result
 *     Description de la boucle
 *     Elle sera complété de la liste de ses critères
 * @return void
 **/
function phraser_criteres($params, &$result)
{
    $err_ci = '';
    // indiquera s'il y a eu une erreur
    $args = array();
    $type = $result->type_requete;
    $doublons = array();
    foreach ($params as $v) {
        $var = $v[1][0];
        $param = $var->type != 'texte' ? "" : $var->texte;
        if (count($v) > 2 && !preg_match(",[^A-Za-z]IN[^A-Za-z],i", $param)) {
            // plus d'un argument et pas le critere IN:
            // detecter comme on peut si c'est le critere implicite LIMIT debut, fin
            if ($var->type != 'texte' or preg_match("/^(n|n-|(n-)?\\d+)\$/S", $param)) {
                $op = ',';
                $not = "";
                $cond = false;
            } else {
                // Le debut du premier argument est l'operateur
                preg_match("/^([!]?)([a-zA-Z][a-zA-Z0-9_]*)[[:space:]]*(\\??)[[:space:]]*(.*)\$/ms", $param, $m);
                $op = $m[2];
                $not = $m[1];
                $cond = $m[3];
                // virer le premier argument,
                // et mettre son reliquat eventuel
                // Recopier pour ne pas alterer le texte source
                // utile au debusqueur
                if ($m[4]) {
                    // une maniere tres sale de supprimer les "' autour de {critere "xxx","yyy"}
                    if (preg_match(',^(["\'])(.*)\\1$,', $m[4])) {
                        $c = null;
                        eval('$c = ' . $m[4] . ';');
                        if (isset($c)) {
                            $m[4] = $c;
                        }
                    }
                    $texte = new Texte();
                    $texte->texte = $m[4];
                    $v[1][0] = $texte;
                } else {
                    array_shift($v[1]);
                }
            }
            array_shift($v);
            // $v[O] est vide
            $crit = new Critere();
            $crit->op = $op;
            $crit->not = $not;
            $crit->cond = $cond;
            $crit->exclus = "";
            $crit->param = $v;
            $args[] = $crit;
        } else {
            if ($var->type != 'texte') {
                // cas 1 seul arg ne commencant pas par du texte brut:
                // erreur ou critere infixe "/"
                if ($v[1][1]->type != 'texte' || trim($v[1][1]->texte) != '/') {
                    $err_ci = array('zbug_critere_inconnu', array('critere' => $var->nom_champ));
                    erreur_squelette($err_ci, $result);
                } else {
                    $crit = new Critere();
                    $crit->op = '/';
                    $crit->not = "";
                    $crit->exclus = "";
                    $crit->param = array(array($v[1][0]), array($v[1][2]));
                    $args[] = $crit;
                }
            } else {
                // traiter qq lexemes particuliers pour faciliter la suite
                // les separateurs
                if ($var->apres) {
                    $result->separateur[] = $param;
                } elseif ($param == 'tout' or $param == 'tous') {
                    $result->modificateur['tout'] = true;
                } elseif ($param == 'plat') {
                    $result->modificateur['plat'] = true;
                } elseif (strcasecmp($type, 'hierarchie') == 0 and !preg_match(",^id_rubrique\\b,", $param) and preg_match(",^id_\\w+\\s*\$,", $param)) {
                    $result->modificateur['tout'] = true;
                } elseif (strcasecmp($type, 'hierarchie') == 0 and $param == "id_rubrique") {
                    // rien a faire sur {id_rubrique} tout seul
                } else {
                    // pas d'emplacement statique, faut un dynamique
                    // mais il y a 2 cas qui ont les 2 !
                    if ($param == 'unique' || preg_match(',^!?doublons *,', $param)) {
                        // cette variable sera inseree dans le code
                        // et son nom sert d'indicateur des maintenant
                        $result->doublons = '$doublons_index';
                        if ($param == 'unique') {
                            $param = 'doublons';
                        }
                    } elseif ($param == 'recherche') {
                        // meme chose (a cause de #nom_de_boucle:URL_*)
                        $result->hash = ' ';
                    }
                    if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
                        $crit = phraser_critere_infixe($m[1], $m[3], $v, '/', '', '');
                    } elseif (preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC . ')[[:space:]]*(\\??)(!?)(<=?|>=?|==?|\\b(?:IN|LIKE)\\b)(.*)$,is', $param, $m)) {
                        $a2 = trim($m[8]);
                        if ($a2 and ($a2[0] == "'" or $a2[0] == '"') and $a2[0] == substr($a2, -1)) {
                            $a2 = substr($a2, 1, -1);
                        }
                        $crit = phraser_critere_infixe($m[2], $a2, $v, $m[2] == 'lang_select' ? $m[2] : $m[7], $m[6], $m[5]);
                        $crit->exclus = $m[1];
                    } elseif (preg_match("/^([!]?)\\s*(" . CHAMP_SQL_PLUS_FONC . ")\\s*(\\??)(.*)\$/is", $param, $m)) {
                        // contient aussi les comparaisons implicites !
                        // Comme ci-dessus:
                        // le premier arg contient l'operateur
                        array_shift($v);
                        if ($m[6]) {
                            $v[0][0] = new Texte();
                            $v[0][0]->texte = $m[6];
                        } else {
                            array_shift($v[0]);
                            if (!$v[0]) {
                                array_shift($v);
                            }
                        }
                        $crit = new Critere();
                        $crit->op = $m[2];
                        $crit->param = $v;
                        $crit->not = $m[1];
                        $crit->cond = $m[5];
                    } else {
                        $err_ci = array('zbug_critere_inconnu', array('critere' => $param));
                        erreur_squelette($err_ci, $result);
                    }
                    if (!preg_match(',^!?doublons *,', $param) || $crit->not) {
                        $args[] = $crit;
                    } else {
                        $doublons[] = $crit;
                    }
                }
            }
        }
    }
    // les doublons non nies doivent etre le dernier critere
    // pour que la variable $doublon_index ait la bonne valeur
    // cf critere_doublon
    if ($doublons) {
        $args = array_merge($args, $doublons);
    }
    // Si erreur, laisser la chaine dans ce champ pour le HTTP 503
    if (!$err_ci) {
        $result->criteres = $args;
    }
}
Beispiel #2
0
function phraser_criteres($params, &$result) {

	$err_ci = ''; // indiquera s'il y a eu une erreur
	$args = array();
	$type = $result->type_requete;
	$doublons = array();
	foreach($params as $v) {
		$var = $v[1][0];
		$param = ($var->type != 'texte') ? "" : $var->texte;
		if ((count($v) > 2) && (!preg_match(",[^A-Za-z]IN[^A-Za-z],i",$param)))
		  {
// plus d'un argument et pas le critere IN:
// detecter comme on peut si c'est le critere implicite LIMIT debut, fin

			if (($var->type != 'texte') ||
			    (strpos("0123456789-", $param[strlen($param)-1])
			     !== false)) {
			  $op = ',';
			  $not = "";
			} else {
			  // Le debut du premier argument est l'operateur
			  preg_match("/^([!]?)([a-zA-Z][a-zA-Z0-9]*)[[:space:]]*(.*)$/ms", $param, $m);
			  $op = $m[2];
			  $not = $m[1];
			  // virer le premier argument,
			  // et mettre son reliquat eventuel
			  // Recopier pour ne pas alterer le texte source
			  // utile au debusqueur

			  if ($m[3]) {
			    $texte = new Texte;
			    $texte->texte = $m[3]; 
			    $v[1][0]= $texte;
			  } else array_shift($v[1]);
			}
			array_shift($v); // $v[O] est vide
			$crit = new Critere;
			$crit->op = $op;
			$crit->not = $not;
			$crit->exclus ="";
			$crit->param = $v;
			$args[] = $crit;
		  } else {
		  if ($var->type != 'texte') {
		    // cas 1 seul arg ne commencant pas par du texte brut: 
		    // erreur ou critere infixe "/"
		    if (($v[1][1]->type != 'texte') || (trim($v[1][1]->texte) !='/')) {
			$err_ci = array('zbug_critere_inconnu', 
					array('critere' => $var->nom_champ));
			erreur_squelette($err_ci, $result);
		    } else {
		      $crit = new Critere;
		      $crit->op = '/';
		      $crit->not = "";
		      $crit->exclus ="";
		      $crit->param = array(array($v[1][0]),array($v[1][2]));
		      $args[] = $crit;
		    }
		  } else {
	// traiter qq lexemes particuliers pour faciliter la suite
	// les separateurs
			if ($var->apres)
				$result->separateur[] = $param;
			elseif (($param == 'tout') OR ($param == 'tous'))
				$result->modificateur['tout'] = true;
			elseif ($param == 'plat') 
				$result->modificateur['plat'] = true;

	// Boucle hierarchie, analyser le critere id_article - id_rubrique
	// - id_syndic, afin, dans les cas autres que {id_rubrique}, de
	// forcer {tout} pour avoir la rubrique mere...

			elseif (!strcasecmp($type, 'hierarchie') AND
				($param == 'id_article' OR $param == 'id_syndic'))
				$result->modificateur['tout'] = true;
			elseif (!strcasecmp($type, 'hierarchie') AND ($param == 'id_rubrique'))
				{;}
			else {
			  // pas d'emplacement statique, faut un dynamique
			  /// mais il y a 2 cas qui ont les 2 !
			  if (($param == 'unique') || (preg_match(',^!?doublons *,', $param)))
			    {
			      // cette variable sera inseree dans le code
			      // et son nom sert d'indicateur des maintenant
			      $result->doublons = '$doublons_index';
			      if ($param == 'unique') $param = 'doublons';
			    }
			  elseif ($param == 'recherche')
			    // meme chose (a cause de #nom_de_boucle:URL_*)
			      $result->hash = ' ';
			  if (preg_match(',^ *([0-9-]+) *(/) *(.+) *$,', $param, $m)) {
			    $crit = phraser_critere_infixe($m[1], $m[3],$v, '/', '', '');
			  } elseif (preg_match(',^([!]?)(' . CHAMP_SQL_PLUS_FONC . 
					 ')[[:space:]]*(\??)(!?)(<=?|>=?|==?|\b(?:IN|LIKE)\b)(.*)$,is', $param, $m)) {
			    $a2 = trim($m[8]);
			    if ($a2 AND ($a2[0]=="'" OR $a2[0]=='"') AND ($a2[0]==substr($a2,-1)))
			      $a2 = substr($a2,1,-1);
			    $crit = phraser_critere_infixe($m[2], $a2, $v,
							   (($m[2] == 'lang_select') ? $m[2] : $m[7]),
							   $m[6], $m[5]);
					$crit->exclus = $m[1];
			  } elseif (preg_match("/^([!]?)\s*(" .
					       CHAMP_SQL_PLUS_FONC .
					       ")\s*(\??)(.*)$/is", $param, $m)) {
		  // contient aussi les comparaisons implicites !
			    // Comme ci-dessus: 
			    // le premier arg contient l'operateur
			    array_shift($v);
			    if ($m[6]) {
			      $v[0][0] = new Texte;
			      $v[0][0]->texte = $m[6];
			    } else {
			      array_shift($v[0]);
			      if (!$v[0]) array_shift($v);
			    }
			    $crit = new Critere;
			    $crit->op = $m[2];
			    $crit->param = $v;
			    $crit->not = $m[1];
			    $crit->cond = $m[5];
			  }
			  else {
			 	$err_ci = array('zbug_critere_inconnu', 
					array('critere' => $param));
				erreur_squelette($err_ci, $result);
			  }
			  if ((!preg_match(',^!?doublons *,', $param)) || $crit->not)
			    $args[] = $crit;
			  else 
			    $doublons[] = $crit;
			}
		  }
		}
	}
	// les doublons non nies doivent etre le dernier critere
	// pour que la variable $doublon_index ait la bonne valeur
	// cf critere_doublon
	if ($doublons) $args= array_merge($args, $doublons);
	// Si erreur, laisser la chaine dans ce champ pour le HTTP 503
	if (!$err_ci) $result->criteres = $args;
}