Exemplo n.º 1
0
/**
 * Met à jour les tables SQL paquets et plugins pour qui concerne
 * les paquets locaux (ceux présents sur le site).
 *
 * On ne met à jour que ce qui a changé, sauf si on force le recalcule
 * de toutes les informations locales avec var_mode=vider_paquets_locaux
 * dans l'URL ou en mettant le paramètre $force à true.
 * 
 * @param bool $force
 *     - false : n'actualise que les paquets modifiés
 *     - true : efface et recrée la liste de tous les paquets locaux
 * @param array $erreurs_xml
 *     Si des erreurs XML sont présentes, elles se retrouvent dans ce tableau
 * @return string
 *     Temps d'exécution
**/
function svp_actualiser_paquets_locaux($force = false, &$erreurs_xml = array())
{
    spip_timer('paquets_locaux');
    $paquets = svp_descriptions_paquets_locaux($erreurs_xml);
    // un mode pour tout recalculer sans désinstaller le plugin... !
    if ($force or _request('var_mode') == 'vider_paquets_locaux') {
        svp_base_supprimer_paquets_locaux();
        svp_base_inserer_paquets_locaux($paquets);
    } else {
        svp_base_modifier_paquets_locaux($paquets);
    }
    svp_base_actualiser_paquets_actifs();
    $temps = spip_timer('paquets_locaux');
    #spip_log('svp_actualiser_paquets_locaux', 'SVP');
    #spip_log($temps, 'SVP');
    return "Éxécuté en : " . $temps;
}
Exemplo n.º 2
0
function charger_dtd($grammaire, $avail, $rotlvl)
{
	static $dtd = array(); # cache bien utile pour le validateur en boucle

	if (isset($dtd[$grammaire]))
		return $dtd[$grammaire];

	if ($avail == 'SYSTEM') {
		$grammaire = find_in_path($grammaire);
	}
	if (!$grammaire) return	$dtd[''] = array();

	$file = _DIR_CACHE_XML . preg_replace('/[^\w.]/','_', $rotlvl) . '.gz';

	if (lire_fichier($file, $r)) {
		if (($avail == 'SYSTEM') AND filemtime($file) < filemtime($grammaire))
				$r = false;
	}

	if ($r) {
		$dtc = unserialize($r);
	} else {
		spip_timer('dtd');
		$dtc = new DTC;
		// L'analyseur retourne un booleen de reussite et modifie $dtc.
		// Retourner vide en cas d'echec
		if (!analyser_dtd($grammaire, $avail, $dtc)) 
			$dtc = array();
		else {
		// tri final pour presenter les suggestions de corrections
			foreach ($dtc->peres as $k => $v) {
				asort($v);
				$dtc->peres[$k] = $v;
			} 

			spip_log("Analyser DTD $avail $grammaire (" . spip_timer('dtd') . ") " . count($dtc->macros)  . ' macros, ' . count($dtc->elements)  . ' elements, ' . count($dtc->attributs) . " listes d'attributs, " . count($dtc->entites) . " entites");
			#	$r = $dtc->regles; ksort($r);foreach($r as $l => $v) {$t=array_keys($dtc->attributs[$l]);echo "<b>$l</b> '$v' ", count($t), " attributs: ", join (', ',$t);$t=$dtc->peres[$l];echo "<br />",count($t), " peres: ", @join (', ',$t), "<br />\n";}exit;
			ecrire_fichier($file, serialize($dtc), true);
		}
		
	}
	$dtd[$grammaire] = $dtc;
	return $dtc;
}
Exemplo n.º 3
0
function typographie_en($letexte)
{
    # version core
    if (!$GLOBALS['tw']) {
        return typographie_en_dist($letexte);
    }
    $debug = _request('var_debug_wheel');
    static $trans;
    if (!isset($trans)) {
        $trans = array("&nbsp;" => '~', "'" => '&#8217;');
        switch ($GLOBALS['meta']['charset']) {
            case 'utf-8':
                $trans[" "] = '~';
                break;
            default:
                $trans[" "] = '~';
                break;
        }
    }
    # cette chaine ne peut pas exister,
    # cf. TYPO_PROTECTEUR dans inc/texte
    $pro = "--";
    if ($debug) {
        spip_timer('trans');
    }
    $letexte = str_replace(array_keys($trans), array_values($trans), $letexte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['trans'] += spip_timer('trans', true);
    }
    if ($debug) {
        spip_timer('cherche1');
    }
    /* 2 */
    $letexte = preg_replace('/ --?,|(?: %)(?:\\W|$)/S', '~$0', $letexte);
    /* 4 */
    $letexte = preg_replace('/Mr\\.? /S', '$0~', $letexte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['cherche1'] += spip_timer('cherche1', true);
    }
    if ($debug) {
        spip_timer('chercheespaces');
    }
    if (strpos($letexte, '~') !== false) {
        $letexte = preg_replace("/ *~+ */S", "~", $letexte);
    }
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['chercheespaces'] += spip_timer('chercheespaces', true);
    }
    if ($debug) {
        spip_timer('cherche2');
    }
    $letexte = preg_replace("/--([^-]|\$)/S", "{$pro}&mdash;\$1", $letexte, -1, $c);
    if ($c) {
        $letexte = preg_replace("/([-\n]){$pro}&mdash;/S", "\$1--", $letexte);
        $letexte = str_replace($pro, '', $letexte);
    }
    $letexte = str_replace('~', '&nbsp;', $letexte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['cherche2'] += spip_timer('cherche2', true);
    }
    return $letexte;
}
Exemplo n.º 4
0
function recherche_en_base($recherche = '', $tables = NULL, $options = array(), $serveur = '')
{
    include_spip('base/abstract_sql');
    if (!is_array($tables)) {
        $liste = liste_des_champs();
        if (is_string($tables) and $tables != '') {
            $toutes = array();
            foreach (explode(',', $tables) as $t) {
                if (isset($liste[$t])) {
                    $toutes[$t] = $liste[$t];
                }
            }
            $tables = $toutes;
            unset($toutes);
        } else {
            $tables = $liste;
        }
    }
    if (!strlen($recherche) or !count($tables)) {
        return array();
    }
    include_spip('inc/autoriser');
    // options par defaut
    $options = array_merge(array('preg_flags' => 'UimsS', 'toutvoir' => false, 'champs' => false, 'score' => false, 'matches' => false, 'jointures' => false, 'serveur' => $serveur), $options);
    $results = array();
    // Utiliser l'iterateur (DATA:recherche)
    // pour recuperer les couples (id_objet, score)
    // Le resultat est au format {
    //      id1 = { 'score' => x, attrs => { } },
    //      id2 = { 'score' => x, attrs => { } },
    // }
    include_spip('inc/memoization');
    foreach ($tables as $table => $champs) {
        # lock via memoization, si dispo
        if (function_exists('cache_lock')) {
            cache_lock($lock = 'recherche ' . $table . ' ' . $recherche);
        }
        spip_timer('rech');
        // TODO: ici plutot charger un iterateur via l'API iterateurs
        include_spip('inc/recherche_to_array');
        $to_array = charger_fonction('recherche_to_array', 'inc');
        $results[$table] = $to_array($recherche, array_merge($options, array('table' => $table, 'champs' => $champs)));
        ##var_dump($results[$table]);
        spip_log("recherche {$table} ({$recherche}) : " . count($results[$table]) . " resultats " . spip_timer('rech'), 'recherche');
        if (isset($lock)) {
            cache_unlock($lock);
        }
    }
    return $results;
}
Exemplo n.º 5
0
/**
 * Valide la conformité XML d'une liste de fichiers dans un répertoire
 *
 * @param array $files
 *     Liste des fichiers
 * @param string $ext
 *     Extension des fichiers
 * @param string $dir
 *     Chemin du répertoire
 * @return array
 **/
