Source for file logic.php
Documentation is available at logic.php
* Fichier de la classe Logic
* LODEL - Logiciel d'Edition ELectronique.
* Copyright (c) 2001-2002, Ghislain Picard, Marin Dacos
* Copyright (c) 2003, Ghislain Picard, Marin Dacos, Luc Santeramo, Nicolas Nutten, Anne Gentil-Beccot
* Copyright (c) 2004, Ghislain Picard, Marin Dacos, Luc Santeramo, Anne Gentil-Beccot, Bruno Cénou
* Copyright (c) 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
* Copyright (c) 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
* Copyright (c) 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
* Home page: http://www.lodel.org
* E-Mail: lodel@lodel.org
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* @author Ghislain Picard
* @author Sophie Malafosse
* @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
* @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
* @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
* @licence http://www.gnu.org/copyleft/gpl.html
* @since Fichier ajouté depuis la version 0.8
* @version CVS:$Id: logic.php 4006 2007-10-05 11:53:41Z malafosse $
* Classe des logiques métiers.
* <p>Cette classe définit les actions de base des différentes logiques métiers utilisées dans Lodel.
* Elle est la classe 'mère' des logiques métiers se trouvant dans le répertoire /logic.
* Elles est aussi la liaison entre la couche d'abstraction de la base de données (DAO/VO) et la
* @author Ghislain Picard
* @copyright 2005, Ghislain Picard, Marin Dacos, Luc Santeramo, Gautier Poupeau, Jean Lamy, Bruno Cénou
* @copyright 2006, Marin Dacos, Luc Santeramo, Bruno Cénou, Jean Lamy, Mikaël Cixous, Sophie Malafosse
* @copyright 2007, Marin Dacos, Bruno Cénou, Sophie Malafosse, Pierre-Alain Mignot
* @licence http://www.gnu.org/copyleft/gpl.html
* @since Fichier ajouté depuis la version 0.8
* Nom de la table SQL centrale et de la classe.
* Table and class name of the central table
* Give the SQL criteria which make a group from the ranking point of view.
* Constructeur de la classe.
* Positionne simplement le nom de la table principale.
* @param string $maintable le nom de la table principale.
function Logic($maintable)
* Implémentation par défaut de l'action permettant d'appeler l'affichage d'un objet.
* Cette fonction récupère les données de l'objet <em>via</em> la DAO de l'objet. Ensuite elle
* met ces données dans le context (utilisation de la fonction privée _populateContext())
* @param array $context le tableau des données passé par référence.
* @param array $error le tableau des erreurs rencontrées passé par référence.
* @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
if ($error) return; // nothing to do if it is an error.
if (!$id) return "_ok"; // just add a new Object
$vo = $dao->getById($id);
if (!$vo) //erreur critique
die("ERROR: can't find object $id in the table ". $this->maintable);
//ajout d'informations supplémentaires dans le contexte (éventuellement)
return $ret ? $ret : "_ok";
* Implémentation par défaut de l'action de copie d'un objet.
* Récupère l'objet que l'on veut créer et le copie en ajoutant un prefixe devant.
* @param array $context le tableau des données passé par référence.
* @param array $error le tableau des erreurs rencontrées passé par référence.
* @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
if (isset ($context['name'])) {
$context['name'] = $copyof. "_". $context['name'];
} elseif (isset ($context['type']) && !is_array($context['type'])) {
$context['type'] = $copyof. "_". $context['type'];
if (isset ($context['title'])) {
$context['title'] = $copyof. " ". $context['title'];
} elseif (isset ($context['username'])) {
$context['username'] = $copyof. "_". $context['username'];
* Implémenation de l'action d'ajout ou d'édition d'un objet.
* <p>Cette fonction crée un nouvel objet ou édite un objet existant. Dans un premier temps les
* 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.
* 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.
* @param array $context le tableau des données passé par référence.
* @param array $error le tableau des erreurs rencontrées passé par référence.
* @param boolean $clean false si on ne doit pas nettoyer les données (par défaut à false).
* @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
function editAction(&$context, &$error, $clean = false)
if ($clean != CLEAN) { // validate the forms data
// get the dao for working with the object
$id = $context['id'] = intval($context['id']);
$dao->instantiateObject($vo);
$vo = $dao->createObject();
if ($dao->rights['protect']) {
$vo->protect = $context['protected'] ? 1 : 0;
if (!$dao->save($vo)) trigger_error("You don't have the rights to modify or create this object", E_USER_ERROR);
return $ret ? $ret : "_back";
* Implémentation par défaut de l'action qui permet de changer le rang d'un objet.
* Cette action modifie la rang (rank) d'un objet. Peut-être restreinte à un status particulier
* et à un étage particulier (groupe).
* @param array $context le tableau des données passé par référence.
* @param array $error le tableau des erreurs rencontrées passé par référence.
* @param string $groupfields champ de groupe. Utilisé pour limité le changement de rang à un étage. Par défaut vide.
* @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
* @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
function changeRankAction(&$context, &$error, $groupfields = "", $status = "status>0")
$vo = $dao->getById($id, $groupfields);
foreach (explode(",", $groupfields) as $field) {
$criterias[] = $field. "='". $vo->$field. "'";
if ($status) $criterias[] = $status;
$criteria = join(" AND ", $criterias);
* Implémentation par défaut de l'action qui permet de supprimer un objet.
* <p>Cette action vérifie tout d'abord que l'objet peut-être supprimé puis prépare
* la suppression (fonction _prepareDelete()) et enfin utilise la DAO pour supprimer l'objet</p>
* @param array $context le tableau des données passé par référence.
* @param array $error le tableau des erreurs rencontrées passé par référence.
* @return string les différentes valeurs possibles de retour d'une action (_ok, _back, _error ou xxxx).
trigger_error("This object is locked for deletion. Please report the bug", E_USER_ERROR);
return $ret ? $ret : '_back';
* Implémentation par défaut de la fonction right
* Cette fonction permet de retourner les droits pour un niveau d'accès particulier
* Return the right for a given kind of access
* @param string $access le niveau d'accès
* @return integer entier représentant le droit pour l'accès demandé.
return $dao->rights[$access];
* Implémentation par défaut de isdeletelocked()
* Indique si un objet donné est supprimable pour l'utilisateur courant.
* Say whether an object (given by its id and status if possible) is deletable by the current user or not
* @param integer $id l'identifiant numérique de l'objet
* @param integer $status status de l'objet. Par défaut vaut 0.
* @return boolean un booléen indiquant si l'objet peut être supprimé.
$criteria = "id='". $id. "'";
$criteria = "id IN ('". join("','", $id). "')";
$nbexpected = count($id);
$nbreal = $dao->count($criteria. " ". $dao->rightsCriteria("write"));
return $nbexpected != $nbreal;
//! Private or protected from this point
* Change the rank of an Object
$dir = $dir == "up" ? - 1 : 1;
$desc = $dir> 0 ? "" : "DESC";
$vos = $dao->findMany($criteria, "rank $desc, id $desc", "id, rank");
$newrank = $dir> 0 ? 1 : $count;
for ($i = 0 ; $i < $count ; $i++ ) {
if ($vos[$i]->id == $id) {
// exchange with the next if it exists
$vos[$i+ 1]->rank = $newrank;
if ($vos[$i]->rank != $newrank) { // rebuild the rank if necessary
$vos[$i]->rank = $newrank;
if ($vos[$i]->id == $id) {
* Validated the public fields and the unicity.
* @return return an array containing the error and warning, null otherwise.
// 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)
// Ne concerne que la partie admin de l'interface, ajouté pour les icônes liées aux classes et aux types
// Cf. par ex. les formulaires edit_types.html ou edit_classes.html
$adminFormLogics = array ('classes', 'entrytypes', 'persontypes', 'types');
require_once "validfunc.php";
foreach ($publicfields as $field => $fielddescr) {
list ($type, $condition) = $fielddescr;
if ($condition == "+" && $type != "boolean" && // boolean false are not transfered by HTTP/POST
!isset ($context[$field]) || // not set
$context[$field] === "" // or empty string
} elseif ($type == "passwd" && !trim($context[$field]) && $context['id']> 0) {
// passwd can be empty only if $context[id] exists... it is a little hack but.
unset ($context[$field]); // remove it
if (($type == "image" || $type == "file") && in_array($this->maintable, $adminFormLogics)){
// traitement particulier des champs de type file et images dans les formulaires de la partie admin
// répertoire de destination pour les fichiers et les images : array ($field, $répertoire)
$directory = array ('icon' => 'lodel/icons');
$valid = validfield($context[$field], $type, "",$field, "", $directory[$field]);
$valid = validfield($context[$field], $type, "",$field);
die("ERROR: \"$type\" can not be validated in logic.php");
foreach ($this->_uniqueFields() as $fields) { // all the unique set of fields
foreach ($fields as $field) { // set of fields which has to be unique.
$conditions[] = $field. "='". $context[$field]. "'";
$ret = $db->getOne("SELECT 1 FROM ". lq("#_TP_". $this->maintable). " WHERE status>-64 AND id!='". $context['id']. "' AND ". join(" AND ", $conditions));
$error[$fields[0]] = "1"; // report the error on the first field
die("call to abstract publicfields");
* Populate the object from the context. Only the public fields are inputted.
foreach ($publicfields as $field => $fielddescr) {
$vo->$field = $context[$field];
* Populate the context from the object. All fields are outputted.
foreach ($vo as $k=> $v) {
//Added by Jean - Be carefull using it
//if value is a string and we want to view it (or edit it in a form,
//open a form is a view action) then we htmlize it
if (is_string($v) && $context['do'] == 'view') {
* Used in editAction to do extra operation before the object is saved.
* Usually it gather information used after in _saveRelatedTables
* Used in deleteAction to do extra operation before the object is saved.
* Usually it gather information used after in _deleteRelatedTables
* Used in editAction to do extra operation after the object has been saved
* Used in deleteAction to do extra operation after the object has been deleted
* Used in viewAction to do extra populate in the context
* process of particular type of fields
* @param string $type the type of the field
* @param array $context the context
* @param int $status the status; by default 0 if no status changed
|