コード例 #1
0
/**
 * Permet de faire un comptage par table liee
 *
 * @syntaxe `{compteur table[, champ]}`
 * @link http://www.spip-contrib.net/Classer-les-articles-par-nombre-de#forum409210
 * 
 * @example
 *     Pour avoir les auteurs classes par articles et
 *     le nombre d'article de chacun :
 * 
 *     ```
 *     <BOUCLE1(AUTEURS){compteur articles}{par compteur_articles}>
 *     #ID_AUTEUR : #COMPTEUR{articles}
 *     </BOUCLE1>
 *     ```
 *
 * @note
 *     Avec un seul argument {compteur autre_table} le groupby est fait
 *     implicitement sur la cle primaire de la boucle en cours.
 *     Avec un second argument {compteur autre_table,champ_fusion}
 *     le groupby est fait sur le champ_fusion"
 * 
 * @param string $idb
 *     Identifiant de la boucle
 * @param Boucle[] $boucles
 *     AST du squelette
 * @param Critere $crit
 *     Paramètres du critère dans cette boucle
 * @param bool $left
 *     true pour utiliser un left join plutôt qu'un inner join.      
 * @return void
 */
function critere_compteur($idb, &$boucles, $crit, $left = false)
{
    $boucle =& $boucles[$idb];
    if (isset($crit->param[1])) {
        $_fusion = calculer_liste($crit->param[1], array(), $boucles, $boucle->id_parent);
    } else {
        $_fusion = "''";
    }
    $params = $crit->param;
    $table = reset($params);
    $table = $table[0]->texte;
    $op = false;
    if (preg_match(',^(\\w+)([<>=])([0-9]+)$,', $table, $r)) {
        $table = $r[1];
        if (count($r) >= 3) {
            $op = $r[2];
        }
        if (count($r) >= 4) {
            $op_val = $r[3];
        }
    }
    $type = objet_type($table);
    $type_id = id_table_objet($type);
    /**
     * Si la clé primaire est une clé multiple, on prend la première partie
     * Utile pour compter les versions de spip_versions par exemple
     */
    if (count($types = explode(',', $type_id)) > 1) {
        $type_id = $types[0];
    }
    $table_sql = table_objet_sql($type);
    $trouver_table = charger_fonction('trouver_table', 'base');
    $arrivee = array($table, $trouver_table($table, $boucle->sql_serveur));
    $depart = array($boucle->id_table, $trouver_table($boucle->id_table, $boucle->sql_serveur));
    // noter les jointures deja installees
    $joins = array_keys($boucle->from);
    if ($compt = calculer_jointure($boucle, $depart, $arrivee)) {
        if ($_fusion != "''") {
            // en cas de jointure, on ne veut pas du group_by sur la cle primaire !
            // cela casse le compteur !
            foreach ($boucle->group as $k => $group) {
                if ($group == $boucle->id_table . '.' . $boucle->primary) {
                    unset($boucle->group[$k]);
                }
            }
            $boucle->group[] = '".($gb=' . $_fusion . ')."';
        }
        $boucle->select[] = "COUNT({$compt}.{$type_id}) AS compteur_{$table}";
        if ($op) {
            $boucle->having[] = array("'" . $op . "'", "'compteur_" . $table . "'", $op_val);
        }
        if ($left) {
            foreach ($boucle->from as $k => $val) {
                if (!in_array($k, $joins)) {
                    $boucle->from_type[$k] = 'left';
                }
            }
        }
    }
}
コード例 #2
0
/**
 * Retourne le code PHP d'un argument de balise s'il est présent
 *
 * @uses calculer_liste()
 * @example
 *     ```
 *     // Retourne le premier argument de la balise
 *     // #BALISE{premier,deuxieme}
 *     $arg = interprete_argument_balise(1,$p);
 *     ```
 *
 * @param int $n
 *     Numéro de l'argument
 * @param Champ $p
 *     Pile au niveau de la balise
 * @return string|null
 *     Code PHP si cet argument est présent, sinon null
 **/
function interprete_argument_balise($n, $p)
{
    if ($p->param && !$p->param[0][0] && count($p->param[0]) > $n) {
        return calculer_liste($p->param[0][$n], $p->descr, $p->boucles, $p->id_boucle);
    } else {
        return null;
    }
}
コード例 #3
0
/**
 * Fonction privee pour mutualiser de code des criteres_MESSAGES_rv_*
 * Retourne le code php pour obtenir la date de reference de comparaison
 * des evenements a trouver
 *
 * @param string $idb
 * @param object $boucles
 * @param object $crit
 *
 * @return string code PHP concernant la date.
**/
function organiseur_calculer_date_reference($idb, &$boucles, $crit)
{
    if (isset($crit->param[0])) {
        return calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
    } else {
        return "date('Y-m-d H:i:00')";
    }
}
コード例 #4
0
ファイル: balises.php プロジェクト: rhertzog/lcs
function interprete_argument_balise($n,$p) {
	if (($p->param) && (!$p->param[0][0]) && (count($p->param[0])>$n))
		return calculer_liste($p->param[0][$n],
			$p->descr,
			$p->boucles,
			$p->id_boucle);
	else
		return NULL;
}
コード例 #5
0
ファイル: auteurs_fonctions.php プロジェクト: spip/SPIP
/**
 * Compter les articles publies lies a un auteur, dans une boucle auteurs
 * pour la vue prive/liste/auteurs.html
 *
 * @param <type> $idb
 * @param <type> $boucles
 * @param <type> $crit
 * @param <type> $left
 */