function valider_dir($files, $ext, $dir)
{
    $res = array();
    $transformer_xml = charger_fonction('valider', 'xml');
    $valideur = $ext == 'php' ? 'valider_script' : 'valider_skel';
    foreach ($files as $f) {
        spip_timer($f);
        $val = $valideur($transformer_xml, $f, $dir, $ext);
        $n = spip_timer($f);
        $val[] = $n;
        spip_log("validation de {$f} en {$n} secondes");
        $res[] = $val;
    }
    return $res;
}
Exemplo n.º 6
0
function expanser_liens_tw($texte, $connect = '')
{
    $debug = _request('var_debug_wheel');
    $texte = pipeline('pre_liens', $texte);
    if ($debug) {
        spip_timer('liensmatch');
    }
    tw_expanser_un_lien($connect, 'init');
    if (strpos($texte, '->') !== false) {
        $texte = preg_replace_callback(_RACCOURCI_LIEN_TW, 'tw_expanser_un_lien', $texte);
    }
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['liensmatch'] += spip_timer('liensmatch', true);
    }
    // on passe a traiter_modeles la liste des liens reperes pour lui permettre
    // de remettre le texte d'origine dans les parametres du modele
    if ($debug) {
        spip_timer('traiter_modeles');
    }
    $texte = traiter_modeles($texte, false, false, $connect, tw_expanser_un_lien('', 'sources'));
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['traiter_modeles'] += spip_timer('traiter_modeles', true);
    }
    if ($debug) {
        spip_timer('corriger_typo');
    }
    $texte = corriger_typo($texte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo'] += spip_timer('corriger_typo', true);
    }
    if ($debug) {
        spip_timer('reinserts');
    }
    $texte = tw_expanser_un_lien($texte, 'reinsert');
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['reinserts'] += spip_timer('reinserts', true);
    }
    return $texte;
}
Exemplo n.º 7
0
function public_parametrer_dist($fond, $contexte = '', $cache = '', $connect = '')
{
    static $composer, $styliser, $notes = null;
    $page = tester_redirection($fond, $contexte, $connect);
    if ($page) {
        return $page;
    }
    if (isset($contexte['lang'])) {
        $lang = $contexte['lang'];
    } elseif (!isset($lang)) {
        $lang = $GLOBALS['meta']['langue_site'];
    }
    $select = ((!isset($GLOBALS['forcer_lang']) or !$GLOBALS['forcer_lang']) and $lang != $GLOBALS['spip_lang']);
    if ($select) {
        $select = lang_select($lang);
    }
    $debug = defined('_VAR_MODE') && _VAR_MODE == 'debug';
    if (!$styliser) {
        $styliser = charger_fonction('styliser', 'public');
    }
    list($skel, $mime_type, $gram, $sourcefile) = $styliser($fond, $contexte, $GLOBALS['spip_lang'], $connect);
    if ($skel) {
        // sauver le nom de l'eventuel squelette en cours d'execution
        // (recursion possible a cause des modeles)
        if ($debug) {
            $courant = @$GLOBALS['debug_objets']['courant'];
            $GLOBALS['debug_objets']['contexte'][$sourcefile] = $contexte;
        }
        // charger le squelette en specifiant les langages cibles et source
        // au cas il faudrait le compiler (source posterieure au resultat)
        if (!$composer) {
            $composer = charger_fonction('composer', 'public');
        }
        $fonc = $composer($skel, $mime_type, $gram, $sourcefile, $connect);
    } else {
        $fonc = '';
    }
    if (!$fonc) {
        // squelette inconnu (==='') ou faux (===false)
        $page = $fonc;
    } else {
        // Preparer l'appel de la fonction principale du squelette
        spip_timer($a = 'calcul page ' . rand(0, 1000));
        // On cree un marqueur de notes unique lie a cette composition
        // et on enregistre l'etat courant des globales de notes...
        if (is_null($notes)) {
            $notes = charger_fonction('notes', 'inc', true);
        }
        if ($notes) {
            $notes('', 'empiler');
        }
        // Rajouter d'office ces deux parametres
        // (mais vaudrait mieux que le compilateur sache le simuler
        // car ca interdit l'usage de criteres conditionnels dessus).
        if (!isset($contexte['date'])) {
            $contexte['date'] = date("Y-m-d H:i:s");
            $contexte['date_default'] = true;
        } else {
            $contexte['date'] = normaliser_date($contexte['date'], true);
        }
        if (!isset($contexte['date_redac'])) {
            $contexte['date_redac'] = date("Y-m-d H:i:s");
            $contexte['date_redac_default'] = true;
        } else {
            $contexte['date_redac'] = normaliser_date($contexte['date_redac'], true);
        }
        // Passer le nom du cache pour produire sa destruction automatique
        $page = $fonc(array('cache' => $cache), array($contexte));
        // Restituer les globales de notes telles qu'elles etaient avant l'appel
        // Si l'inclus n'a pas affiche ses notes, tant pis (elles *doivent*
        // etre dans son resultat, autrement elles ne seraient pas prises en
        // compte a chaque calcul d'un texte contenant un modele, mais seulement
        // quand le modele serait calcule, et on aurait des resultats incoherents)
        if ($notes) {
            $notes('', 'depiler');
        }
        // reinjecter en dynamique la pile des notes
        // si il y a des inclure dynamiques
        // si la pile n'est pas vide
        // la generalisation de cette injection permettrait de corriger le point juste au dessus
        // en faisant remonter les notes a l'incluant (A tester et valider avant application)
        if ($notes) {
            $page['notes'] = $notes('', 'sauver_etat');
        }
        // spip_log: un joli contexte
        $infos = array();
        foreach (array_filter($contexte) as $var => $val) {
            if (is_array($val)) {
                $val = serialize($val);
            }
            if (strlen("{$val}") > 30) {
                $val = substr("{$val}", 0, 27) . '..';
            }
            if (strstr($val, ' ')) {
                $val = "'{$val}'";
            }
            $infos[] = $var . '=' . $val;
        }
        $profile = spip_timer($a);
        spip_log("calcul ({$profile}) [{$skel}] " . join(', ', $infos) . ' (' . strlen($page['texte']) . ' octets)');
        if (defined('_CALCUL_PROFILER') and intval($profile) > _CALCUL_PROFILER) {
            spip_log("calcul ({$profile}) [{$skel}] " . join(', ', $infos) . ' (' . strlen($page['texte']) . ' octets) | ' . $_SERVER['REQUEST_URI'], "profiler" . _LOG_AVERTISSEMENT);
        }
        if ($debug) {
            // si c'est ce que demande le debusqueur, lui passer la main
            $t = strlen($page['texte']) ? $page['texte'] : " ";
            $GLOBALS['debug_objets']['resultat'][$fonc . 'tout'] = $t;
            $GLOBALS['debug_objets']['courant'] = $courant;
            $GLOBALS['debug_objets']['profile'][$sourcefile] = $profile;
            if ($GLOBALS['debug_objets']['sourcefile'] and _request('var_mode_objet') == $fonc and _request('var_mode_affiche') == 'resultat') {
                erreur_squelette();
            }
        }
        // Si #CACHE{} n'etait pas la, le mettre a $delais
        if (!isset($page['entetes']['X-Spip-Cache'])) {
            // Dans l'espace prive ou dans un modeles/ on pose un cache 0 par defaut
            // si aucun #CACHE{} spécifié
            // le contexte implicite qui conditionne le cache assure qu'on retombe pas sur le meme
            // entre public et prive
            if (test_espace_prive() or strncmp($fond, 'modeles/', 8) == 0) {
                $page['entetes']['X-Spip-Cache'] = 0;
            } else {
                $page['entetes']['X-Spip-Cache'] = isset($GLOBALS['delais']) ? $GLOBALS['delais'] : 36000;
            }
        }
        $page['contexte'] = $contexte;
        // faire remonter le fichier source
        static $js_inclus = false;
        if (defined('_VAR_INCLURE') and _VAR_INCLURE) {
            $page['sourcefile'] = $sourcefile;
            $page['texte'] = "<div class='inclure_blocs'><h6>" . $page['sourcefile'] . "</h6>" . $page['texte'] . "</div>" . ($js_inclus ? "" : "<script type='text/javascript'>jQuery(function(){jQuery('.inclure_blocs > h6:first-child').hover(function(){jQuery(this).parent().addClass('hover')},function(){jQuery(this).parent().removeClass('hover')})});</script>");
            $js_inclus = true;
        }
        // Si un modele contenait #SESSION, on note l'info dans $page
        if (isset($GLOBALS['cache_utilise_session'])) {
            $page['invalideurs']['session'] = $GLOBALS['cache_utilise_session'];
            unset($GLOBALS['cache_utilise_session']);
        }
    }
    if ($select) {
        lang_select();
    }
    return $page;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
function tw_propre($t, $connect = null)
{
    // les appels directs a cette fonction depuis le php de l'espace
    // prive etant historiquement ecrits sans argment $connect
    // on utilise la presence de celui-ci pour distinguer les cas
    // ou il faut passer interdire_script explicitement
    // les appels dans les squelettes (de l'espace prive) fournissant un $connect
    // ne seront pas perturbes
    $interdire_script = false;
    if (is_null($connect)) {
        $connect = '';
        $interdire_script = true;
    }
    if (!$t) {
        return strval($t);
    }
    $debug = _request('var_debug_wheel');
    if ($debug) {
        spip_timer('echappe_html');
    }
    $t = echappe_html($t);
    if ($debug) {
        $GLOBALS['totaux']['echappe_html'] += spip_timer('echappe_html', true);
    }
    if ($debug) {
        spip_timer('expanser_liens');
    }
    $t = expanser_liens_tw($t, $connect);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens'] += spip_timer('expanser_liens', true);
    }
    if ($debug) {
        spip_timer('tw_traiter_raccourcis');
    }
    $t = tw_traiter_raccourcis($t);
    if ($debug) {
        $GLOBALS['totaux']['tw_traiter_raccourcis'] += spip_timer('tw_traiter_raccourcis', true);
    }
    if ($debug) {
        spip_timer('tw_echappe_retour_modeles');
    }
    $t = tw_echappe_retour_modeles($t, $interdire_script);
    if ($debug) {
        $GLOBALS['totaux']['tw_echappe_retour_modeles'] += spip_timer('tw_echappe_retour_modeles', true);
    }
    return $t;
}
Exemplo n.º 10
0
/**
 * Déclenche le cron en asynchrone ou retourne le code HTML pour le déclencher
 *
 * Retourne le HTML à ajouter à la page pour declencher le cron
 * ou rien si on a réussi à le lancer en asynchrone.
 *
 * Un verrou (cron.lock) empêche l'exécution du cron plus d'une fois par seconde.
 *
 * @uses queue_sleep_time_to_next_job()
 * @see  action_cron() L'URL appelée pour déclencher le cron
 *
 * @return string
 */
