phpDocumentor lodel
[ class tree: lodel ] [ index: lodel ] [ all elements ]

Source for file lodelparser.php

Documentation is available at lodelparser.php

  1. <?php
  2. /**
  3.  * Fichier LodelParser
  4.  * PHP versions 4 et 5
  5.  *
  6.  * LODEL - Logiciel d'Edition ELectronique.
  7.  *
  8.  * Copyright (c) 2001-2002, Ghislain Picard, Marin Dacos
  9.  * Copyright (c) 2003, Ghislain Picard, Marin Dacos, Luc Santeramo, Nicolas Nutten, Anne Gentil-Beccot
  10.  * Copyright (c) 2004, Ghislain Picard, Marin Dacos, Luc Santeramo, Anne Gentil-Beccot, Bruno Cénou
  11.  * Copyright (c) 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  12.  * Copyright (c) 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  13.  * Copyright (c) 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  14.  *
  15.  * Home page: http://www.lodel.org
  16.  *
  17.  * E-Mail: lodel@lodel.org
  18.  *
  19.  * All Rights Reserved
  20.  *
  21.  * This program is free software; you can redistribute it and/or modify
  22.  * it under the terms of the GNU General Public License as published by
  23.  * the Free Software Foundation; either version 2 of the License, or
  24.  * (at your option) any later version.
  25.  *
  26.  * This program is distributed in the hope that it will be useful,
  27.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  28.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  29.  * GNU General Public License for more details.
  30.  *
  31.  * You should have received a copy of the GNU General Public License
  32.  * along with this program; if not, write to the Free Software
  33.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  34.  *
  35.  * @author Ghislain Picard
  36.  * @author Jean Lamy
  37.  * @author Sophie Malafosse
  38.  * @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  39.  * @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  40.  * @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  41.  * @licence http://www.gnu.org/copyleft/gpl.html
  42.  * @version CVS:$Id:
  43.  * @package lodel
  44.  */
  45.  
  46. // traitement particulier des attributs d'une loop
  47. // l'essentiel des optimisations et aide a l'uitilisateur doivent
  48. // en general etre ajouter ici
  49. //
  50.  
  51. require_once "func.php";
  52. require_once "balises.php";
  53. require_once "parser.php";
  54.  
  55. /**
  56.  * Classe LodelParser
  57.  * 
  58.  * Classe utilitaire pour parser le Lodelscript - Fille de la classe Parser
  59.  *
  60.  * @package lodel
  61.  * @author Ghislain Picard
  62.  * @author Jean Lamy
  63.  * @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  64.  * @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  65.  * @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  66.  * @licence http://www.gnu.org/copyleft/gpl.html
  67.  * @since Classe ajoutée depuis la version 0.8
  68.  * @see parser.php
  69.  */
  70. class LodelParser extends Parser
  71. {
  72.     var $filterfunc_loaded = FALSE;
  73.     /**
  74.      * Tableau associatif concernant le status des textes
  75.      *
  76.      * @var array 
  77.      */
  78.     var $textstatus = array ('-1' => ' traduire''1' => ' revoir''2' => 'traduit');
  79.     
  80.     /**
  81.      * Tableau associatif concernant le status associé à la couleur
  82.      *
  83.      * @var array 
  84.      */
  85.     var $colorstatus = array ('-1' => 'red''1' => 'orange'=> 'green');
  86.  
  87.     /**
  88.      * Liste des langues de la traduction
  89.      *
  90.      * @var array 
  91.      */
  92.     var $translationlanglist = "'fr','en','es','de'";
  93.  
  94.  
  95.     /**
  96.      * Constructeur.
  97.      */
  98.     function LodelParser()
  99.     // constructor
  100.         $this->Parser();
  101.         $this->commands['TEXT'// catch the text
  102.         $this->variablechar = '@'// catch the @
  103.  
  104.         if (DBDRIVER == 'mysql'{
  105.             $this->codepieces['sqlquery'"mysql_query(lq(%s))";
  106.         }    else // call the ADODB driver
  107.             die("DBDRIVER not supported currently for the parser");
  108.             $this->codepieces['sqlerror'"or die($GLOBALS[db]->errormsg())";
  109.             $this->codepieces['sqlquery'"$GLOBALS[db]->execute(%s)";
  110.             $this->codepieces['sqlfetch''';
  111.         }
  112.     }
  113.  
  114.     function parse_loop_extra($tables$tablesinselect$extrainselect$selectparts)
  115.     {
  116.         global $site$home$db;
  117.         static $tablefields// charge qu'une seule fois
  118.         if (!$tablefields{
  119.             require ('tablefields.php');
  120.         }
  121.  
  122.         // split the SQL parts into quoted/non-quoted par
  123.         foreach ($selectparts as $k => $v{
  124.             $selectparts[$k$this->sqlsplit($v);
  125.         }
  126.  
  127.         $where $selectparts['where'];
  128.  
  129.         // convertion des codes specifiques dans le where
  130.         // ce bout de code depend du parenthesage et du trim fait dans parse_loop.
  131.         #  $where=preg_replace (array(
  132.         #            "/\(trash\)/i",
  133.         #            "/\(ok\)/i",
  134.         #            "/\(rightgroup\)/i"
  135.         #            ),
  136.         #          array(
  137.         #            "status<=0",
  138.         #            "status>0",
  139.         #            '".($GLOBALS[lodeluser][admin] ? "1" : "(usergroup IN ($GLOBALS[lodeluser][groups]))")."'
  140.         #            ),$where);
  141.         //
  142.         if ($tablefields[lq("#_TP_classes")]{
  143.  
  144.             $dao &getDAO("classes");
  145.             $classes $dao->findMany("status > 0");
  146.             foreach ($classes as $class{
  147.                 // manage the linked tables...
  148.                 // do we have the table class in $tables ?
  149.                 $ind array_search($class->class$tables);
  150.                 if ($ind === FALSE || $ind === NULL{
  151.                     continue;
  152.                 }
  153.  
  154.                 $alias "alias_".$class->classtype."_".$class->class;
  155.                 $aliastype "aliastype_".$class->classtype"_"$class->class;
  156.                 $aliasbyclasstype[$class->classtype$alias;
  157.                 $classbyclasstype[$class->classtype$class->class;
  158.  
  159.                 switch ($class->classtype{
  160.                 case "entities" :
  161.                     $typetable "types";
  162.                     protect($selectparts$alias"id|idtype|identifier|usergroup|iduser|rank|status|idparent|creationdate|modificationdate|g_title");
  163.                     $longid "identity";
  164.                     break;
  165.                 case "entries" :
  166.                     $typetable "entrytypes";
  167.                     protect($selectparts$alias"id|idtype|g_name|sortkey|rank|status|idparent");
  168.                     $longid "identry";
  169.                     break;
  170.                 case "persons" :
  171.                     $typetable "persontypes";
  172.                     protect($selectparts$alias"id|idtype|g_familyname|g_firstname|status");
  173.                     $longid "idperson";
  174.                     break;
  175.                 default :
  176.                     die("ERROR: internal error in lodelparser");
  177.                 }
  178.  
  179.                 array_push($tables$class->classtype" AS "$aliastypestable($class->classtype)" AS "$aliastype);
  180.  
  181.                 // put entites just after the class table
  182.                 array_splice($tablesinselect$ind +10$alias);
  183.  
  184.                 $where[count($where1.= " AND "$class->class"."$longid."="$alias".id AND ".$alias.".idtype="$aliastype.".id AND "$aliastype".class=";
  185.                 $where["'"$class->class"'"// quoted part
  186.                 $where["";
  187.                 $extrainselect .= ", ".$aliastype".type , "$aliastype".class";
  188.  
  189.                 if (preg_match_sql("/\bparent\b/"$where&& 
  190.                         ($class->classtype == "entities" || $class->classtype == "entries")) {
  191.                     array_push($tables$class->classtype" AS "$alias"_parent");
  192.                     $fullid $class->classtype == "entries" "g_name" "identifier";
  193.                     preg_replace_sql("/\bparent\b/"$alias"_parent.".$fullid$where);
  194.                     $where[count($where1.= " AND "$alias"_parent.id="$alias".idparent";
  195.                 }
  196.             }
  197.         }
  198.  
  199.         if (in_array("entities"$tables)) {
  200.             if (preg_match_sql("/\bclass\b/"$where|| preg_match_sql("/\btype\b/"$where)) {
  201.                 array_push($tables"types");
  202.                 protect($selectparts"entities""id|status|rank");
  203.                 $jointypesentitiesadded 1;
  204.                 $where[count($where1.= " AND entities.idtype=types.id";
  205.             }
  206.             if (preg_match_sql("/\bparent\b/"$where)) {
  207.                 array_push($tables"entities as entities_parent");
  208.                 protect($selectparts"entities""id|idtype|identifier|usergroup|iduser|rank|status|idparent|creationdate|modificationdate|g_title");
  209.                 preg_replace_sql("/\bparent\b/""entities_parent.identifier"$where);
  210.                 $where[count($where1.= " AND entities_parent.id=entities.idparent";
  211.             }
  212.             if (in_array("types"$tables)) // compatibilite avec avant... et puis c est pratique quand meme.
  213.                 $extrainselect .= ", types.type , types.class";
  214.             }
  215.         // fin de entities
  216.  
  217.         // verifie le status
  218.         if (!preg_match_sql("/\bstatus\b/i"$where)) // test que l'element n'est pas a la poubelle
  219.             $teststatus array ();
  220.             foreach ($tables as $table{
  221.                 list ($table$aliaspreg_split("/\s+AS\s+/i"$table);
  222.                 if (!$alias){
  223.                     $alias $table;
  224.                 }
  225.  
  226.                 $realtable $this->prefixTableName($table);
  227.                 if (!$tablefields[$realtable|| !in_array("status"$tablefields[$realtable])) {
  228.                     continue;
  229.                 }
  230.                 if ($table == "session"{
  231.                     continue;
  232.                 }
  233.                 if ($table == "entities"{
  234.                     $lowstatus '"-64".($GLOBALS[lodeluser][admin] ? "" : "*('.$alias.'.usergroup IN (".$GLOBALS[lodeluser][groups]."))")';
  235.                 }    else {
  236.                     $lowstatus "-64";
  237.                 }
  238.                 $where[count($where1.= " AND (".$alias.".status>\".(\$GLOBALS[lodeluser][visitor] ? $lowstatus : \"0\").\")";
  239.             }
  240.         }
  241.         #  echo "where 2:",htmlentities($where),"<br>";
  242.  
  243.         if ($site{
  244.             ///////// CODE SPECIFIQUE -- gere les tables croisees
  245.             //
  246.             // les regexp ci-dessous sont insuffisantes, il faudrait tester que ce n'est pas dans une zone quotee de la clause where !!!!
  247.             //
  248.             // persons and entries
  249.             foreach (array ("persons" => "persontypes""entries" => "entrytypes"as $table => $typetable{
  250.                 if (in_array($table$tables&& preg_match_sql("/\b(type|g_type)\b/"$where)) {
  251.                     protect($selectparts$table"id|status|rank");
  252.                     array_push($tables$typetable);
  253.                     $where[count($where1.= " AND ".$table.".idtype=".$typetable.".id";
  254.                 }
  255.  
  256.                 if (in_array($table$tables|| $aliasbyclasstype[$table])    {
  257.                     if ($aliasbyclasstype[$table]{
  258.                         $class $classbyclasstype[$table];
  259.                         $table $aliasbyclasstype[$table];
  260.                     }    else {
  261.                         $class "";
  262.                     }
  263.                     // fait ca en premier
  264.                     if (preg_match_sql("/\b(iddocument|identity)\b/"$where)) {
  265.                         // on a besoin de la table croisee entities_persons
  266.                         $alias "relation_entities_".$table// use alias for security
  267.                         array_push($tables"relations as ".$alias)###,"entities_persons");
  268.                         #print_R($where);
  269.                         preg_replace_sql("/\b(iddocument|identity)\b/"$alias.".id1"$where);
  270.                         #print_R($where);
  271.                         $where[count($where1.= " AND $alias.id2=$table.id";
  272.  
  273.                         if ($class && $typetable == "persontypes"// related table for persons only
  274.                             $relatedtable "entities_".$class;
  275.                             if (!in_array($relatedtable$tables)) {
  276.                                 array_push($tables$relatedtable);
  277.                                 $where[count($where1.= " AND ".$relatedtable.".idrelation=".$alias.".idrelation";
  278.                                 $extrainselect .= ", ".$relatedtable.".* ";
  279.                             }
  280.                         }
  281.                     }
  282.                 }
  283.             }
  284.  
  285.             if ($aliasbyclasstype['entities'|| in_array("entities"$tables))    {
  286.                 foreach (array ("persons" => "idperson""entries" => "identry"as $table => $regexp{
  287.  
  288.                     if (!preg_match_sql("/\b($regexp)\b/"$where)) {
  289.                         continue;
  290.                     }
  291.                     // on a besoin de la table croise relation
  292.                     $alias "relation2_".$table// use alias for security
  293.                     array_push($tables"relations as ".$alias);
  294.                     preg_replace_sql("/\b($regexp)\b/"$alias.".id2"$where);
  295.                     $where[count($where1.= " AND ".$alias.".id1="($aliasbyclasstype['entities'$aliasbyclasstype['entities'"entities").".id";
  296.  
  297.                     if ($table == "persons" && $classbyclasstype['persons']// related table for persons only
  298.                         $relatedtable "entities_".$classbyclasstype['persons'];
  299.                         if (!in_array($relatedtable$tables)) {
  300.                             array_push($tables$relatedtable);
  301.                             $where[count($where1.= " AND ".$relatedtable.".idrelation=".$alias.".idrelation";
  302.                             $extrainselect .= ", ".$relatedtable.".* ";
  303.                         }
  304.                     }
  305.                 }
  306.             }
  307.  
  308.             if (in_array("usergroups"$tables&& preg_match_sql("/\biduser\b/"$where)) {
  309.                 // on a besoin de la table croise users_groupes
  310.                 array_push($tables"users_usergroups");
  311.                 $where[count($where1.= " AND idgroup=usergroups.id";
  312.             }
  313.             if (in_array("users"$tables&& in_array("session"$tables))    {
  314.                 $where[count($where1.= " AND iduser=users.id";
  315.             }
  316.  
  317.         // site
  318.  
  319.         // join the SQL parts
  320.         foreach ($selectparts as $k => $v{
  321.             if (is_array($v)) {
  322.                 $selectparts[$kjoin(""$v);
  323.             }
  324.         }
  325.  
  326.         $selectparts['where'lq($selectparts['where']);
  327.         if (preg_match("/\b(count|min|max|avg|bit_and|bit_or|bit_xor|group_concat|std|stddev|stddev_pop|stddev_samp|sum|var_pop|var_samp|variance)\s*\(/i"$selectparts['select']))
  328.             $extrainselect ""// group by function
  329.  
  330.         $extrainselect lq($extrainselect);
  331.  
  332.         $tables array_map(array ($this"prefixTableName")$tables);
  333.         $tablesinselect array_map(array ($this"prefixTableName")$tablesinselect);
  334.     }
  335.  
  336.     //
  337.     // Traitement special des variables
  338.     //
  339.     function parse_variable_extra($prefix$varname)
  340.     {
  341.         // VARIABLES SPECIALES
  342.         if ($prefix == "#"{
  343.             if ($varname == "GROUPRIGHT"{
  344.                 return '($GLOBALS[lodeluser][admin] || in_array($context[usergroup],explode(\',\',$GLOBALS[lodeluser][groups])))';
  345.             }
  346.             if (preg_match("/^OPTION[_.]/"$varname)) // options
  347.                 return "getoption('".strtolower(substr($varname7))."')";
  348.             }
  349.         }
  350.  
  351.         if ($prefix == "@"{
  352.             $dotpos strpos($varname".");
  353.             if ($dotpos{
  354.                 $name substr($varname$dotpos +1);
  355.                 $group substr($varname0$dotpos);
  356.             }    else {
  357.                 $name $varname;
  358.                 $group "site";
  359.             }
  360.             return $this->maketext($name$group"@");
  361.         }
  362.         return FALSE;
  363.     }
  364.  
  365.     //
  366.     // fonction qui gere les decodage du contenu des differentes parties
  367.     // d'une loop (DO*)
  368.     // fonction speciale pour lodel 
  369.     //
  370.     function decode_loop_content_extra($balise$content$options$tables)
  371.     {
  372.         global $home;
  373.  
  374.         $havepublications in_array("publications"$tables);
  375.         $havedocuments in_array("documents"$tables);
  376.         //
  377.         // est-ce qu'on veut le prev et next publication ?
  378.         //
  379.  
  380.         // desactive le 10/03/04
  381.         //  if ($havepublications && preg_match("/\[\(?#(PREV|NEXT)PUBLICATION\b/",$content[$balise])) {
  382.         //    $content["PRE_".$balise]='include_once("$GLOBALS[home]/func.php"); export_prevnextpublication($context);';
  383.         //  }
  384.         // les filtrages automatiques
  385.         if ($havedocuments || $havepublications{
  386.             $options['sqlfetchassoc''filtered_mysql_fetch_assoc($context,%s)';
  387.             if (!$this->filterfunc_loaded){
  388.                 $this->filterfunc_loaded = TRUE;
  389.                 $this->fct_txt .= 'if (!(@include_once("CACHE/filterfunc.php"))) require_once("filterfunc.php");';
  390.             }
  391.         }
  392.     }
  393.  
  394.     function parse_TEXT()
  395.     {
  396.         $attr $this->_decode_attributs($this->arr[$this->ind + 1]);
  397.  
  398.         if (!$attr['NAME']{
  399.             $this->errmsg("ERROR: The TEXT tag has no NAME attribute");
  400.         }
  401.         $name addslashes(stripslashes(trim($attr['NAME'])));
  402.  
  403.         $group addslashes(stripslashes(trim($attr['GROUP'])));
  404.         if (!$group{
  405.             $group "site";
  406.         }
  407.  
  408.         $this->_clearposition();
  409.         $this->arr[$this->ind$this->maketext($name$group"text");
  410.     }
  411.  
  412.     function maketext($name$group$tag)
  413.     {
  414.         global $db;
  415.  
  416.         $name strtolower($name);
  417.         $group strtolower($group);
  418.  
  419.         if ($GLOBALS['righteditor']// cherche si le texte existe
  420.             require_once TOINCLUDE."connect.php";
  421.  
  422.             if ($group != "site"{
  423.                 usemaindb();
  424.                 $prefix lq("#_MTP_");
  425.             else    {
  426.                 $prefix lq("#_TP_");
  427.             }
  428.             $textexists $db->getOne("SELECT 1 FROM ".$prefix."texts WHERE name='$name