From bddbb03fc8815787996ff9d896ee85ced5622a58 Mon Sep 17 00:00:00 2001 From: Fil <fil@rezo.net> Date: Sat, 11 Dec 2010 18:17:49 +0000 Subject: [PATCH] un peu de nettoyage et un debut de boucle POUR definie sous forme d'iterateur ; ce que je ne vois pas encore bien comment structurer, c'est la possibilite d'aller chercher un iterateur dans un plugin --- .gitattributes | 1 + ecrire/public/compiler.php | 16 +++- ecrire/public/composer.php | 2 +- ecrire/public/creer_boucle_pour.php | 28 +++++++ ecrire/public/interfaces.php | 2 + ecrire/public/iterateur.php | 123 +++++++++++++++++++++++++++- 6 files changed, 165 insertions(+), 7 deletions(-) create mode 100644 ecrire/public/creer_boucle_pour.php diff --git a/.gitattributes b/.gitattributes index 59c27ec16c..2997230f17 100644 --- a/.gitattributes +++ b/.gitattributes @@ -297,6 +297,7 @@ ecrire/plugins/get_infos.php -text ecrire/plugins/verifie_conformite.php -text ecrire/prive.php -text ecrire/public/aiguiller.php -text +ecrire/public/creer_boucle_pour.php -text ecrire/public/decompiler.php -text ecrire/public/format_html.php -text ecrire/public/index.php -text diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php index 35b7a0c778..e839b7c31b 100644 --- a/ecrire/public/compiler.php +++ b/ecrire/public/compiler.php @@ -242,7 +242,7 @@ function calculer_boucle_rec($id_boucle, &$boucles, $trace) { define('CODE_CORPS_BOUCLE', '%s $t0 = ""; // REQUETE - $iter = new Iter("SQL"); + $iter = new %s(); $iter->init( array( "select"=>$select, "from"=>$from, @@ -401,7 +401,7 @@ function calculer_boucle_nonrec($id_boucle, &$boucles, $trace) { . calculer_requete_sql($boucles[$id_boucle]); $contexte = memoriser_contexte_compil($boucle); - $a = sprintf(CODE_CORPS_BOUCLE, $init, $contexte, $nums, $init_lang, $corps, $fin_lang, $trace); + $a = sprintf(CODE_CORPS_BOUCLE, $init, $boucle->iterateur, $contexte, $nums, $init_lang, $corps, $fin_lang, $trace); # var_dump($a);exit; return $a; @@ -880,14 +880,22 @@ function compiler_squelette($squelette, $boucles, $nom, $descr, $sourcefile, $co // 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))) + if (!$show + AND $show=$trouver_table($type, strtolower($type))) { $boucles[$id]->sql_serveur = strtolower($type); - if ($show) { + } + + if ($g = charger_fonction( + 'creer_boucle_'.$boucle->type_requete, 'public', true)) { + $boucles[$id] = $g($boucle); + + } else 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]->iterateur = 'IterSQL'; $boucles[$id]->descr = &$descr; if ((!$boucles[$id]->jointures) diff --git a/ecrire/public/composer.php b/ecrire/public/composer.php index ecc139cdcc..1393a8fa92 100644 --- a/ecrire/public/composer.php +++ b/ecrire/public/composer.php @@ -12,12 +12,12 @@ if (!defined("_ECRIRE_INC_VERSION")) return; -include_spip('public/iterateur'); include_spip('inc/texte'); include_spip('inc/documents'); include_spip('inc/distant'); include_spip('inc/rubriques'); # pour calcul_branche (cf critere branche) include_spip('inc/acces'); // Gestion des acces pour ical +include_spip('public/iterateur'); include_spip('public/interfaces'); include_spip('public/quete'); diff --git a/ecrire/public/creer_boucle_pour.php b/ecrire/public/creer_boucle_pour.php new file mode 100644 index 0000000000..cd5a559663 --- /dev/null +++ b/ecrire/public/creer_boucle_pour.php @@ -0,0 +1,28 @@ +<?php + +/***************************************************************************\ + * SPIP, Systeme de publication pour l'internet * + * * + * Copyright (c) 2001-2010 * + * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * + * * + * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * + * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. * +\***************************************************************************/ + +// +// creer une boucle sur un iterateur POUR +// definir les "champs" existants pour le compilo +// +function public_creer_boucle_POUR_dist($b) { + $b->iterateur = 'IterPOUR'; # designe la classe d'iterateur + $b->show = array( + 'field' => array( + 'tableau' => 'ARRAY', + 'cle' => 'STRING', + 'valeur' => 'STRING', + ) + ); + return $b; +} + diff --git a/ecrire/public/interfaces.php b/ecrire/public/interfaces.php index b1da7b90a1..002870b5ae 100644 --- a/ecrire/public/interfaces.php +++ b/ecrire/public/interfaces.php @@ -83,6 +83,8 @@ class Boucle { var $modificateur = array(); // table pour stocker les modificateurs de boucle tels que tout, plat ..., utilisable par les plugins egalement + var $iterateur = ''; // type d'iterateur + // obsoletes, conserves provisoirement pour compatibilite var $tout = false; var $plat = false; diff --git a/ecrire/public/iterateur.php b/ecrire/public/iterateur.php index 419b470d49..2ce263bc19 100644 --- a/ecrire/public/iterateur.php +++ b/ecrire/public/iterateur.php @@ -24,10 +24,31 @@ class Iter { private $result = false; + public function Iter() { + $this->type = '??'; + } - public function Iter($type) { - $this->type = $type; + /* + * array command: les commandes d'initialisation + * array info: les infos sur le squelette + */ + public function init($command, $info=array()) { + $this->command = $command; + $this->info = $info; } + public function seek($n=0, $continue=null) {} + public function next() {} + public function free() {} + public function count() {} +} + +class IterSQL extends Iter { + var $ok = false; + var $type; + var $command; + var $info; + + private $result = false; private function select() { $v = &$this->command; @@ -40,6 +61,7 @@ class Iter { * array info: les infos sur le squelette */ public function init($command, $info=array()) { + $this->type='SQL'; $this->command = $command; $this->info = $info; $this->select(); @@ -64,6 +86,103 @@ class Iter { } } +class IterPOUR extends Iter { + var $ok = false; + var $type; + var $command; + var $info; + + var $tableau = array(); + var $filtre = array(); + + private $result = false; + + /* + * array command: les commandes d'initialisation + * array info: les infos sur le squelette + */ + public function init($command, $info=array()) { + $this->type='POUR'; + $this->command = $command; + $this->info = $info; + + // les commandes connues pour l'iterateur POUR + // sont : tableau=#ARRAY ; cle=...; valeur=... + if (is_array($this->command['where'])) + foreach ($this->command['where'] as $k => $com) { + switch($com[1]) { + case 'tableau': + if ($com[0] !== '=') { + // erreur + } + # sql_quote a l'envers : pas propre... + $x = null; + eval ('$x = '.str_replace('\"', '"', $com[2]).';'); + if (is_array($x) OR is_array($x = @unserialize($x))) { + $this->tableau = $x; + $this->ok = true; + } + else + { + // erreur + } + break; + case 'cle': + case 'valeur': + unset($op); + if ($com[0] == 'REGEXP') + $this->filtre[] = 'preg_match("/". '.str_replace('\"', '"', $com[2]).'."/", $'.$com[1].')'; + else if ($com[0] == '=') + $op = '=='; + else if (in_array($com[0], array('<','<=', '>', '>='))) + $op = $com[0]; + + if ($op) + $this->filtre[] = '$'.$com[1].$op.str_replace('\"', '"', $com[2]); + + break; + } + + } + + // Appliquer les filtres sur (cle,valeur) + if ($this->filtre) { + $filtre = create_function('$cle,$valeur', $b = 'return ('.join(') AND (', $this->filtre).');'); + #var_dump($b); + foreach($this->tableau as $cle=>$valeur) { + if (!$filtre($cle,$valeur)) + unset($this->tableau[$cle]); + } + } + + // critere {2,7} + if ($this->command['limit']) { + $limit = explode(',',$this->command['limit']); + $this->tableau = array_slice($this->tableau, + $limit[0],$limit[1],true); + } + + + reset($this->tableau); + #var_dump($this->tableau); + } + public function seek($n=0, $continue=null) { + reset($this->tableau); + while($n-->0 AND list($cle, $valeur) = each($this->tableau)){}; + return true; + } + public function next(){ + if (list($cle, $valeur) = each($this->tableau)) { + return array('cle' => $cle, 'valeur' => $valeur); + } + } + public function free(){ + } + public function count() { + return count($this->tableau); + } +} + ?> -- GitLab