function queue_affichage_cron()
{
    $texte = "";
    $time_to_next = queue_sleep_time_to_next_job();
    // rien a faire si le prochain job est encore dans le futur
    if ($time_to_next > 0 or defined('_DEBUG_BLOCK_QUEUE')) {
        return $texte;
    }
    // ne pas relancer si on vient de lancer dans la meme seconde par un hit concurent
    if (file_exists($lock = _DIR_TMP . "cron.lock") and !(@filemtime($lock) < $_SERVER['REQUEST_TIME'])) {
        return $texte;
    }
    @touch($lock);
    // il y a des taches en attentes
    // si depuis plus de 5min, on essaye de lancer le cron par tous les moyens pour rattraper le coup
    // on est sans doute sur un site qui n'autorise pas http sortant ou avec peu de trafic
    $urgent = false;
    if ($time_to_next < -300) {
        $urgent = true;
    }
    $url_cron = generer_url_action('cron', '', false, true);
    if (!defined('_HTML_BG_CRON_FORCE') or !_HTML_BG_CRON_FORCE) {
        // methode la plus rapide :
        // Si fsockopen est possible, on lance le cron via un socket en asynchrone
        // si fsockopen echoue (disponibilite serveur, firewall) on essaye pas cURL
        // car on a toutes les chances d'echouer pareil mais sans moyen de le savoir
        // on passe direct a la methode background-image
        if (function_exists('fsockopen')) {
            $parts = parse_url($url_cron);
            switch ($parts['scheme']) {
                case 'https':
                    $scheme = 'ssl://';
                    $port = 443;
                    break;
                case 'http':
                default:
                    $scheme = '';
                    $port = 80;
            }
            $fp = @fsockopen($scheme . $parts['host'], isset($parts['port']) ? $parts['port'] : $port, $errno, $errstr, 1);
            if ($fp) {
                $timeout = 200;
                // ms
                stream_set_timeout($fp, 0, $timeout * 1000);
                $query = $parts['path'] . ($parts['query'] ? "?" . $parts['query'] : "");
                $out = "GET " . $query . " HTTP/1.1\r\n";
                $out .= "Host: " . $parts['host'] . "\r\n";
                $out .= "Connection: Close\r\n\r\n";
                fwrite($fp, $out);
                spip_timer('read');
                $t = 0;
                // on lit la reponse si possible pour fermer proprement la connexion
                // avec un timeout total de 200ms pour ne pas se bloquer
                while (!feof($fp) and $t < $timeout) {
                    @fgets($fp, 1024);
                    $t += spip_timer('read', true);
                    spip_timer('read');
                }
                fclose($fp);
                if (!$urgent) {
                    return $texte;
                }
            }
        } elseif (function_exists("curl_init")) {
            //setting the curl parameters.
            $ch = curl_init($url_cron);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            // cf bug : http://www.php.net/manual/en/function.curl-setopt.php#104597
            curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
            // valeur mini pour que la requete soit lancee
            curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200);
            // lancer
            curl_exec($ch);
            // fermer
            curl_close($ch);
            if (!$urgent) {
                return $texte;
            }
        }
    }
    // si deja force, on retourne sans rien
    if (defined('_DIRECT_CRON_FORCE')) {
        return $texte;
    }
    // si c'est un bot
    // inutile de faire un appel par image background,
    // on force un appel direct en fin de hit
    if (defined('_IS_BOT') and _IS_BOT) {
        define('_DIRECT_CRON_FORCE', true);
        return $texte;
    }
    // en derniere solution, on insere une image background dans la page
    $texte = '<!-- SPIP-CRON --><div style="background-image: url(\'' . generer_url_action('cron') . '\');"></div>';
    return $texte;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
