Source for file Widget.php

Documentation is available at Widget.php

  1. <?php
  2. // vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 fdm=marker encoding=utf8 :
  3. /**
  4.  * Pxxo - build self-supported and interoperable Web graphical components
  5.  *
  6.  * Copyright (c) 2008, Nicolas Thouvenin
  7.  *
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions are met:
  12.  *
  13.  *     * Redistributions of source code must retain the above copyright
  14.  *       notice, this list of conditions and the following disclaimer.
  15.  *     * Redistributions in binary form must reproduce the above copyright
  16.  *       notice, this list of conditions and the following disclaimer in the
  17.  *       documentation and/or other materials provided with the distribution.
  18.  *     * Neither the name of the author nor the names of its contributors may be
  19.  *       used to endorse or promote products derived from this software without
  20.  *       specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
  23.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25.  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
  26.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32.  
  33.  * @package    Pxxo
  34.  * @copyright  Copyright (c) 2008 Nicolas Thouvenin
  35.  * @license    http://opensource.org/licenses/bsd-license.php
  36.  * @version    $Id$
  37.  */
  38.  
  39. require_once 'Pxxo.php';
  40. require_once 'Pxxo/View.php';
  41. require_once 'Pxxo/Buffers.php';
  42. require_once 'Pxxo/Config.php';
  43. require_once 'Zend/Translate.php';
  44.  
  45. define('P_M_COMBINE',   4);
  46. define('P_M_OUTPUT',    8);
  47. define('P_M_RESOURCE'16);
  48.  
  49. /**
  50.  * Classe mère de tous les widgets
  51.  *
  52.  * @package    Pxxo
  53.  * @copyright  Copyright (c) 2008 Nicolas Thouvenin
  54.  * @license    http://opensource.org/licenses/bsd-license.php
  55.  */
  56. class Pxxo_Widget extends Pxxo
  57. {
  58.     // {{{ Attributs
  59.     /**
  60.      * Pointeur vers l'objet parent de l'objet courant
  61.      * @var        Pxxo_Action 
  62.      */
  63.     public $Parent = null;
  64.  
  65.     /**
  66.      * Tableau d'objet Pxxo_Component contenant tous fils de l'objet courant
  67.      * @var        array 
  68.      */
  69.     public $Components = array();
  70.  
  71.     /**
  72.      * Tableau d'objet Pxxo_Buffer contenant toutes les ressources de l'objet courant
  73.      * @var        Pxxo_Buffers 
  74.      */
  75.     public $Resources;
  76.  
  77.     /**
  78.      * @var        Pxxo_Buffers Tableau contenant des informations destinées à l'entete HTML de la page terminale
  79.      */
  80.     public $Headers;
  81.  
  82.     /**
  83.      * @var        Pxxo_Response Gestion de l'entete HTTP
  84.      */
  85.     public $Response = null;
  86.  
  87.     /**
  88.      * Object View
  89.      * @var object Pxxo_View 
  90.      */
  91.     private $_view = null;
  92.  
  93.     /**
  94.      * Liste des variables utilisées pas l'objet
  95.      * @var array 
  96.      */
  97.     private $_vars = array();
  98.  
  99.     /**
  100.      * Liste des variables publique de la classe (calculées automatiquement)
  101.      * @var array 
  102.      */
  103.     private $_vars_public = null;
  104.  
  105.     /**
  106.      * Liste des variables privées de l'objet en plus des variables préfixées par _
  107.      * @var        mixed 
  108.      */
  109.     private $_vars_privates = array('Parent''Templates''Components''Resources''widget''Response');
  110.  
  111.     /**
  112.      * Liste des variables devant être mise en cache en plus des variables non privées
  113.      * @var        mixed 
  114.      */
  115.     private $_vars_protected = array('Resources''CurrentMode');
  116.  
  117.     /**
  118.      * Liste des modes "OneTime"
  119.      * @var        array 
  120.      */
  121.     private $_onetime = array();
  122.  
  123.     /**
  124.      * Mode (ou action) en cours de traitment
  125.      * @var        string 
  126.      */
  127.     public $CurrentMode = null;
  128.  
  129.     /**
  130.      * Mode (ou action) à exécuter par défaut
  131.      * @var        string 
  132.      */
  133.     public $DefaultMode = 'index';
  134.  
  135.     /**
  136.      * Type de contenu produit en sortie
  137.      * @var        string 
  138.      */
  139.     public $OutputMode  = 'html';
  140.  
  141.     /**
  142.      * Niveau de filtre appliqué sur la sortie
  143.      * @var        integer 
  144.      */
  145.     public $MinifyLevel  = null;
  146.  
  147.     /**
  148.      * mode persistant ou non (cad : le mode reste actif tant que l'on n'en change pas explicitement)
  149.      * @var        boolean 
  150.      */
  151.     public $PersistentMode = false;
  152.  
  153.     /**
  154.      * Cet objet va produire une page terminale
  155.      * @var        string 
  156.      */
  157.     public $StandaloneMode = false;
  158.  
  159.     /**
  160.      * @var        boolean active le chargement automatiques des ressources
  161.      */
  162.     public $LoadingMode = true;
  163.  
  164.     /**
  165.      * Active le mode caché ! Attention incompatible avec le controller...
  166.      * Ne peut être modidfié uniquement un surchargant cette déclaration
  167.      * @var        string 
  168.      */
  169.     public $HiddenMode = false;
  170.  
  171.     /**
  172.      * @var        boolean  vient-on de changer de mode ?
  173.      */
  174.     public $ModeChanged = false;
  175.  
  176.     /**
  177.      * @var        boolean  le mode actuel vient-il d'être séléctionné volontairement
  178.      */
  179.     public $ModeSelected = false;
  180.  
  181.     /**
  182.      * @var        boolean  le mode actuel ne pourra produire de résultat car un mode fils à déclencher le mode Standalone
  183.      */
  184.     public $ModeCaptived = false;
  185.  
  186.     /**
  187.      * @var        boolean  le Mode précendent
  188.      */
  189.     public $PreviousMode = '';
  190.  
  191.     /**
  192.      * Permet d'ajouter automatiquement un prefix aux variables accessible avec les méthodes getXxxxVar() et setXxxxVar()
  193.      * @var        boolean 
  194.      */
  195.     public $PrependVar = false;
  196.  
  197.     /**
  198.      * @var        boolean Active ou non le mode cache
  199.      */
  200.     public $CacheMode = null;
  201.  
  202.     /**
  203.      * @var        string lieu de stockage du cache
  204.      */
  205.     public $CachePath = '';
  206.  
  207.     /**
  208.      * @var        string temps de stockage dans le cache
  209.      */
  210.     public $CacheTime = 4000;
  211.  
  212.     /**
  213.      * Indique l'état dans lequel se trouve l'objet
  214.      * @var        mixed 
  215.      */
  216.     public $State = false;
  217.  
  218.     /**
  219.      * Nom de la variable permettant de choisir le mode (ou l'action) à traiter
  220.      * @var        mixed 
  221.      */
  222.     public $varnamemode = null;
  223.  
  224.     /**
  225.      * Langue active
  226.      * @var        string null par défaut ce qui indique que cette valeur prendra la même que son objet parent
  227.      */
  228.     public $Lang = null;
  229.  
  230.     /**
  231.      * Donnée permettant les traductions
  232.      * @var        mixed 
  233.      */
  234.     public $TranslateData = null;
  235.  
  236.     /**
  237.      * Adapter de traduction
  238.      * @var        string 
  239.      */
  240.     public $TranslateAdapter = 'Array';
  241.  
  242.     /**
  243.      * Options du Module de Traduction
  244.      * @var        array 
  245.      */
  246.     public $TranslateOptions = array();
  247.  
  248.     /**
  249.      * Module de Traduction
  250.      * @var        Zend_Translate 
  251.      */
  252.     public $Translate = null;
  253.  
  254.  
  255.     /**
  256.      * Nom du thème actif
  257.      * @var        string 
  258.      */
  259.     public $Theme = '';
  260.  
  261.     /**
  262.      * Liste de chemin physique de répertoire contenant des themes
  263.      * Exemple :
  264.      *  ./themes:/var/httpd/www/themes
  265.      * @var        string des chemins séparer par PATH_SEPARATOR
  266.      */
  267.     public $ThemePaths = '';
  268.  
  269.     /**
  270.      * Chemin physique par défaut des templates de l'objet
  271.      * @var        string 
  272.      */
  273.     public $TemplatePath = '';
  274.  
  275.     /**
  276.      * Tableau associant un mode à un objet Pxxo_Buffer
  277.      * @var        array 
  278.      */
  279.     public $Templates = array();
  280.  
  281.     /**
  282.      * URL d'accès aux ressources du composant
  283.      * @var        string 
  284.      */
  285.     public $ResourceURL = '';
  286.  
  287.     /**
  288.      * Chemin physique correspondant à l'URL d'accès aux ressources du composant
  289.      * @var        string 
  290.      */
  291.     public $ResourcePath = '';
  292.  
  293.     /**
  294.      * Nom UNIQUE de définition de la classe
  295.      * @var        mixed 
  296.      */
  297.     public $ClassName = null;
  298.  
  299.     /**
  300.      * Identifiant UNIQUE pour chaque instance de la classe
  301.      * @var        mixed 
  302.      */
  303.     public $ClassID = null;
  304.  
  305.     /**
  306.      * Nom donné par un Composant Parent
  307.      * @var        mixed 
  308.      */
  309.     public $ClassAlias = null;
  310.  
  311.     /**
  312.      * Contenu du cache
  313.      * @var        string 
  314.      */
  315.     private $_cached = false;
  316.  
  317.     /**
  318.      * @var        mixed  Contient la valeur retournée par la méthode du dernier mode executé...
  319.      */
  320.     public $Return = null;
  321.  
  322.     /**
  323.      * @var        boolean la première méthode correspondant à un mode qui retourne une valeur à gagner...
  324.      */
  325.     private $_returned = false;
  326.  
  327.  
  328.     /**
  329.      * @var        array Tableau contenant les variables de classes modifiables à la construction de l'objet
  330.      */
  331.     private $_options = array(
  332.         //  Variable de classe => son equivalent dans Pxxo::config
  333.         'Theme'           => 'theme_name',
  334.         'ThemePaths'      => 'theme_path',
  335.         'TemplatePath'    => 'templates_path',
  336.         'ResourcePath'    => 'resources_path',
  337.         'ResourceURL'     => 'resources_url',
  338.         'CachePath'       => 'cache_path',
  339.         'CacheMode'       => 'cache_flag',
  340.         'CacheTime'       => 'cache_time',
  341.         'Lang'            => 'language',
  342.         'PrependVar'      => 'undefined',
  343.         'MinifyLevel'     => 'undefined',
  344.         'StandaloneMode'  => 'undefined',
  345.         'PersistentMode'  => 'undefined',
  346.         'DefaultMode'     => 'undefined',
  347.         'CurrentMode'     => 'undefined',
  348.         'ClassName'       => 'undefined',
  349.         'TranslateData'   => 'undefined',
  350.         'TranslateAdapter'=> 'undefined',
  351.         'TranslateOptions'=> 'undefined',
  352.     );
  353.  
  354.     /**
  355.      * @var        array liste des options du widgets
  356.      */
  357.     protected $_params = array();
  358.  
  359.     /**
  360.      * @var Pxxo_Widget_Decorator instance de l'éventuel décorateur
  361.      */
  362.     protected $_decorator = NULL;
  363.  
  364.     /**
  365.      * @var Pxxo_Widget instance de ce que l'on décore (peut pointer sur un décorateur)
  366.      */
  367.     protected $_decorated = NULL;
  368.  
  369.     /**
  370.      * @var Pxxo_Widget instance du widget que l'on décore (ne peut pas pointer sur un decorateur)
  371.      */
  372.     protected $_decorated_leaf = NULL;
  373.  
  374.  
  375.     // }}}
  376.     // {{{ Constructeur
  377.     /**
  378.      * Constructeur
  379.      *
  380.      * @param string tableau des  paramètres du composants
  381.      * @param string chemin complet du fichier de définition du widget
  382.      */
  383.     function __construct($options$filename)
  384.     {
  385.         parent::__construct();
  386.  
  387.         $this->Headers = new Pxxo_Buffers;
  388.         $this->Resources = new Pxxo_Buffers;
  389.  
  390.         $this->_options['LoadingMode''undefined'// ?
  391.  
  392.         $this->_view = new Pxxo_View($options);
  393.  
  394.         // {{{ Assignation automtiques des attributs de l'objet
  395.         // Paramètres Génériques
  396.         foreach($this->_options as $opt => $cfg{
  397.             if (is_array($optionsand array_key_exists($opt$options)) {
  398.                 $this->$opt $options[$opt];
  399.             }
  400.             elseif (is_array($optionsand array_key_exists(strtolower($opt)$options)) {
  401.                 $this->$opt $options[strtolower($opt)];
  402.             }
  403.             elseif ($cfg !== 'undefined'{
  404.                 $this->{$optPxxo_Config::get($cfg);
  405.             }
  406.         }
  407.         // Paramètres Spécifiques
  408.         foreach($this->_params as $p{
  409.             if (isset($options[$p])) {
  410.                 $this->$p $options[$p];
  411.             }
  412.         }
  413.         // }}}
  414.  
  415.         // {{{ Caclul pseudo automatique d'un identifiant unique pour le composant
  416.         $class get_class($this);
  417.         if (!is_null($this->varnamemode)) {
  418.             // Retro compatibilité 3.6 et précedente
  419.             $this->ClassID $this->ClassName $this->varnamemode;
  420.         }
  421.         else {
  422.             if (is_null($this->ClassName)) $this->ClassName $class;
  423.             if (!isset($GLOBALS['PXXO_GLOBALS'][$this->ClassName])) $GLOBALS['PXXO_GLOBALS'][$this->ClassName0;
  424.  
  425.             if ($GLOBALS['PXXO_GLOBALS'][$this->ClassName!== 0)
  426.                 $this->ClassID $this->ClassName.$GLOBALS['PXXO_GLOBALS'][$this->ClassName];
  427.             else
  428.                 $this->ClassID $this->ClassName;
  429.  
  430.             if ($this->HiddenMode)
  431.                 $this->ClassID 'x'.strtoupper(base_convert(sprintf("%u"crc32($this->ClassID))1036));
  432.  
  433.             ++$GLOBALS['PXXO_GLOBALS'][$this->ClassName];
  434.         }
  435.         // }}}
  436.  
  437.  
  438.  
  439.         // {{{ Réglage du cache
  440.         if (!empty($this->CachePath)) {
  441.             $this->CachePath rtrim($this->CachePathDIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
  442.             $this->setCacheOption('backendFile|cache_dir'$this->CachePath);
  443.         }
  444.         if (!is_null($this->CacheMode))  {
  445.             if ($this->CacheMode)
  446.                 $this->enableCache();
  447.             else
  448.                 $this->disableCache();
  449.         }
  450.         if (!is_null($this->CacheTime))  {
  451.             $this->setLifetime($this->CacheTime);
  452.         }
  453.         // }}}
  454.  
  455.  
  456.         // {{{ Detection des variables publique du widget
  457.         $tab get_object_vars($this);
  458.         $res array();
  459.         foreach($tab as $k => $v{
  460.             if (!$this->isPrivateVar($k)) $this->_vars_public[$k;
  461.         }
  462.         // }}}
  463.  
  464.  
  465.  
  466.         // {{{ gestion du ThemePaths
  467.         $filepath dirname($filename).DIRECTORY_SEPARATOR.basename($filename'.php');
  468.         if (isset($options['themepath'])) $this->addThemePath($options['themepath']);
  469.         if (!empty($this->TemplatePath)) {
  470.             // Dans cette classe, On considère le TemplatePath comme commun à tous les widgets
  471.             $tplpath rtrim($this->TemplatePath,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$this->ClassName;
  472.             if ($this->addThemePath($tplpath)) {
  473.                 $tplpath rtrim($this->TemplatePath,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.strtolower($this->ClassName)// retro compatibilté PHP4
  474.                 if ($this->addThemePath($tplpath)) {
  475.                     $tplpath $filepath;
  476.                 }
  477.             }
  478.             $this->TemplatePath $tplpath;
  479.         }
  480.         else {
  481.             $this->TemplatePath $filepath;
  482.         }
  483.         $this->addThemePath($filepath);
  484.         // }}}
  485.  
  486.  
  487.  
  488.     }
  489.     // }}}
  490.     // {{{ putWidget
  491.     /**
  492.      * Ajout d'un widget sous forme de composant
  493.      *
  494.      * si l'identifiant est null on attache un widget au Widget courant
  495.      * sans pour autant le mettre à disposition du template
  496.      * mais renvoyant simplement le rendu sous forme d'une chaine de caractères
  497.      *
  498.      * @param string identifiant du widget dans les templates
  499.      * @param Pxxo_Widget  instance d'un widget
  500.      * @return mixed 
  501.      */
  502.     function putWidget($id$o)
  503.     {
  504.         if ($this->State 1trigger_error("`$this->ClassID::putWidgetcalled in the __construct() method : you should call it in the initMode() method"E_USER_NOTICE);
  505.         $o->ClassId $id;
  506.         $obj $this->stackComponent($o);
  507.         if (!is_null($obj)) {
  508.             if (is_null($idor $id === false{
  509.                 return $obj->get();
  510.             }
  511.             else {
  512.                 $this->_view->assign($id$obj->get());
  513.             }
  514.         }
  515.     }
  516.     // }}}
  517.     // {{{ putData
  518.     /**
  519.      * Ajout de donnée
  520.      *
  521.      * @param string identifiant dans les templates
  522.      * @param Pxxo_Buffer  instance d'un flux
  523.      */
  524.     function putData($id$value)
  525.     {
  526.         if ($this->State 1trigger_error("`$this->ClassID::putDatacalled in the __construct() method : you should call it in the initMode() method"E_USER_NOTICE);
  527.  
  528.         $this->_view->assign($id$value);
  529.     }
  530.     // }}}
  531.     // {{{ putFile
  532.     /**
  533.      * Ajout le contenu d'un template dans une zone
  534.      *
  535.      * @param string identifiant dans les templates
  536.      * @param string fichier
  537.      */
  538.     function putFile($id$filename)
  539.     {
  540.         if ($this->State 1trigger_error("`$this->ClassID::putFilecalled in the __construct() method : you should call it in the initMode() method"E_USER_NOTICE);
  541.  
  542.         $themefile $this->getThemeFile($filename);
  543.         $stm Pxxo_Buffer::factory('tpl'$themefile);
  544.         $this->copyto($stm);
  545.         $this->_view->setInputBuffer($stm);
  546.         $this->_view->assign($this->getPublicVars());
  547.         $this->_view->assign('Self'$this);
  548.         $this->_view->transform($typ_rsc);
  549.         $out $this->_view->getOutputBuffer();
  550.         $this->_view->assign($id$out->get());
  551.     }
  552.     // }}}
  553.     // {{{ putOnceStyle
  554.     /**
  555.      * Ajout de CSS
  556.      *
  557.      * le CSS est contenu dans un fichier. Ce fichier fonctionne comme un template.
  558.      *
  559.      * @param string nom du fichier (son emplacement sera déduit en fonction du theme)
  560.      * @param string media destibation des templates
  561.      * @return string identifiant de la ressources dans $this->Resources
  562.      */
  563.     function putOnceStyle($filename$media 'screen')
  564.     {
  565.         if (isset($this->_memory_cache[__METHOD__][$filename][$media.'X'])) return $this->_memory_cache[__METHOD__][$filename][$media.'X'];
  566.  
  567.         $id_rsc $this->dynResource($filename'css');
  568.         /* CAS Internet explorer */
  569.         if (substr($media03=== 'if '{
  570.             $this->Resources->get($id_rsc)->condition $media;
  571.             $media 'screen';
  572.