function critere_compteur_articles_filtres_dist($idb, &$boucles, $crit, $left = false)
{
    $boucle =& $boucles[$idb];
    $_statut = calculer_liste($crit->param[0], array(), $boucles, $boucle->id_parent);
    $not = '';
    if ($crit->not) {
        $not = ", 'NOT'";
    }
    $boucle->from['LAA'] = 'spip_auteurs_liens';
    $boucle->from_type['LAA'] = 'left';
    $boucle->join['LAA'] = array("'auteurs'", "'id_auteur'", "'id_auteur'", "'LAA.objet=\\'article\\''");
    $boucle->from['articles'] = 'spip_articles';
    $boucle->from_type['articles'] = 'left';
    $boucle->join['articles'] = array("'LAA'", "'id_article'", "'id_objet'", "'(articles.statut IS NULL OR '.sql_in('articles.statut',_q({$_statut}){$not}).')'");
    $boucle->select[] = 'COUNT(articles.id_article) AS compteur_articles';
    $boucle->group[] = 'auteurs.id_auteur';
}
コード例 #6
0
/**
 * {agendafull ..} variante etendue du crietre agenda du core
 * qui accepte une date de debut et une date de fin
 *
 * {agendafull date_debut, date_fin, jour, #ENV{annee}, #ENV{mois}, #ENV{jour}}
 * {agendafull date_debut, date_fin, semaine, #ENV{annee}, #ENV{mois}, #ENV{jour}}
 * {agendafull date_debut, date_fin, mois, #ENV{annee}, #ENV{mois}}
 * {agendafull date_debut, date_fin, periode, #ENV{annee}, #ENV{mois}, #ENV{jour},
 *                                            #ENV{annee_fin}, #ENV{mois_fin}, #ENV{jour_fin}}
 *
 * @param string $idb
 * @param object $boucles
 * @param object $crit
 */
function critere_agendafull_dist($idb, &$boucles, $crit)
{
    $params = $crit->param;
    if (count($params) < 1) {
        erreur_squelette(_T('zbug_info_erreur_squelette'), "{agenda ?} BOUCLE{$idb}");
    }
    $parent = $boucles[$idb]->id_parent;
    // les valeurs $date et $type doivent etre connus a la compilation
    // autrement dit ne pas etre des champs
    $date_deb = array_shift($params);
    $date_deb = $date_deb[0]->texte;
    $date_fin = array_shift($params);
    $date_fin = $date_fin[0]->texte;
    $type = array_shift($params);
    $type = $type[0]->texte;
    $annee = $params ? array_shift($params) : "";
    $annee = "\n" . 'sprintf("%04d", ($x = ' . calculer_liste($annee, array(), $boucles, $parent) . ') ? $x : date("Y"))';
    $mois = $params ? array_shift($params) : "";
    $mois = "\n" . 'sprintf("%02d", ($x = ' . calculer_liste($mois, array(), $boucles, $parent) . ') ? $x : date("m"))';
    $jour = $params ? array_shift($params) : "";
    $jour = "\n" . 'sprintf("%02d", ($x = ' . calculer_liste($jour, array(), $boucles, $parent) . ') ? $x : date("d"))';
    $annee2 = $params ? array_shift($params) : "";
    $annee2 = "\n" . 'sprintf("%04d", ($x = ' . calculer_liste($annee2, array(), $boucles, $parent) . ') ? $x : date("Y"))';
    $mois2 = $params ? array_shift($params) : "";
    $mois2 = "\n" . 'sprintf("%02d", ($x = ' . calculer_liste($mois2, array(), $boucles, $parent) . ') ? $x : date("m"))';
    $jour2 = $params ? array_shift($params) : "";
    $jour2 = "\n" . 'sprintf("%02d", ($x = ' . calculer_liste($jour2, array(), $boucles, $parent) . ') ? $x : date("d"))';
    $boucle =& $boucles[$idb];
    $date = $boucle->id_table . ".{$date}";
    $quote_end = ",'" . $boucle->sql_serveur . "','text'";
    if ($type == 'jour') {
        $boucle->where[] = array("'AND'", array("'<='", "'DATE_FORMAT({$date_deb}, \\'%Y%m%d\\')'", "sql_quote({$annee} . {$mois} . {$jour}{$quote_end})"), array("'>='", "'DATE_FORMAT({$date_fin}, \\'%Y%m%d\\')'", "sql_quote({$annee} . {$mois} . {$jour}{$quote_end})"));
    } elseif ($type == 'mois') {
        $boucle->where[] = array("'AND'", array("'<='", "'DATE_FORMAT({$date_deb}, \\'%Y%m\\')'", "sql_quote({$annee} . {$mois}{$quote_end})"), array("'>='", "'DATE_FORMAT({$date_fin}, \\'%Y%m\\')'", "sql_quote({$annee} . {$mois}{$quote_end})"));
    } elseif ($type == 'semaine') {
        $boucle->where[] = array("'AND'", array("'>='", "'DATE_FORMAT({$date_fin}, \\'%Y%m%d\\')'", "date_debut_semaine({$annee}, {$mois}, {$jour})"), array("'<='", "'DATE_FORMAT({$date_deb}, \\'%Y%m%d\\')'", "date_fin_semaine({$annee}, {$mois}, {$jour})"));
    } elseif (count($crit->param) > 3) {
        $boucle->where[] = array("'AND'", array("'>='", "'DATE_FORMAT({$date_fin}, \\'%Y%m%d\\')'", "sql_quote({$annee} . {$mois} . {$jour}{$quote_end})"), array("'<='", "'DATE_FORMAT({$date_deb}, \\'%Y%m%d\\')'", "sql_quote({$annee2} . {$mois2} . {$jour2}{$quote_end})"));
    }
    // sinon on prend tout
}
コード例 #7
0
ファイル: criteres.php プロジェクト: phenix-factory/SPIP
/**
 * Compile le critère {tableau} d'une boucle POUR
 *
 * {tableau #XX} pour compatibilite ascendante boucle POUR
 * ... préférer la notation (DATA){source tableau,#XX}
 *
 * @deprecated Utiliser une boucle (DATA){source tableau,#XX}
 *
 * @param string $idb     Identifiant de la boucle
 * @param array $boucles  AST du squelette
 * @param Critere $crit   Paramètres du critère dans cette boucle
 */
