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

Source for file logic.php

Documentation is available at logic.php

  1. <?php
  2. /**
  3.  * Fichier de la classe Logic
  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.  * @author Sophie Malafosse
  39.  * @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  40.  * @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  41.  * @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  42.  * @licence http://www.gnu.org/copyleft/gpl.html
  43.  * @since Fichier ajouté depuis la version 0.8
  44.  * @version CVS:$Id: logic.php 4006 2007-10-05 11:53:41Z malafosse $
  45.  */
  46.  
  47.  
  48. /**
  49.  * Classe des logiques métiers.
  50.  * 
  51.  * <p>Cette classe définit les actions de base des différentes logiques métiers utilisées dans Lodel.
  52.  * Elle est la classe 'mère' des logiques métiers se trouvant dans le répertoire /logic.
  53.  * Elles est aussi la liaison entre la couche d'abstraction de la base de données (DAO/VO) et la
  54.  * vue</p>.
  55.  *
  56.  * @package lodel
  57.  * @author Ghislain Picard
  58.  * @author Jean Lamy
  59.  * @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
  60.  * @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
  61.  * @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
  62.  * @licence http://www.gnu.org/copyleft/gpl.html
  63.  * @version CVS:$Id:
  64.  * @since Fichier ajouté depuis la version 0.8
  65.  * @see controler.php
  66.  * @see view.php
  67.  */
  68. class Logic
  69. {
  70.     /**#@+
  71.      * @access private
  72.      */
  73.     /**
  74.      * Nom de la table SQL centrale et de la classe.
  75.      *
  76.      * Table and class name of the central table
  77.      * @var string 
  78.      */
  79.     var $maintable;
  80.  
  81.     /**
  82.      * critère SQL du rang
  83.      * Give the SQL criteria which make a group from the ranking point of view.
  84.      * @var string 
  85.      */
  86.     var $rankcriteria;
  87.     /**#@-*/
  88.  
  89.  
  90.     /** 
  91.      * Constructeur de la classe.
  92.      * 
  93.      * Positionne simplement le nom de la table principale.
  94.      * @param string $maintable le nom de la table principale.
  95.      */
  96.     function Logic($maintable
  97.     {
  98.         $this->maintable = $maintable;
  99.     }
  100.  
  101.  
  102.     /**
  103.      * Implémentation par défaut de l'action permettant d'appeler l'affichage d'un objet.
  104.      *
  105.      * Cette fonction récupère les données de l'objet <em>via</em> la DAO de l'objet. Ensuite elle
  106.      * met ces données dans le context (utilisation de la fonction privée _populateContext())
  107.      * 
  108.      * view an object Action
  109.      * @param array $context le tableau des données passé par référence.
  110.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  111.      * @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
  112.      */
  113.     function viewAction(&$context&$error)
  114.     {
  115.         if ($errorreturn// nothing to do if it is an error.
  116.         $id intval($context['id']);
  117.         if (!$idreturn "_ok"// just add a new Object
  118.         $dao $this->_getMainTableDAO();
  119.         $vo  $dao->getById($id);
  120.         if (!$vo//erreur critique
  121.             die("ERRORcan't find object $id in the table "$this->maintable);
  122.         $this->_populateContext($vo$context)//rempli le context
  123.  
  124.         //ajout d'informations supplémentaires dans le contexte (éventuellement)
  125.         $ret=$this->_populateContextRelatedTables($vo$context)
  126.  
  127.         return $ret $ret "_ok";
  128.     }
  129.  
  130.     /**
  131.      * Implémentation par défaut de l'action de copie d'un objet.
  132.      * Récupère l'objet que l'on veut créer et le copie en ajoutant un prefixe devant.
  133.      *
  134.      * copy an object Action
  135.      *
  136.      * @param array $context le tableau des données passé par référence.
  137.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  138.      * @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
  139.      */
  140.     function copyAction(&$context&$error)
  141.     {
  142.         $ret $this->viewAction($context$error);
  143.         $copyof getlodeltextcontents("copyof""common");
  144.         if (isset($context['name'])) {
  145.             $context['name'$copyof"_"$context['name'];
  146.         elseif (isset($context['type']&& !is_array($context['type'])) {
  147.             $context['type'$copyof"_"$context['type'];
  148.         }
  149.         if (isset($context['title'])) {
  150.             $context['title'$copyof" "$context['title'];
  151.         elseif (isset($context['username'])) {
  152.             $context['username'$copyof"_"$context['username'];
  153.         }
  154.         unset($context['id']);
  155.         return $ret;
  156.     }
  157.  
  158.     /**
  159.      * Implémenation de l'action d'ajout ou d'édition d'un objet.
  160.      *
  161.      * <p>Cette fonction crée un nouvel objet ou édite un objet existant. Dans un premier temps les
  162.      * données sont validées (suivant leur type) puis elles sont rentrées dans la base de données <em>via</em> la DAO associée à l'objet.
  163.      * Utilise _prepareEdit() pour effectuer des opérations de préparation avant l'édition de l'objet puis _populateContext() pour ajouter des informations supplémentaires au context. Et enfin _saveRelatedTables() pour sauver d'éventuelles informations dans des tables liées.
  164.      * </p>
  165.     
  166.      * add/edit Action
  167.      * @param array $context le tableau des données passé par référence.
  168.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  169.      * @param boolean $clean false si on ne doit pas nettoyer les données (par défaut à false).
  170.      * @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
  171.      */
  172.     function editAction(&$context&$error$clean false)
  173.     {
  174.         if ($clean != CLEAN{      // validate the forms data
  175.             if (!$this->validateFields($context$error)) {
  176.                 return '_error';
  177.             }
  178.         }
  179.         // get the dao for working with the object
  180.         $dao $this->_getMainTableDAO();
  181.         $id $context['id'intval($context['id']);
  182.         $this->_prepareEdit($dao$context);
  183.         // create or edit
  184.         if ($id{
  185.             $dao->instantiateObject($vo);
  186.             $vo->id $id;
  187.         else {
  188.             $vo $dao->createObject();
  189.         }
  190.         if ($dao->rights['protect']{
  191.             $vo->protect $context['protected'0;
  192.         }
  193.         // put the context into 
  194.         $this->_populateObject($vo$context);
  195.         if (!$dao->save($vo)) trigger_error("You don't have the rights to modify or create this object"E_USER_ERROR);
  196.         $ret $this->_saveRelatedTables($vo$context);
  197.         
  198.         require_once 'func.php';
  199.         update();
  200.         return $ret $ret "_back";
  201.     }
  202.  
  203.     /**
  204.      * Implémentation par défaut de l'action qui permet de changer le rang d'un objet.
  205.      * 
  206.      * Cette action modifie la rang (rank) d'un objet. Peut-être restreinte à un status particulier
  207.      * et à un étage particulier (groupe).
  208.      *
  209.      * Change rank action
  210.      * Default implementation
  211.      *
  212.      * @param array $context le tableau des données passé par référence.
  213.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  214.      * @param string $groupfields champ de groupe. Utilisé pour limité le changement de rang à un étage. Par défaut vide.
  215.      * @param string $status utilisé pour changer le rang d'objets ayant un status particulier. il s'agit d'une condition. Par défaut est : status>0
  216.      * @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
  217.      */
  218.     function changeRankAction(&$context&$error$groupfields ""$status "status>0")
  219.     {
  220.         $criterias array();
  221.         $id $context['id'];
  222.         if ($groupfields{
  223.             $dao $this->_getMainTableDAO();
  224.             $vo  $dao->getById($id$groupfields);
  225.             foreach (explode(","$groupfieldsas $field{
  226.                 $criterias[$field"='"$vo->$field"'";
  227.             }
  228.         }
  229.         if ($status$criterias[$status;
  230.  
  231.         $criteria join(" AND "$criterias);
  232.         $this->_changeRank($id$context['dir']$criteria);
  233.  
  234.         require_once 'func.php';
  235.         update();
  236.         return '_back';
  237.     }
  238.  
  239.     /**
  240.      * Implémentation par défaut de l'action qui permet de supprimer un objet.
  241.      * <p>Cette action vérifie tout d'abord que l'objet peut-être supprimé puis prépare
  242.      * la suppression (fonction _prepareDelete()) et enfin utilise la DAO pour supprimer l'objet</p>
  243.      * Delete
  244.      * Default implementation
  245.      * @param array $context le tableau des données passé par référence.
  246.      * @param array $error le tableau des erreurs rencontrées passé par référence.
  247.      * @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
  248.      */
  249.     function deleteAction(&$context&$error)
  250.     {
  251.         global $db$home;
  252.         $id $context['id'];
  253.  
  254.         if ($this->isdeletelocked($id)) {
  255.             trigger_error("This object is locked for deletion. Please report the bug"E_USER_ERROR);
  256.         }
  257.         $dao $this->_getMainTableDAO();
  258.         $this->_prepareDelete($dao$context);
  259.         $dao->deleteObject($id);
  260.  
  261.         $ret=$this->_deleteRelatedTables($id);
  262.  
  263.         require_once 'func.php';
  264.         update();
  265.         return $ret $ret '_back';
  266.     }
  267.  
  268.  
  269.     /**
  270.      * Implémentation par défaut de la fonction right
  271.      * 
  272.      * Cette fonction permet de retourner les droits pour un niveau d'accès particulier
  273.      * 
  274.      * Return the right for a given kind of access
  275.      * @param string $access le niveau d'accès
  276.      * @return integer entier représentant le droit pour l'accès demandé.
  277.      */
  278.     function rights($access
  279.     {
  280.         $dao $this->_getMainTableDAO();
  281.         return $dao->rights[$access];
  282.     }
  283.  
  284.     /**
  285.      * Implémentation par défaut de isdeletelocked()
  286.      *
  287.      * Indique si un objet donné est supprimable pour l'utilisateur courant.
  288.      *
  289.      * Say whether an object (given by its id and status if possible) is deletable by the current user or not
  290.      * @param integer $id l'identifiant numérique de l'objet
  291.      * @param integer $status status de l'objet. Par défaut vaut 0.
  292.      * @return boolean un booléen indiquant si l'objet peut être supprimé.
  293.      */
  294.     function isdeletelocked($id$status=0)
  295.     {
  296.         global $lodeluser;
  297.         // basic
  298.         $dao $this->_getMainTableDAO();
  299.         if (is_numeric($id)) {
  300.             $criteria "id='"$id"'";
  301.             $nbexpected 1;
  302.         else {
  303.             $criteria "id IN ('"join("','"$id)"')";
  304.             $nbexpected count($id);
  305.         }
  306.         $nbreal $dao->count($criteria" "$dao->rightsCriteria("write"));
  307.         return $nbexpected != $nbreal;
  308.     }
  309.  
  310.  
  311.     //! Private or protected from this point
  312.     /**#@+
  313.      * @access private
  314.      */
  315.     
  316.     function &_getMainTableDAO(
  317.     {
  318.         return getDAO($this->maintable);
  319.     }
  320.    
  321.  
  322.     /**
  323.      * Change the rank of an Object
  324.      */
  325.     function _changeRank($id$dir$criteria)
  326.     {
  327.         global $db;
  328.         if (is_numeric($dir)) {
  329.             $dir $dir>: -1;
  330.         else {
  331.             $dir $dir == "up" ? -1;
  332.          }
  333.  
  334.         $desc $dir>"" "DESC";
  335.  
  336.         $dao $this->_getMainTableDAO();
  337.         $vos $dao->findMany($criteria"rank $descid $desc""id, rank");
  338.  
  339.         $count count($vos);
  340.         $newrank $dir>$count;
  341.         for ($i $i $count $i++{
  342.             if ($vos[$i]->id == $id{
  343.                 // exchange with the next if it exists
  344.                 if (!$vos[$i+1]{
  345.                     break;
  346.                 }
  347.                 $vos[$i+1]->rank $newrank;
  348.                 $dao->save($vos[$i+1]);
  349.                 $newrank+= $dir;
  350.             }
  351.             if ($vos[$i]->rank != $newrank// rebuild the rank if necessary
  352.                 $vos[$i]->rank $newrank;
  353.                 $dao->save($vos[$i]);
  354.             }
  355.             if ($vos[$i]->id == $id{
  356.                 $i++;
  357.             }
  358.             $newrank+= $dir;
  359.         }
  360.     }
  361.  
  362.     /**
  363.      * Validated the public fields and the unicity.
  364.      * @return return an array containing the error and warning, null otherwise.
  365.      */
  366.     function validateFields(&$context&$error
  367.     {
  368.         global $db;
  369.         
  370.         // Noms des logics qui sont traitées par des formulaires dans lesquels il y a des champs de type file ou image, et qui ont besoin d'un traitement particulier pour ces champs (i.e. pas des docs annexes)
  371.         // Ne concerne que la partie admin de l'interface, ajouté pour les icônes liées aux classes et aux types
  372.         // Cf. par ex. les formulaires edit_types.html ou edit_classes.html
  373.         $adminFormLogics array ('classes''entrytypes''persontypes''types');
  374.         require_once "validfunc.php";
  375.         $publicfields $this->_publicfields();
  376.         foreach ($publicfields as $field => $fielddescr{
  377.             list($type$condition$fielddescr;
  378.             if ($condition == "+" && $type != "boolean" && // boolean false are not transfered by HTTP/POST
  379.                     (
  380.                         !isset($context[$field]||   // not set
  381.                         $context[$field=== ""  // or empty string
  382.                     )) {
  383.                 $error[$field]="+";
  384.             elseif ($type == "passwd" && !trim($context[$field]&& $context['id']>0{
  385.                 // passwd can be empty only if $context[id] exists... it is a little hack but.
  386.                 unset($context[$field])// remove it
  387.             else {
  388.                 if (($type == "image" || $type == "file"&& in_array($this->maintable$adminFormLogics)){
  389.                     // traitement particulier des champs de type file et images dans les formulaires de la partie admin
  390.                     
  391.                     // répertoire de destination pour les fichiers et les images : array ($field, $répertoire)
  392.                     $directory =array ('icon' => 'lodel/icons');
  393.                     $valid validfield($context[$field]$type"",$field""$directory[$field]);
  394.                 else {
  395.                     $valid validfield($context[$field]$type"",$field);
  396.                 }
  397.                 if ($valid === false{
  398.                     die("ERROR: \"$type\" can not be validated in logic.php");
  399.                 }
  400.                 if (is_string($valid)) {
  401.                     $error[$field]=$valid;
  402.                 }
  403.             }
  404.         }
  405.         if ($error{
  406.             return false;
  407.         }
  408.  
  409.         $conditions=array();
  410.         foreach ($this->_uniqueFields(as $fields// all the unique set of fields
  411.             foreach ($fields as $field// set of fields which has to be unique.
  412.                 $conditions[$field"='"$context[$field]"'";
  413.             }
  414.             // check
  415.             $ret $db->getOne("SELECT 1 FROM "lq("#_TP_"$this->maintable)" WHERE status>-64 AND id!='"$context['id']"' AND "join(" AND "$conditions));
  416.             if ($db->errorno()) {
  417.                 dberror();
  418.             }
  419.             if ($ret{
  420.                 $error[$fields[0]] "1"// report the error on the first field
  421.             }
  422.         }
  423.  
  424.         return empty($error);
  425.     }
  426.  
  427.     function _publicfields(
  428.     {
  429.         die("call to abstract publicfields");
  430.         return array();
  431.     }
  432.  
  433.     function _uniqueFields(
  434.     {
  435.         return array();
  436.     }
  437.  
  438.     /**
  439.      * Populate the object from the context. Only the public fields are inputted.
  440.      * @private
  441.      */
  442.     function _populateObject(&$vo&$context
  443.     {
  444.         $publicfields $this->_publicfields();
  445.         foreach ($publicfields as $field => $fielddescr{
  446.             $vo->$field $context[$field];
  447.         }
  448.     }
  449.  
  450.     /**
  451.      * Populate the context from the object. All fields are outputted.
  452.      * @protected
  453.      */
  454.     function _populateContext(&$vo&$context
  455.     {
  456.         foreach ($vo as $k=>$v{
  457.             //Added by Jean - Be carefull using it
  458.             //if value is a string and we want to view it (or edit it in a form, 
  459.             //open a form is a view action) then we htmlize it
  460.             if (is_string($v&& $context['do'== 'view'{
  461.                 $v htmlspecialchars($v);
  462.             }
  463.             $context[$k$v;
  464.         }
  465.     }
  466.  
  467.     /**
  468.      * Used in editAction to do extra operation before the object is saved.
  469.      * Usually it gather information used after in _saveRelatedTables
  470.      */
  471.     function _prepareEdit($dao&$context{}
  472.  
  473.     /**
  474.      * Used in deleteAction to do extra operation before the object is saved.
  475.      * Usually it gather information used after in _deleteRelatedTables
  476.      */
  477.     function _prepareDelete($dao&$context{}
  478.  
  479.     /**
  480.      * Used in editAction to do extra operation after the object has been saved
  481.      */
  482.     function _saveRelatedTables($vo&$context{}
  483.  
  484.     /**
  485.      * Used in deleteAction to do extra operation after the object has been deleted
  486.      */
  487.     function _deleteRelatedTables($id{}
  488.  
  489.     /**
  490.      * Used in viewAction to do extra populate in the context
  491.      */
  492.     function _populateContextRelatedTables(&$vo&$context{}
  493.     
  494.     /**
  495.      * process of particular type of fields
  496.      * @param string $type the type of the field
  497.      * @param array $context the context
  498.      * @param int $status the status; by default 0 if no status changed
  499.      */
  500.     function _processSpecialFields($type$context$status 0
  501.     {
  502.         global $db;