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-2008 qadram software S.L. <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 $use_html_entity_decode;
  33.  
  34. $use_html_entity_decode=true;
  35.  
  36. global $output_enabled;
  37.  
  38. $output_enabled=true;
  39.  
  40. global $checkduplicatenames;
  41.  
  42. $checkduplicatenames=true;
  43.  
  44. function typesafeequal($default$value)
  45. {
  46.     if ($default===$valuereturn(true);
  47.     else
  48.     {
  49.         if ($default==$value)
  50.         {
  51.                 if ((is_scalar($default)) && ($default==0&& (((is_string($value)) && ($value=="0")) || ((is_bool($value)) && ($value==false)))) return(true);
  52.                 else
  53.                 if ((is_scalar($default)) && ($default!=0&& (is_string($value))) return(true);
  54.                 else
  55.                 if ((is_scalar($default)) && ($default==1&& (is_bool($value)) && ($value==true)) return(true);
  56.                 else
  57.                 {
  58.                         $temp=$default;
  59.                         $default=$value;
  60.                         $value=$temp;
  61.  
  62.                         if ((is_scalar($default)) && ($default==0&& (((is_string($value)) && ($value=="0")) || ((is_bool($value)) && ($value==false)))) return(true);
  63.                         else
  64.                         if ((is_scalar($default)) && ($default!=0&& (is_string($value))) return(true);
  65.                         else
  66.                         if ((is_scalar($default)) && ($default==1&& (is_bool($value)) && ($value==true)) return(true);
  67.                 }
  68.         }
  69.     }
  70.     return(false);
  71. }
  72.  
  73.  
  74. /**
  75.  * Component it's being loaded
  76.  *
  77.  */
  78. define('csLoading',1);
  79.  
  80. /**
  81.  * Component it's being edited on the IDE designer
  82.  *
  83.  */
  84. define('csDesigning',2);
  85.  
  86.  
  87.  //TODO: Provide a way to show this info using templates so is customizable by final users
  88.  
  89. /**
  90.  * Common exception handler for VCL for PHP applications.
  91.  *
  92.  * It provides a way to pretty format exceptions and to get an stack trace to find out where the problem is. This
  93.  * function is registered to the PHP engine using set_exception_handler and it receives exceptions as the last step
  94.  * in the exception process.
  95.  *
  96.  *
  97.  * @link http://www.php.net/manual/en/function.set-exception-handler.php
  98.  *
  99.  * @param Exception $exception Exception to raise
  100.  */
  101. function exception_handler($exception)
  102. {
  103. ?>
  104. <script type="text/javascript">
  105. function toggleLayer( whichLayer )
  106. {
  107.   var elem;
  108.   if( document.getElementById ) elem = document.getElementById( whichLayer );
  109.   else if( document.all ) elem = document.all[whichLayer];
  110.   else if( document.layers ) elem = document.layers[whichLayer];
  111.   if(elem.style.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined) elem.style.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
  112.   elem.style.display = (elem.style.display==''||elem.style.display=='block')?'none':'block';
  113. }
  114. </script>
  115. <?php
  116.         echo "<pre>";
  117.         $tolog="";
  118.         $stacktrace="";
  119.         $stacktrace.="Application raised an exception class <b>".get_class($exception)."</b> with message <b>'".$exception->getMessage()."'</b>\n";
  120.         $msg=strip_tags($stacktrace)."|";
  121.         $stack=array_reverse($exception->getTrace());
  122.         reset($stack);
  123.         $tab="";
  124.         $c="";
  125.         $stacktrace.='<a href="javascript:toggleLayer(\'callstack\');">Click for detailed information</a><div id="callstack" style="display:none;">';
  126.         while (list($k,$v)=each($stack))
  127.         {
  128.                 $stacktrace.=$tab.$c."Callstack #$k File: <b><A HREF=\"d4p://$v[file],$v[line]\">".$v['file']."</A></b> Line: <b>".$v['line']."</b>\n";
  129.                 $tolog.=$v['line']."@".$v['file'].'@'.$msg;
  130.                 $tab.="  ";
  131.                 $c="|_";
  132.         }
  133.         echo $stacktrace;
  134.         echo '</div>';
  135.         echo "</pre>";
  136.         error_log($tolog);
  137. }
  138.  
  139. function call_stack()
  140. {
  141.         echo "<pre>";
  142.         debug_print_backtrace();
  143.         echo "</pre>";
  144. }
  145.  
  146. set_exception_handler('exception_handler');
  147.  
  148. /**
  149.  * Exception thrown when a resource is not found on an xml stream
  150.  *
  151.  * This exception is thrown by the stream system when loading an XML resource and
  152.  * the file it doesn't exists or it cannot be found
  153.  *
  154.  */
  155. class EResNotFound extends Exception
  156. {
  157.         function __construct($message = null$code = 0)
  158.         {
  159.                 $message=sprintf("Resource not found [%s]"$message);
  160.  
  161.        // make sure everything is assigned properly
  162.        parent::__construct($message$code);
  163.         }
  164. }
  165.  
  166. /**
  167.  * Exception thrown when a component has the same name on the same owner
  168.  *
  169.  * This exception is usually thrown by the Name property when it detects there are
  170.  * two objects that have the same Name
  171.  *
  172.  */
  173. class ENameDuplicated extends Exception
  174. {
  175.         function __construct($message = null$code = 0)
  176.         {
  177.                 $message=sprintf("A component named %s already exists"$message);
  178.  
  179.        // make sure everything is assigned properly
  180.        parent::__construct($message$code);
  181.         }
  182. }
  183.  
  184. /**
  185.  * Exception thrown when trying to assign an object to another
  186.  *
  187.  * This exception is thrown by the assign method when is impossible to assign the objects
  188.  * you are trying to assign
  189.  */
  190. class EAssignError extends Exception
  191. {
  192.         function __construct($sourcename$classname)
  193.         {
  194.                 $message=sprintf("Cannot assign a %s to a %s"$sourcename$classname);
  195.  
  196.                // Makes sure everything is assigned properly
  197.                parent::__construct($message0);
  198.         }
  199. }
  200.  
  201. /**
  202.  * Exception thrown for Collection errors
  203.  *
  204.  * This exception is used by the Collection class when, for example, you are trying
  205.  * to access an item specifying an index out of the bounds of the collection.
  206.  *
  207.  */
  208. class ECollectionError extends Exception
  209. {
  210.         function __construct($message = null$code = 0)
  211.         {
  212.                 $message=sprintf("List index out of bounds (%s)"$message);
  213.  
  214.        // Makes sure everything is assigned properly
  215.        parent::__construct($message$code);
  216.         }
  217. }
  218.  
  219. /**
  220.  * A base class that reads/writes components from/to an xml stream
  221.  *
  222.  * This is an internal class used by the streaming system to load all objects
  223.  * from an XML file. It uses the XML parser to read the file, creates the objects and
  224.  * assign property values
  225.  *
  226.  * @link http://www.php.net/manual/en/ref.xml.php
  227.  * @see Reader
  228.  *
  229.  */
  230. class Filer extends Object
  231. {
  232.         protected $_xmlparser;
  233.         protected $_root;
  234.         protected $_lastread;
  235.         protected $_parents;
  236.         protected $_properties;
  237.         protected $_lastproperty;
  238.         protected $_rootvars;
  239.         public $createobjects=true;
  240.  
  241.  
  242.         /**
  243.          * Initializes the object by setting up a list of parents and the xml parser used to read/write components
  244.          * @param xmlparser $xmlparser xml parser to read/write components
  245.          */
  246.         function __construct($xmlparser)
  247.         {
  248.                 //List of parents to provide a stack
  249.                 $this->_parents=new Collection();
  250.  
  251.                 //TODO: Develop a TStringList class
  252.                 $this->_properties=array();
  253.  
  254.                 //Root members, to initialize them with the right components
  255.                 $this->_rootvars=array();
  256.  
  257.                 //Last component read
  258.                 $this->_lastread=null;
  259.  
  260.  
  261.                 //Last property read
  262.                 $this->_lastproperty=null;
  263.  
  264.                 //The xml parser
  265.                 $this->_xmlparser=$xmlparser;
  266.                 xml_set_object($this->_xmlparser$this);
  267.                 xml_set_element_handler($this->_xmlparser"tagOpen""tagClose");
  268.                 xml_set_character_data_handler($this->_xmlparser"cData");
  269.    }
  270.  
  271.         /**
  272.          * Processes the opening tags to select which action to take
  273.          *
  274.          * @param xmlparser $parser xml parser in use
  275.          * @param string    $tag    opening tag
  276.          * @param array     $attributes attributes of the opening tag
  277.          *
  278.          * @see cData(), tagClose(), Component::readControlState()
  279.          *
  280.          * @link http://www.php.net/manual/en/ref.xml.php
  281.          */
  282.         function tagOpen($parser$tag$attributes)
  283.         {
  284.                 switch ($tag)
  285.                 {
  286.                         case 'OBJECT'//Reads object parameters
  287.                         $new=true;
  288.  
  289.                         //Class and name for that component
  290.                         $class=$attributes['CLASS'];
  291.                         $name=$attributes['NAME'];
  292.  
  293.                         //If there is a root component and it has not been read yet
  294.                         if ((is_object($this->_root)) && (!is_object($this->_lastread)))
  295.                         {
  296.                                 //And the class being read matches
  297.                                 if (($this->_root->classNameIs($class)) || ($this->_root->inheritsFrom($class)))
  298.                                 {
  299.                                         //Reads the root properties and sets the lastread to the root
  300.                                         $new=false;
  301.                                         $this->_lastread=$this->_root;
  302.                                         $this->_lastread->Name=$name;
  303.  
  304.                                 }
  305.                         }
  306.  
  307.                         //Creates a new object of the class just read
  308.                         if ($new)
  309.                         {
  310.                                 //If that class has been declared somewhere
  311.                                 if (class_exists($class))
  312.                                 {
  313.                                         $this->_lastread=null;
  314.  
  315.                                         //Creates a new instance of that class
  316.                                         if ($this->createobjects)
  317.                                         {
  318.                                                 $this->_lastread=new $class($this->_root);
  319.  
  320.                                                 //Gets the correct reference to the newly created component
  321.                                                 $this->_lastread=$this->_root->components->items[count($this->_root->components->items)-1];
  322.                                         }
  323.                                         else
  324.                                         {
  325.                                                 if (array_key_exists($name,$this->_rootvars))
  326.                                                 {
  327.                                                         $this->_lastread=$this->_rootvars[$name];
  328.                                                 }
  329.                                                 else
  330.                                                 {
  331.                                                         echo "Error reading language resource file, object ($name) not found";
  332.                                                 }
  333.                                         }
  334.  
  335.                                         $this->_lastread->ControlState=csLoading;
  336.                                         $this->_lastread->Name=$name;
  337.  
  338.  
  339.                                         //Finds the member of the root object and sets the reference
  340.                                         if (array_key_exists($name,$this->_rootvars))
  341.                                         {
  342.                                                 $this->_root->$name=$this->_lastread;
  343.                                         }
  344.                                         //TODO: Decide to dump here an error or not
  345.  
  346.                                         //Sets the parent
  347.                                         if ($this->_lastread->inheritsfrom("Control"))
  348.                                         {
  349.                                                 $this->_lastread->Parent=$this->_parents->items[count($this->_parents->items)-1];
  350.                                         }
  351.  
  352.                                         //Pushes it onto the stack
  353.                                         $this->_parents->add($this->_lastread);
  354.                                 }
  355.                                 else
  356.                                 {
  357.                                         //TODO: Change this by an exception when possible, there's a bug in PHP 5, because the exception is raised inside an xml reader
  358.                                         echo "Error reading resource file, class ($class) doesn't exists";
  359.                                         //Throws new EResNotFound("Error reading resource file, class ($class) doesn't exists");
  360.                                 }
  361.                         }
  362.                         break;
  363.  
  364.                         case 'PROPERTY':
  365.                         $new=true;
  366.                         $name=$attributes['NAME'];
  367.  
  368.                         //If reading a property, must be inside an object
  369.                         if (!is_object($this->_lastread))
  370.                         {
  371.                                 echo "Error reading resource file, property ($name) doesn't have an object to assign to";
  372.                         }
  373.                         else
  374.                         {
  375.                                 $this->_lastproperty=$name;
  376.                                 $this->_properties[]=$name;
  377.                         }
  378.                         break;
  379.  
  380.                         default: echo "Error reading resource file, tag ($tag) not recognized"break;
  381.                 }
  382.         }
  383.  
  384.         function VCLDecodeUnicode($orgstr)
  385.         {
  386.             if(!function_exists('mb_convert_encoding'))
  387.             {
  388.                 return $orgstr;
  389.             }
  390.  
  391.             $pattern '/&#([0-9]+);/';
  392.             preg_match_all($pattern$orgstr$matches);
  393.             $size count($matches[0]);
  394.             if$size <= 0 )
  395.             {
  396.               return $orgstr;
  397.             }
  398.  
  399.             $rep_tbl = array();
  400.             for($i = 0$i $size$i++)
  401.             {
  402.               $dec_val intval($matches[1][$i])// &#yyyyy; -> yyyyy
  403.               $utf8_str '';
  404.               if$dec_val >= 0x0001 && $dec_val <= 0x007F )
  405.               {
  406.                 $utf8_str .= chr($dec_val);
  407.               }
  408.               else
  409.               {
  410.                 if$dec_val > 0x07FF )
  411.                 {
  412.                   $utf8_str .= chr(0xE0 | (($dec_val >> 120x0F));
  413.                   $utf8_str .= chr(0x80 | (($dec_val >>  60x3F));
  414.                   $utf8_str .= chr(0x80 | (($dec_val >>  00x3F));
  415.                 }
  416.                 else
  417.                 {
  418.                   $utf8_str .= chr(0xC0 | (($dec_val >>  60x1F));
  419.                   $utf8_str .= chr(0x80 | (($dec_val >>  00x3F));
  420.                 }
  421.               }
  422.             $rep_tbl[$matches[0][$i]] $utf8_str;
  423.           }
  424.           $nwestr strtr($orgstr$rep_tbl);
  425.           $internal_str mb_convert_encoding($nwestrmb_internal_encoding()'UTF-8');
  426.           return $internal_str;
  427.         }
  428.  
  429.         /**
  430.          * Processes the data for tags
  431.          * @param xmlparser $parser xml parser in use
  432.          * @param string $cdata data to be processed
  433.          *
  434.          * @see tagOpen(), tagClose(), $use_html_entity_decode, safeunserialize()
  435.          *
  436.          * @link http://www.php.net/manual/en/ref.xml.php
  437.          */
  438.         function cData($parser$cdata)
  439.         {
  440.                 global $use_html_entity_decode;
  441.  
  442.                 if ($use_html_entity_decode && strpos$cdata'&' !== false{$cdata=html_entity_decode($cdata)$cdata $this->VCLDecodeUnicode($cdata)}
  443.  
  444.                 //Check if there is an object and a property
  445.                 if ((is_object($this->_lastread)) && ($this->_lastproperty!=null))
  446.                 {
  447.                         $aroot=$this->_lastread;
  448.                         $aproperty=$this->_lastproperty;
  449.  
  450.                         if (count($this->_properties)>1)
  451.                         {
  452.                                 reset($this->_properties);
  453.  
  454.                                 while (list($k,$v)=each($this->_properties))
  455.                                 {
  456.                                         if ($v==$this->_lastproperty)
  457.                                         {
  458.                                                 $aproperty=$v;
  459.                                                 break;
  460.                                         }
  461.                                         else
  462.                                         {
  463.  
  464.                                                 $am='get' $v;
  465.                                                 $aroot=$aroot->$am();
  466.                                         }
  467.                                 }
  468.                         }
  469.  
  470.                                                 $isarray=false;
  471.                         //Getter
  472.                         $method='get'.$aproperty;
  473.                         //If there is a getter
  474.                         if ($aroot->methodExists($method))
  475.                         {
  476.                                         $value=$aroot->$method();
  477.                                         $isarray=is_array($value);
  478.  
  479.                         }
  480.  
  481.                         //Setter
  482.                         $method='set'.$aproperty;
  483.  
  484.  
  485.                         //If there is a setter
  486.                         if ($aroot->methodExists($method))
  487.                         {
  488.                                 //Sets the property
  489.                                 $value=$cdata;
  490.  
  491.                                 if ($isarray)
  492.                                 {
  493.                                         $value=safeunserialize($value);
  494.                                 }
  495.  
  496.                                 $aroot->$method($value);
  497.  
  498.                         }
  499.                         else
  500.                         {
  501.                                 if (($aroot->inheritsFrom('Component')) && (!$aroot->inheritsFrom('Control')) && ($aproperty=='Left'))
  502.                                 {
  503.  
  504.                                 }
  505.                                 else if (($aroot->inheritsFrom('Component')) && (!$aroot->inheritsFrom('Control')) && ($aproperty=='Top'))
  506.                                 {
  507.  
  508.                                 }
  509.                                 else echo "Error setting property (".$aroot->className()."::$this->_lastproperty), doesn't exists";
  510.                         }
  511.                 }
  512.         }
  513.  
  514.         /**
  515.          * Processes tag closing
  516.          * @param xmlparser $parser xml parser in use
  517.          * @param string $tag tag being closed
  518.          *
  519.          * @link http://www.php.net/manual/en/ref.xml.php
  520.          *
  521.          * @see cData(), tagOpen(), Component::readControlState(), Persistent::unserialize(), Component::loaded(), Component::preinit(), Component::init()
  522.          *
  523.          */
  524.         function tagClose($parser$tag)
  525.         {
  526.                 switch($tag)
  527.                 {
  528.                         case 'PROPERTY':
  529.                             // Pops last array element
  530.                             array_pop($this->_properties);
  531.                             $this->_lastproperty=null;
  532.                             break;
  533.                         case 'OBJECT':
  534.                                 //Pops the parent from the stack
  535.                                 $this->_parents->delete(count($this->_parents->items)-1);
  536.  
  537.  
  538.                                 //Calls the last read component
  539.                                 //TODO: Check if the last item from the stack is the right one to call loaded
  540.  
  541.                                 $this->_lastread->ControlState=0;
  542.  
  543.                                 if ($this->createobjects)
  544.                                 {
  545.                                 //Unserialize
  546.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule'))  || ($this->_lastread->inheritsFrom('FlexPage')))
  547.                                 {
  548.                                         $this->_lastread->unserialize();
  549.                                         $this->_lastread->unserializeChildren();
  550.                                 }
  551.  
  552.                                 //Loaded
  553.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule'))  || ($this->_lastread->inheritsFrom('FlexPage')))
  554.                                 {
  555.                                         $this->_lastread->loadedChildren();
  556.                                         $this->_lastread->loaded();
  557.                                 }
  558.  
  559.                                 //PreInit
  560.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule'))  || ($this->_lastread->inheritsFrom('FlexPage')))
  561.                                 {
  562.                                         $this->_lastread->preinit();
  563.                                 }
  564.  
  565.                                 //Init
  566.                                 if (($this->_lastread->inheritsFrom('Page')) || ($this->_lastread->inheritsFrom('DataModule'))  || ($this->_lastread->inheritsFrom('FlexPage')))
  567.                                 {
  568.                                         $this->_lastread->init();
  569.                                 }
  570.                                 }
  571.  
  572.                                 /*
  573.                                 if ($this->_root->inheritsFrom('Page'))
  574.                                 {
  575.                                         if (!$this->_root->UseAjax) $this->_lastread->loaded();
  576.                                 }
  577.                                 else
  578.                                 {
  579.                                         $this->_lastread->loaded();
  580.                                 }
  581.                                 */
  582.  
  583.                                 if (count($this->_parents->items)>=1$this->_lastread=$this->_parents->items[count($this->_parents->items)-1];
  584.                                 else $this->_lastread=null;
  585.                                 break;
  586.                 }
  587.         }
  588.  
  589.          /**
  590.          * Root component
  591.          *
  592.          * This property specifies the root component for which all read components
  593.          * are going to be owned.
  594.          *
  595.          * @return object 
  596.          */
  597.         function getRoot(return($this->_root)}
  598.         function setRoot($value)
  599.         {
  600.                 //TODO: Check here $value for null
  601.                 $this->_root=$value;
  602.                 //Gets the vars from the root object to get the pointers for the components
  603.                 $this->_rootvars=get_object_vars($this->_root);
  604.  
  605.                 //Clears parents list and sets the root as the first parent
  606.                 $this->_parents->clear();
  607.                 $this->_parents->add($this->_root);
  608.  
  609.         }
  610. }
  611.  
  612. /**
  613.  * A class for reading components from an xml stream
  614.  *
  615.  * Inherits from Filer and provides a method to start the read process which will
  616.  * create the components stored on the XML file and will assign all properties.
  617.  *
  618.  * @see Filer
  619.  * @link http://www.php.net/manual/en/function.xml-parse.php
  620.  */
  621. class Reader extends Filer
  622. {
  623.         /**
  624.          * Reads a component and all its children from a stream
  625.          * @param object $root Root component to read
  626.          * @param string $stream XML stream to read from
  627.          */
  628.         function readRootComponent($root,$stream)
  629.         {
  630.                 $this->Root=$root;
  631.  
  632.                 xml_parse($this->_xmlparser$stream);
  633.  
  634.                 $this->_root->ControlState=0;
  635.         }
  636. }
  637.  
  638. /**
  639.  * A class for storing and managing a list of objects. This class acts as a wrapper over a PHP array.
  640.  *
  641.  * Collection, which stores an array of items, is often used to maintain lists of objects. Collection introduces
  642.  * properties and methods to:
  643.  *
  644.  * Add or delete the objects in the list.
  645.  *
  646.  * Rearrange the objects in the list.
  647.  *
  648.  * Locate and access objects in the list.
  649.  *
  650.  * Sort the objects in the list.
  651.  *
  652.  * @link http://www.php.net/manual/en/ref.array.php
  653.  */
  654. class Collection extends Object
  655. {
  656.         //Items array
  657.         public $items;
  658.  
  659.         function __construct()
  660.         {
  661.                 //Initializes the array
  662.                 $this->clear();
  663.         }
  664.  
  665.          /**
  666.          * Inserts a new item at the end of the list.
  667.          *
  668.          * Call Add to insert a new object at the end of the array. Add returns
  669.          * the index of the new item, where the first item in the list has an
  670.          * index of 0.
  671.          *
  672.          * Note: Add always inserts the Item at the end of the array, even if
  673.          * the internal position pointer of the array is at another position
  674.          *
  675.          * @see delete()
  676.          *
  677.          * @param mixed $item Object to add to the list
  678.          * @return integer Number of items in the collection
  679.          */
  680.         function add($item)
  681.         {
  682.                 //Sets the array to the end
  683.                 end($this->items);
  684.  
  685.                 //Adds the item as the last one
  686.                 $this->items[]=$item;
  687.  
  688.                 return($this->count());
  689.         }
  690.  
  691.          /**
  692.          * Deletes all items from the list
  693.          *
  694.          * Call Clear to empty the array and set the Count to 0. Clear also
  695.          * frees the memory used to store the Items.
  696.          *
  697.          * @see add(), delete()
  698.          *
  699.          */
  700.         function clear()
  701.         {
  702.                 $this->items=array();
  703.         }
  704.  
  705.          /**
  706.          * Removes the item at the position given by the Index parameter.
  707.          *
  708.          * Call Delete to remove the item at a specific position from the list.
  709.          * The index is zero-based, so the first item has an Index value of 0, the second
  710.          * item has an Index value of 1, and so on. Calling Delete moves up all items in
  711.          * the array that follow the deleted item, and reduces the Count.
  712.          *
  713.          * If the item is not in the list, an ECollectionError exception is raised.
  714.          *
  715.          * @see add(), clear(), remove()
  716.          *
  717.          * @param integer $index Index of the item to delete
  718.          */
  719.         function delete($index)
  720.         {
  721.                 //Deletes the item from the array so the rest of items are reordered
  722.                 if ($index<$this->count())
  723.                 {
  724.                         array_splice($this->items$index1);
  725.                 }
  726.                 else
  727.                 {
  728.                         throw new ECollectionError($index);
  729.                 }
  730.         }
  731.  
  732.          /**
  733.          * Returns the index of the first entry in the Items array with a specified value.
  734.          *
  735.          * Call IndexOf to get the index for an item in the array. Specify the item as the Item parameter.
  736.          *
  737.          * The first item in the array has index 0, the second item has index 1, and so on. If an item is
  738.          * not in the list, IndexOf returns -1. If an item appears more than once in the array, IndexOf returns
  739.          * the index of the first appearance.
  740.          *
  741.          * @param object $item Item to find
  742.          * @return integer Index of the item or -1 if not found
  743.          */
  744.         function indexof($item)
  745.         {
  746.                 $result=-1;
  747.  
  748.                 reset($this->items);
  749.                 while (list($k,$v)=each($this->items))
  750.                 {
  751.                         if ($v===$item)
  752.                         {
  753.                                 $result=$k;
  754.                                 break;
  755.                         }
  756.                 }
  757.  
  758.                 return($result);
  759.         }
  760.  
  761.         /**
  762.          * Deletes the first reference to the Item parameter from the Items array.
  763.          *
  764.          * Call Remove to remove a specific item from the array when its index is unknown.
  765.          * The value returned is the index of the item in the array before it was removed.
  766.          * After an item is removed, all the items that follow it are moved up in index
  767.          * position and the Count is reduced by one.
  768.          *
  769.          * If the array contains more than one copy of the pointer, only the first copy is deleted.
  770.          *
  771.          * @see delete()
  772.          *
  773.          * @param object $item Item to delete from the list
  774.          * @return integer Index of the item removed or -1 if it's not found
  775.          */
  776.         function remove($item)
  777.         {
  778.                 //Finds the pointer
  779.                 $index=$this->indexof($item);
  780.  
  781.                 //Deletes the index if it exists
  782.                 if ($index>=0)
  783.                 {
  784.                         $this->delete($index);
  785.                 }
  786.  
  787.                 return($index);
  788.         }
  789.  
  790.         /**
  791.          * Indicates the number of entries in the list that are in use
  792.          *
  793.          * Call Count to determine the number of entries in the Items array.
  794.          *
  795.          * @see $items
  796.          *
  797.          * @return integer 
  798.          */
  799.         function count()
  800.         {
  801.                 return(count($this->items));
  802.         }
  803.  
  804.          /**
  805.          * Returns the last element from the collection.
  806.          *
  807.          * Call this method to get the last item added to the list, if the list is empty,
  808.          * this method returns null
  809.          *
  810.          * @see $items
  811.          *
  812.          * @return object 
  813.          */
  814.         function last()
  815.         {
  816.                 if ($this->count()>=1)
  817.                 {
  818.                         return($this->items[count($this->items)-1]);
  819.                 }
  820.                 else
  821.                 {
  822.                         return(null);
  823.                 }
  824.         }
  825.  
  826. }
  827.  
  828. global $methodCache;
  829.  
  830. $methodCache = array();
  831.  
  832. /**
  833.  * A base class for persistent objects which are the ones which provide the required
  834.  * features to be serialized/unserialized easily.
  835.  *
  836.  * If you want to create a component that has persistance capabilities, you can inherit
  837.  * from this class to get all the mecanisms you need. The internal session handling uses
  838.  * properties and methods found on this class to serialize/unserialize components to the session
  839.  * and recover application state.
  840.  *
  841.  * @see serialize(), unserialize()
  842.  *
  843.  */
  844. class Persistent extends Object
  845. {
  846.                 /**
  847.                  * Used to serialize/unserialize. It returns the full path to identify this component.
  848.                  *
  849.                  * @see className(), serialize(), unserialize()
  850.                  *
  851.                  * @return string 
  852.                  */
  853.         function readNamePath()
  854.         {
  855.                 $result=$this->className();
  856.  
  857.                 if ($this->readOwner()!=null)
  858.                 {
  859.                         $s=$this->readOwner()->readNamePath();
  860.  
  861.                         if ($s!=""$result $s "." $result;
  862.  
  863.                 }
  864.  
  865.                 return($result);
  866.         }
  867.  
  868.         /**
  869.         * Owner of the component.
  870.         *
  871.         * In Persistent, it always returns null. In Component,
  872.         * it returns the owner of the component if assigned.
  873.         *
  874.         * @return Component 
  875.         */
  876.         function readOwner()
  877.         {
  878.                 return(null);
  879.         }
  880.  
  881.         /**
  882.          * Assigns the source properties to this object.
  883.          *
  884.          * This method calls the assignTo method of the source component. If
  885.          * $source is null, an assign error is raised.
  886.          *
  887.          * @see assignTo(), assignError()
  888.          *
  889.          * @param Persistent $source Object to get assigned to this object
  890.          */
  891.         function assign($source)
  892.         {
  893.                 if ($source!=null$source->assignTo($this);
  894.                 else $this->assignError(null);
  895.         }
  896.  
  897.         /**
  898.          * Assigns this object to another object.
  899.          *
  900.          * Override this method to implement the code required to copy one object
  901.          * instance into this one.
  902.          *
  903.          * @see assign(), assignError()
  904.          *
  905.          * @param Persistent $dest Object to assign this object to
  906.          */
  907.         function assignTo($dest)
  908.         {
  909.                 $dest->assignError($this);
  910.         }
  911.  
  912.         /**
  913.          * Raises an assignation error.
  914.          *
  915.          * $source can be null, but if not, the class name will be used to show
  916.          * the error and give the user more info.
  917.          *
  918.          * @see assign(), assignTo()
  919.          *
  920.          * @param Persistent $source Component tried to assign
  921.          */
  922.         function assignError($source)
  923.         {
  924.                 if ($source!=null$sourcename=$source->className();
  925.                 else $sourcename='null';
  926.  
  927.                 throw new EAssignError($sourcename,$this->className());
  928.         }
  929.  
  930.         /**
  931.          * Stores this object into the session.
  932.          *
  933.          * It uses PHP reflection
  934.          * to get the published properties that will be stored. Component
  935.          * persistance is achieved by iterating through all published properties
  936.          * (the ones starting with get) and storing that value into the session.
  937.          *
  938.          * Those values are retrieved at the right time to recover the component
  939.          * state.
  940.          *
  941.          * To be serialized, components need an owner to be unique on the session array.
  942.          * If an owner is not assigned, an exception will be raised.
  943.          *
  944.          * @see readOwner(), readNamePath()
  945.          * @link http://www.php.net/manual/en/language.oop5.reflection.php
  946.          * @link http://www.php.net/manual/en/ref.session.php
  947.          *
  948.          */
  949.         function serialize()
  950.         {
  951.                 $owner=$this->readOwner();
  952.  
  953.         if ($owner!=null)
  954.         {
  955.  
  956.                 $_SESSION['insession.'.$this->readNamePath()]=1;
  957.  
  958.                 $refclass=new ReflectionClass($this->ClassName());
  959.                 $methods=$refclass->getMethods();
  960.  
  961.                 reset($methods);
  962.  
  963.                 while (list($k,$method)=each($methods))
  964.                 {
  965.                         $methodname=$method->name;
  966.                         if ($methodname[0== 's' && $methodname[1== 'e' && $methodname[2== 't')   // fast check of: substr($methodname,0,3)=='set'
  967.                         {
  968.                                 $propname=substr($methodname3);
  969.  
  970.                                 if($propname=='Name')
  971.                                     $propvalue $this->_name;
  972.                                 else
  973.                                     $propvalue=$this->$propname;
  974.  
  975.                                 if (is_object($propvalue))
  976.                                 {
  977.                                     if ($propvalue->inheritsFrom('Component'))
  978.                                     {
  979.                                         $apropvalue='';
  980.                                         $aowner=$propvalue->readOwner();
  981.                                         if ($aowner!=null$apropvalue=$aowner->getName().'.';
  982.                                         $apropvalue.=$propvalue->getName();
  983.                                         $propvalue=$apropvalue;
  984.                                     }
  985.                                     else if ($propvalue->inheritsFrom('Persistent'))
  986.                                     {
  987.                                        $propvalue->serialize();
  988.                                     }
  989.                                 }
  990.  
  991.                                 if ((!is_object($propvalue))  && ($this->allowserialize($propname)))
  992.                                 {
  993.                                         $defmethod='default'.$propname;
  994.  
  995.                                         if (method_exists($this,$defmethod))
  996.                                         {
  997.                                             $defvalue=$this->$defmethod();
  998.  
  999.                                             if (typesafeequal($defvalue,$propvalue))
  1000.                                             {
  1001.                                                 unset($_SESSION[$this->readNamePath().".".$propname]);
  1002.                                                 continue;
  1003.                                             }
  1004.                                         }
  1005.  
  1006.                                         //TODO: Optimize this
  1007.                                         $_SESSION[$this->readNamePath().".".$propname]=$propvalue;
  1008.                                 }
  1009.                         }
  1010.                 }
  1011.  
  1012.                 if ($this->inheritsFrom('Component')) $this->serializeChildren();
  1013.         }
  1014.         else
  1015.         {
  1016.                 global $exceptions_enabled;
  1017.  
  1018.                 if ($exceptions_enabled)
  1019.                 {
  1020.                         throw new Exception('Cannot serialize a component without an owner');
  1021.                 }
  1022.         }
  1023.   }
  1024.  
  1025.   /**
  1026.   * This method provides an opportunity for the component developer to prevent the
  1027.   * serialization/unserialization of a property.
  1028.   *
  1029.   * Override the filter $propname, and return false if you do not want to allow a
  1030.   * property to be serialized.
  1031.   *
  1032.   * @see serialize()
  1033.   *
  1034.   * @param string $propname Name of the property
  1035.   * @return boolean True if the property can be serialized
  1036.   */
  1037.   function allowserialize($propname)
  1038.   {
  1039.     return(true);
  1040.   }
  1041.  
  1042.   /**
  1043.   * This method determines if this object exists in the current session.
  1044.   *
  1045.   * @see serialize(), readOwner(), readNamePath()
  1046.   *
  1047.   * @return boolean True if the component exists in the session
  1048.   */
  1049.   function inSession($name)
  1050.   {
  1051.     return(isset($_SESSION['insession.'.$this->readNamePath()]));
  1052.   }
  1053.  
  1054.   /**
  1055.    * This method uses PHP reflection to iterate through published properties
  1056.    * (the ones starting with get) and retrieve the properties stored by a previous serialize() call.
  1057.    *
  1058.    * To be unserialized, components need the owner to be unique on the session array.
  1059.    * If the owner is notassigned, an exception will be raised.
  1060.    *
  1061.    *
  1062.    * @see serialize(), readOwner(), readNamePath(), Component::readControlState()
  1063.    * @link http://www.php.net/manual/en/language.oop5.reflection.php
  1064.    * @link http://www.php.net/manual/en/ref.session.php
  1065.    *
  1066.    */
  1067.   function unserialize()
  1068.   {
  1069.         global $methodCache;
  1070.  
  1071.         $owner=$this->readOwner();
  1072.  
  1073.         if ($owner!=null)
  1074.         {
  1075.                 if ($this->inheritsFrom('Component')) $this->ControlState=csLoading;
  1076.  
  1077.                 $myclassName $this->ClassName();
  1078.  
  1079.                 ifisset$methodCache$myclassName ) )
  1080.                 {
  1081.                     $methods $methodCache$myclassName ];
  1082.                 }
  1083.                 else
  1084.                 {
  1085.                     $refclass=new ReflectionClass$myclassName );
  1086.                     $methods=$refclass->getMethods();
  1087.  
  1088.                     $methods array_filter$methods'filterSet' );
  1089.  
  1090.                     array_walk$methods'processMethods' );
  1091.  
  1092.                     $methodCache$myclassName $methods;
  1093.                 }
  1094.  
  1095.                 $ourNamePath $this->readNamePath();
  1096.  
  1097.                 foreach$methods as $methodname )
  1098.                 {
  1099.                         $propname=substr($methodname3);
  1100.  
  1101.                         $fullname $ourNamePath '.' $propname;
  1102.                         if (isset($_SESSION[$fullname]))
  1103.                         {
  1104.                                 $this->$methodname($_SESSION[$fullname]);
  1105.                         }
  1106.                         else
  1107.                         {
  1108.                             $propname 'get' $propname;
  1109.                             $ob=$this->$propname();
  1110.                             if (is_object($ob))
  1111.                             {
  1112.                                 if ($ob->inheritsFrom('Persistent'))
  1113.                                 {
  1114.                                     $ob->unserialize();
  1115.                                 }
  1116.                             }
  1117.                         }
  1118.                 }
  1119.  
  1120.                 if ($this->inheritsFrom('Component')) $this->ControlState=0;
  1121.         }
  1122.         else
  1123.         {
  1124.                 global $exceptions_enabled;
  1125.  
  1126.                 if ($exceptions_enabled)
  1127.                 {
  1128.                         throw new Exception('Cannot unserialize a component without an owner');
  1129.                 }
  1130.         }
  1131.   }
  1132. }
  1133.  
  1134.  
  1135. /**
  1136.  * Component is the common ancestor of all component classes.
  1137.  *
  1138.  * A base class for components that provides owner relationship properties and
  1139.  * basic methods for calling events.
  1140.  *
  1141.  * Non-visible components must inherit from Component and not from Control. The
  1142.  * IDE automatically handles the component as iconic.
  1143.  *
  1144.  * Components are persistent objects that have the following capabilities:
  1145.  *
  1146.  * IDE integration. The ability to appear on an IDE palette and be manipulated in a form designer.
  1147.  *
  1148.  * Ownership. The ability to manage other components. If component A owns component B, then A is responsible
  1149.  * for destroying B when A is destroyed.
  1150.  *
  1151.  * Streaming and filing. Enhancements of the persistence features inherited from Persistent.
  1152.  *
  1153.  * Component does not provide any user interface or display features. These features are provided by
  1154.  * two classes that directly descend from Control.
  1155.  *
  1156.  * Control, in the controls.inc.php unit, is the base class for "visual" components in visual applications.
  1157.  *
  1158.  * Components that can be visible at runtime are sometimes called "visual components". Other components, which are never
  1159.  * visible at runtime, are sometimes called "non-visual components". However it is more common to refer to "visual components" as
  1160.  * "controls" and "non-visual components" simply as "components."
  1161.  *
  1162.  * Do not create instances of Component. Use Component as a base class when declaring non-visual components that
  1163.  * can appear on the component palette and be used in the form designer. Properties and methods of Component
  1164.  * provide basic behavior that descendant classes inherit as well as behavior that components can override to
  1165.  * customize their behavior.
  1166.  *
  1167.  * @see Persistent
  1168.  */
  1169. class Component extends Persistent
  1170. {
  1171.         public $owner;
  1172.         public $components;
  1173.         public $_name;
  1174.         public $lastresourceread="";
  1175.         public $reallastresourceread=array();
  1176.         public $alreadycreated=false;
  1177.         public $_controlstate=0;
  1178.  
  1179.         public $_childnames = array();
  1180.  
  1181.         public $_tag=0;
  1182.  
  1183.         protected $_namepath = '';
  1184.  
  1185.         /**
  1186.         * Component constructor
  1187.         *
  1188.         * It creates the component and set $aowner as the Owner of the component,
  1189.         * it also creates the Collection to hold components owned by this component
  1190.         *
  1191.         * @see $components, readOwner(), insertComponent()
  1192.         *
  1193.         * @param object $aowner The owner of this component
  1194.         */
  1195.         function __construct($aowner=null)
  1196.         {
  1197.                 //Calls the inherited constructor
  1198.                 parent::__construct($aowner);
  1199.  
  1200.                 //List of children
  1201.                 $this->components=new Collection();
  1202.  
  1203.                 //Initializes the owner
  1204.                 $this->owner=null;
  1205.  
  1206.                 //Initializes the name
  1207.                 $this->_name="";
  1208.  
  1209.                 $this->_controlstate=0;
  1210.  
  1211.                 if ($aowner!=null)
  1212.                 {
  1213.                         //If there is an owner
  1214.                         if (is_object($aowner))
  1215.                         {
  1216.                                 //Stores it
  1217.                                 $this->owner=$aowner;
  1218.  
  1219.                                 //Adds itself to the list of components from the owner
  1220.                                 $this->owner->insertComponent($this);
  1221.                         }
  1222.                         else
  1223.                         {
  1224.                                 throw new Exception("Owner must be an object");
  1225.                         }
  1226.                 }
  1227.  
  1228.         }
  1229.  
  1230.         /**
  1231.         * Initializes the component after the form file has been read into memory.
  1232.         *
  1233.         * Do not call the Loaded method. The streaming system calls this method after it
  1234.         * loads the component’s form from a stream.
  1235.         *
  1236.         * When the streaming system loads a form or data module from its form file,
  1237.         * it first constructs the form component by calling its constructor, then reads
  1238.         * its property values from the form file. After reading all the property values
  1239.         * for all the components, the streaming system calls the Loaded methods of each
  1240.         * component in the order the components were created. This gives the components a
  1241.         * chance to initialize any data that depends on the values of other components or
  1242.         * other parts of itself.
  1243.         *
  1244.         * Note: All references to sibling components are resolved by the time Loaded is called.
  1245.         * Loaded is the first place that sibling pointers can be used after being streamed in.
  1246.         *
  1247.         * As for the reading operation, the reader sets the ComponentState in csLoading
  1248.         *
  1249.         * Warning: Loaded may be called multiple times on inherited forms. It is called every time
  1250.         * a level of inheritance is streamed in.
  1251.         *
  1252.         * @see init(), preinit(), loadedChildren()
  1253.         *
  1254.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Execution_Order
  1255.         *
  1256.         */
  1257.         function loaded()
  1258.         {
  1259.  
  1260.         }
  1261.  
  1262.         /**
  1263.          * Calls childrens loaded
  1264.          *
  1265.          * This method iterates all children and call loaded for each of them.
  1266.          * The list used for children is the Components property.
  1267.          *
  1268.          * @see $components, loaded()
  1269.          *
  1270.          */
  1271.         function loadedChildren()
  1272.         {
  1273.                 //Calls childrens loaded recursively
  1274.                 reset($this->components->items);
  1275.                 while (list($k,$v)=each($this->components->items))
  1276.                 {
  1277.                         $v->loaded();
  1278.                 }
  1279.         }
  1280.  
  1281.         /**
  1282.         * Provides accessibility info to the embedded RPC engine.
  1283.         *
  1284.         * Override this method to provide accessibility info for the RPC engine.
  1285.         * If you use RPC in your component, you can override this method to provide
  1286.         * the RPC engine with the accesibility information on the methods you want to publish.
  1287.         *
  1288.         * This is required to prevent remote execution of methods.
  1289.         *
  1290.         * @see DBGrid::UpdateRow()
  1291.         *
  1292.         * @param string $method Name of the method to check accessibility
  1293.         * @param integer $defaccessibility Default accesibility if method is not found
  1294.         * @return integer Accesibility level
  1295.         */
  1296.         function readAccessibility($method$defaccessibility)
  1297.         {
  1298.                 use_unit("rpc/rpc.inc.php");
  1299.                 return(Accessibility_Fail);
  1300.         }
  1301.  
  1302.         /**
  1303.          * Dumps javascript code for an event
  1304.          *
  1305.          * This method dumps a javascript named $event. This function is called when generating the
  1306.          * page code in the header to create all the functions to hold the javascript code
  1307.          * written by the user.
  1308.          *
  1309.          * This method is interesting for you if you are a component developer, as you can use it
  1310.          * to generate javascript code for an event
  1311.          *
  1312.          * @param string $event Name of the event you want to generate
  1313.          */
  1314.         function dumpJSEvent($event)
  1315.         {
  1316.                 if ($event!=null)
  1317.                 {
  1318.                         if ($this->owner!=null)
  1319.                         {
  1320.                         if (!defined($this->owner->Name.'_'.$event))
  1321.                         {
  1322.                                 define($this->owner->Name.'_'.$event,1);
  1323.                                 echo "function $event(event)\n";
  1324.                                 echo "{\n\n";
  1325.                                 echo "var event = event || window.event;\n";            //To get the right event object
  1326.                                 echo "var params=null;\n";                               //For Ajax calls
  1327.  
  1328.                                 if ($this->inheritsFrom('CustomPage'))
  1329.                                 {
  1330.                                     $this->$event($thisarray());
  1331.                                 }
  1332.                                 else
  1333.                                 {
  1334.                                     if ($this->owner!=null$this->owner->$event($thisarray());
  1335.                                 }
  1336.                                 echo "\n}\n";
  1337.                                 echo "\n";
  1338.                         }
  1339.                         }
  1340.                 }
  1341.         }
  1342.  
  1343.  
  1344.         /**
  1345.         * Resolves the right reference to an object property
  1346.         *
  1347.         * This method returns the right object (or the input string if object not found) for an object name.
  1348.         * Use on the loaded method for object properties to find the right reference.
  1349.         *
  1350.         * When properties are loaded from the stream, object properties are set with the Name of the component to
  1351.         * which they must link. Those properties are strings on that moment, to get the right reference to the object,
  1352.         * you can use this method to make the link.
  1353.         *
  1354.         * @param mixed $value string or object to set the property to
  1355.         *
  1356.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Adding_properties
  1357.         *
  1358.         * @see Component::readControlState(), loaded(), init()
  1359.         */
  1360.         function fixupProperty($value)
  1361.         {
  1362.                 if (($this->ControlState csDesigning)!=csDesigning)
  1363.                 {
  1364.                         if (!empty($value))
  1365.                         {
  1366.                                 if (!is_object($value))
  1367.                                 {
  1368.                                         if ($this->inheritsFrom('CustomPage')) $form=$this;
  1369.                                         else $form=$this->owner;
  1370.  
  1371.                                         if (strpos($value,'.'))
  1372.                                         {
  1373.                                                 $pieces=explode('.',$value);
  1374.                                                 if (count($pieces)==2)
  1375.                                                 {
  1376.                                                         $form=$pieces[0];
  1377.                                                         $value=$pieces[1];
  1378.                                                 }
  1379.                                                 else if (count($pieces)==3)
  1380.                                                 {
  1381.                                                         $form=$pieces[1];
  1382.                                                         $value=$pieces[2];
  1383.                                                 }
  1384.  
  1385.                                                 global $$form;
  1386.  
  1387.                                                 $form=$$form;
  1388.                                         }
  1389.                                         if (is_object($form->$value))
  1390.                                         {
  1391.                                                 $value=$form->$value;
  1392.                                         }
  1393.                                 }
  1394.                         }
  1395.                 }
  1396.                 return($value);
  1397.         }
  1398.  
  1399.         /**
  1400.          * Unserializes all children by calling unserialize for all the components
  1401.          *
  1402.          * This method iterates the components property and calls the unserialize()
  1403.          * method of each one, to recover the state of all published properties from
  1404.          * the session.
  1405.          *
  1406.          * This is used to ensure the persistance of the status of the application.
  1407.          *
  1408.          * @see unserialize()
  1409.          *
  1410.          */
  1411.         function unserializeChildren()
  1412.         {
  1413.                 reset($this->components->items);
  1414.                 while (list($k,$v)=each($this->components->items))
  1415.                 {
  1416.                         $v->unserialize();
  1417.                 }
  1418.         }
  1419.  
  1420.  
  1421.         /**
  1422.          * Calls a server event.
  1423.          *
  1424.          * This method provides you an easy way to fire an
  1425.          * event in your component and check if it is assigned.
  1426.          *
  1427.          * Example: $this->callEvent($this->_onclick, array());
  1428.          *
  1429.          * You can send any params you want the user of your component to receive.
  1430.          * This method is useful if you are a component developer and you can use it
  1431.          * to fire your server events easily, as it performs any check is needed to
  1432.          * call the right event.
  1433.          *
  1434.          * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Adding_events
  1435.          *
  1436.          * @param string $event Name of the event to call
  1437.          * @param mixed $params Parameters to send to the event handler
  1438.          * @return mixed Calling event result, if the event handler returns something
  1439.          */
  1440.         function callEvent($event,$params)
  1441.         {
  1442.                 //Prevent event executions for this component
  1443.                 if (!$this->inheritsFrom('Page'))
  1444.                 {
  1445.                   if (!acl_isallowed($this->className().'::'.$this->Name"Execute")) return;
  1446.                 }
  1447.  
  1448.                 $result=null;
  1449.                 $ievent="_".$event;
  1450.  
  1451.                 if ($this->$ievent!=null)
  1452.                 {
  1453.                         $event=$this->$ievent;
  1454.                         if (!$this->owner->classNameIs('application'))
  1455.                         {
  1456.                                 return($this->owner->$event($this,$params));
  1457.                         }
  1458.                         else return($this->$event($this,$params));
  1459.                 }
  1460.                 return($result);
  1461.         }
  1462.  
  1463.         /**
  1464.          * Returns the javascript code to generate an ajax call.
  1465.          *
  1466.          * This method returns the js event attribute to call the server using Ajax.
  1467.          * Use xajax to handle everything related to ajax. This method is useful for you if
  1468.          * you are a component developer and want to implement ajax easily in your component.
  1469.          *
  1470.          * @see ajaxCall()
  1471.          *
  1472.          * @param string $jsevent  javascript event
  1473.          * @param string $phpevent php event to call
  1474.          * @return string Event attribute to add to your tag
  1475.          */
  1476.         function generateAjaxEvent($jsevent$phpevent)
  1477.         {
  1478.                 $result=" $jsevent=\"xajax_ajaxProcess('".$this->owner->Name."','".$this->Name."',null,'$phpevent',xajax.getFormValues('".$this->owner->Name."'))\" ";
  1479.  
  1480.                 return($result);
  1481.         }
  1482.  
  1483.         //TODO: Fully implement the param exchange
  1484.         /**
  1485.          * Dumps the javascript code to make an ajax call to the server.
  1486.          *
  1487.          * Use this method in your javascript events to generate the required
  1488.          * javascript code to perform an ajax call to the server.
  1489.          *
  1490.          * By default, all components are updated after returning from the server,
  1491.          * but to save bandwidth and prevent some components to get updated if are not
  1492.          * need, you can use the $comps parameter and specify which components you want
  1493.          * to get updated.
  1494.          *
  1495.          * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Ajax_Integration#Simple_Ajax_using_xajax
  1496.          *
  1497.          * @see Page::getUseAjax(), Page::getUseAjaxDebug()
  1498.          * @example Ajax/Basic/basicajax.php How to use ajaxCall
  1499.          *
  1500.          * @param string $phpevent php event to call
  1501.          * @param array $params values to send to the server
  1502.          * @param array $comps Array with the names of the components to get updated
  1503.          * @return string Javascript code to execute to perform the ajax call
  1504.          */
  1505.         function ajaxCall($phpevent$params=array()$comps=array())
  1506.         {
  1507.                 $jcomps="";
  1508.  
  1509.                 reset($comps);
  1510.                 while(list($key$val)=each($comps))
  1511.                 {
  1512.                     if ($jcomps!=''$jcomps.=',';
  1513.                     $jcomps.='"'.$val.'"';
  1514.                 }
  1515.  
  1516.                 $jcomps="[$jcomps]";
  1517.  
  1518.                 $result =" xajax_ajaxProcess('".$this->owner->Name."','".$this->Name."',params,'$phpevent',xajax.getFormValues('".$this->owner->Name."'),$jcomps);\n ";
  1519.  
  1520.                 return($result);
  1521.         }
  1522.  
  1523.         /**
  1524.          * Method called before init()
  1525.          *
  1526.          * The streaming system calls this method before calling init() so if you need
  1527.          * to perform a process before, this is the right method to override.
  1528.          *
  1529.          * You need to know about this method only if you are a component developer
  1530.          *
  1531.          * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Ajax_Integration#Simple_Ajax_using_xajax
  1532.          * @see $components, init(), loaded()
  1533.          *
  1534.          */
  1535.         function preinit()
  1536.         {
  1537.                 //Calls children's init recursively
  1538.                 reset($this->components->items);
  1539.                 while (list($k,$v)=each($this->components->items))
  1540.                 {
  1541.                         $v->preinit();
  1542.                 }
  1543.         }
  1544.  
  1545.         /**
  1546.          * Initializes a component
  1547.          *
  1548.          * This method is the right method to override if you want to fire events
  1549.          * after a server request, because all components have been loaded, all properties
  1550.          * have been fixed up and no output has been dump yet.
  1551.          *
  1552.          * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Ajax_Integration#Simple_Ajax_using_xajax
  1553.          * @see $components, preinit(), loaded()
  1554.          */
  1555.         function init()
  1556.         {
  1557.                 //Copy components to comps, so you can alter components properties
  1558.                 //on init() methods
  1559.                 $comps=$this->components->items;
  1560.                 //Calls children's init recursively
  1561.                 reset($comps);
  1562.                 while (list($k,$v)=each($comps))
  1563.                 {
  1564.                         $v->init();
  1565.                 }
  1566.         }
  1567.  
  1568.         /**
  1569.         * Updates the field on the dataset attached, if any
  1570.         *
  1571.         * Checks if there is any datafield attached to the component.
  1572.         * If so, sets the dataset in edit state and all the fields with
  1573.         * the appropiate values so the dataset is able to update the
  1574.         * right record.
  1575.         *
  1576.         * Properties for data-aware components must be named
  1577.         *
  1578.         * DataField
  1579.         *
  1580.         * DataSource
  1581.         *
  1582.         * This is for basic single-field data-aware controls. For more
  1583.         * complicated controls like DBGrid, each component must create
  1584.         * its own mechanism to update information in the database.
  1585.         *
  1586.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Data-aware_Controls
  1587.         * @see hasValidDataField()
  1588.         * @param mixed $value Value to use to update the DataField
  1589.         *
  1590.         *
  1591.         */
  1592.         function updateDataField($value)
  1593.         {
  1594.                 if ($this->_datafield!="")
  1595.                 {
  1596.                         if ($this->_datasource!=null)
  1597.                         {
  1598.                                 if ($this->_datasource->Dataset!=null)
  1599.                                 {
  1600.                                         //Checks for the index fields
  1601.                                         $keyfields=$this->Name."_key";
  1602.                                         $keys=$this->input->$keyfields;
  1603.                                         // Checks if the keys were posted
  1604.                                         if (is_object($keys))
  1605.                                         {
  1606.                                                 $fname=$this->DataField;
  1607.  
  1608.                                                 //Sets to Edit State
  1609.                                                 $this->_datasource->Dataset->edit();
  1610.  
  1611.  
  1612.                                                 $values=$keys->asStringArray();
  1613.  
  1614.                                                 //Sets the key values
  1615.                                                 reset($values);
  1616.                                                 while (list($k,$v)=each($values))
  1617.                                                 {
  1618.                                                         $this->_datasource->Dataset->fieldset($k,$v);
  1619.                                                 }
  1620.  
  1621.                                                 //Sets the field value
  1622.                                                 $this->_datasource->Dataset->fieldset($fname,$value);
  1623.                                         }
  1624.                                         else $this->_datasource->Dataset->fieldset($this->_datafield,$value);
  1625.                                 }
  1626.                         }
  1627.                 }
  1628.         }
  1629.  
  1630.         /**
  1631.         * Returns true if a valid data field is attached to the component
  1632.         *
  1633.         * Use this method if you want to know if there is a valid data field attached
  1634.         * to the component. For that, datafield property must be assigned, datasource must be
  1635.         * assigned also, and datasource must have a dataset assigned.
  1636.         *
  1637.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Data-aware_Controls
  1638.         *
  1639.         * @see updateDataField()
  1640.         *
  1641.         * @return boolean True if the component has a valid data field attached
  1642.         *
  1643.         */
  1644.         function hasValidDataField()
  1645.         {
  1646.                 $result=false;
  1647.  
  1648.                 if ($this->_datafield!="")
  1649.                 {
  1650.                         if ($this->_datasource!=null)
  1651.                         {
  1652.                                 if ($this->_datasource->Dataset!=null)
  1653.                                 {
  1654.                                         $result=true;
  1655.                                 }
  1656.                         }
  1657.                 }
  1658.  
  1659.                 return($result);
  1660.         }
  1661.  
  1662.         /**
  1663.         * This property returns the value of the datafield if any.
  1664.         *
  1665.         * Use this property to get the value to the attached datafield, if any.
  1666.         * If not datatafield assigned, this property returns false.
  1667.         *
  1668.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Data-aware_Controls
  1669.         *
  1670.         * @see hasValidDataField()
  1671.         *
  1672.         * @return mixed Value for the data field attached
  1673.         */
  1674.         function readDataFieldValue()
  1675.         {
  1676.                 $result=false;
  1677.                 if ($this->hasValidDataField())
  1678.                 {
  1679.                         $fname=$this->DataField;
  1680.                         $value=$this->_datasource->Dataset->fieldget($fname);
  1681.                         $result=$value;
  1682.                 }
  1683.                 return($result);
  1684.         }
  1685.  
  1686.         /**
  1687.         * Dumps hidden field values for the key record
  1688.         *
  1689.         * This function dumps out the key fields for the current row. This is useful
  1690.         * for sending information about the current register.
  1691.         *
  1692.         * Use this method when developing data-aware components to set a mark to
  1693.         * an specific register on the attached dataset. This can be useful to get those
  1694.         * values when the form is posted to the server.
  1695.         *
  1696.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Component_Writer%27s_Guide_::_Data-aware_Controls
  1697.         *
  1698.         * @see Dataset::dumpHiddenKeyFields()
  1699.         * @param boolean $force If true, hidden keys will be dumped, no matter the state of the dataset
  1700.         *
  1701.         */
  1702.         function dumpHiddenKeyFields($force=false)
  1703.         {
  1704.                 if ($this->_datasource!=null)
  1705.                 {
  1706.                         if ($this->_datasource->Dataset!=null)
  1707.                         {
  1708.                                 if (($this->_datasource->Dataset->State!=dsInsert|| ($force))
  1709.                                 {
  1710.                                     //Dumps the key values for this record so updating is possible in the future
  1711.                                     $this->_datasource->Dataset->dumpHiddenKeyFields($this->Name."_key");
  1712.                                 }
  1713.                         }
  1714.                 }
  1715.         }
  1716.  
  1717.         /**
  1718.          * Serializes all children
  1719.          *
  1720.          * This method iterates through all the children and calls serialize for each one.
  1721.          * Serializing stores published properties on the session with an specific format
  1722.          * so it can restore them on the next request, that way, recovering application state
  1723.          * and emulating desktop applications.
  1724.          *
  1725.          * @see $components, serialize()
  1726.          *
  1727.          */
  1728.         function serializeChildren()
  1729.         {
  1730.                 //Calls children's serialize recursively
  1731.                 reset($this->components->items);
  1732.                 while (list($k,$v)=each($this->components->items))
  1733.                 {
  1734.                         $v->serialize();
  1735.                 }
  1736.         }
  1737.  
  1738.         /**
  1739.          * Dumps the javascript code needed by this component
  1740.          *
  1741.          * If you write components, override this method to dump all javascript
  1742.          * required by your component to work.
  1743.          *
  1744.          * @see dumpHeaderCode()
  1745.          *
  1746.          */
  1747.         function dumpJavascript()
  1748.         {
  1749.                 //Do nothing yet
  1750.         }
  1751.  
  1752.         /**
  1753.          * Dumps header code required
  1754.          *
  1755.          * If you write components, override this method to dump all header code
  1756.          * you need to make your component work.
  1757.          *
  1758.          * @see dumpJavascript()
  1759.          *
  1760.          */
  1761.         function dumpHeaderCode()
  1762.         {
  1763.                 //Do nothing yet
  1764.         }
  1765.  
  1766.         /**
  1767.          * Dumps the javascript code for all the children
  1768.          *
  1769.          * @see $components, dumpJavascript()
  1770.          */
  1771.         function dumpChildrenJavascript()
  1772.         {
  1773.                 //Iterates through components, dumping all javascript
  1774.                 $this->dumpJavascript();
  1775.                 reset($this->components->items);
  1776.                 while (list($k,$v)=each($this->components->items))
  1777.                 {
  1778.                         if ($v->inheritsFrom('Control'))
  1779.                         {
  1780.                                 if ($v->canShow())
  1781.                                 {
  1782.                                         $v->dumpJavascript();
  1783.                                 }
  1784.                         }
  1785.                         else $v->dumpJavascript();
  1786.                 }
  1787.         }
  1788.  
  1789.         /**
  1790.          * Dumps the header code for all the children
  1791.          *
  1792.          * @see $components, dumpHeaderCode()
  1793.          * @link http://www.php.net/manual/en/ref.outcontrol.php
  1794.          *
  1795.          * @param boolean $return_contents If true, code is returned instead be dumped
  1796.          * @return string Children header code if $return_contents is true
  1797.          */
  1798.         function dumpChildrenHeaderCode($return_contents=false)
  1799.         {
  1800.                 //Iterates through components, dumping all javascript
  1801.                 reset($this->components->items);
  1802.  
  1803.                 if ($return_contentsob_start();
  1804.                 while (list($k,$v)=each($this->components->items))
  1805.                 {
  1806.                         if ($v->inheritsFrom('Control'))
  1807.                         {
  1808.                                 if ($v->canShow())
  1809.                                 {
  1810.                                         $v->dumpHeaderCode();
  1811.                                 }
  1812.                         }
  1813.                         else $v->dumpHeaderCode();
  1814.                 }
  1815.                 if ($return_contents)
  1816.                 {
  1817.                         $contents=ob_get_contents();
  1818.                         ob_end_clean();
  1819.                         return($contents);
  1820.                 }
  1821.         }
  1822.  
  1823.         /**
  1824.         * Dumps code just after the form tag, useful to dump hidden fields for
  1825.         * state retrieving for non visible components
  1826.         *
  1827.         * This method is useful for component developers and is not intended
  1828.         * to be called by an application developer.
  1829.         *
  1830.         * Component developers may override this method to provide specific code
  1831.         *
  1832.         */
  1833.         function dumpFormItems()
  1834.         {
  1835.                 //Override
  1836.         }
  1837.  
  1838.         /**
  1839.         * This method is called by the page just after dumping the starting form
  1840.         * tag.
  1841.         *
  1842.         * Provides an opportunity for a component developer to dump hidden fields
  1843.         * (or other stuff) on that section of the page. Is also used by templates
  1844.         * to get that code.
  1845.         *
  1846.         * @param boolean $return_contents If true, the form items will be returned as string
  1847.         * @return mixed If $return_contents is true, it will return a string
  1848.         */
  1849.         function dumpChildrenFormItems($return_contents=false)
  1850.         {
  1851.                 //Iterates through components, dumping all form items
  1852.                 reset($this->components->items);
  1853.  
  1854.                 if ($return_contentsob_start();
  1855.                 while (list($k,$v)=each($this->components->items))
  1856.                 {
  1857.                         if ($v->inheritsFrom('Control'))
  1858.                         {
  1859.                                 if ($v->canShow())
  1860.                                 {
  1861.                                         $v->dumpFormItems();
  1862.                                 }
  1863.                         }
  1864.                         else $v->dumpFormItems();
  1865.                 }
  1866.                 if ($return_contents)
  1867.                 {
  1868.                         $contents=ob_get_contents();
  1869.                         ob_end_clean();
  1870.                         return($contents);
  1871.                 }
  1872.         }
  1873.  
  1874.         /**
  1875.          * Loads this component from a string
  1876.          *
  1877.          * @see readFromResource()
  1878.          *
  1879.          * @param string $filename  xml file name
  1880.          * @param boolean $inherited specifies if we are going to read an inherited resource
  1881.          * @param boolean $storelastresource If true, the component stores the name of the last resource read
  1882.          */
  1883.         function loadResource($filename$inherited=false$storelastresource=true)
  1884.         {
  1885.            global $application;
  1886.  
  1887.            if (!isset($_SESSION['comps.'.$this->readNamePath()]&& !$inherited)
  1888.            {
  1889.                    if ($this->inheritsFrom('Page'))
  1890.                    {
  1891.                         if ($this->classParent()!='Page')
  1892.                         {
  1893.                                 $varname=$this->classParent();
  1894.                                 global $$varname;
  1895.                                 $baseobject=$$varname;
  1896.                                 $this->loadResource($baseobject->lastresourcereadtrue);
  1897.                         }
  1898.                    }
  1899.            }
  1900.  
  1901.            if ($storelastresource)
  1902.            {
  1903.             $this->lastresourceread=$filename;
  1904.            }
  1905.            //TODO: Check here for the path to the resource file
  1906.            //$resourcename=basename($filename);
  1907.            $resourcename=$filename;
  1908.            $l="";
  1909.  
  1910.            if ((($application->Language!='')) || (($this->inheritsFrom('Page')) && ($this->Language!='(default)')))
  1911.            {
  1912.                 $resourcename=str_replace('.php',$l.'.xml.php',$filename);
  1913.                 $this->readFromResource($resourcename);
  1914.  
  1915.                 $l=".".$application->Language;
  1916.                 $resourcename=str_replace('.php',$l.'.xml.php',$filename);
  1917.                 if (file_exists($resourcename))
  1918.                 {
  1919.                         $this->readFromResource($resourcenamefalsefalse);
  1920.                 }
  1921.            }
  1922.            else
  1923.            {
  1924.                    $resourcename=str_replace('.php',$l.'.xml.php',$resourcename);
  1925.                    $this->readFromResource($resourcename);
  1926.            }
  1927.         }
  1928.  
  1929.         /**
  1930.          * Reads a component from a resource file
  1931.          *
  1932.          * @see Reader, Filer
  1933.          *
  1934.          * @param string $filename Filename of the resource file
  1935.          * @param boolean $createobjects Specifies if create the objects found or just read properties
  1936.          */
  1937.         function readFromResource($filename=""$createobjects=true)
  1938.         {
  1939.                 $readfromfile=true;
  1940.  
  1941.                 global $application;
  1942.  
  1943.                 $path=$application->Name.'.'.$this->className();
  1944.  
  1945.                 //If there are components in the session, don't read from the resource file
  1946.                 if (isset($_SESSION['comps.'.$path]))
  1947.                 {
  1948.                         $readfromfile=false;
  1949.                 }
  1950.  
  1951.                 //Recover last resources read from the session
  1952.                 if (isset($_SESSION[$path.'._reallastresourceread']))
  1953.                 {
  1954.                         $this->reallastresourceread=$_SESSION[$path.'._reallastresourceread'];
  1955.                 }
  1956.  
  1957.                 //If there is a file to read and has not been read yet
  1958.                 if (($filename!=""&& (!in_array($filename,$this->reallastresourceread)))
  1959.                 {
  1960.                         $this->reallastresourceread[]=$filename;
  1961.                         $readfromfile=true;
  1962.                 }
  1963.  
  1964.                 if ((!$readfromfile&& (!$this->alreadycreated))
  1965.                 {
  1966.                         $this->alreadycreated=true;
  1967.                     global $checkduplicatenames;
  1968.                     $form_fields=get_object_vars($this);
  1969.  
  1970.                     $checkduplicatenames=false;
  1971.  
  1972.                     $this->Name=$this->className();
  1973.                     $components=$_SESSION['comps.'.$application->Name.'.'.$this->className()];
  1974.  
  1975.                     reset($components);
  1976.                     while(list($name$classparts)=each($components))
  1977.                     {
  1978.                         $class=$classparts[1];
  1979.                         $parent=$classparts[0];
  1980.                         $var=new $class($this);
  1981.                         //$var->setTag($name);
  1982.                         $var->setName($name);
  1983.                         if (array_key_exists($name,$form_fields)) $this->$name=$var;
  1984.                         if ($parent!='')
  1985.                         {
  1986.                             if ($parent==$this->Name$var->parent=$this;
  1987.                             else
  1988.                             {
  1989.                                 $var->parent=$var->fixupProperty($parent);
  1990.                             }
  1991.                         }
  1992.                     }
  1993.  
  1994.                     $this->unserialize();
  1995.                     $this->unserializeChildren();
  1996.                     $this->loadedChildren();
  1997.                     $this->loaded();
  1998.                     $this->preinit();
  1999.                     $this->init();
  2000.                 }
  2001.                 else
  2002.                 {
  2003.                 //Default filename
  2004.                 if ($filename==""$filename=strtolower($this->className()).".xml.php";
  2005.  
  2006.                 if ($filename!="")
  2007.                 {
  2008.                         if (file_exists($filename))
  2009.                         {
  2010.                                 //Reads the component from an xml stream
  2011.                                 $xml=xml_parser_create("UTF-8");
  2012.                                 $reader=new Reader($xml);
  2013.                                 $filelines=file($filename);
  2014.  
  2015.                                 array_shift($filelines);
  2016.                                 array_pop($filelines);
  2017.  
  2018.                                 $file=implode('',$filelines);
  2019.  
  2020.                                 $reader->createobjects=$createobjects;
  2021.  
  2022.                                 $reader->readRootComponent($this$file);
  2023.                         }
  2024.                         else
  2025.                         {
  2026.                                 global $exceptions_enabled;
  2027.  
  2028.                                 if ($exceptions_enabledthrow new EResNotFound($filename);
  2029.                         }
  2030.                 }
  2031.                 }
  2032.         }
  2033.  
  2034.          /**
  2035.          * Inserts a component into the component's collection
  2036.          *
  2037.          * @see $components, readOwner()
  2038.          *
  2039.          * @param object $acomponent Component to insert
  2040.          */
  2041.         function insertComponent($acomponent)
  2042.         {
  2043.                 //Adds a component to the components list
  2044.                 $acomponent->owner=$this;
  2045.  
  2046.                 $this->_childnames$acomponent->_name $acomponent;
  2047.  
  2048.                 $this->components->add($acomponent);
  2049.         }
  2050.  
  2051.         /**
  2052.          * Removes a component from the component's collection
  2053.          *
  2054.          * @see $components, readOwner()
  2055.          *
  2056.          * @param object $acomponent Component to remove
  2057.          */
  2058.         function removeComponent($acomponent)
  2059.         {
  2060.                 //Removes a component from the component's list
  2061.                 $this->components->remove($acomponent);
  2062.  
  2063.                 unset$this->_childnames$acomponent->_name );
  2064.         }
  2065.  
  2066.  
  2067.         /**
  2068.         * Lists all the components owned by this component.
  2069.         *
  2070.         * Use Components to access any of the components owned by this component,
  2071.         * such as the components owned by a form. The Components property is most
  2072.         * useful when referring to owned components by number rather than name.
  2073.         * It is also used internally for iterative processing of all owned components.
  2074.         *
  2075.         * Index ranges from 0 to ComponentCount minus 1.
  2076.         *
  2077.         * @see $components, readOwner()
  2078.         *
  2079.         *
  2080.         * @return Collection 
  2081.         */
  2082.         function readComponents(return $this->components}
  2083.  
  2084.         /**
  2085.         * Indicates the number of components owned by the component.
  2086.         *
  2087.         * Use ComponentCount to find or verify the number of components owned by
  2088.         * a component, or when iterating through the Components list to perform
  2089.         * some action on all owned components. ComponentCount is used internally
  2090.         * for such iterative procedures.
  2091.         *
  2092.         * Note: The ComponentCount of a component contains the same number of items
  2093.         * as in the Components list for that component, and is always 1 more than the
  2094.         * highest Components index, because the first Components index is always 0.
  2095.         *
  2096.         *
  2097.         * @see $components, readOwner()
  2098.         *
  2099.         * @return integer 
  2100.         */
  2101.         function readComponentCount(return $this->components->count()}
  2102.  
  2103.         /**
  2104.         * A flag to know the state of the control, csLoading, csDesigning
  2105.         * Example: To test if the component is rendered inside the IDE:
  2106.         * <code>
  2107.         * if (($this->ControlState & csDesigning)==csDesigning)
  2108.         * {
  2109.         *    //Write the design-time code here
  2110.         * }
  2111.         * </code>
  2112.         *
  2113.         * @return integer 
  2114.         */
  2115.         function readControlState(return $this->_controlstate}
  2116.         function writeControlState($value$this->_controlstate=$value}
  2117.  
  2118.         /**
  2119.         * Specifies the path to uniquely identify a component, qualified by the owner when required.
  2120.         *
  2121.         *
  2122.         * @see readOwner()
  2123.         *
  2124.         * @return string 
  2125.         */
  2126.         function readNamePath()
  2127.         {
  2128.                 $result='';
  2129.  
  2130.                 if ($this->Name!='')
  2131.                 {
  2132.                     $result=$this->Name;
  2133.  
  2134.                     if ($this->readOwner()!=null)
  2135.                     {
  2136.                             $s=$this->readOwner()->readNamePath();
  2137.                             if ($s!="")
  2138.                             {
  2139.                                 $result $s "." $result;
  2140.                             }
  2141.  
  2142.                     }
  2143.                 }
  2144.                 else
  2145.                 {
  2146.                     $result=$this->className();
  2147.  
  2148.                     if ($this->readOwner()!=null)
  2149.                     {
  2150.                             $s=$this->readOwner()->readNamePath();
  2151.                             if ($s!="")
  2152.                             {
  2153.                                 $result $s "." $result;
  2154.                             }
  2155.  
  2156.                     }
  2157.                 }
  2158.  
  2159.                 return($result);
  2160.  
  2161.             //return($this->_name);
  2162.         }
  2163.  
  2164.         /**
  2165.         * Indicates the component that is responsible for streaming and freeing this component.
  2166.         *
  2167.         * Use Owner to find the owner of a component. The Owner of a component is responsible
  2168.         * for two things:
  2169.         *
  2170.         *
  2171.         * The memory for the owned component is freed when its owner's memory is freed.
  2172.         * This means that when a form is destroyed, all the components on the form are also destroyed.
  2173.         *
  2174.         *
  2175.         * The Owner is responsible for loading and saving the published properties of its owned controls.
  2176.         *
  2177.         * By default, a form owns all components that are on it. In turn, the form is owned by the
  2178.         * application. Thus when the application shuts down and its memory is freed, the memory for all
  2179.         * forms (and all their owned components) is also freed. When a form is loaded into memory,
  2180.         * it loads all of the components that are on it.
  2181.         *
  2182.         *
  2183.         * The owner of a component is determined by the parameter passed to the constructor when the
  2184.         * component is created. For components created in the form designer, the form is automatically
  2185.         * assigned as the Owner.
  2186.         *
  2187.         * Warning: If a component has an Owner other than a form or data module, it will not be saved or
  2188.         * loaded with its Owner.
  2189.         *
  2190.         * @link http://www.qadram.com/vcl4php/docwiki/index.php/Developer%27s_Guide_::_Owner_Parent
  2191.         * @see readComponents(), readComponentCount()
  2192.         *
  2193.         *
  2194.         * @return Component 
  2195.         */
  2196.         function readOwner(return($this->owner)}
  2197.  
  2198.         //Published properties
  2199.  
  2200.         /**
  2201.         * Specifies the name for the component. The name is used as an identifier and should be unique.
  2202.         *
  2203.         * Use Name to change the name of a component to reflect its purpose in the current application.
  2204.         * By default, the IDE assigns sequential names based on the type of the component, such as 'Button1', 'Button2',
  2205.         * and so on.
  2206.         *
  2207.         * @see readOwner(), ENameDuplicated
  2208.         *
  2209.         * @return string 
  2210.         */
  2211.         function getName(return $this->_name}
  2212.         function setName($value)
  2213.         {
  2214.                 global $checkduplicatenames;
  2215.  
  2216.                 if ($checkduplicatenames)
  2217.                 {
  2218.                     //TODO: If there is an owner, checks that there are no other components with the same name
  2219.                     if ($value!=$this->_name)
  2220.                     {
  2221.                         if ($this->owner!=null)
  2222.                             {
  2223.                                 if (!$this->owner->classNameIs('application'))
  2224.                                     {
  2225.                                             ifisset$this->owner->_childnames$value ) )
  2226.                                                 throw new ENameDuplicated($value);
  2227.  
  2228.                                             if$this->_name )
  2229.                                                 unset$this->owner->_childnames$this->_name );
  2230.  
  2231.                                             $this->_name=$value;
  2232.                                     }
  2233.                                     else $this->_name=$value;
  2234.                             }
  2235.                             else $this->_name=$value;
  2236.                     }
  2237.                 }
  2238.                 else
  2239.                 {
  2240.                     $this->_name=$value;
  2241.                 }
  2242.  
  2243.                 if$this->owner != null )
  2244.                     $this->owner->_childnames$value $this;
  2245.         }
  2246.         f