function critere_FORUMS_meme_parent_dist($idb, &$boucles, $crit) { global $exceptions_des_tables; $boucle =& $boucles[$idb]; $arg = kwote(calculer_argument_precedent($idb, 'id_parent', $boucles)); $id_parent = isset($exceptions_des_tables[$boucle->id_table]['id_parent']) ? $exceptions_des_tables[$boucle->id_table]['id_parent'] : 'id_parent'; $mparent = $boucle->id_table . '.' . $id_parent; $boucle->where[] = array("'='", "'{$mparent}'", $arg); $boucle->where[] = array("'>'", "'{$mparent}'", 0); $boucle->modificateur['plat'] = true; }
/** * Compile une boucle HIERARCHIE * * La boucle `<BOUCLE(HIERARCHIE)>` retourne la liste des RUBRIQUES * qui mènent de la racine du site à la rubrique ou à l’article en cours. * * Cette boucle (aliasée sur la table RUBRIQUES) * * - recherche un id_rubrique dans les boucles parentes, * - extrait sa hiérarchie, en prenant ou non la rubrique en cours en fonction du critère {tout} * - crée une condition WHERE avec ces identifiants ansi qu'une clause ORDER * - compile la boucle. * * Le code compilé calculant la hierarchie est ajouté au tout début de la * fonction de boucle et quitte la boucle si aucune rubrique n'est trouvée. * * @link http://www.spip.net/913 * * @param string $id_boucle * Identifiant de la boucle * @param array $boucles * AST du squelette * @return string * Code PHP compilé de la boucle **/ function boucle_HIERARCHIE_dist($id_boucle, &$boucles) { $boucle =& $boucles[$id_boucle]; $id_table = $boucle->id_table . ".id_rubrique"; // Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille // sauf en presence du critere {tout} (vu par phraser_html) // ou {id_article} qui positionne aussi le {tout} $boucle->hierarchie = 'if (!($id_rubrique = intval(' . calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles) . ")))\n\t\treturn '';\n\t" . "include_spip('inc/rubriques');\n\t" . '$hierarchie = calcul_hierarchie_in($id_rubrique,' . (isset($boucle->modificateur['tout']) ? 'true' : 'false') . ");\n\t" . 'if (!$hierarchie) return "";' . "\n\t"; $boucle->where[] = array("'IN'", "'{$id_table}'", '"($hierarchie)"'); $order = "FIELD({$id_table}, \$hierarchie)"; if (!isset($boucle->default_order[0]) or $boucle->default_order[0] != " DESC") { $boucle->default_order[] = "\"{$order}\""; } else { $boucle->default_order[0] = "\"{$order} DESC\""; } return calculer_boucle($id_boucle, $boucles); }
/** * Compile une boucle HIERARCHIE * * <BOUCLE(HIERARCHIE)> * * Cette boucle (aliasée sur la table RUBRIQUES) * - recherche un id_rubrique dans les boucles parentes, * - extrait sa hiérarchie, en prenant ou non la rubrique en cours en fonction du critère {tout} * - crée une condition WHERE avec ces identifiants ansi qu'une clause ORDER * - compile la boucle. * * Le code compilé calculant la hierarchie est ajouté au tout début de la * fonction de boucle et quitte la boucle si aucune rubrique n'est trouvée. * * @param string $id_boucle * Identifiant de la boucle * @param array $boucles * AST du squelette * @return string * Code PHP compilé de la boucle **/ function boucle_HIERARCHIE_dist($id_boucle, &$boucles) { $boucle =& $boucles[$id_boucle]; $id_table = $boucle->id_table . ".id_rubrique"; // Si la boucle mere est une boucle RUBRIQUES il faut ignorer la feuille // sauf en presence du critere {tout} (vu par phraser_html) // ou {id_article} qui positionne aussi le {tout} $boucle->hierarchie = 'if (!($id_rubrique = intval(' . calculer_argument_precedent($boucle->id_boucle, 'id_rubrique', $boucles) . ")))\n\t\treturn '';\n\t" . '$hierarchie = ' . (isset($boucle->modificateur['tout']) ? '",$id_rubrique"' : "''") . ";\n\t" . 'while ($id_rubrique = sql_getfetsel("id_parent","spip_rubriques","id_rubrique=" . $id_rubrique,"","","", "", $connect)) { $hierarchie = ",$id_rubrique$hierarchie"; } if (!$hierarchie) return ""; $hierarchie = substr($hierarchie,1);'; $boucle->where[] = array("'IN'", "'{$id_table}'", '"($hierarchie)"'); $order = "FIELD({$id_table}, \$hierarchie)"; if (!isset($boucle->default_order[0]) or $boucle->default_order[0] != " DESC") { $boucle->default_order[] = "\"{$order}\""; } else { $boucle->default_order[0] = "\"{$order} DESC\""; } return calculer_boucle($id_boucle, $boucles); }
/** * Calcul des critères {suivant} et {precedent} (avant l'existence d'Iterateurs). * On reprend en grande partie le fonctionnement de {pagination} avec debut_xx=@yy * en jouant de sql_seek pour se déplacer à la bonne position sur les résultats de * la boucle. * * @param string $type type de décalage : 'suivant' ou 'precedent' **/ function calculer_critere_suivant_precedent_dist($idb, &$boucles, $crit, $type) { $boucle = &$boucles[$idb]; $primary = $boucle->primary; $arg = kwote(calculer_argument_precedent($idb, $primary, $boucles)); $partie = "0;\n" ."\tif (\$id_actuel = $arg) {\n" ."\t\t".'$debut_boucle = quete_position_primary(\''.$primary.'\', $id_actuel, "'.$type.'", $result, '._q($boucle->sql_serveur).');'."\n" // pas de resultat, on cree une selection vide ."\t\t".'if ($debut_boucle === false){'."\n" ."\t\t\t".'@sql_free($result,'._q($boucle->sql_serveur).");\n" ."\t\t\t"."\$where[] = array('=','0','1');\n" // forcer 0 resultat ."\t\t\t".'$result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);'."\n" //."\t\t\t"."\$Numrows['$idb']['total'] = 0;\n" ."\t\t} else {\n" // si on a des resultats, il faut remettre le compteur a zero. ."\t\t".'if (!sql_seek($result,0,'._q($boucle->sql_serveur).")){\n" ."\t\t\t".'@sql_free($result,'._q($boucle->sql_serveur).");\n" ."\t\t\t".'$result = calculer_select($select, $from, $type, $where, $join, $groupby, $orderby, $limit, $having, $table, $id, $connect);'."\n" ."\t\t}\n" // donner un bon GRAND_TOTAL pour la fonction calculer_parties() // NAN ça marche pas non plus... mah que passa ? //."\t\t\t"."\$Numrows['$idb']['total'] = (\$Numrows['$idb']['total'] >= 1 ? 2 : 0);\n" ."\t\t}\n" ."\t}\n" ."\t".'$debut_boucle = intval($debut_boucle)'; $boucle->total_parties = 1; calculer_parties($boucles, $idb, $partie, '++'); // ajouter la cle primaire dans le select // sauf si pas de primaire, ou si primaire composee // dans ce cas, on ne sait pas gerer une pagination indirecte // : il faut id_xx dans le select pour la fonction quete_position_primary() $t = $boucle->id_table . '.' . $primary; if ($boucle->primary AND !preg_match('/[,\s]/',$primary) AND !in_array($t, $boucle->select)) { $boucle->select[]= $t; } // forcer le compilo à ne pas prendre en static a cause du $where fluctuant $boucle->where[]= array("'='","'1'","sql_quote(1)"); }
/** * Calcule les cas particuliers de critères de date * * Lorsque la colonne correspond à un critère de date, tel que * jour, jour_relatif, jour_x, age, age_relatif, age_x... * * @param string $idb Identifiant de la boucle * @param array $boucles AST du squelette * @param string $col Nom du champ demandé * @return string|array * chaine vide si ne correspond pas à une date, * sinon liste * - expression SQL de calcul de la date, * - nom de la colonne de date (si le calcul n'est pas relatif) **/ function calculer_critere_infixe_date($idb, &$boucles, $col) { if (!preg_match(",^((age|jour|mois|annee)_relatif|date|mois|annee|jour|heure|age)(_[a-z]+)?\$,", $col, $regs)) { return ''; } $boucle = $boucles[$idb]; $table = $boucle->show; // si c'est une colonne de la table, ne rien faire if (isset($table['field'][$col])) { return ''; } if (!$table['date'] && !isset($GLOBALS['table_date'][$table['id_table']])) { return ''; } $pred = $date_orig = isset($GLOBALS['table_date'][$table['id_table']]) ? $GLOBALS['table_date'][$table['id_table']] : $table['date']; $pred = $date_orig = $table['date']; $col = $regs[1]; if (isset($regs[3]) and $suite = $regs[3]) { # Recherche de l'existence du champ date_xxxx, # si oui choisir ce champ, sinon choisir xxxx if (isset($table['field']["date{$suite}"])) { $date_orig = 'date' . $suite; } else { $date_orig = substr($suite, 1); } $pred = $date_orig; } else { if (isset($regs[2]) and $rel = $regs[2]) { $pred = 'date'; } } $date_compare = "\"' . normaliser_date(" . calculer_argument_precedent($idb, $pred, $boucles) . ") . '\""; $col_vraie = $date_orig; $date_orig = $boucle->id_table . '.' . $date_orig; switch ($col) { case 'date': $col = $date_orig; break; case 'jour': $col = "DAYOFMONTH({$date_orig})"; break; case 'mois': $col = "MONTH({$date_orig})"; break; case 'annee': $col = "YEAR({$date_orig})"; break; case 'heure': $col = "DATE_FORMAT({$date_orig}, \\'%H:%i\\')"; break; case 'age': $col = calculer_param_date("NOW()", $date_orig); $col_vraie = ""; // comparer a un int (par defaut) break; case 'age_relatif': $col = calculer_param_date($date_compare, $date_orig); $col_vraie = ""; // comparer a un int (par defaut) break; case 'jour_relatif': $col = "(TO_DAYS(" . $date_compare . ")-TO_DAYS(" . $date_orig . "))"; $col_vraie = ""; // comparer a un int (par defaut) break; case 'mois_relatif': $col = "MONTH(" . $date_compare . ")-MONTH(" . $date_orig . ")+12*(YEAR(" . $date_compare . ")-YEAR(" . $date_orig . "))"; $col_vraie = ""; // comparer a un int (par defaut) break; case 'annee_relatif': $col = "YEAR(" . $date_compare . ")-YEAR(" . $date_orig . ")"; $col_vraie = ""; // comparer a un int (par defaut) break; } return array($col, $col_vraie); }
function critere_popularite_branche($idb, &$boucles, $crit){ $op=''; $boucle = &$boucles[$idb]; $params = $crit->param; $type = array_shift($params); $type = $type[0]->texte; if(preg_match(',^(\w+)([<>=])([0-9]+)$,',$type,$r)){ $type=$r[1]; $op=$r[2]; $op_val=$r[3]; } $type_id = 'pop.id_'.$type; $pop = 'lf.popularite'; $type_requete = $boucle->type_requete; $id_table = $boucle->id_table . '.' . $boucle->primary; $pop_max=max(1 , 0 + $GLOBALS['meta']['popularite_max']); $boucle->select[]= 'CEIL(SUM('.$pop.'*100/'.$pop_max.')) AS popularite_relative'; $boucle->from['pop']="spip_'.$type_requete.'_".$type."s"; $boucle->where[]= array("'='", "'".$id_table."'", "'pop.".$boucle->primary."'"); $boucle->from['lf']="spip_".$type."s"; $boucle->where[]= array("'='", "'".$type_id."'", "'lf.id_".$type."'"); $boucle->group[]=$id_table; if ($op) $boucle->having[]= array("'".$op."'", "'popularite_relative'",$op_val); $not = $crit->not; $boucle = &$boucles[$idb]; $arg = calculer_argument_precedent($idb, 'id_rubrique', $boucles); $c = "calcul_mysql_in('lf.id_rubrique', calcul_branche($arg), '')"; $c = "($arg ? $c : 1)"; if ($not) $boucle->where[]= array("'NOT'", $c); else $boucle->where[]= $c; }
function calculer_critere_infixe_date($idb, &$boucles, $regs) { global $table_date; $boucle = $boucles[$idb]; $col = $regs[1]; $date_orig = $pred = isset($table_date[$boucle->type_requete])?$table_date[$boucle->type_requete]:'date'; if (isset($regs[3]) AND $suite=$regs[3]) { # Recherche de l'existence du champ date_xxxx, # si oui choisir ce champ, sinon choisir xxxx $t = $boucle->show; if ($t['field']["date$suite"]) $date_orig = 'date'.$suite; else $date_orig = substr($suite, 1); $pred = $date_orig; } else if (isset($regs[2]) AND $rel=$regs[2]) $pred = 'date'; $date_compare = "\"' . normaliser_date(" . calculer_argument_precedent($idb, $pred, $boucles) . ") . '\""; $date_orig = $boucle->id_table . '.' . $date_orig; switch ($col) { case 'date': $col = $date_orig; break; case 'jour': $col = "DAYOFMONTH($date_orig)"; break; case 'mois': $col = "MONTH($date_orig)"; break; case 'annee': $col = "YEAR($date_orig)"; break; case 'heure': $col = "DATE_FORMAT($date_orig, '%H:%i')"; break; case 'age': $col = calculer_param_date("NOW()", $date_orig); break; case 'age_relatif': $col = calculer_param_date($date_compare, $date_orig); break; case 'jour_relatif': $col = "LEAST(TO_DAYS(" .$date_compare . ")-TO_DAYS(" . $date_orig . "), DAYOFMONTH(" . $date_compare . ")-DAYOFMONTH(" . $date_orig . ")+30.4368*(MONTH(" . $date_compare . ")-MONTH(" . $date_orig . "))+365.2422*(YEAR(" . $date_compare . ")-YEAR(" . $date_orig . ")))"; break; case 'mois_relatif': $col = "MONTH(" . $date_compare . ")-MONTH(" . $date_orig . ")+12*(YEAR(" . $date_compare . ")-YEAR(" . $date_orig . "))"; break; case 'annee_relatif': $col = "YEAR(" . $date_compare . ")-YEAR(" . $date_orig . ")"; break; } return $col; }