function valider_dir($files, $ext, $dir)
{
	$res = array();
	$transformer_xml = charger_fonction('valider', 'xml');
	$valideur = $ext=='php' ? 'valider_script' : 'valider_skel' ;
	include_spip('public/assembler');
	foreach($files as $f) {
		spip_timer($f);
		$val = $valideur($transformer_xml, $f, $dir, $ext);
		// Ne pas saturer la memoire, donner juste la taille de la page
		// avec un nombre negatif quand c'est un message d'erreur
		if (is_string($val[0])) {
			$n = strlen($val[0]);
			$val[0] = strpos($val[0], "id='minipres'") ? (0-$n):$n;
		}
		$n = spip_timer($f); 
		$val[]= $n;
		array_unshift($val, count($val[1]));
		spip_log("validation de $f en $n secondes");
		$res[]= $val;
	}
	return $res;
}
Exemplo n.º 13
0
function typographie_fr($letexte)
{
    # version core
    if (!$GLOBALS['tw']) {
        return typographie_fr_dist($letexte);
    }
    $debug = _request('var_debug_wheel');
    static $trans;
    if (!isset($trans)) {
        $trans = array("&nbsp;" => '~', "&raquo;" => '&#187;', "&laquo;" => '&#171;', "&rdquo;" => '&#8221;', "&ldquo;" => '&#8220;', "&deg" => '&#176;', "'" => '&#8217;');
        switch ($GLOBALS['meta']['charset']) {
            case 'utf-8':
                $trans[" "] = '~';
                $trans["»"] = '&#187;';
                $trans["«"] = '&#171;';
                $trans["”"] = '&#8221;';
                $trans["“"] = '&#8220;';
                $trans["°"] = '&#176;';
                break;
            default:
                $trans["�"] = '~';
                $trans["�"] = '&#171;';
                $trans["�"] = '&#187;';
                $trans["�"] = '&#176;';
                break;
        }
    }
    # cette chaine ne peut pas exister,
    # cf. TYPO_PROTECTEUR dans inc/texte
    $pro = "--";
    if ($debug) {
        spip_timer('trans');
    }
    $letexte = str_replace(array_keys($trans), array_values($trans), $letexte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['trans'] += spip_timer('trans', true);
    }
    if ($debug) {
        spip_timer('cherche1');
    }
    # la typo du ; risque de clasher avec les entites &xxx;
    if (strpos($letexte, ';') !== false) {
        $letexte = str_replace(';', '~;', $letexte);
        $letexte = preg_replace(',(&#?[0-9a-z]+)~;,iS', '$1;', $letexte);
    }
    /* 2 */
    $letexte = preg_replace('/&#187;| --?,|(?::| %)(?:\\W|$)/S', '~$0', $letexte);
    /* 3 */
    $letexte = preg_replace('/[!?][!?\\.]*/S', "{$pro}~\$0", $letexte, -1, $c);
    if ($c) {
        $letexte = preg_replace("/([\\[<\\(!\\?\\.]){$pro}~/S", '$1', $letexte);
        $letexte = str_replace("{$pro}", '', $letexte);
    }
    /* 4 */
    $letexte = preg_replace('/&#171;|M(?:M?\\.|mes?|r\\.?|&#176;) |[nN]&#176; /S', '$0~', $letexte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['cherche1'] += spip_timer('cherche1', true);
    }
    if ($debug) {
        spip_timer('chercheespaces');
    }
    if (strpos($letexte, '~') !== false) {
        $letexte = preg_replace("/ *~+ */S", "~", $letexte);
    }
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['chercheespaces'] += spip_timer('chercheespaces', true);
    }
    if ($debug) {
        spip_timer('cherche2');
    }
    $letexte = preg_replace("/--([^-]|\$)/S", "{$pro}&mdash;\$1", $letexte, -1, $c);
    if ($c) {
        $letexte = preg_replace("/([-\n]){$pro}&mdash;/S", "\$1--", $letexte);
        $letexte = str_replace($pro, '', $letexte);
    }
    $letexte = preg_replace(',(https?|ftp|mailto)~((://[^"\'\\s\\[\\]\\}\\)<>]+)~([?]))?,S', '$1$3$4', $letexte);
    $letexte = str_replace('~', '&nbsp;', $letexte);
    if ($debug) {
        $GLOBALS['totaux']['expanser_liens:']['corriger_typo:']['cherche2'] += spip_timer('cherche2', true);
    }
    return $letexte;
}
Exemplo n.º 14
0
function inc_genie_dist($taches = array()) {

	if (!$taches)
		$taches = taches_generales();

	// Quelle est la tache la plus urgente ?
	$tache = '';
	$tmin = $t = time();
	foreach ($taches as $nom => $periode) {
		$celock = _DIR_TMP . $nom . '.lock';
		$date_lock = @filemtime($celock);
		if ($date_lock + $periode < $tmin) {
			$tmin = $date_lock + $periode;
			$tache = $nom;
			$lock = $celock;
			$last = $date_lock;
		}
	// debug : si la date du fichier est superieure a l'heure actuelle,
	// c'est que les serveurs Http et de fichiers sont desynchro.
	// Ca peut mettre en peril les taches cron : signaler dans le log
	// (On laisse toutefois flotter sur une heure, pas la peine de s'exciter
	// pour si peu)
		else if ($date_lock > $t + 3600)
			spip_log("Erreur de date du fichier $lock : $date_lock > $t !");
	}
	if ($tache) {
		spip_timer('tache');
		spip_log('cron: debut '.$tache, 'genie');
		touch($lock);
		$cron = charger_fonction($tache, 'genie');
		$retour = $cron($last);
		// si la tache a eu un effet : log
		if ($retour) {
			spip_log("cron: $tache (" . spip_timer('tache') . ") $retour", 'genie');
			if ($retour < 0)
				@touch($lock, 0 - $retour);
		}
	}
}