VCL
[ class tree: VCL ] [ index: VCL ] [ all elements ]

Source for file classes.inc.php

Documentation is available at classes.inc.php

  1. <?php
  2. /**
  3. *  This file is part of the VCL for PHP project
  4. *
  5. *  Copyright (c) 2004-2007 qadram software <support@qadram.com>
  6. *
  7. *  Checkout AUTHORS file for more information on the developers
  8. *
  9. *  This library is free software; you can redistribute it and/or
  10. *  modify it under the terms of the GNU Lesser General Public
  11. *  License as published by the Free Software Foundation; either
  12. *  version 2.1 of the License, or (at your option) any later version.
  13. *
  14. *  This library is distributed in the hope that it will be useful,
  15. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. *  Lesser General Public License for more details.
  18. *
  19. *  You should have received a copy of the GNU Lesser General Public
  20. *  License along with this library; if not, write to the Free Software
  21. *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  22. *  USA
  23. *
  24. */
  25.  
  26. use_unit("system.inc.php");
  27.  
  28. global $exceptions_enabled;
  29.  
  30. $exceptions_enabled=true;
  31.  
  32. global $output_enabled;
  33.  
  34. $output_enabled=true;
  35.  
  36. /**
  37.  * Component it's being loaded
  38.  *
  39.  */
  40. define('csLoading',1);
  41.  
  42. /**
  43.  * Component it's being edited on the IDE designer
  44.  *
  45.  */
  46. define('csDesigning',2);
  47.  
  48.  
  49.  //TODO: Provide a way to show this info using templates so is customizable by final users
  50.  
  51. /**
  52.  * Common exception handler, it provides a way to pretty format exceptions and to
  53.  * get an stack trace to find out where the problem is
  54.  *
  55.  * @param Exception $exception Exception to raise
  56.  */
  57. function exception_handler($exception)
  58. {
  59.         echo "<pre>";
  60.         $tolog="";
  61.         $stacktrace="";
  62.         $stacktrace.="Application raised an exception class <b>".get_class($exception)."</b> with message <b>'".$exception->getMessage()."'</b>\n";
  63.         $msg=strip_tags($stacktrace)."|";
  64.         $stack=array_reverse($exception->getTrace());
  65.         reset($stack);
  66.         $tab="";
  67.         $c="";
  68.         while (list($k,$v)=each($stack))
  69.         {
  70.                 $stacktrace.=$tab.$c."Callstack #$k File: <b>".$v['file']."</b> Line: <b>".$v['line']."</b>\n";
  71.                 $tolog.=$v['line']."@".$v['file'].'@'.$msg;
  72.                 $tab.="  ";
  73.                 $c="|_";
  74.         }
  75.         echo $stacktrace;
  76.         echo "</pre>";
  77.         error_log($tolog);
  78. }
  79.  
  80. set_exception_handler('exception_handler');
  81.  
  82. /**
  83.  * EResNotFound exception
  84.  *
  85.  * Exception thrown when a resource is not found on an xml stream
  86.  */
  87. class EResNotFound extends Exception
  88. {
  89.         function __construct($message null$code 0)
  90.         {
  91.                 $message=sprintf("Resource not found [%s]"$message);
  92.  
  93.        // make sure everything is assigned properly
  94.        parent::__construct($message$code);
  95.         }
  96. }
  97.  
  98. /**
  99.  * ENameDuplicated exception
  100.  *
  101.  * Exception thrown when a component has the same name on the same owner
  102.  */
  103. class ENameDuplicated extends Exception
  104. {
  105.         function __construct($message null$code 0)
  106.         {
  107.                 $message=sprintf("A component named %s already exists"$message);
  108.  
  109.        // make sure everything is assigned properly
  110.        parent::__construct($message$code);
  111.         }
  112. }
  113.  
  114. /**
  115.  * EAssignError exception
  116.  *
  117.  * Exception thrown when trying to assign an object to another
  118.  */
  119. class EAssignError extends Exception
  120. {
  121.         function __construct($sourcename$classname)
  122.         {
  123.                 $message=sprintf("Cannot assign a %s to a %s"$sourcename$classname);
  124.  
  125.                // make sure everything is assigned properly
  126.                parent::__construct($message0);
  127.         }
  128. }
  129.  
  130. /**
  131.  * ECollectionError exception
  132.  *
  133.  * Exception thrown for Collection errors
  134.  */
  135. class ECollectionError extends Exception
  136. {
  137.         function __construct($message null$code 0)
  138.         {
  139.                 $message=sprintf("List index out of bounds (%s)"$message);
  140.  
  141.        // make sure everything is assigned properly
  142.        parent::__construct($message$code);
  143.         }
  144. }
  145.  
  146. /**
  147.  * Filer class
  148.  *
  149.  * A base class to read/write components from/to an xml stream
  150.  */
  151. class Filer extends Object
  152. {
  153.         protected $_xmlparser;
  154.         protected $_root;
  155.         protected $_lastread;
  156.         protected $_parents;
  157.         protected $_properties;
  158.         protected $_lastproperty;
  159.         protected $_rootvars;
  160.         public $createobjects=true;
  161.  
  162.  
  163.         /**
  164.          * Initializes the object by setting up a list of parents and the xml parser used to read/write components
  165.          * @param xmlparser $xmlparser xml parser to read/write components
  166.          */
  167.         function __construct($xmlparser)
  168.         {
  169.                 //List of parents to provide a stack
  170.                 $this->_parents=new Collection();
  171.  
  172.                 //TODO: Develop a TStringList class
  173.                 $this->_properties=array();
  174.  
  175.                 //Root members, to initialize them with the right components
  176.                 $this->_rootvars=array();
  177.  
  178.                 //Last component read
  179.                 $this->_lastread=null;
  180.  
  181.  
  182.                 //Last property read
  183.                 $this->_lastproperty=null;
  184.  
  185.                 //The xml parser
  186.                 $this->_xmlparser=$xmlparser;
  187.                 xml_set_object($this->_xmlparser$this);
  188.                 xml_set_element_handler($this->_xmlparser"tagOpen""tagClose");
  189.                 xml_set_character_data_handler($this->_xmlparser"cData");
  190.    }
  191.  
  192.         /**
  193.          * Processed the opening tags to select which action to take
  194.          * @param xmlparser $parser xml parser in use
  195.          * @param string    $tag    opening tag
  196.          * @param array     $attributes attributes of the opening tag
  197.          */
  198.         function tagOpen($parser$tag$attributes)
  199.         {
  200.                 switch ($tag)
  201.                 {
  202.                         case 'OBJECT'//Read object parameters
  203.                         $new=true;
  204.  
  205.                         //Class and name for that component
  206.                         $class=$attributes['CLASS'];
  207.                         $name=$attributes['NAME'];
  208.  
  209.                         //If there is a root component and it has not been read yet
  210.                         if ((is_object($this->_root)) && (!is_object($this->_lastread)))
  211.                         {
  212.                                 //And the class we are reading matches
  213.                                 if (($this->_root->classNameIs($class)) || ($this->_root->inheritsFrom($class)))
  214.                                 {
  215.                                         //We must read root properties, so set the lastread to the root
  216.                                         $new=false;
  217.                                         $this->_lastread=$this->_root;
  218.                                         $this->_lastread->Name=$name;
  219.  
  220.                                 }
  221.                         }
  222.  
  223.                         //We must create a new object of the class just read
  224.                         if ($new)
  225.                         {
  226.                                 //If that class has been declared somewhere
  227.                                 if (class_exists($class))
  228.                                 {
  229.                                         $this->_lastread=null;
  230.  
  231.                                         //Creates a new instance of that class
  232.                                         if ($this->createobjects)
  233.                                         {
  234.                                                 $this->_lastread=new $class($this->_root);
  235.  
  236.                                                 //This is a kind of a hack to get the right reference to the newly created component
  237.                                                 $this->_lastread=$this->_root->components->items[count($this->_root->components->items)-1];
  238.                                         }
  239.                                         else
  240.                                         {
  241.                                                 if (array_key_exists($name,$this->_rootvars))
  242.                                                 {
  243.                                                         $this->_lastread=$this->_rootvars[$name];
  244.                                                 }
  245.                                                 else
  246.                                                 {
  247.                                                         echo "Error reading language resource fileobject ($namenot found";
  248.                                                 }
  249.                                         }
  250.  
  251.                                         $this->_lastread->ControlState=csLoading;
  252.                                         $this->_lastread->Name=$name;
  253.  
  254.  
  255.                                         //We find the member of the root object and we set the reference
  256.                                         if (array_key_exists($name,$this->_rootvars))
  257.                                         {
  258.                                                 $this->_root->$name=$this->_lastread;
  259.                                         }
  260.                                         //TODO: Decide to dump here an error or not
  261.  
  262.                                         //Set the parent
  263.                                         if ($this->_lastread->inheritsfrom("Control"))
  264.                                         {
  265.                                                 $this->_lastread->Parent=$this->_parents->items[count($this->_parents->items)-1];
  266.                                         }
  267.  
  268.                                         //Push it onto the stack
  269.                                         $this->_parents->add($this->_lastread);
  270.                                 }
  271.                                 else
  272.                                 {
  273.                                         //TODO: Change this by an exception when possible, there's a bug in PHP 5, because the exception is raised inside an xml reader
  274.                                         echo "Error reading resource fileclass ($classdoesn't exists";
  275.                                         //throw new EResNotFound("Error reading resource file, class ($class) doesn't exists");
  276.                                 }
  277.                         }
  278.                         break;
  279.  
  280.                         case 'PROPERTY':
  281.                         $new=true;
  282.                         $name=$attributes['NAME'];
  283.  
  284.                         //If we are reading a property, must be inside an object
  285.                         if (!is_object($this->_lastread))
  286.                         {
  287.                                 echo "Error reading resource fileproperty ($namedoesn't have an object to assign to";
  288.                         }
  289.                         else
  290.                         {
  291.                                 $this->_lastproperty=$name;
  292.                                 $this->_properties[]=$name;
  293.                         }
  294.                         break;
  295.  
  296.                         default: echo "Error reading resource filetag ($tagnot recognized"break;
  297.                 }
  298.         }
  299.  
  300.         /**
  301.          * Processed the data for tags
  302.          * @param xmlparser $parser xml parser in use
  303.          * @param string $cdata data to be processed
  304.          */
  305.         function cData($parser$cdata)
  306.         {
  307.                 $cdata=html_entity_decode($cdata);
  308.  
  309.                 //If we have an object and a property
  310.                 if ((is_object($this->_lastread)) && ($this->_lastproperty!=null))
  311.                 {
  312.                         $aroot=$this->_lastread;
  313.                         $aproperty=$this->_lastproperty;
  314.  
  315.                         if (count($this->_properties)>1)
  316.                         {
  317.                                 reset($this->_properties);
  318.  
  319.                                 while (list($k,$v)=each($this->_properties))
  320.                                 {
  321.                                         if ($v==$this->_lastproperty)
  322.                                         {
  323.                                                 $aproperty=$v;
  324.                                                 break;
  325.                                         }
  326.                                         else
  327.                                         {
  328.  
  329.                                                 $am="get$v";
  330.                                                 $aroot=$aroot->$v;
  331.                                         }
  332.                                 }
  333.                         }
  334.  
  335.                                                 $isarray=false;
  336.                         //Getter
  337.                         $method='get'.$aproperty;
  338.                         //If there is a getter
  339.                         if ($aroot->methodExists($method))
  340.                         {
  341.                                         $value=$aroot->$method();
  342.                                         $isarray=is_array($value);
  343.  
  344.                         }
  345.  
  346.                         //Setter
  347.                         $method='set'.$aproperty;
  348.  
  349.  
  350.                         //If there is a setter
  351.                         if ($aroot->methodExists($method))
  352.                         {
  353.                                 //Set the property
  354.                                 $value=$cdata;
  355.  
  356.                                 if ($isarray)
  357.                                 {
  358.                                         $value=safeunserialize($value);
  359.                                 }
  360.  
  361.                                 $aroot->$method($value);
  362.  
  363.                         }
  364.                         else
  365.                         {
  366.                                 if (($aroot->inheritsFrom('Component')) && (!$aroot->inheritsFrom('Control')) && ($aproperty=='Left'))
  367.                                 {
  368.  
  369.                                 }
  370.                                 else if (($aroot->inheritsFrom('Component')) && (!$aroot->inheritsFrom('Control')) && ($aproperty=='Top'))
  371.                                 {
  372.  
  373.                                 }
  374.                                 else echo "Error setting property (".$aroot->className()."::$this->_lastproperty), doesn't exists";
  375.                         }
  376.                 }
  377.         }
  378.  
  379.         /**
  380.          * Processes tag closing
  381.          * @param xmlparser $parser xml parser in use
  382.          * @param string $tag tag being closed
  383.          */
  384.         function tagClose($parser$tag)
  385.         {
  386.                 switch($tag)
  387.                 {
  388.                         case 'PROPERTY':
  389.                             // Pop last array element
  390.                             array_pop($this->_properties);
  391.                             $this->_lastproperty=null;
  392.                             break;
  393.                         case 'OBJECT':
  394.                                 //Pop the parent from the stack
  395.                                 $this->_parents->delete(count($this->_parents->items)-1);
  396.  
  397.  
  398.                                 //Call the last read component
  399.                                 //TODO: Check if the last item from the stack is the right one to call loaded
  400.  
  401.                                 $this->_lastread->ControlState=0;
  402.  
  403.                                 if ($this->createobjects)
  404.                                 {
  405.                                 //Unserialize
  406.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule')))
  407.                                 {
  408.                                         $this->_lastread->unserialize();
  409.                                         $this->_lastread->unserializeChildren();
  410.                                 }
  411.  
  412.                                 //Loaded
  413.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule')))
  414.                                 {
  415.                                         $this->_lastread->loadedChildren();
  416.                                         $this->_lastread->loaded();
  417.                                 }
  418.  
  419.                                 //PreInit
  420.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule')))
  421.                                 {
  422.                                         $this->_lastread->preinit();
  423.                                 }
  424.  
  425.                                 //Init
  426.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule')))
  427.                                 {
  428.                                         $this->_lastread->init();
  429.                                 }
  430.                                 }
  431.  
  432.                                 /*
  433.                                 if ($this->_root->inheritsFrom('Page'))
  434.                                 {
  435.                                         if (!$this->_root->UseAjax) $this->_lastread->loaded();
  436.                                 }
  437.                                 else
  438.                                 {
  439.                                         $this->_lastread->loaded();
  440.                                 }
  441.                                 */
  442.  
  443.                                 if (count($this->_parents->items)>=1$this->_lastread=$this->_parents->items[count($this->_parents->items)-1];
  444.                                 else $this->_lastread=null;
  445.                                 break;
  446.                 }
  447.         }
  448.  
  449.          /**
  450.          * Root component
  451.          * @return object 
  452.          */
  453.         function getRoot(return($this->_root)}
  454.  
  455.          /**
  456.          * Root component
  457.          * @param object $value new property value
  458.          */
  459.         function setRoot($value)
  460.         {
  461.                 //TODO: Check here $value for null
  462.                 $this->_root=$value;
  463.                 //Get the vars from the root object to get the pointers for the components
  464.                 $this->_rootvars=get_object_vars($this->_root);
  465.  
  466.                 //Clear parents list and set the root as the first parent
  467.                 $this->_parents->clear();
  468.                 $this->_parents->add($this->_root);
  469.  
  470.         }
  471. }
  472.  
  473. /**
  474.  * Reader class
  475.  *
  476.  * A class to read components from an xml stream
  477.  */
  478. class Reader extends Filer
  479. {
  480.         /**
  481.          * Read a component and all its children from a stream
  482.          * @param object $root Root component to read
  483.          * @param string $stream XML stream to read from
  484.          */
  485.         function readRootComponent($root,$stream)
  486.         {
  487.                 $this->Root=$root;
  488.  
  489.                 xml_parse($this->_xmlparser$stream);
  490.  
  491.                 $this->_root->ControlState=0;
  492.         }
  493. }
  494.  
  495. /**
  496.  * Collection class
  497.  *
  498.  * A class to store and manage a list of objects
  499.  */
  500. class Collection extends Object
  501. {
  502.         //Items array
  503.         
  504.         public $items;
  505.  
  506.         function __construct()
  507.         {
  508.                 //Initialize the array
  509.                 $this->clear();
  510.         }
  511.  
  512.          /**
  513.          * Add an item to the list
  514.          * @param object $item Object to add to the list
  515.          * @return integer 
  516.          */
  517.         function add($item)
  518.         {
  519.                 //Set the array to the end
  520.                 end($this->items);
  521.  
  522.                 //Adds the item as the last one
  523.                 $this->items[]=$item;
  524.  
  525.                 return($this->count());
  526.         }
  527.  
  528.          /**
  529.          * Clears the list
  530.          */
  531.         function clear()
  532.         {
  533.                 $this->items=array();
  534.         }
  535.  
  536.          /**
  537.          * Delete an item from the list by its index
  538.          * @param integer $index Index of the item to delete
  539.          */
  540.         function delete($index)
  541.         {
  542.                 //Deletes the item from the array, so the rest of items are reordered
  543.                 if ($index<$this->count())
  544.                 {
  545.                         array_splice($this->items$index1);
  546.                 }
  547.                 else
  548.                 {
  549.                         throw new ECollectionError($index);
  550.                 }
  551.         }
  552.  
  553.          /**
  554.          * Finds an item into the list
  555.          * @param object $item Item to find
  556.          */
  557.         function indexof($item)
  558.         {
  559.                 $result=-1;
  560.  
  561.                 reset($this->items);
  562.                 while (list($k,$v)=each($this->items))
  563.                 {
  564.                         if ($v===$item)
  565.                         {
  566.                                 $result=$k;
  567.                                 break;
  568.                         }
  569.                 }
  570.  
  571.                 return($result);
  572.         }
  573.  
  574.         /**
  575.          * Remove an item from the list
  576.          * @param object $item Item to delete from the list
  577.          */
  578.         function remove($item)
  579.         {
  580.                 //Find the pointer
  581.                 $index=$this->indexof($item);
  582.  
  583.                 //Delete the index if exists
  584.                 if ($index>=0)
  585.                 {
  586.                         $this->delete($index);
  587.                 }
  588.         }
  589.  
  590.         /**
  591.          * Return the number of items in the list
  592.          * @return integer 
  593.          */
  594.         function count()
  595.         {
  596.                 return(count($this->items));
  597.         }
  598.  
  599.                  /**
  600.          * Return the last element from the collection
  601.          * @return object 
  602.          */
  603.         function last()
  604.         {
  605.                 if ($this->count()>=1)
  606.                 {
  607.                         return($this->items[count($this->items)-1]);
  608.                 }
  609.                 else
  610.                 {
  611.                         return(null);
  612.                 }
  613.         }
  614.  
  615. }
  616.  
  617. /**
  618.  * Persistent class
  619.  *
  620.  * Base class for persistent objects, which are the ones provide the required
  621.  * features to be serialized/unserialized easily
  622.  */
  623. class Persistent extends Object
  624. {
  625.                 /**
  626.                  * Used to serialize/unserialize
  627.                  *
  628.                  * @return string 
  629.                  */
  630.         function readNamePath()
  631.         {
  632.                 $result=$this->className();
  633.  
  634.                 if ($this->readOwner()!=null)
  635.                 {
  636.                         $s=$this->readOwner()->readNamePath();
  637.  
  638.                         if ($s!=""$result $s "." $result;
  639.  
  640.                 }
  641.  
  642.                 return($result);
  643.         }
  644.  
  645.         /**
  646.         * Owner of the component, in Persistent always return null
  647.         * @return Component 
  648.         */
  649.         function readOwner()
  650.         {
  651.                 return(null);
  652.         }
  653.  
  654.         /**
  655.          * Assing the source properties to this object
  656.          *
  657.          * @param Persistent $source Object to get assigned to this object
  658.          */
  659.         function assign($source)
  660.         {
  661.                 if ($source!=null$source->assignTo($this);
  662.                 else $this->assignError(null);
  663.         }
  664.  
  665.         /**
  666.          * Assign this object to another object
  667.          *
  668.          * @param Persistent $dest Object to assign this object to
  669.          */
  670.         function assignTo($dest)
  671.         {
  672.                 $dest->assignError($this);
  673.         }
  674.  
  675.         /**
  676.          * Raises an assignation error
  677.          *
  678.          * @param Persistent $source Component tried to assign
  679.          */
  680.         function assignError($source)
  681.         {
  682.                 if ($source!=null$sourcename=$source->className();
  683.                 else $sourcename='null';
  684.  
  685.                 throw new EAssignError($sourcename,$this->className());
  686.         }
  687.  
  688.         /**
  689.          * Stores this object into the session, it uses PHP reflection system
  690.          * to get published properties, the ones that will be stored.
  691.          *
  692.          * Components need an owner to be serialized
  693.          *
  694.          */
  695.         function serialize()
  696.         {
  697.                 $owner=$this->readOwner();
  698.  
  699.         if ($owner!=null)
  700.         {
  701.                 $refclass=new ReflectionClass($this->ClassName());
  702.                 $methods=$refclass->getMethods();
  703.  
  704.                 reset($methods);
  705.  
  706.                 while (list($k,$method)=each($methods))
  707.                 {
  708.                         $methodname=$method->name;
  709.  
  710.                         if ($methodname[0== 's' && $methodname[1== 'e' && $methodname[2== 't')   // fast check of: substr($methodname,0,3)=='set'
  711.                         {
  712.                                 $propname=substr($methodname3);
  713.                                 $propvalue=$this->$propname;
  714.                                 if (!is_object($propvalue))
  715.                                 {
  716.                                         $_SESSION[$owner->readNamePath().".".$this->readNamePath().".".$propname]=$propvalue;
  717.                                 }
  718.                         }
  719.                 }
  720.  
  721.                 $this->serializeChildren();
  722.         }
  723.         else
  724.         {
  725.                 global $exceptions_enabled;
  726.  
  727.                 if ($exceptions_enabled)
  728.                 {
  729.                         throw new Exception('Cannot serialize a component without an owner');
  730.                 }
  731.         }
  732.   }
  733.  
  734.  
  735.   /**
  736.    * Read this object properties from the session, only published properties
  737.    * will be recovered, components need an owner to be unserialized.
  738.    *
  739.    */
  740.   function unserialize()
  741.   {
  742.         $owner=$this->readOwner();
  743.  
  744.         if ($owner!=null)
  745.         {
  746.                 $refclass=new ReflectionClass($this->ClassName());
  747.                 $methods=$refclass->getMethods();
  748.  
  749.                 $this->ControlState=csLoading;
  750.  
  751.                 reset($methods);
  752.  
  753.                 while (list($k,$method)=each($methods))
  754.                 {
  755.                         $methodname=$method->name;
  756.  
  757.                         if ($methodname[0== 's' && $methodname[1== 'e' && $methodname[2== 't')     // fast check of: substr($methodname,0,3)=='set'
  758.                         {
  759.                                 $propname=substr($methodname3);
  760.  
  761.                                 $fullname $owner->readNamePath().".".$this->readNamePath().".".$propname;
  762.                                 if (isset($_SESSION[$fullname]))
  763.                                 {
  764.                                         $this->$propname=$_SESSION[$fullname];
  765.                                 }
  766.                         }
  767.                 }
  768.  
  769.                 $this->ControlState=0;
  770.         }
  771.         else
  772.         {
  773.                 global $exceptions_enabled;
  774.  
  775.                 if ($exceptions_enabled)
  776.                 {
  777.                         throw new Exception('Cannot unserialize a component without an owner');
  778.                 }
  779.         }
  780.   }
  781. }
  782.  
  783.  
  784. /**
  785.  * Component class
  786.  *
  787.  * Base class for components, it provides owner relationships properties and
  788.  * basic methods to call events.
  789.  *
  790.  * Non-visible components must inherit from Component and not from Control, the
  791.  * IDE automatically handles the component as iconic.
  792.  */
  793. class Component extends Persistent
  794. {
  795.         public $owner;
  796.         public $components;
  797.         public $_name;
  798.         public $lastresourceread="";
  799.         protected $_controlstate=0;
  800.  
  801.         public $_tag=0;
  802.  
  803.         /**
  804.         * Constructor
  805.         * @param object $aowner The owner of this component
  806.         */
  807.         function __construct($aowner=null)
  808.         {
  809.                 //Calls the inherited constructor
  810.                 parent::__construct($aowner);
  811.  
  812.                 //List of children
  813.                 $this->components=new Collection();
  814.  
  815.                 //Initialize owner
  816.                 $this->owner=null;
  817.  
  818.                 //Initialize name
  819.                 $this->_name="";
  820.  
  821.                 $this->_controlstate=0;
  822.  
  823.                 if ($aowner!=null)
  824.                 {
  825.                         //If there is an owner
  826.                         if (is_object($aowner))
  827.                         {
  828.                                 //Store it
  829.                                 $this->owner=$aowner;
  830.  
  831.                                 //Adds itself to the list of components from the owner
  832.                                 $this->owner->insertComponent($this);
  833.                         }
  834.                         else
  835.                         {
  836.                                 throw new Exception("Owner must be an object");
  837.                         }
  838.                 }
  839.  
  840.         }
  841.  
  842.         /**
  843.         *  A virtual method to get notified when the object has been fully loaded from a stream
  844.         */
  845.         function loaded()
  846.         {
  847.  
  848.         }
  849.  
  850.         /**
  851.          * Calls childrens loaded recursively
  852.          *
  853.          */
  854.         function loadedChildren()
  855.         {
  856.                 //Calls childrens loaded recursively
  857.                 reset($this->components->items);
  858.                 while (list($k,$v)=each($this->components->items))
  859.                 {
  860.                         $v->loaded();
  861.                 }
  862.         }
  863.  
  864.         /**
  865.         * Overwrite this method to provide accessibility info for the RPC engine
  866.         * @return integer 
  867.         * @see DBGrid::UpdateRow
  868.         */
  869.         function readAccessibility($method$defaccessibility)
  870.         {
  871.                 return(Accessibility_Fail);
  872.         }
  873.  
  874.         /**
  875.         * This method returns the right object (or the input string if object not found) for an object name
  876.         * Should be used on the loaded method for object properties to find the right reference
  877.         *
  878.         * @param mixed $value string or object to set the property to
  879.         */
  880.         function fixupProperty($value)
  881.         {
  882.                 if (($this->ControlState csDesigning)!=csDesigning)
  883.                 {
  884.                         if (!empty($value))
  885.                         {
  886.                                 if (!is_object($value))
  887.                                 {
  888.                                         $form=$this->owner;
  889.                                         if (strpos($value,'.'))
  890.                                         {
  891.                                                 $pieces=explode('.',$value);
  892.                                                 $form=$pieces[0];
  893.  
  894.                                                 global $$form;
  895.  
  896.                                                 $form=$$form;
  897.  
  898.                                                 $value=$pieces[1];
  899.                                         }
  900.                                         if (is_object($form->$value))
  901.                                         {
  902.                                                 $value=$form->$value;
  903.                                         }
  904.                                 }
  905.                         }
  906.                 }
  907.                 return($value);
  908.         }
  909.  
  910.         /**
  911.          * Unserialize all children
  912.          *
  913.          */
  914.         function unserializeChildren()
  915.         {
  916.                 reset($this->components->items);
  917.                 while (list($k,$v)=each($this->components->items))
  918.                 {
  919.                         $v->unserialize();
  920.                 }
  921.         }
  922.  
  923.  
  924.         /**
  925.          * Calls a server event
  926.          *
  927.          * @param string $event 
  928.          * @param mixed $params 
  929.          * @return mixed calling event result
  930.          */
  931.         function callEvent($event,$params)
  932.         {
  933.                 $ievent="_".$event;
  934.  
  935.                 if ($this->$ievent!=null)
  936.                 {
  937.                         $event=$this->$ievent;
  938.                         if (!$this->owner->classNameIs('application'))
  939.                         {
  940.                                 return($this->owner->$event($this,$params));
  941.                         }
  942.                         else return($this->$event($this,$params));
  943.                 }
  944.         }
  945.  
  946.         /**
  947.          * Returns the js event attribute to call the server using Ajax
  948.          * we use xajax to handle all the ajax stuff.
  949.          *
  950.          * @param string $jsevent  javascript event
  951.          * @param string $phpevent php event to call
  952.          * @return string 
  953.          */
  954.         function generateAjaxEvent($jsevent$phpevent)
  955.         {
  956.                 $result=" $jsevent=\"xajax_ajaxProcess('".$this->owner->Name."','".$this->Name."',null,'$phpevent',xajax.getFormValues('".$this->owner->Name."'))\" ";
  957.  
  958.                 return($result);
  959.         }
  960.  
  961.         //TODO: Full implement the param exchange
  962.         
  963.         /**
  964.          * Returns the js event attribute to call the server using ajax
  965.          *
  966.          * @param string $phpevent php event to call
  967.          * @param array $params values to send to the server
  968.          * @return string 
  969.          */
  970.         function ajaxCall($phpevent$params=array())
  971.         {
  972.  
  973.                 $result=" xajax_ajaxProcess('".$this->owner->Name."','".$this->Name."',params,'$phpevent',xajax.getFormValues('".$this->owner->Name."'));\n ";
  974.  
  975.                 return($result);
  976.         }
  977.  
  978.         /**
  979.          * To initialize a component, called before init()
  980.          */
  981.         function preinit()
  982.         {
  983.                 //Calls childrens init recursively
  984.                 reset($this->components->items);
  985.                 while (list($k,$v)=each($this->components->items))
  986.                 {
  987.                         $v->preinit();
  988.                 }
  989.         }
  990.  
  991.         /**
  992.          * To initialize a component, the right place to process events
  993.          */
  994.         function init()
  995.         {
  996.                 //Calls childrens init recursively
  997.                 reset($this->components->items);
  998.                 while (list($k,$v)=each($this->components->items))
  999.                 {
  1000.                         $v->init();
  1001.                 }
  1002.         }
  1003.  
  1004.         /**
  1005.         * Checks if there is any datafield attached to the component
  1006.         * and sets the dataset in edit state and all the fields with
  1007.         * the appropiate values so the dataset is able to update the
  1008.         * right record
  1009.         *
  1010.         * Properties for data-aware components must be named
  1011.         * DataField
  1012.         * DataSource
  1013.         *
  1014.         * This is for basic single-field data-aware controls, for more
  1015.         * complicated controls like DBGrid, each component must create
  1016.         * its own mechanism to update information in the database
  1017.         */
  1018.         function updateDataField($value)
  1019.         {
  1020.                 if ($this->_datafield!="")
  1021.                 {
  1022.                         if ($this->_datasource!=null)
  1023.                         {
  1024.                                 if ($this->_datasource->Dataset!=null)
  1025.                                 {
  1026.                                         //Check here for the index fields
  1027.                                         $keyfields=$this->Name."_key";
  1028.                                         $keys=$this->input->$keyfields;
  1029.                                         // check if the keys were posted
  1030.                                         if (is_object($keys))
  1031.                                         {
  1032.                                                 $fname=$this->DataField;
  1033.  
  1034.                                                 //Set in Edit State
  1035.                                                 $this->_datasource->Dataset->edit();
  1036.  
  1037.  
  1038.                                                 $values=$keys->asStringArray();
  1039.  
  1040.                                                 //Sets the key values
  1041.                                                 reset($values);
  1042.                                                 while (list($k,$v)=each($values))
  1043.                                                 {
  1044.                                                         $this->_datasource->Dataset->$k=$v;
  1045.                                                 }
  1046.  
  1047.                                                 //Set the field value
  1048.                                                 $this->_datasource->Dataset->$fname=$value;
  1049.                                         }
  1050.                                         else $this->_datasource->Dataset->{$this->_datafield}=$value;
  1051.                                 }
  1052.                         }
  1053.                 }
  1054.         }
  1055.  
  1056.         /**
  1057.         * This function returns true if the datafield is valid
  1058.         *
  1059.         * @return boolean 
  1060.         *
  1061.         */
  1062.         function hasValidDataField()
  1063.         {
  1064.                 $result=false;
  1065.  
  1066.                 if ($this->_datafield!="")
  1067.                 {
  1068.                         if ($this->_datasource!=null)
  1069.                         {
  1070.                                 if ($this->_datasource->Dataset!=null)
  1071.                                 {
  1072.                                         $result=true;
  1073.                                 }
  1074.                         }
  1075.                 }
  1076.  
  1077.                 return($result);
  1078.         }
  1079.  
  1080.         /**
  1081.         * This function returns the value of the datafield, if any
  1082.         *
  1083.         * @return mixed 
  1084.         */
  1085.         function readDataFieldValue()
  1086.         {
  1087.                 $result=false;
  1088.                 if ($this->hasValidDataField())
  1089.                 {
  1090.                         $fname=$this->DataField;
  1091.                         $value=$this->_datasource->Dataset->$fname;
  1092.                         $result=$value;
  1093.                 }
  1094.                 return($result);
  1095.         }
  1096.  
  1097.         /**
  1098.         * This function dumps out the key fields for the current row, useful to
  1099.         * send information about the current register
  1100.         */
  1101.         function dumpHiddenKeyFields($force=false)
  1102.         {
  1103.                 if ($this->_datasource!=null)
  1104.                 {
  1105.                         if ($this->_datasource->Dataset!=null)
  1106.                         {
  1107.                                 if (($this->_datasource->Dataset->State!=dsInsert|| ($force))
  1108.                                 {
  1109.                                     //Dump the key values for this record so I'm able to update it in the future
  1110.                                     $this->_datasource->Dataset->dumpHiddenKeyFields($this->Name."_key");
  1111.                                 }
  1112.                         }
  1113.                 }
  1114.         }
  1115.  
  1116.         /**
  1117.          * Serialize all children
  1118.          *
  1119.          */
  1120.         function serializeChildren()
  1121.         {
  1122.                 //Calls childrens serialize recursively
  1123.                 reset($this->components->items);
  1124.                 while (list($k,$v)=each($this->components->items))
  1125.                 {
  1126.                         $v->serialize();
  1127.                 }
  1128.         }
  1129.  
  1130.         /**
  1131.          * To dump the javascript code needed by this component
  1132.          */
  1133.         function dumpJavascript()
  1134.         {
  1135.                 //Do nothing yet
  1136.         }
  1137.  
  1138.         /**
  1139.          * To dump header code required
  1140.          */
  1141.         function dumpHeaderCode()
  1142.         {
  1143.                 //Do nothing yet
  1144.         }
  1145.  
  1146.         /**
  1147.          * Dump the javascript code for all the children
  1148.          */
  1149.         function dumpChildrenJavascript()
  1150.         {
  1151.                 //Iterates through components, dumping all javascript
  1152.                 $this->dumpJavascript();
  1153.                 reset($this->components->items);
  1154.                 while (list($k,$v)=each($this->components->items))
  1155.                 {
  1156.                         if ($v->inheritsFrom('Control'))
  1157.                         {
  1158.                                 if ($v->canShow())
  1159.                                 {
  1160.                                         $v->dumpJavascript();
  1161.                                 }
  1162.                         }
  1163.                         else $v->dumpJavascript();
  1164.                 }
  1165.         }
  1166.  
  1167.         /**
  1168.          * Dump the header code for all the children
  1169.          *
  1170.          * @param boolean $return_contents If true, code is returned instead be dumped
  1171.          * @return string 
  1172.          */
  1173.         function dumpChildrenHeaderCode($return_contents=false)
  1174.         {
  1175.                 //Iterates through components, dumping all javascript
  1176.                 reset($this->components->items);
  1177.  
  1178.                 if ($return_contentsob_start();
  1179.                 while (list($k,$v)=each($this->components->items))
  1180.                 {
  1181.                         if ($v->inheritsFrom('Control'))
  1182.                         {
  1183.                                 if ($v->canShow())
  1184.                                 {
  1185.                                         $v->dumpHeaderCode();
  1186.                                 }
  1187.                         }
  1188.                         else $v->dumpHeaderCode();
  1189.                 }
  1190.                 if ($return_contents)
  1191.                 {
  1192.                         $contents=ob_get_contents();
  1193.                         ob_end_clean();
  1194.                         return($contents);
  1195.                 }
  1196.         }
  1197.  
  1198.         /**
  1199.          * Load this component from a string
  1200.          *
  1201.          * @param string $filename  xml file name
  1202.          * @param boolean $inherited specifies if we are going to read an inherited resource
  1203.          */
  1204.         function loadResource($filename$inherited=false$storelastresource=true)
  1205.         {
  1206.            global $application;
  1207.  
  1208.            if (!$inherited)
  1209.            {
  1210.                    if ($this->inheritsFrom('Page'))
  1211.                    {
  1212.                         if ($this->classParent()!='Page')
  1213.                         {
  1214.                                 $varname=$this->classParent();
  1215.                                 global $$varname;
  1216.                                 $baseobject=$$varname;
  1217.                                 $this->loadResource($baseobject->lastresourcereadtrue);
  1218.                         }
  1219.                    }
  1220.            }
  1221.  
  1222.            if ($storelastresource$this->lastresourceread=$filename;
  1223.            //TODO: Check here for the path to the resource file
  1224.            //$resourcename=basename($filename);
  1225.            $resourcename=$filename;
  1226.            $l="";
  1227.  
  1228.            if ((($application->Language!='')) || (($this->inheritsFrom('Page')) && ($this->Language!='(default)')))
  1229.            {
  1230.                 $resourcename=str_replace('.php',$l.'.xml.php',$filename);
  1231.                 $this->readFromResource($resourcename);
  1232.  
  1233.                 $l=".".$application->Language;
  1234.                 $resourcename=str_replace('.php',$l.'.xml.php',$filename);
  1235.                 if (file_exists($resourcename))
  1236.                 {
  1237.                         $this->readFromResource($resourcenamefalsefalse);
  1238.                 }
  1239.            }
  1240.            else
  1241.            {
  1242.                    $resourcename=str_replace('.php',$l.'.xml.php',$resourcename);
  1243.                    $this->readFromResource($resourcename);
  1244.            }
  1245.         }
  1246.  
  1247.         /**
  1248.          * Read a component from a resource file
  1249.          * @param string $filename Filename of the resource file
  1250.          * @param boolean $createobjects Specifies if create the objects found or just read properties
  1251.          */
  1252.         function readFromResource($filename=""$createobjects=true)
  1253.         {
  1254.                 //Default filename
  1255.                 if ($filename==""$filename=strtolower($this->className()).".xml.php";
  1256.  
  1257.                 if ($filename!="")
  1258.                 {
  1259.                         if (file_exists($filename))
  1260.                         {
  1261.                                 //Reads the component from an xml stream
  1262.                                 $xml=xml_parser_create("UTF-8");
  1263.                                 $reader=new Reader($xml);
  1264.                                 $filelines=file($filename);
  1265.  
  1266.                                 array_shift($filelines);
  1267.                                 array_pop($filelines);
  1268.  
  1269.                                 $file=implode('',$filelines);
  1270.  
  1271.                                 $reader->createobjects=$createobjects;
  1272.  
  1273.                                 $reader->readRootComponent($this$file);
  1274.                         }
  1275.                         else
  1276.                         {
  1277.                                 global $exceptions_enabled;
  1278.  
  1279.                                 if ($exceptions_enabledthrow new EResNotFound($filename);
  1280.                         }
  1281.                 }
  1282.  
  1283.         }
  1284.  
  1285.          /**
  1286.          * Insert a component into the components collection
  1287.          * @param object $acomponent Component to insert
  1288.          */
  1289.         function insertComponent($acomponent)
  1290.         {
  1291.                 //Adds a component to the components list
  1292.                 $acomponent->owner=$this;
  1293.                 $this->components->add($acomponent);
  1294.         }
  1295.  
  1296.         /**
  1297.          * Remove a component from the components collection
  1298.          * @param object $acomponent Component to remove
  1299.          */
  1300.         function removeComponent($acomponent)
  1301.         {
  1302.                 //Remove a component from the components list
  1303.                 $this->components->remove($acomponent);
  1304.         }
  1305.  
  1306.  
  1307.         //Properties
  1308.  
  1309.         
  1310.  
  1311.         /**
  1312.         * Component list containing all the components owned by this component
  1313.         *
  1314.         * @return Collection 
  1315.         */
  1316.         function readComponents(return $this->components}
  1317.  
  1318.         /**
  1319.         * Indicates how many components this component is owner
  1320.         *
  1321.         * @return integer 
  1322.         */
  1323.         function readComponentCount(return $this->components->count()}
  1324.  
  1325.         /**
  1326.         * A flag to know the state of the control, csLoading, csDesigning
  1327.         * Example: To test if the component is rendered inside the IDE:
  1328.         * <code>
  1329.         * if (($this->ControlState & csDesigning)==csDesigning)
  1330.         * {
  1331.         *    //Write here the design-time code
  1332.         * }
  1333.         * </code>
  1334.         *
  1335.         * @return integer 
  1336.         */
  1337.         function readControlState(return $this->_controlstate}
  1338.         function writeControlState($value$this->_controlstate=$value}
  1339.  
  1340.         /**
  1341.         * The path to uniquely identify a component, qualified by the owner when required
  1342.         * @return string 
  1343.         */
  1344.         function readNamePath(return($this->_name)}
  1345.  
  1346.         /**
  1347.         * The owner of this component, usually the page component, but the owner of pages is the application object
  1348.         * @return Component 
  1349.         */
  1350.         function readOwner(return($this->owner)}
  1351.  
  1352.         //Published properties
  1353.  
  1354.         
  1355.  
  1356.         /**
  1357.         * Name for the component, to be used as an identifier, should be unique
  1358.         * @return string 
  1359.         */
  1360.         function getName(return $this->_name}
  1361.         function setName($value)
  1362.         {
  1363.                 //TODO: If there is an owner, check there are no any other component with the same name
  1364.                 if ($value!=$this->_name)
  1365.                 {
  1366.                         if ($this->owner!=null)
  1367.                         {
  1368.                                 if (!$this->owner->classNameIs('application'))
  1369.                                 {
  1370.                                         $owner=$this->owner;
  1371.                                         reset($owner->components->items);
  1372.                                         while (list($k,$v)=each($owner->components->items))
  1373.                                         {
  1374.                                                 if (strtolower($v->Name)==strtolower($value))
  1375.                                                 {
  1376.                                                         throw new ENameDuplicated($value);
  1377.                                                 }
  1378.                                         }
  1379.                                         $this->_name=$value;
  1380.                                 }
  1381.                                 else $this->_name=$value;
  1382.                         }
  1383.                         else $this->_name=$value;
  1384.                 }
  1385.         }
  1386.         function defaultName(return("")}
  1387.  
  1388.         /**
  1389.         * A versatily property of every Component that can be used in any way you want
  1390.         * @return mixed 
  1391.         */
  1392.         function getTag(return $this->_tag}
  1393.         function setTag($value$this->_tag=$value}
  1394.         function defaultTag(return 0}
  1395. }
  1396.  
  1397. ?>

Documentation generated on Tue, 27 Mar 2007 13:33:29 +0200 by phpDocumentor 1.3.1