function critere_POUR_tableau_dist($idb, &$boucles, $crit)
{
    $boucle =& $boucles[$idb];
    $boucle->hash .= '
	$command[\'source\'] = array(' . calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent) . ');
	$command[\'sourcemode\'] = \'table\';';
}
コード例 #8
0
ファイル: svp_fonctions.php プロジェクト: loorenzooo/aslfc
/**
 * Critère de compatibilité avec une version précise ou une branche de SPIP.
 * 
 * Fonctionne sur les tables spip_paquets et spip_plugins
 *
 * Si aucune valeur n'est explicité dans le critère, tous les enregistrements
 * sont retournés.
 *
 * Le ! (NOT) fonctionne sur le critère BRANCHE
 * 
 * @critere compatible_spip
 * @example
 *   {compatible_spip}
 *   {compatible_spip 2.0.8} ou {compatible_spip 1.9}
 *   {compatible_spip #ENV{vers}} ou {compatible_spip #ENV{vers, 1.9.2}}
 *   {compatible_spip #GET{vers}} ou {compatible_spip #GET{vers, 2.1}}
 * 
 * @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 void
 */
function critere_compatible_spip_dist($idb, &$boucles, $crit)
{
    $boucle =& $boucles[$idb];
    $table = $boucle->id_table;
    // Si on utilise ! la fonction LOCATE doit retourner 0.
    // -> utilise uniquement avec le critere BRANCHE
    $op = $crit->not == '!' ? '=' : '>';
    $boucle->hash .= '
	// COMPATIBILITE SPIP
	$creer_where = charger_fonction(\'where_compatible_spip\', \'inc\');';
    // version/branche explicite dans l'appel du critere
    if (isset($crit->param[0][0])) {
        $version = calculer_liste(array($crit->param[0][0]), array(), $boucles, $boucle->id_parent);
        $boucle->hash .= '
		$where = $creer_where(' . $version . ', \'' . $table . '\', \'' . $op . '\');
		';
    } else {
        $boucle->hash .= '
		$version = isset($Pile[0][\'compatible_spip\']) ? $Pile[0][\'compatible_spip\'] : \'\';
		$where = $creer_where($version, \'' . $table . '\', \'' . $op . '\');
		';
    }
    $boucle->where[] = '$where';
}
コード例 #9
0
ファイル: logo_.php プロジェクト: genma/spip_ynh
function balise_LOGO__dist($p)
{
    preg_match(",^LOGO_([A-Z_]+?)(|_NORMAL|_SURVOL|_RUBRIQUE)\$,i", $p->nom_champ, $regs);
    $type = strtolower($regs[1]);
    $suite_logo = $regs[2];
    // cas de #LOGO_SITE_SPIP
    if ($type == 'site_spip') {
        $type = 'site';
        $_id_objet = "\"'0'\"";
    }
    $id_objet = id_table_objet($type);
    if (!isset($_id_objet) or !$_id_objet) {
        $_id_objet = champ_sql($id_objet, $p);
    }
    $fichier = $p->etoile === '**' ? -1 : 0;
    $coord = array();
    $align = $lien = '';
    $mode_logo = '';
    if ($p->param and !$p->param[0][0]) {
        $params = $p->param[0];
        array_shift($params);
        foreach ($params as $a) {
            if ($a[0]->type === 'texte') {
                $n = $a[0]->texte;
                if (is_numeric($n)) {
                    $coord[] = $n;
                } elseif (in_array($n, array('top', 'left', 'right', 'center', 'bottom'))) {
                    $align = $n;
                } elseif (in_array($n, array('auto', 'icone', 'apercu', 'vignette'))) {
                    $mode_logo = $n;
                }
            } else {
                $lien = calculer_liste($a, $p->descr, $p->boucles, $p->id_boucle);
            }
        }
    }
    $coord_x = !$coord ? 0 : intval(array_shift($coord));
    $coord_y = !$coord ? 0 : intval(array_shift($coord));
    if ($p->etoile === '*') {
        include_spip('balise/url_');
        $lien = generer_generer_url_arg($type, $p, $_id_objet);
    }
    $connect = $p->id_boucle ? $p->boucles[$p->id_boucle]->sql_serveur : '';
    if ($type == 'document') {
        $qconnect = _q($connect);
        $doc = "quete_document({$_id_objet}, {$qconnect})";
        if ($fichier) {
            $code = "quete_logo_file({$doc}, {$qconnect})";
        } else {
            $code = "quete_logo_document({$doc}, " . ($lien ? $lien : "''") . ", '{$align}', '{$mode_logo}', {$coord_x}, {$coord_y}, {$qconnect})";
        }
        // (x=non-faux ? y : '') pour affecter x en retournant y
        if ($p->descr['documents']) {
            $code = '(($doublons["documents"] .= ",". ' . $_id_objet . ") ? {$code} : '')";
        }
    } elseif ($connect) {
        $code = "''";
        spip_log("Les logos distants ne sont pas prevus");
    } else {
        $code = logo_survol($id_objet, $_id_objet, $type, $align, $fichier, $lien, $p, $suite_logo);
    }
    // demande de reduction sur logo avec ecriture spip 2.1 : #LOGO_xxx{200, 0}
    if ($coord_x or $coord_y) {
        $code = "filtrer('image_graver',filtrer('image_reduire'," . $code . ", '{$coord_x}', '{$coord_y}'))";
    }
    $p->code = $code;
    $p->interdire_scripts = false;
    return $p;
}
コード例 #10
0
ファイル: compiler.php プロジェクト: JLuc/SPIP
function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect = '')
{
    static $trouver_table;
    spip_timer('calcul_skel');
    if (defined('_VAR_MODE') and _VAR_MODE == 'debug') {
        $GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
        $GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;
        if (!isset($GLOBALS['debug_objets']['principal'])) {
            $GLOBALS['debug_objets']['principal'] = $nom;
        }
    }
    foreach ($boucles as $id => $boucle) {
        $GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
    }
    $descr['documents'] = compile_inclure_doublons($squelette);
    // Demander la description des tables une fois pour toutes
    // et reperer si les doublons sont demandes
    // pour un inclure ou une boucle document
    // c'est utile a la fonction champs_traitements
    if (!$trouver_table) {
        $trouver_table = charger_fonction('trouver_table', 'base');
    }
    foreach ($boucles as $id => $boucle) {
        if (!($type = $boucle->type_requete)) {
            continue;
        }
        if (!$descr['documents'] and ($type == 'documents' and $boucle->doublons or compile_inclure_doublons($boucle->avant) or compile_inclure_doublons($boucle->apres) or compile_inclure_doublons($boucle->milieu) or compile_inclure_doublons($boucle->altern))) {
            $descr['documents'] = true;
        }
        if ($type != TYPE_RECURSIF) {
            if (!$boucles[$id]->sql_serveur and $connect) {
                $boucles[$id]->sql_serveur = $connect;
            }
            // chercher dans les iterateurs du repertoire iterateur/
            if ($g = charger_fonction(preg_replace('/\\W/', '_', $boucle->type_requete), 'iterateur', true)) {
                $boucles[$id] = $g($boucle);
                // sinon, en cas de requeteur d'un type predefini,
                // utiliser les informations donnees par le requeteur
                // cas "php:xx" et "data:xx".
            } else {
                if ($boucle->sql_serveur and $requeteur = charger_fonction($boucle->sql_serveur, 'requeteur', true)) {
                    $requeteur($boucles, $boucle, $id);
                    // utiliser la description des champs transmis
                } else {
                    $show = $trouver_table($type, $boucles[$id]->sql_serveur);
                    // si la table n'existe pas avec le connecteur par defaut,
                    // c'est peut etre une table qui necessite son connecteur dedie fourni
                    // permet une ecriture allegee (GEO) -> (geo:GEO)
                    if (!$show and $show = $trouver_table($type, strtolower($type))) {
                        $boucles[$id]->sql_serveur = strtolower($type);
                    }
                    if ($show) {
                        $boucles[$id]->show = $show;
                        // recopie les infos les plus importantes
                        $boucles[$id]->primary = isset($show['key']["PRIMARY KEY"]) ? $show['key']["PRIMARY KEY"] : '';
                        $boucles[$id]->id_table = $x = preg_replace(",^spip_,", "", $show['id_table']);
                        $boucles[$id]->from[$x] = $nom_table = $show['table'];
                        $boucles[$id]->iterateur = 'SQL';
                        $boucles[$id]->descr =& $descr;
                        if (!$boucles[$id]->jointures and is_array($show['tables_jointures']) and count($x = $show['tables_jointures'])) {
                            $boucles[$id]->jointures = $x;
                        }
                        if ($boucles[$id]->jointures_explicites) {
                            $jointures = preg_split("/\\s+/", $boucles[$id]->jointures_explicites);
                            while ($j = array_pop($jointures)) {
                                array_unshift($boucles[$id]->jointures, $j);
                            }
                        }
                    } else {
                        // Pas une erreur si la table est optionnelle
                        if ($boucles[$id]->table_optionnelle) {
                            $boucles[$id]->type_requete = '';
                        } else {
                            $boucles[$id]->type_requete = false;
                            $boucle = $boucles[$id];
                            $x = (!$boucle->sql_serveur ? '' : $boucle->sql_serveur . ":") . $type;
                            $msg = array('zbug_table_inconnue', array('table' => $x));
                            erreur_squelette($msg, $boucle);
                        }
                    }
                }
            }
        }
    }
    // Commencer par reperer les boucles appelees explicitement
    // car elles indexent les arguments de maniere derogatoire
    foreach ($boucles as $id => $boucle) {
        if ($boucle->type_requete == TYPE_RECURSIF and $boucle->param) {
            $boucles[$id]->descr =& $descr;
            $rec =& $boucles[$boucle->param[0]];
            if (!$rec) {
                $msg = array('zbug_boucle_recursive_undef', array('nom' => $boucle->param[0]));
                erreur_squelette($msg, $boucle);
                $boucles[$id]->type_requete = false;
            } else {
                $rec->externe = $id;
                $descr['id_mere'] = $id;
                $boucles[$id]->return = calculer_liste(array($rec), $descr, $boucles, $boucle->param);
            }
        }
    }
    foreach ($boucles as $id => $boucle) {
        $id = strval($id);
        // attention au type dans index_pile
        $type = $boucle->type_requete;
        if ($type and $type != TYPE_RECURSIF) {
            $res = '';
            if ($boucle->param) {
                // retourne un tableau en cas d'erreur
                $res = calculer_criteres($id, $boucles);
            }
            $descr['id_mere'] = $id;
            $boucles[$id]->return = calculer_liste($boucle->milieu, $descr, $boucles, $id);
            // Si les criteres se sont mal compiles
            // ne pas tenter d'assembler le code final
            // (mais compiler le corps pour detection d'erreurs)
            if (is_array($res)) {
                $boucles[$id]->type_requete = false;
            }
        }
    }
    // idem pour la racine
    $descr['id_mere'] = '';
    $corps = calculer_liste($squelette, $descr, $boucles);
    // Calcul du corps de toutes les fonctions PHP,
    // en particulier les requetes SQL et TOTAL_BOUCLE
    // de'terminables seulement maintenant
    foreach ($boucles as $id => $boucle) {
        $boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
        if ($boucle->return === false) {
            $corps = false;
            continue;
        }
        // appeler la fonction de definition de la boucle
        if ($req = $boucle->type_requete) {
            // boucle personnalisée ?
            $table = strtoupper($boucle->type_requete);
            $serveur = strtolower($boucle->sql_serveur);
            if ((!$serveur or !function_exists($f = "boucle_" . $serveur . "_" . $table) and !function_exists($f = $f . "_dist")) and !function_exists($f = "boucle_" . $table) and !function_exists($f = $f . "_dist")) {
                // fonction de boucle standard
                if (!function_exists($f = 'boucle_DEFAUT')) {
                    $f = 'boucle_DEFAUT_dist';
                }
            }
            $req = "\n\n\tstatic \$command = array();\n\t" . "static \$connect;\n\t" . "\$command['connect'] = \$connect = " . _q($boucle->sql_serveur) . ";" . $f($id, $boucles);
        } else {
            $req = "\n\treturn '';";
        }
        $boucles[$id]->return = "\n\nfunction BOUCLE" . strtr($id, "-", "_") . $nom . '(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' . $req . "\n}\n";
    }
    // Au final, si le corps ou un critere au moins s'est mal compile
    // retourner False, sinon inserer leur decompilation
    if (is_bool($corps)) {
        return false;
    }
    $principal = "\nfunction " . $nom . '($Cache, $Pile, $doublons=array(), $Numrows=array(), $SP=0) {
' . '
	if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);

	$connect = ' . _q($connect) . ';
	$page = ' . $corps . ";\n\n\treturn analyse_resultat_skel(" . var_export($nom, true) . ", \$Cache, \$page, " . var_export($sourcefile, true) . ");\n}";
    $secondes = spip_timer('calcul_skel');
    spip_log("COMPIL ({$secondes}) [{$sourcefile}] {$nom}.php");
    // $connect n'est pas sûr : on nettoie
    $connect = preg_replace(',[^\\w],', '', $connect);
    // Assimiler la fct principale a une boucle anonyme, pour retourner un resultat simple
    $code = new Boucle();
    $code->descr = $descr;
    $code->return = '
//
// Fonction principale du squelette ' . $sourcefile . ($connect ? " pour {$connect}" : '') . (!CODE_COMMENTE ? '' : "\n// Temps de compilation total: {$secondes}") . "\n//\n" . $principal;
    $boucles[''] = $code;
    return $boucles;
}
コード例 #11
0
ファイル: criteres.php プロジェクト: rhertzog/lcs
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);
}
コード例 #12
0
ファイル: references.php プロジェクト: rhertzog/lcs
function compose_filtres_args($p, $args, $sep)
{
	$arglist = "";
	foreach ($args as $arg) {
		$arglist .= $sep . 
		  calculer_liste($arg, $p->descr, $p->boucles, $p->id_boucle);
	}
	return $arglist;
}
コード例 #13
0
ファイル: compiler.php プロジェクト: rhertzog/lcs
function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $connect = ''){
	global $tables_jointures;
	static $trouver_table;
	spip_timer('calcul_skel');

	if (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode']=='debug'){
		$GLOBALS['debug_objets']['squelette'][$nom] = $descr['squelette'];
		$GLOBALS['debug_objets']['sourcefile'][$nom] = $sourcefile;

		if (!isset($GLOBALS['debug_objets']['principal']))
			$GLOBALS['debug_objets']['principal'] = $nom;
	}
	foreach ($boucles as $id => $boucle){
		$GLOBALS['debug_objets']['boucle'][$nom . $id] = $boucle;
	}
	$descr['documents'] = compile_inclure_doublons($squelette);

	// Demander la description des tables une fois pour toutes
	// et reperer si les doublons sont demandes
	// pour un inclure ou une boucle document
	// c'est utile a la fonction champs_traitements
	if (!$trouver_table)
		$trouver_table = charger_fonction('trouver_table', 'base');

	foreach ($boucles as $id => $boucle){
		if (!($type = $boucle->type_requete)) continue;
		if (!$descr['documents'] AND (
			(($type=='documents') AND $boucle->doublons) OR
				compile_inclure_doublons($boucle->avant) OR
				compile_inclure_doublons($boucle->apres) OR
				compile_inclure_doublons($boucle->milieu) OR
				compile_inclure_doublons($boucle->altern))
		)
			$descr['documents'] = true;
		if ($type!='boucle'){
			if (!$boucles[$id]->sql_serveur AND $connect)
				$boucles[$id]->sql_serveur = $connect;
			$show = $trouver_table($type, $boucles[$id]->sql_serveur);
			// si la table n'existe pas avec le connecteur par defaut, 
			// c'est peut etre une table qui necessite son connecteur dedie fourni
			// permet une ecriture allegee (GEO) -> (geo:GEO)
			if (!$show AND $show = $trouver_table($type, strtolower($type)))
				$boucles[$id]->sql_serveur = strtolower($type);
			if ($show){
				$boucles[$id]->show = $show;
				// recopie les infos les plus importantes
				$boucles[$id]->primary = $show['key']["PRIMARY KEY"];
				$boucles[$id]->id_table = $x = $show['id_table'];
				$boucles[$id]->from[$x] = $nom_table = $show['table'];

				$boucles[$id]->descr = &$descr;
				if ((!$boucles[$id]->jointures)
					AND (isset($tables_jointures[$nom_table]))
						AND is_array($x = $tables_jointures[$nom_table])
				)
					$boucles[$id]->jointures = $x;
				if ($boucles[$id]->jointures_explicites){
					$jointures = preg_split("/\s+/", $boucles[$id]->jointures_explicites);
					while ($j = array_pop($jointures))
						array_unshift($boucles[$id]->jointures, $j);
				}
			} else {
				// Pas une erreur si la table est optionnelle
				if ($boucles[$id]->table_optionnelle)
					$boucles[$id]->type_requete = '';
				else {
					$boucles[$id]->type_requete = false;
					$boucle = $boucles[$id];
					$x = (!$boucle->sql_serveur ? '' :
						($boucle->sql_serveur . ":")) .
						$type;
					$msg = array('zbug_table_inconnue',
						array('table' => $x));
					erreur_squelette($msg, $boucle);
				}
			}
		}
	}

	// Commencer par reperer les boucles appelees explicitement 
	// car elles indexent les arguments de maniere derogatoire
	foreach ($boucles as $id => $boucle){
		if ($boucle->type_requete=='boucle' AND $boucle->param){
			$boucles[$id]->descr = &$descr;
			$rec = &$boucles[$boucle->param[0]];
			if (!$rec){
				$msg = array('zbug_boucle_recursive_undef',
					array('nom' => $boucle->param[0]));
				erreur_squelette($msg, $boucle);
				$boucles[$id]->type_requete = false;
			} else {
				$rec->externe = $id;
				$descr['id_mere'] = $id;
				$boucles[$id]->return =
					calculer_liste(array($rec),
						$descr,
						$boucles,
						$boucle->param);
			}
		}
	}
	foreach ($boucles as $id => $boucle){
		$id = strval($id); // attention au type dans index_pile
		$type = $boucle->type_requete;
		if ($type AND $type!='boucle'){
			$crit = !$boucle->param ? true : calculer_criteres($id, $boucles);
			$descr['id_mere'] = $id;
			$boucles[$id]->return =
				calculer_liste($boucle->milieu,
					$descr,
					$boucles,
					$id);
			// Si les criteres se sont mal compiles
			// ne pas tenter d'assembler le code final
			// (mais compiler le corps pour detection d'erreurs)
			if (is_array($crit))
				$boucles[$id]->type_requete = false;
		}
	}

	// idem pour la racine
	$descr['id_mere'] = '';
	$corps = calculer_liste($squelette, $descr, $boucles);
	$debug = (isset($GLOBALS['var_mode']) AND $GLOBALS['var_mode']=='debug');

	if ($debug){
		include_spip('public/decompiler');
		include_spip('public/format_' . _EXTENSION_SQUELETTES);
	}
	// Calcul du corps de toutes les fonctions PHP,
	// en particulier les requetes SQL et TOTAL_BOUCLE
	// de'terminables seulement maintenant

	foreach ($boucles as $id => $boucle){
		$boucle = $boucles[$id] = pipeline('pre_boucle', $boucle);
		if ($boucle->return===false) continue;
		// appeler la fonction de definition de la boucle

		if ($req = $boucle->type_requete){
			$f = 'boucle_' . strtoupper($req);
			// si pas de definition perso, definition spip
			if (!function_exists($f)) $f = $f . '_dist';
			// laquelle a une definition par defaut
			if (!function_exists($f)) $f = 'boucle_DEFAUT';
			if (!function_exists($f)) $f = 'boucle_DEFAUT_dist';
			$req = "\n\n\tstatic \$connect = " .
				_q($boucle->sql_serveur) .
				";" .
				$f($id, $boucles);
		} else $req = ("\n\treturn '';");

		$boucles[$id]->return =
			"function BOUCLE" . strtr($id, "-", "_") . $nom .
				'(&$Cache, &$Pile, &$doublons, &$Numrows, $SP) {' .
				$req .
				"\n}\n\n";

		if ($debug)
			$GLOBALS['debug_objets']['code'][$nom . $id] = $boucles[$id]->return;
	}

	// Au final, si le corps ou un critere au moins s'est mal compile
	// retourner False, sinon inserer leur decompilation
	if (is_bool($corps)) return false;
	foreach ($boucles as $id => $boucle){
		if ($boucle->return===false) return false;
		$boucle->return = "\n\n/* BOUCLE " .
			$boucle->type_requete .
			" " .
			(!$debug ? '' :
				str_replace('*/', '* /',
					decompiler_criteres($boucle->param,
						$boucle->criteres))) .
			" */\n\n " .
			$boucle->return;
	}

	$secondes = spip_timer('calcul_skel');
	spip_log("COMPIL ($secondes) [$sourcefile] $nom.php");
	// $connect n'est pas sûr : on nettoie
	$connect = preg_replace(',[^\w],', '', $connect);

	// Assimiler la fct principale a une boucle anonyme, c'est plus simple
	$code = new Boucle;
	$code->descr = $descr;
	$code->return = '
//
// Fonction principale du squelette ' .
		$sourcefile .
		($connect ? " pour $connect" : '') .
		(!CODE_COMMENTE ? '' : "\n// Temps de compilation total: $secondes") .
		"\n//" .
		(!$debug ? '' : ("\n/*\n" .
			str_replace('*/', '* /', public_decompiler($squelette))
			. "\n*/")) . "

function " . $nom . '($Cache, $Pile, $doublons=array(), $Numrows=array(), $SP=0) {

'
		// reporter de maniere securisee les doublons inclus
		. '
	if (isset($Pile[0]["doublons"]) AND is_array($Pile[0]["doublons"]))
		$doublons = nettoyer_env_doublons($Pile[0]["doublons"]);

	$connect = ' .
		_q($connect) . ';
	$page = ' .
		// ATTENTION, le calcul de l'expression $corps affectera $Cache
		// c'est pourquoi on l'affecte a la variable auxiliaire $page.
		// avant de referencer $Cache
		$corps . ";

	return analyse_resultat_skel(" . var_export($nom, true)
		. ", \$Cache, \$page, " . var_export($sourcefile, true) . ");
}";

	$boucles[''] = $code;
	return $boucles;
}
コード例 #14
0
ファイル: criteres_agenda.php プロジェクト: rhertzog/lcs
/**
 * Plugin Agenda pour Spip 2.0
 * Licence GPL
 * 
 *
 */

function critere_agendafull_dist($idb, &$boucles, $crit)
{
	$params = $crit->param;

	if (count($params) < 1)
	      erreur_squelette(_T('zbug_info_erreur_squelette'),
			       "{agenda ?} BOUCLE$idb");

	$parent = $boucles[$idb]->id_parent;

	// les valeurs $date et $type doivent etre connus a la compilation
	// autrement dit ne pas etre des champs

	$date_deb = array_shift($params);
	$date_deb = $date_deb[0]->texte;

	$date_fin = array_shift($params);
	$date_fin = $date_fin[0]->texte;

	$type = array_shift($params);
	$type = $type[0]->texte;

	$annee = $params ? array_shift($params) : "";
	$annee = "\n" . 'sprintf("%04d", ($x = ' .
		calculer_liste($annee, array(), $boucles, $parent) .
		') ? $x : date("Y"))';

	$mois =  $params ? array_shift($params) : "";
	$mois = "\n" . 'sprintf("%02d", ($x = ' .
		calculer_liste($mois, array(), $boucles, $parent) .
		') ? $x : date("m"))';

	$jour =  $params ? array_shift($params) : "";
	$jour = "\n" . 'sprintf("%02d", ($x = ' .
		calculer_liste($jour, array(), $boucles, $parent) .
		') ? $x : date("d"))';

	$annee2 = $params ? array_shift($params) : "";
	$annee2 = "\n" . 'sprintf("%04d", ($x = ' .
		calculer_liste($annee2, array(), $boucles, $parent) .
		') ? $x : date("Y"))';

	$mois2 =  $params ? array_shift($params) : "";
	$mois2 = "\n" . 'sprintf("%02d", ($x = ' .
		calculer_liste($mois2, array(), $boucles, $parent) .
		') ? $x : date("m"))';

	$jour2 =  $params ? array_shift($params) : "";
	$jour2 = "\n" .  'sprintf("%02d", ($x = ' .
		calculer_liste($jour2, array(), $boucles, $parent) .
		') ? $x : date("d"))';

	$boucle = &$boucles[$idb];
	$date = $boucle->id_table . ".$date";

	if ($type == 'jour')
		$boucle->where[]= array("'AND'", 
					array("'<='", "'DATE_FORMAT($date_deb, \'%Y%m%d\')'",("$annee . $mois . $jour")),
					array("'>='", "'DATE_FORMAT($date_fin, \'%Y%m%d\')'",("$annee . $mois . $jour")));
	elseif ($type == 'mois')
		$boucle->where[]= array("'AND'", 
					array("'<='", "'DATE_FORMAT($date_deb, \'%Y%m\')'",("$annee . $mois")),
					array("'>='", "'DATE_FORMAT($date_fin, \'%Y%m\')'",("$annee . $mois")));
	elseif ($type == 'semaine')
		$boucle->where[]= array("'AND'", 
					array("'>='",
					     "'DATE_FORMAT($date_fin, \'%Y%m%d\')'", 
					      ("date_debut_semaine($annee, $mois, $jour)")),
					array("'<='",
					      "'DATE_FORMAT($date_deb, \'%Y%m%d\')'",
					      ("date_fin_semaine($annee, $mois, $jour)")));
	elseif (count($crit->param) > 3)
		$boucle->where[]= array("'AND'",
					array("'>='",
					      "'DATE_FORMAT($date_fin, \'%Y%m%d\')'",
					      ("$annee . $mois . $jour")),
					array("'<='", "'DATE_FORMAT($date_deb, \'%Y%m%d\')'", ("$annee2 . $mois2 . $jour2")));
	// sinon on prend tout
}
コード例 #15
0
ファイル: spip_bonux_criteres.php プロジェクト: rhertzog/lcs
/**
 * {tri [champ_par_defaut][,sens_par_defaut][,nom_variable]}
 * champ_par_defaut : un champ de la table sql
 * sens_par_defaut : -1 ou inverse pour decroissant, 1 ou direct pour croissant
 * nom_variable : nom de la variable utilisee (par defaut tri_nomboucle)
 * 
 * {tri titre}
 * {tri titre,inverse}
 * {tri titre,-1}
 * {tri titre,-1,truc}
 * 
 * @param unknown_type $idb
 * @param unknown_type $boucles
 * @param unknown_type $crit
 */
function critere_tri_dist($idb, &$boucles, $crit) {
	$boucle = &$boucles[$idb];
	$id_table = $boucle->id_table;

	// definition du champ par defaut
	$_champ_defaut = !isset($crit->param[0][0]) ? "''" : calculer_liste(array($crit->param[0][0]), array(), $boucles, $boucle->id_parent);
	$_sens_defaut = !isset($crit->param[1][0]) ? "1" : calculer_liste(array($crit->param[1][0]), array(), $boucles, $boucle->id_parent);
	$_variable = !isset($crit->param[2][0]) ? "'$idb'" : calculer_liste(array($crit->param[2][0]), array(), $boucles, $boucle->id_parent);

	$_tri = "((\$t=(isset(\$Pile[0]['tri'.$_variable]))?\$Pile[0]['tri'.$_variable]:$_champ_defaut)?tri_protege_champ(\$t):'')";
	
	$_sens_defaut = "(is_array(\$s=$_sens_defaut)?(isset(\$s[\$st=$_tri])?\$s[\$st]:reset(\$s)):\$s)";
	$_sens ="((intval(\$t=(isset(\$Pile[0]['sens'.$_variable]))?\$Pile[0]['sens'.$_variable]:$_sens_defaut)==-1 OR \$t=='inverse')?-1:1)";

	$boucle->modificateur['tri_champ'] = $_tri;
	$boucle->modificateur['tri_sens'] = $_sens;
	$boucle->modificateur['tri_nom'] = $_variable;
	// faut il inserer un test sur l'existence de $tri parmi les champs de la table ?
	// evite des erreurs sql, mais peut empecher des tri sur jointure ...
	$boucle->hash .= "
	\$senstri = '';
	\$tri = $_tri;
	if (\$tri){
		\$senstri = $_sens;
		\$senstri = (\$senstri<0)?' DESC':'';
	};
	";
	$field = serialize(array_keys($boucle->show['field']));
	$boucle->select[] = "\".tri_champ_select(\$tri).\"";
	$boucle->order[] = "tri_champ_order(\$tri,'$id_table','$field').\$senstri";
}
コード例 #16
0
ファイル: agenda.php プロジェクト: rhertzog/lcs
/**
 * Fonction privee pour mutualiser de code des criteres_evenement_*
 * Retourne le code php pour obtenir la date de reference de comparaison
 * des evenements a trouver 
 *
 * @param <type> $idb
 * @param <type> $boucles
 * @param <type> $crit
 * 
 * @return string code PHP concernant la date.
**/
function agenda_calculer_date_reference($idb, &$boucles, $crit) {
	if (isset($crit->param[0]))
		return calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent);
	else
		return "date('Y-m-d H:i:00')";
}
コード例 #17
0
ファイル: frequence_fonctions.php プロジェクト: rhertzog/lcs
function critere_frequence_dist($idb, &$boucles, $crit) {
	global $table_des_tables;
	$not = $crit->not;
	$boucle = &$boucles[$idb];

	if ($not)
		erreur_squelette(_T('zbug_info_erreur_squelette'), $crit->op);

	if (empty($boucle->jointures)) {
		erreur_squelette(_T('zbug_info_erreur_squelette'), _L('frequence sur table sans jointures'));
		return;
	}

	//analyser chaque criteres de frequence
	$nom = $table_des_tables[$boucle->type_requete];
	$parent = $boucles[$idb]->id_parent;
	$criteres = array();
	//Pour l'instant, un seul parametre
	while(list(,$p) = each($crit->param)) {
 		$param = calculer_liste($p, array(), $boucles, $parent);
 		$type = preg_match(',^\(?\'(\w+)(\s*)?([!=<>]+)?(\s*)?,', $param, $regs) ? $regs[1] : $boucle->jointures[0];
		$op = $regs[3] ? $regs[3] : '>=';
		if($val = $regs[0] ? preg_replace(',' . preg_quote($regs[0]) . ',', '', $param) : 0) {
			$val = preg_replace(',\'$,', '', $val);
			$val = preg_replace(',^\'\s\.\s(.*)\)$,Um', '$1', $val);
			$val = $val ? $val : 0;
		}
		//Trouver une jointure n:n (cad table spip_mots_articles)
		if(in_array($_type = $nom.'_'.$type, $boucle->jointures))
			$criteres[] = array($op, $_type, $val);
		else {
			erreur_squelette(_T('zbug_info_erreur_squelette'), _L('frequence '.$type.': jointure inconnue'));
		}
	}
	if(empty($criteres)) $criteres[0] = array('>=', $boucle->jointures[0], 0);
	
	//composer la requete pour la jointure
	$primary = $boucle->primary;
	$id_table = $boucle->id_table . '.' . $primary;
	foreach($criteres as $critere) {
		$frequence = $boucle->modificateur['frequence'] = "frequence".$idb;
		list($op, $type, $val) = $critere;
		//compatibilite SVN et 1.9.2
		if(function_exists('trouver_def_table')) {
			$nom = $table_des_tables[$type];
			list($table, $desc) = trouver_def_table($nom ? $nom : $type, $boucle);
		}
		else {
      $trouver_table = charger_fonction('trouver_table','base');
      $desc=$trouver_table($type, $boucle->sql_serveur);
      $table = $desc['table'];
    }
		/*Ajouter ici un test et produire une erreur si table non trouvee*/
		$ids = $desc['key']['PRIMARY KEY'];
		foreach(split(',', $ids) as $_id)
			if(trim($_id) != $primary) $id = $_id;
		$boucle->select[]= 'COUNT('.$frequence.'.'.$id.') AS '.$frequence;
		$boucle->from[$frequence] = $table;
		$boucle->where[] = array("'='", "'$id_table'", "'$frequence.$primary'");
		$boucle->group[] = $id_table;
		$boucle->having[] = array("'$op'", "'$frequence'", $val);		
	}
}