/** * 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); }
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); }