From 02600a4abb5b8f12b32f41ea51da9ea755427d6a Mon Sep 17 00:00:00 2001 From: Fil <fil@rezo.net> Date: Sun, 12 Dec 2010 08:50:48 +0000 Subject: [PATCH] les boucles ENUM et DATA arrivent : Boucle POUR: ============ <BOUCLE_x(POUR){tableau=#CONFIG**}{valeur>0}{cle==version}> Boucle DATA: ============ <BOUCLE_r(DATA){datasource http://localhost/spip/?page=backend, rss}> <BOUCLE_r1(DATA){datasource http://localhost/spip/rien.json, json}> <BOUCLE_r2(DATA){datasource http://localhost/spip/rien.yaml, yaml}{pagination 5}> <BOUCLE_r3(DATA){datasource TEST.CSV, csv}{valeur==France}> Boucle ENUM: ============ [(#REM) Echiquier ]<B_z> <table> <BOUCLE_z(ENUM){1,8}> <tr> <BOUCLE_y(ENUM){1,8}> <td> [(#_z:VALEUR|plus{64}|chr)]#VALEUR </td> </BOUCLE_y> </tr> </BOUCLE_z> </table> </B_z> [(#REM) Une pagination qui va jusqu'au max possible ]<B_a> [<p class="pagination">(#PAGINATION)</p>] <BOUCLE_a(ENUM){pagination 10}> #VALEUR </BOUCLE_a> --- .gitattributes | 2 + ecrire/public/compiler.php | 58 +++++++++---- ecrire/public/creer_boucle_data.php | 27 ++++++ ecrire/public/creer_boucle_enum.php | 26 ++++++ ecrire/public/creer_boucle_pour.php | 2 +- ecrire/public/criteres.php | 10 +++ ecrire/public/iterateur.php | 130 ++++++++++++++++++++++++++-- 7 files changed, 231 insertions(+), 24 deletions(-) create mode 100644 ecrire/public/creer_boucle_data.php create mode 100644 ecrire/public/creer_boucle_enum.php diff --git a/.gitattributes b/.gitattributes index 2997230f17..e10285bbb5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -297,6 +297,8 @@ 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_data.php -text +ecrire/public/creer_boucle_enum.php -text ecrire/public/creer_boucle_pour.php -text ecrire/public/decompiler.php -text ecrire/public/format_html.php -text diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php index e839b7c31b..b97d623ae0 100644 --- a/ecrire/public/compiler.php +++ b/ecrire/public/compiler.php @@ -242,21 +242,8 @@ function calculer_boucle_rec($id_boucle, &$boucles, $trace) { define('CODE_CORPS_BOUCLE', '%s $t0 = ""; // REQUETE - $iter = new %s(); - $iter->init( array( - "select"=>$select, - "from"=>$from, - "type"=>$type, - "where"=>$where, - "join"=>$join, - "groupby"=>$groupby, - "orderby"=>$orderby, - "limit"=>$limit, - "having"=>$having, - "table"=>$table, - "id"=>$id, - "connect"=>$connect - ), + $iter = new %s( + %s, array(%s) ); if ($iter->ok) { @@ -401,7 +388,46 @@ 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, $boucle->iterateur, $contexte, $nums, $init_lang, $corps, $fin_lang, $trace); + + switch ($boucle->iterateur) { + case 'IterSQL': + $command = 'array( + "select"=>$select, + "from"=>$from, + "type"=>$type, + "where"=>$where, + "join"=>$join, + "groupby"=>$groupby, + "orderby"=>$orderby, + "limit"=>$limit, + "having"=>$having, + "table"=>$table, + "id"=>$id, + "connect"=>$connect + )'; + break; + + case 'IterPOUR': + case 'IterENUM': + $command = 'array("where" => $where, "source"=>$source, "sourcemode"=>$sourcemode, "limit" => $limit)'; + break; + + default: + $command = 'array()'; + break; + } + + $a = sprintf(CODE_CORPS_BOUCLE, + $init, + $boucle->iterateur, + $command, + $contexte, + $nums, + $init_lang, + $corps, + $fin_lang, + $trace + ); # var_dump($a);exit; return $a; diff --git a/ecrire/public/creer_boucle_data.php b/ecrire/public/creer_boucle_data.php new file mode 100644 index 0000000000..28dcd84df8 --- /dev/null +++ b/ecrire/public/creer_boucle_data.php @@ -0,0 +1,27 @@ +<?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 DATA +// annonce au compilo les "champs" disponibles +// +function public_creer_boucle_DATA_dist($b) { + $b->iterateur = 'IterPOUR'; # designe la classe d'iterateur + $b->show = array( + 'field' => array( + 'cle' => 'STRING', + 'valeur' => 'STRING', + ) + ); + return $b; +} + diff --git a/ecrire/public/creer_boucle_enum.php b/ecrire/public/creer_boucle_enum.php new file mode 100644 index 0000000000..b970d04562 --- /dev/null +++ b/ecrire/public/creer_boucle_enum.php @@ -0,0 +1,26 @@ +<?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 ENUM +// annonce au compilo les "champs" disponibles +// +function public_creer_boucle_ENUM_dist($b) { + $b->iterateur = 'IterENUM'; # designe la classe d'iterateur + $b->show = array( + 'field' => array( + 'valeur' => 'STRING', + ) + ); + return $b; +} + diff --git a/ecrire/public/creer_boucle_pour.php b/ecrire/public/creer_boucle_pour.php index cd5a559663..141112006d 100644 --- a/ecrire/public/creer_boucle_pour.php +++ b/ecrire/public/creer_boucle_pour.php @@ -12,7 +12,7 @@ // // creer une boucle sur un iterateur POUR -// definir les "champs" existants pour le compilo +// annonce au compilo les "champs" disponibles // function public_creer_boucle_POUR_dist($b) { $b->iterateur = 'IterPOUR'; # designe la classe d'iterateur diff --git a/ecrire/public/criteres.php b/ecrire/public/criteres.php index c0265cf7a6..4d10729e1a 100644 --- a/ecrire/public/criteres.php +++ b/ecrire/public/criteres.php @@ -1380,4 +1380,14 @@ function calculer_param_date($date_compare, $date_orig) { $date_orig . ")))"; } + +function critere_datasource($idb, &$boucles, $crit) { + $boucle = &$boucles[$idb]; + $boucle->hash .= ' + $source = '.calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent).'; + $sourcemode = '.calculer_liste($crit->param[1], array(), $boucles, $boucles[$idb]->id_parent).';'; + $boucle->where['sourcemode'] = '$sourcemode'; + $boucle->where['source'] = '$source'; +} + ?> diff --git a/ecrire/public/iterateur.php b/ecrire/public/iterateur.php index 2ce263bc19..70444e5a1f 100644 --- a/ecrire/public/iterateur.php +++ b/ecrire/public/iterateur.php @@ -24,15 +24,12 @@ class Iter { private $result = false; - public function Iter() { - $this->type = '??'; - } - /* * array command: les commandes d'initialisation * array info: les infos sur le squelette */ - public function init($command, $info=array()) { + public function Iter($command, $info=array()) { + $this->type = '??'; $this->command = $command; $this->info = $info; } @@ -60,7 +57,7 @@ class IterSQL extends Iter { * array command: les commandes d'initialisation * array info: les infos sur le squelette */ - public function init($command, $info=array()) { + public function IterSQL($command, $info=array()) { $this->type='SQL'; $this->command = $command; $this->info = $info; @@ -86,6 +83,85 @@ class IterSQL extends Iter { } } +class IterENUM extends Iter { + var $ok = true; + var $type; + var $command; + var $info; + + var $n = 0; + var $max = 1000000; + + var $filtre = array(); + + private $result = false; + + /* + * array command: les commandes d'initialisation + * array info: les infos sur le squelette + */ + public function IterENUM($command, $info=array()) { + $this->type='ENUM'; + $this->command = $command; + $this->info = $info; + + if (is_array($this->command['where'])) + foreach ($this->command['where'] as $k => $com) { + switch($com[1]) { + 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; + } + + } + + // critere {2,7} + if ($this->command['limit']) { + $limit = explode(',',$this->command['limit']); + $this->n = $limit[0]; + $this->max = $limit[0]+$limit[1]-1; + } + + + // Appliquer les filtres sur (valeur) + if ($this->filtre) { + $this->filtre = create_function('$valeur', $b = 'return ('.join(') AND (', $this->filtre).');'); + } + + } + public function seek($n=0, $continue=null) { + $this->n = $n; + return true; + } + public function next() { + if ($f = $this->filtre) { + while ( + $this->n < $this->max + AND !$f($a = $this->n++)){}; + } else + $a = $this->n++; + + if ($this->n <= 1+$this->max) + return array('valeur' => $a); + } + public function free(){ + } + public function count() { + return $this->max; + } +} + + class IterPOUR extends Iter { var $ok = false; var $type; @@ -101,13 +177,53 @@ class IterPOUR extends Iter { * array command: les commandes d'initialisation * array info: les infos sur le squelette */ - public function init($command, $info=array()) { + public function IterPOUR($command, $info=array()) { $this->type='POUR'; $this->command = $command; $this->info = $info; // les commandes connues pour l'iterateur POUR // sont : tableau=#ARRAY ; cle=...; valeur=... + // source URL + if (isset($this->command['source'])) { + if (preg_match(',^http://,', $this->command['source'])) { + include_spip('inc/distant'); + $u = recuperer_page($this->command['source']); + } else + $u = spip_file_get_contents($this->command['source']); + + // si c'est du RSS + if (isset($this->command['sourcemode'])) { + switch ($this->command['sourcemode']) { + case 'rss': + include_spip('inc/syndic'); + if (is_array($rss = analyser_backend($u))) { + $this->tableau = $rss; + $this->ok = true; + } + break; + case 'json': + if (is_array($json = json_decode($u))) { + $this->tableau = $json; + $this->ok = true; + } + break; + case 'yaml': + include_spip('inc/yaml'); + if (is_array($yaml = yaml_decode($u))) { + $this->tableau = $yaml; + $this->ok = true; + } + break; + case 'csv': + # decodage csv a peaufiner :-) + foreach(explode("\n",$u) as $ligne) + $this->tableau[] = explode(',', $ligne); + $this->ok = true; + } + } + } + if (is_array($this->command['where'])) foreach ($this->command['where'] as $k => $com) { switch($com[1]) { -- GitLab