Example #1
0
/**
 * Détermine l'operateur et les opérandes d'un critère non déclaré
 *
 * Lorsque l'opérateur n'est pas explicite comme sur {id_article>0} c'est
 * l'opérateur '=' qui est utilisé.
 *
 * Traite les cas particuliers id_parent, id_enfant, date, lang
 *
 * @param string $idb     Identifiant de la boucle
 * @param array $boucles  AST du squelette
 * @param Critere $crit   Paramètres du critère dans cette boucle
 * @return array
 *     Liste :
 *     - string $fct       Nom d'une fonction SQL sur le champ ou vide (ex: SUM)
 *     - string $col       Nom de la colonne SQL utilisée
 *     - string $op        Opérateur
 *     - string[] $val
 *         Liste de codes PHP obtenant les valeurs des comparaisons (ex: id_article sur la boucle parente)
 *         Souvent un tableau d'un seul élément.
 *     - string $args_sql  Suite des arguments du critère. ?
**/
function calculer_critere_infixe_ops($idb, &$boucles, $crit)
{
    // cas d'une valeur comparee a elle-meme ou son referent
    if (count($crit->param) == 0) {
        $op = '=';
        $col = $val = $crit->op;
        if (preg_match('/^(.*)\\.(.*)$/', $col, $r)) {
            $val = $r[2];
        }
        // Cas special {lang} : aller chercher $GLOBALS['spip_lang']
        if ($val == 'lang') {
            $val = array(kwote('$GLOBALS[\'spip_lang\']'));
        } else {
            $defaut = null;
            if ($val == 'id_parent') {
                // Si id_parent, comparer l'id_parent avec l'id_objet
                // de la boucle superieure.... faudrait verifier qu'il existe
                // pour eviter l'erreur SQL
                $val = $boucles[$idb]->primary;
                // mais si pas de boucle superieure, prendre id_parent dans l'env
                $defaut = "\$Pile[0]['id_parent']";
            } elseif ($val == 'id_enfant') {
                // Si id_enfant, comparer l'id_objet avec l'id_parent
                // de la boucle superieure
                $val = 'id_parent';
            } elseif ($crit->cond and ($col == "date" or $col == "date_redac")) {
                // un critere conditionnel sur date est traite a part
                // car la date est mise d'office par SPIP,
                $defaut = "(\$Pile[0]['{$col}_default']?'':\$Pile[0]['" . $col . "'])";
            }
            $val = calculer_argument_precedent($idb, $val, $boucles, $defaut);
            $val = array(kwote($val));
        }
    } else {
        // comparaison explicite
        // le phraseur impose que le premier param soit du texte
        $params = $crit->param;
        $op = $crit->op;
        if ($op == '==') {
            $op = 'REGEXP';
        }
        $col = array_shift($params);
        $col = $col[0]->texte;
        $val = array();
        $desc = array('id_mere' => $idb);
        $parent = $boucles[$idb]->id_parent;
        // Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
        // celui ne sachant pas ce qu'est un critere infixe
        // et a fortiori son 2e operande qu'entoure " ou '
        if (count($params) == 1 and count($params[0] == 3) and $params[0][0]->type == 'texte' and @$params[0][2]->type == 'texte' and ($p = $params[0][0]->texte) == $params[0][2]->texte and ($p == "'" or $p == '"') and $params[0][1]->type == 'champ') {
            $val[] = "{$p}\\{$p}#" . $params[0][1]->nom_champ . "\\{$p}{$p}";
        } else {
            foreach ($op != 'IN' ? $params : calculer_vieux_in($params) as $p) {
                $a = calculer_liste($p, $desc, $boucles, $parent);
                if (strcasecmp($op, 'IN') == 0) {
                    $val[] = $a;
                } else {
                    $val[] = kwote($a, $boucles[$idb]->sql_serveur, 'char');
                }
                // toujours quoter en char ici
            }
        }
    }
    $fct = $args_sql = '';
    // fonction SQL ?
    // chercher FONCTION(champ) tel que CONCAT(titre,descriptif)
    if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
        $fct = $m[1];
        preg_match('/^\\(([^,]*)(.*)\\)$/', $m[2], $a);
        $col = $a[1];
        if (preg_match('/^(\\S*)(\\s+AS\\s+.*)$/i', $col, $m)) {
            $col = $m[1];
            $args_sql = $m[2];
        }
        $args_sql .= $a[2];
    }
    return array($fct, $col, $op, $val, $args_sql);
}
Example #2
0
function calculer_critere_infixe_ops($idb, &$boucles, $crit)
{
	// cas d'une valeur comparee a elle-meme ou son referent
	if (count($crit->param) == 0)
	  { $op = '=';
	    $col = $val = $crit->op;
	    if (preg_match('/^(.*)\.(.*)$/', $col, $r)) $val = $r[2];
	    // Cas special {lang} : aller chercher $GLOBALS['spip_lang']
	    if ($val == 'lang')
	      $val = array(kwote('$GLOBALS[\'spip_lang\']'));
	    else {
	    // Si id_parent, comparer l'id_parent avec l'id_objet
	    // de la boucle superieure.... faudrait verifier qu'il existe
	      // pour eviter l'erreur SQL
	      if ($val == 'id_parent')
		$val = $boucles[$idb]->primary;
	      // Si id_enfant, comparer l'id_objet avec l'id_parent
	      // de la boucle superieure
	      else if ($val == 'id_enfant')
		$val = 'id_parent';
	// un critere conditionnel sur date est traite a part
	// car la date est mise d'office par SPIP, 
	      $val = calculer_argument_precedent($idb, $val, $boucles);
	      if ($crit->cond AND ($col == "date" OR $col == "date_redac")) {
		      if($val == "\$Pile[0]['".$col."']") {
			$val = "(\$Pile[0]['{$col}_default']?'':$val)";
		      }
	      }
	      $val = array(kwote($val));
	    }
	  } else {
	    // comparaison explicite
	    // le phraseur impose que le premier param soit du texte
		$params = $crit->param;
		$op = $crit->op;
		if ($op == '==') $op = 'REGEXP';
		$col = array_shift($params);
		$col = $col[0]->texte;

		$val = array();
		$desc = array('id_mere' => $idb);
		$parent = $boucles[$idb]->id_parent;

		// Dans le cas {x=='#DATE'} etc, defaire le travail du phraseur,
		// celui ne sachant pas ce qu'est un critere infixe
		// et a fortiori son 2e operande qu'entoure " ou '
		if (count($params)==1
		AND count($params[0]==3)
		AND $params[0][0]->type == 'texte' 
		AND @$params[0][2]->type == 'texte' 
		AND ($p=$params[0][0]->texte) == $params[0][2]->texte
		AND (($p == "'") OR ($p == '"'))
		AND $params[0][1]->type == 'champ' ) {
			$val[]= "$p\\$p#" . $params[0][1]->nom_champ . "\\$p$p";
		} else 
			foreach ((($op != 'IN') ? $params : calculer_vieux_in($params)) as $p) {
				$a = calculer_liste($p, $desc, $boucles, $parent);
				if ($op == 'IN') $val[]= $a;
				else $val[]=kwote($a);
			}
	}

	$fct = $args_sql = '';
	// fonction SQL ?
	if (preg_match('/^(.*)' . SQL_ARGS . '$/', $col, $m)) {
	  $fct = $m[1];
	  preg_match('/^\(([^,]*)(.*)\)$/', $m[2], $a);
	  $col = $a[1];
	  if (preg_match('/^(\S*)(\s+AS\s+.*)$/i', $col, $m)) {
	    $col=$m[1];
	    $args_sql = $m[2];
	  }
	  $args_sql .= $a[2];;
	}

	return array($fct, $col, $op, $val, $args_sql);
}