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

Source for file genericlogic.php

Documentation is available at genericlogic.php

  1. <?php
  2. /**
  3.  * Fichier de la classe Genericlogic
  4.  *
  5.  * PHP versions 4 et 5
  6.  *
  7.  * LODEL - Logiciel d'Edition ELectronique.
  8.  *
  9.  * Copyright (c) 2001-2002, Ghislain Picard, Marin Dacos
  10.  * Copyright (c) 2003, Ghislain Picard, Marin Dacos, Luc Santeramo, Nicolas Nutten, Anne Gentil-Beccot
  11.  * Copyright (c) 2004, Ghislain Picard, Marin Dacos, Luc Santeramo, Anne Gentil-Beccot, Bruno Cénou
  12.  * Copyright (c) 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  13.  * Copyright (c) 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  14.  * Copyright (c) 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  15.  *
  16.  * Home page: http://www.lodel.org
  17.  *
  18.  * E-Mail: lodel@lodel.org
  19.  *
  20.  * All Rights Reserved
  21.  *
  22.  * This program is free software; you can redistribute it and/or modify
  23.  * it under the terms of the GNU General Public License as published by
  24.  * the Free Software Foundation; either version 2 of the License, or
  25.  * (at your option) any later version.
  26.  *
  27.  * This program is distributed in the hope that it will be useful,
  28.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  29.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  30.  * GNU General Public License for more details.
  31.  *
  32.  * You should have received a copy of the GNU General Public License
  33.  * along with this program; if not, write to the Free Software
  34.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  35.  *
  36.  * @author Ghislain Picard
  37.  * @author Jean Lamy
  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.  * @since Fichier ajouté depuis la version 0.8
  43.  * @version CVS:$Id:
  44.  */
  45.  
  46.  
  47. /**
  48.  * Classe des logiques métiers générique.
  49.  * 
  50.  * <p>Cette classe définit la logique par défaut pour les objets dynamiques de l'interface :
  51.  * entrées, personnes par exemple</p>
  52.  *
  53.  * @package lodel
  54.  * @author Ghislain Picard
  55.  * @author Jean Lamy
  56.  * @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  57.  * @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  58.  * @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  59.  * @licence http://www.gnu.org/copyleft/gpl.html
  60.  * @version CVS:$Id:
  61.  * @since Classe ajoutée depuis la version 0.8
  62.  * @see logic.php
  63.  */
  64.  
  65. class GenericLogic extends Logic
  66. {
  67.     var $_publicfields_array;
  68.     /** 
  69.      * Constructeur de la classe
  70.      *
  71.      * Définit le nom de la table type pour l'objet ainsi que le nom du champ identifiant unique.
  72.      *
  73.      * @param string $classtype le type d'objet generique, parmis : entities, entries et persons.
  74.      */
  75.     function GenericLogic($classtype)
  76.     {
  77.         switch ($classtype{
  78.         case 'entities' :
  79.             $this->_typetable "types";
  80.             $this->_idfield "identity";
  81.             break;
  82.         case 'entries' :
  83.             $this->_typetable "entrytypes";
  84.             $this->_idfield "identry";
  85.             break;
  86.         case 'persons' :
  87.             $this->_typetable "persontypes";
  88.             $this->_idfield "idperson";
  89.         }
  90.         $this->Logic($classtype);
  91.     }
  92.  
  93.     /**
  94.      * Implémentation pour les objets générique de l'action permettant d'appeler l'affichage d'un objet.
  95.      *
  96.      * Cette fonction récupère les données de l'objet <em>via</em> la DAO de l'objet. Ensuite elle
  97.      * met ces données dans le context (utilisation de la fonction privée _populateContext())
  98.      * 
  99.      * view an object Action
  100.      * @param array $context le tableau des données passé par référence.
  101.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  102.      * @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
  103.      */
  104.     function viewAction(&$context&$error)
  105.     {
  106.         // define some loop functions
  107.         require_once 'lang.php';
  108.         if(!function_exists('loop_edition_fields')) {
  109.             function loop_edition_fields($context$funcname)
  110.             {
  111.                 global $db$home;
  112.                 require_once 'validfunc.php';
  113.                 if ($context['class']{
  114.                     validfield($context['class']'class''''','data');
  115.                     $class $context['class'];
  116.                 }    elseif ($context['type']['class'])    {
  117.                     validfield($context['type']['class']'class''''''data');
  118.                     $class $context['type']['class'];
  119.                 }    else {
  120.                     die("ERROR: internal error in loop_edition_fields");
  121.                 }
  122.                 if ($context['classtype'== "persons")    {
  123.                     $criteria "class='".$class."'";
  124.                     // degree is defined only when the persons is related to a document. Is it a hack ? A little no more...
  125.                     if ($context['identifier']{
  126.                         $criteria .= " OR class='entities_".$class."'";
  127.                     }
  128.                 }    elseif ($context['classtype'== "entries")    {
  129.                     $criteria "class='".$class."'";
  130.                 }    else {
  131.                     $criteria "idgroup='"$context['id']."'";
  132.                     $context['idgroup'$context['id'];
  133.                 }
  134.                 $result $db->execute(lq("SELECT * FROM #_TP_tablefields WHERE ".$criteria." AND status>0 AND edition!='' AND edition!='none'  AND edition!='importable' ORDER BY rank")) or dberror();
  135.     
  136.                 $haveresult !empty ($result->fields);
  137.                 if ($haveresult{
  138.                     call_user_func("code_before_$funcname"$context);
  139.                 }
  140.                 while (!$result->EOF)    {
  141.                     $localcontext array_merge($context$result->fields);
  142.                     $name $result->fields['name'];
  143.                     $localcontext['value'$result->fields['edition'!= "display" && is_string($context['data'][$name]htmlspecialchars($context['data'][$name]$context['data'][$name];
  144.                     call_user_func("code_do_$funcname"$localcontext);
  145.                     $result->MoveNext();
  146.                 }
  147.                 if ($haveresult{
  148.                     call_user_func("code_after_$funcname"$context);
  149.                 }
  150.             //function }}}
  151.         }
  152.         $id $context['id'];
  153.         if ($id && !$error{
  154.             $dao $this->_getMainTableDAO();
  155.             $vo $dao->getById($id);
  156.             if (!$vo{
  157.                 die("ERRORcan't find object $id in the table ".$this->maintable);
  158.             }
  159.             $this->_populateContext($vo$context);
  160.         }
  161.  
  162.         $daotype &getDAO($this->_typetable);
  163.         $votype $daotype->getById($context['idtype']);
  164.         if (!$votype{
  165.             die("ERROR: idtype must me known in GenericLogic::viewAction");
  166.         }
  167.         $this->_populateContext($votype$context['type']);
  168.  
  169.         if ($id && !$error)    {
  170.             $gdao &getGenericDAO($votype->class$this->_idfield);
  171.             $gvo $gdao->getById($id);
  172.             if (!$gvo{
  173.                 die("ERRORcan't find object $id in the associated tablePlease report this bug");
  174.             }
  175.             $this->_populateContext($gvo$context['data']);
  176.             $ret $this->_populateContextRelatedTables($vo$context);
  177.         }
  178.         // nettoyage avant affichage
  179.         require_once('func.php');
  180.         postprocessing($context);
  181.         return $ret $ret "_ok";
  182.     }
  183.  
  184.     
  185.  
  186.     /**
  187.      * Validated the public fields and the unicity as usual and in addition the typescompatibility
  188.      *
  189.      * Validation des champs publics et de l'unicité comme dans la fonction de logic.php. Mais vérifie
  190.      * la compatibilité des types d'objet en plus.
  191.      *
  192.      * @param array $context le tableau des données passé par référence.
  193.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  194.      */
  195.     function validateFields(&$context&$error)
  196.     {
  197.         global $home;
  198.  
  199.         // get the fields of class
  200.         require_once "validfunc.php";
  201.         if ($context['class']{
  202.             validfield($context['class']'class''''''data');
  203.             $class $context['class'];
  204.         }    elseif ($context['type']['class']{
  205.             validfield($context['type']['class']"class"'''''data');
  206.             $class $context['type']['class'];
  207.         }    else {
  208.             die("ERROR: internal error in loop_edition_fields");
  209.         }
  210.  
  211.         $daotablefields &getDAO("tablefields");
  212.         $fields $daotablefields->findMany("(class='"$class"' OR class='entities_"$class"') AND status>0 """"name,type,class,cond,defaultvalue,allowedtags,edition,g_name");
  213.  
  214.         // file to move once the document id is know.
  215.         $this->files_to_move array ();
  216.         $this->_publicfields array ();
  217.         require_once "fieldfunc.php";
  218.  
  219.         foreach ($fields as $field{
  220.             if ($field->g_name{
  221.                 $this->addGenericEquivalent($class$field->g_name$field->name)// save the generic field
  222.             }
  223.             $type $field->type;
  224.             $name $field->name;
  225.  
  226.             // check if the field is required or not, and rise an error if any problem.
  227.             $value &$context['data'][$name];
  228.  
  229.             if (!is_array($value)) {
  230.                 $value trim($value);
  231.             }
  232.             if ($value{
  233.                   if(is_array($value))
  234.                  {
  235.                     $keys array_keys($value);
  236.                     $j sizeof($value);
  237.                      for($i=0;$i<$j;$i++{
  238.                          $value[$keys[$i]] lodel_strip_tags($value[$keys[$i]]$field->allowedtags);
  239.                      }
  240.                  }
  241.                  else {
  242.                     $value lodel_strip_tags($value$field->allowedtags);
  243.                 }
  244.             }
  245.  
  246.             // is empty ?
  247.             $empty $type != "boolean" && (// boolean are always true or false
  248.                             !isset ($context['data'][$name]|| // not set
  249.                             $context['data'][$name=== "")// or empty string
  250.  
  251.             if (($context['do'== "edit" && ($field->edition == "importable" || 
  252.                     $field->edition == "none" || $field->edition == "display"))) {
  253.  
  254.                 // in edition interface and field is not editable in the interface
  255.                 if ($field->cond != "+"// the field is not required.
  256.                     unset ($value);
  257.                     continue;
  258.                 else {
  259.                     $value lodel_strip_tags($field->default$field->allowedtags)// default value
  260.                     $empty false;
  261.                 }
  262.             }
  263.             if ($context['id'&& (($field->cond == "permanent"|| ($field->cond == "defaultnew" && $empty))) {
  264.                 // or a permanent field
  265.                 // or field is empty and the default value must not be used
  266.                 unset ($value);
  267.                 continue;
  268.             }
  269.  
  270.             if ($type != "persons" && $type != "entries" && $type != "entities"{
  271.                 
  272.                 $this->_publicfields[$field->class][$nametrue// this field is public
  273.             }
  274.             if ($field->edition == "none"{
  275.                 unset ($value);
  276.             }            
  277.             if ($empty{
  278.                 $value lodel_strip_tags($field->default$field->allowedtags)// default value
  279.             }
  280.             if ($field->cond == "+" && $empty{
  281.                 $error[$name"+"// required
  282.                 continue;
  283.             }
  284.  
  285.             // champ unique
  286.             if ($field->cond == 'unique' && !$this->_is_unique($class$name$value$context['id'])) {
  287.                 $error[$name"1"// must be unique
  288.                 continue;
  289.             }
  290.  
  291.             // clean automatically the fields when required.
  292.             if (!is_array($value&& $GLOBALS['lodelfieldtypes'][$type]['autostriptags']{
  293.                 $value trim(strip_tags($value));
  294.             }
  295.  
  296.             $valid validfield($value$type$field->default$name'data');
  297.             if ($valid === true)    {                
  298.                 // good, nothing to do.
  299.                 if ($type == "file" || $type == "image"{
  300.                     if (preg_match("/\/tmpdir-\d+\/[^\/]+$/"$value)) {
  301.                         // add this file to the file to move.
  302.                         $this->files_to_move[$namearray ('filename' => $value'type' => $type'name' => $name);
  303.                     }
  304.                 }
  305.             }    elseif (is_string($valid))    {
  306.                 $error[$name$valid// error
  307.             }    else    {
  308.  
  309.                 // not validated... let's try other type
  310.                 switch ($type{
  311.                 case 'persons' :
  312.                 case 'entries' :
  313.                     // get the type
  314.                     if ($type == "persons"{
  315.                         $dao &getDAO("persontypes");
  316.                     }    else    {
  317.                         $dao &getDAO("entrytypes");
  318.                     }
  319.                     $vo $dao->find("type='".$name."'""class,id");
  320.                     $idtype $vo->id;
  321.  
  322.                     $localcontext &$context[$type][$idtype];
  323.                     if (!$localcontext{
  324.                         break;
  325.                     }
  326.                     if ($type == "entries" && !is_array($localcontext))    {
  327.                         $keys explode(","$localcontext);
  328.                         $localcontext array ();
  329.                         foreach ($keys as $key)    {
  330.                             $localcontext[array ("g_name" => $key);
  331.                         }
  332.                     }
  333.                     $logic &getLogic($type)// the logic is used to validate
  334.                     if (!is_array($localcontext)) {
  335.                         die("ERROR: internal error in GenericLogic::validateFields");
  336.                     }
  337.  
  338.                     foreach (array_keys($localcontextas $k)    {
  339.                         if (!is_numeric($k|| !$localcontext[$k]{
  340.                             continue;
  341.                         }
  342.                         $localcontext[$k]['class'$vo->class;
  343.                         $localcontext[$k]['idtype'$idtype;
  344.                         $err array ();
  345.                         $logic->validateFields($localcontext[$k]$err);
  346.                         if ($err{
  347.                             $error[$type][$idtype][$k$err;
  348.                         }
  349.                     }
  350.                     break;
  351.                 case 'entities' :
  352.                     $value &$context['entities'][$name];
  353.                     if (!$value{
  354.                         unset ($context['entities'][$name]);
  355.                         break;
  356.                     }
  357.                     $ids array ();
  358.                     foreach (explode(","$valueas $id{
  359.                         if ($id 0{
  360.                             $ids[intval($id);
  361.                         }
  362.                     }
  363.                     $value $ids;
  364.                     $count $GLOBALS['db']->getOne(lq("SELECT count(*) FROM #_TP_entities WHERE status>-64 AND id ".sql_in_array($value)));
  365.                     if ($GLOBALS['db']->errorno()) {
  366.                         dberror();
  367.                     }
  368.                     if ($count != count($value)) {
  369.                         die("ERRORsome entities in $name are invalidPlease report the bug");
  370.                     }
  371.                     // don't check they exists, the interface ensure it ! (... hum)
  372.                     break;
  373.                 default :
  374.                     die("ERROR: unable to check the validity of the field ".$name." of type ".$type);
  375.                 // switch
  376.             // if valid
  377.          // foreach files
  378.         return empty ($error);
  379.     }
  380.     /**#@+
  381.      * @access private
  382.      */
  383.     /**
  384.      * Déplacement des fichiers associés à l'objet dans le bon répertoire
  385.      *
  386.      * @param integer $id l'identifiant numérique de l'objet
  387.      * @param array $files_to_move un tableau contenant les informations de tous les fichiers (nom et type)
  388.      * @param object &$vo l'objet virtuel correspondant à l'objet passé par référence
  389.      */
  390.     function _moveFiles($id$files_to_move&$vo)
  391.     {
  392.         foreach ($files_to_move as $file)    {
  393.             $src preg_match("`".SITEROOT."`"$file['filename']$file['filename'SITEROOT.$file['filename'];
  394.             $dest basename($file['filename'])// basename
  395.             if (!$dest{
  396.                 die("ERROR: error in move_files");
  397.             }
  398.             // new path to the file
  399.             $dirdest "docannexe/"$file['type']"/"$id;
  400.             checkdocannexedir($dirdest);
  401.             $dest $dirdest"/"$dest;
  402.  
  403.             $vo->$file['name'addslashes($dest);
  404.             if ($src == SITEROOT$dest{
  405.                 continue;
  406.             }
  407.