Example #1
0
function decompiler_boucle($struct, $fmt='', $prof=0)
{
	$nom = $struct->id_boucle;
	$avant = public_decompiler($struct->avant, $fmt, $prof);
	$apres = public_decompiler($struct->apres, $fmt, $prof);
	$altern = public_decompiler($struct->altern, $fmt, $prof);
	$milieu = public_decompiler($struct->milieu, $fmt, $prof);

	$type = $struct->sql_serveur ? "$struct->sql_serveur:" : '';
	$type .= ($struct->type_requete ? $struct->type_requete :
			    $struct->table_optionnelle);

	if ($struct->jointures_explicites)
	  $type .= " " . $struct->jointures_explicites;
	if ($struct->table_optionnelle)
	  $type .= "?";
	// Revoir le cas de la boucle recursive

	$crit = $struct->param;
	if ($crit AND !is_array($crit[0])) {
		$type = strtolower($type) . array_shift($crit);
	}
	$crit = decompiler_criteres($crit, $struct->criteres, $fmt, $prof) ;

	$f = 'format_boucle_' . ($fmt ? $fmt : _EXTENSION_SQUELETTES);
	return $f($avant, $nom, $type, $crit, $milieu, $apres, $altern, $prof);
}
function decompiler_boucle($struct, $fmt = '', $prof = 0)
{
    $nom = $struct->id_boucle;
    $avant = decompiler_($struct->avant, $fmt, $prof);
    $apres = decompiler_($struct->apres, $fmt, $prof);
    $altern = decompiler_($struct->altern, $fmt, $prof);
    $milieu = decompiler_($struct->milieu, $fmt, $prof);
    $type = $struct->sql_serveur ? "{$struct->sql_serveur}:" : '';
    $type .= $struct->type_requete ? $struct->type_requete : $struct->table_optionnelle;
    if ($struct->jointures_explicites) {
        $type .= " " . $struct->jointures_explicites;
    }
    if ($struct->table_optionnelle) {
        $type .= "?";
    }
    // Revoir le cas de la boucle recursive
    $crit = $struct->param;
    if ($crit and !is_array($crit[0])) {
        $type = strtolower($type) . array_shift($crit);
    }
    $crit = decompiler_criteres($struct, $fmt, $prof);
    $f = 'format_boucle_' . $fmt;
    return $f($avant, $nom, $type, $crit, $milieu, $apres, $altern, $prof);
}
Example #3
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;
}
Example #4
0
function debusquer_navigation_boucles($boucles, $nom_skel, $self)
{
	$i = 0;
	$res = '';
	$var_mode_objet = _request('var_mode_objet');
	foreach ($boucles as $objet => $boucle) {
		if (substr($objet, 0, strlen($nom_skel)) == $nom_skel) {
			$i++;
			$nom = $boucle->id_boucle;
			$req = $boucle->type_requete;
			$crit = decompiler_criteres($boucle->param, $boucle->criteres);
			$self2 = $self .  "&var_mode_objet=" .  $objet;

			$res .= "\n<tr style='background-color: " .
			  ($i%2 ? '#e0e0f0' : '#f8f8ff') .
			  "'><td  align='right'>$i</td><td>\n" .
			  "<a  class='debug_link_boucle' href='" .
			  $self2 .
			  "&amp;var_mode_affiche=boucle#$nom_skel$nom'>" .
			  _T('zbug_boucle') .
			  "</a></td><td>\n<a class='debug_link_boucle' href='" .
			  $self2 .
			  "&amp;var_mode_affiche=resultat#$nom_skel$nom'>" .
			  _T('zbug_resultat') .
			  "</a></td><td>\n<a class='debug_link_resultat' href='" .
			  $self2 .
			  "&amp;var_mode_affiche=code#$nom_skel$nom'>" .
			  _T('zbug_code') .
			  "</a></td><td>\n<a class='debug_link_resultat' href='" .
			  str_replace('var_mode=','var_profile=', $self2) .
			  "'>" .
			  _T('zbug_calcul') .
			  "</a></td><td>\n" .
			  (($var_mode_objet == $objet) ? "<b>$nom</b>" : $nom) .
			  "</td><td>\n" .
			  $req .
			  "</td><td>\n" .
			  $crit .
			  "</td></tr>";
		}
	}
	return $res;
}