HEX
Server: Microsoft-IIS/10.0
System: Windows NT ITPWINWEBSVR22 10.0 build 20348 (Windows Server 2022) AMD64
User: www.conferencesearch.co.uk (0)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: D:/web/itpartnership/radphp/AddToMemoV1/rpcl/classes.inc.php
<?php
/**
*  This file is part of the RPCL project
*
*  Copyright (c) 2004-2011 Embarcadero Technologies, Inc.
*
*  Checkout AUTHORS file for more information on the developers
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
*  USA
*
*/

use_unit("system.inc.php");

global $exceptions_enabled;

$exceptions_enabled=true;

global $use_html_entity_decode;

$use_html_entity_decode=true;

global $output_enabled;

$output_enabled=true;

global $checkduplicatenames;

$checkduplicatenames=true;

function typesafeequal($default, $value)
{
    if ($default===$value) return(true);
    else
    {
        if ($default==$value)
        {
                if ((is_scalar($default)) && ($default==0) && (((is_string($value)) && ($value=="0")) || ((is_bool($value)) && ($value==false)))) return(true);
                else
                if ((is_scalar($default)) && ($default!=0) && (is_string($value))) return(true);
                else
                if ((is_scalar($default)) && ($default==1) && (is_bool($value)) && ($value==true)) return(true);
                else
                {
                        $temp=$default;
                        $default=$value;
                        $value=$temp;

                        if ((is_scalar($default)) && ($default==0) && (((is_string($value)) && ($value=="0")) || ((is_bool($value)) && ($value==false)))) return(true);
                        else
                        if ((is_scalar($default)) && ($default!=0) && (is_string($value))) return(true);
                        else
                        if ((is_scalar($default)) && ($default==1) && (is_bool($value)) && ($value==true)) return(true);
                }
        }
    }
    return(false);
}


/**
 * Component it's being loaded
 *
 */
define('csLoading',1);

/**
 * Component it's being edited on the IDE designer
 *
 */
define('csDesigning',2);


 //TODO: Provide a way to show this info using templates so is customizable by final users

/**
 * Common exception handler for RPCL applications.
 *
 * It provides a way to pretty format exceptions and to get an stack trace to find out where the problem is. This
 * function is registered to the PHP engine using set_exception_handler and it receives exceptions as the last step
 * in the exception process.
 *
 *
 * @link http://www.php.net/manual/en/function.set-exception-handler.php
 *
 * @param Exception $exception Exception to raise
 */
function exception_handler($exception)
{
?>
<script type="text/javascript">
function toggleLayer( whichLayer )
{
  var elem;
  if( document.getElementById ) elem = document.getElementById( whichLayer );
  else if( document.all ) elem = document.all[whichLayer];
  else if( document.layers ) elem = document.layers[whichLayer];
  if(elem.style.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined) elem.style.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'block':'none';
  elem.style.display = (elem.style.display==''||elem.style.display=='block')?'none':'block';
}
</script>
<?php
        echo "<pre>";
        $tolog="";
        $stacktrace="";
        $stacktrace.="Application raised an exception class <b>".get_class($exception)."</b> with message <b>'".$exception->getMessage()."'</b>\n";
        $msg=strip_tags($stacktrace)."|";
        $stack=array_reverse($exception->getTrace());
        reset($stack);
        $tab="";
        $c="";
        $stacktrace.='<a href="javascript:toggleLayer(\'callstack\');">Click for detailed information</a><div id="callstack" style="display:none;">';
        while (list($k,$v)=each($stack))
        {
                $stacktrace.=$tab.$c."Callstack #$k File: <b><A HREF=\"rphp://$v[file],$v[line]\">".$v['file']."</A></b> Line: <b>".$v['line']."</b>\n";
                $tolog.=$v['line']."@".$v['file'].'@'.$msg;
                $tab.="  ";
                $c="|_";
        }
        echo $stacktrace;
        echo '</div>';
        echo "</pre>";
        error_log($tolog);
}

function call_stack()
{
        echo "<pre>";
        debug_print_backtrace();
        echo "</pre>";
}

set_exception_handler('exception_handler');

/**
 * Exception thrown when a resource is not found on an xml stream
 *
 * This exception is thrown by the stream system when loading an XML resource and
 * the file it doesn't exists or it cannot be found
 *
 */
class EResNotFound extends Exception
{
        function __construct($message = null, $code = 0)
        {
                $message=sprintf("Resource not found [%s]", $message);

       // make sure everything is assigned properly
       parent::__construct($message, $code);
        }
}

/**
 * Exception thrown when a component has the same name on the same owner
 *
 * This exception is usually thrown by the Name property when it detects there are
 * two objects that have the same Name
 *
 */
class ENameDuplicated extends Exception
{
        function __construct($message = null, $code = 0)
        {
                $message=sprintf("A component named %s already exists", $message);

       // make sure everything is assigned properly
       parent::__construct($message, $code);
        }
}

/**
 * Exception thrown when trying to assign an object to another
 *
 * This exception is thrown by the assign method when is impossible to assign the objects
 * you are trying to assign
 */
class EAssignError extends Exception
{
        function __construct($sourcename, $classname)
        {
                $message=sprintf("Cannot assign a %s to a %s", $sourcename, $classname);

               // Makes sure everything is assigned properly
               parent::__construct($message, 0);
        }
}

/**
 * Exception thrown for Collection errors
 *
 * This exception is used by the Collection class when, for example, you are trying
 * to access an item specifying an index out of the bounds of the collection.
 *
 */
class ECollectionError extends Exception
{
        function __construct($message = null, $code = 0)
        {
                $message=sprintf("List index out of bounds (%s)", $message);

       // Makes sure everything is assigned properly
       parent::__construct($message, $code);
        }
}

/**
 * A base class that reads/writes components from/to an xml stream
 *
 * This is an internal class used by the streaming system to load all objects
 * from an XML file. It uses the XML parser to read the file, creates the objects and
 * assign property values
 *
 * @link http://www.php.net/manual/en/ref.xml.php
 * @see Reader
 *
 */
class Filer extends Object
{
        protected $_xmlparser;
        protected $_root;
        protected $_lastread;
        protected $_parents;
        protected $_properties;
        protected $_lastproperty;
        protected $_rootvars;
        public $createobjects=true;
        private $incdata=false;

        /**
         * Initializes the object by setting up a list of parents and the xml parser used to read/write components
         * @param xmlparser $xmlparser xml parser to read/write components
         */
        function __construct($xmlparser)
        {
                //List of parents to provide a stack
                $this->_parents=new Collection();

                //TODO: Develop a TStringList class
                $this->_properties=array();

                //Root members, to initialize them with the right components
                $this->_rootvars=array();

                //Last component read
                $this->_lastread=null;


                //Last property read
                $this->_lastproperty=null;

                //The xml parser
                $this->_xmlparser=$xmlparser;
                xml_set_object($this->_xmlparser, $this);
                xml_set_element_handler($this->_xmlparser, "tagOpen", "tagClose");
                xml_set_character_data_handler($this->_xmlparser, "cData");
   }

        /**
         * Processes the opening tags to select which action to take
         *
         * @param xmlparser $parser xml parser in use
         * @param string    $tag    opening tag
         * @param array     $attributes attributes of the opening tag
         *
         * @see cData(), tagClose(), Component::readControlState()
         *
         * @link http://www.php.net/manual/en/ref.xml.php
         */
        function tagOpen($parser, $tag, $attributes)
        {
                $this->incdata=false;
                switch ($tag)
                {
                        case 'OBJECT': //Reads object parameters
                        $new=true;

                        //Class and name for that component
                        $class=$attributes['CLASS'];
                        $name=$attributes['NAME'];

                        //If there is a root component and it has not been read yet
                        if ((is_object($this->_root)) && (!is_object($this->_lastread)))
                        {
                                //And the class being read matches
                                if (($this->_root->classNameIs($class)) || ($this->_root->inheritsFrom($class)))
                                {
                                        //Reads the root properties and sets the lastread to the root
                                        $new=false;
                                        $this->_lastread=$this->_root;
                                        $this->_lastread->Name=$name;

                                }
                        }

                        //Creates a new object of the class just read
                        if ($new)
                        {
                                //If that class has been declared somewhere
                                if (class_exists($class))
                                {
                                        $this->_lastread=null;

                                        //Creates a new instance of that class
                                        if ($this->createobjects)
                                        {
                                                $this->_lastread=new $class($this->_root);

                                                //Gets the correct reference to the newly created component
                                                $this->_lastread=$this->_root->components->items[count($this->_root->components->items)-1];
                                        }
                                        else
                                        {
                                                if (array_key_exists($name,$this->_rootvars))
                                                {
                                                        $this->_lastread=$this->_rootvars[$name];
                                                }
                                                else
                                                {
                                                        echo "Error reading language resource file, object ($name) not found";
                                                }
                                        }

                                        $this->_lastread->ControlState=csLoading;
                                        $this->_lastread->Name=$name;


                                        //Finds the member of the root object and sets the reference
                                        if (array_key_exists($name,$this->_rootvars))
                                        {
                                                $this->_root->$name=$this->_lastread;
                                        }
                                        //TODO: Decide to dump here an error or not

                                        //Sets the parent
                                        if ($this->_lastread->inheritsfrom("Control"))
                                        {
                                                $this->_lastread->Parent=$this->_parents->items[count($this->_parents->items)-1];
                                        }

                                        //Pushes it onto the stack
                                        $this->_parents->add($this->_lastread);
                                }
                                else
                                {
                                        //TODO: Change this by an exception when possible, there's a bug in PHP 5, because the exception is raised inside an xml reader
                                        echo "Error reading resource file, class ($class) doesn't exists";
                                        //Throws new EResNotFound("Error reading resource file, class ($class) doesn't exists");
                                }
                        }
                        break;

                        case 'PROPERTY':
                        $new=true;
                        $name=$attributes['NAME'];

                        //If reading a property, must be inside an object
                        if (!is_object($this->_lastread))
                        {
                                echo "Error reading resource file, property ($name) doesn't have an object to assign to";
                        }
                        else
                        {
                                $this->_lastproperty=$name;
                                $this->_properties[]=$name;
                        }
                        break;

                        default: echo "Error reading resource file, tag ($tag) not recognized"; break;
                }
        }

        function VCLDecodeUnicode($orgstr)
        {
            if(!function_exists('mb_convert_encoding'))
            {
                return $orgstr;
            }

            $pattern = '/&#([0-9]+);/';
            preg_match_all($pattern, $orgstr, $matches);
            $size = count($matches[0]);
            if( $size <= 0 )
            {
              return $orgstr;
            }

            $rep_tbl = array();
            for($i = 0; $i < $size; $i++)
            {
              $dec_val = intval($matches[1][$i]); // &#yyyyy; -> yyyyy
              $utf8_str = '';
              if( $dec_val >= 0x0001 && $dec_val <= 0x007F )
              {
                $utf8_str .= chr($dec_val);
              }
              else
              {
                if( $dec_val > 0x07FF )
                {
                  $utf8_str .= chr(0xE0 | (($dec_val >> 12) & 0x0F));
                  $utf8_str .= chr(0x80 | (($dec_val >>  6) & 0x3F));
                  $utf8_str .= chr(0x80 | (($dec_val >>  0) & 0x3F));
                }
                else
                {
                  $utf8_str .= chr(0xC0 | (($dec_val >>  6) & 0x1F));
                  $utf8_str .= chr(0x80 | (($dec_val >>  0) & 0x3F));
                }
              }
            $rep_tbl[$matches[0][$i]] = $utf8_str;
          }
          $nwestr = strtr($orgstr, $rep_tbl);
          $internal_str = mb_convert_encoding($nwestr, mb_internal_encoding(), 'UTF-8');
          return $internal_str;
        }

        /**
         * Processes the data for tags
         * @param xmlparser $parser xml parser in use
         * @param string $cdata data to be processed
         *
         * @see tagOpen(), tagClose(), $use_html_entity_decode, safeunserialize()
         *
         * @link http://www.php.net/manual/en/ref.xml.php
         */
        function cData($parser, $cdata)
        {
                global $use_html_entity_decode;

                if ($use_html_entity_decode && strpos( $cdata, '&' ) !== false) {$cdata=html_entity_decode($cdata); $cdata = $this->VCLDecodeUnicode($cdata); }

                //Check if there is an object and a property
                if ((is_object($this->_lastread)) && ($this->_lastproperty!=null))
                {
                        $aroot=$this->_lastread;
                        $aproperty=$this->_lastproperty;

                        if (count($this->_properties)>1)
                        {
                                reset($this->_properties);

                                while (list($k,$v)=each($this->_properties))
                                {
                                        if ($v==$this->_lastproperty)
                                        {
                                                $aproperty=$v;
                                                break;
                                        }
                                        else
                                        {

                                                $am='get' . $v;
                                                $aroot=$aroot->$am();
                                        }
                                }
                        }

                                                $isarray=false;
                        //Getter
                        $method='get'.$aproperty;
                        //If there is a getter
                        if ($aroot->methodExists($method))
                        {
                                        $value=$aroot->$method();
                                        $isarray=is_array($value);

                        }

                        //dData function may be called multiple times by XML parser for one segment
                        if($this->incdata!=false) {
                          $cdata = $value . $cdata;
                        }
                        $this->incdata=true;

                        //Setter
                        $method='set'.$aproperty;


                        //If there is a setter
                        if ($aroot->methodExists($method))
                        {
                                //Sets the property
                                $value=$cdata;

                                if ($isarray)
                                {
                                        $value=safeunserialize($value);
                                }

                                $aroot->$method($value);

                        }
                        else
                        {
                                if (($aroot->inheritsFrom('Component')) && (!$aroot->inheritsFrom('Control')) && ($aproperty=='Left'))
                                {

                                }
                                else if (($aroot->inheritsFrom('Component')) && (!$aroot->inheritsFrom('Control')) && ($aproperty=='Top'))
                                {

                                }
                                else $aroot->handleUndefinedProperty($this->_lastproperty,$value);
                        }
                }
        }

        /**
         * Processes tag closing
         * @param xmlparser $parser xml parser in use
         * @param string $tag tag being closed
         *
         * @link http://www.php.net/manual/en/ref.xml.php
         *
         * @see cData(), tagOpen(), Component::readControlState(), Persistent::unserialize(), Component::loaded(), Component::preinit(), Component::init()
         *
         */
        function tagClose($parser, $tag)
        {
                $this->incdata=false;
                switch($tag)
                {
                        case 'PROPERTY':
                            // Pops last array element
                            array_pop($this->_properties);
                            $this->_lastproperty=null;
                            break;
                        case 'OBJECT':
                                //Pops the parent from the stack
                                $this->_parents->delete(count($this->_parents->items)-1);


                                //Calls the last read component
                                //TODO: Check if the last item from the stack is the right one to call loaded

                                $this->_lastread->ControlState=0;

                                if ($this->createobjects)
                                {
                                //Unserialize
                                if ($this->_lastread->inheritsFrom('CustomPage'))
                                {
                                        $this->_lastread->unserialize();
                                        $this->_lastread->unserializeChildren();
                                }

                                //Loaded
                                if ($this->_lastread->inheritsFrom('CustomPage'))
                                {
                                        $this->_lastread->loadedChildren();
                                        $this->_lastread->loaded();
                                }

                                //PreInit
                                if ($this->_lastread->inheritsFrom('CustomPage'))
                                {
                                        $this->_lastread->preinit();
                                }

                                //Init
                                if ($this->_lastread->inheritsFrom('CustomPage'))
                                {
                                        $this->_lastread->init();
                                }
                                }

                                /*
                                if ($this->_root->inheritsFrom('Page'))
                                {
                                        if (!$this->_root->UseAjax) $this->_lastread->loaded();
                                }
                                else
                                {
                                        $this->_lastread->loaded();
                                }
                                */

                                if (count($this->_parents->items)>=1) $this->_lastread=$this->_parents->items[count($this->_parents->items)-1];
                                else $this->_lastread=null;
                                break;
                }
        }

         /**
         * Root component
         *
         * This property specifies the root component for which all read components
         * are going to be owned.
         *
         * @return object
         */
        function getRoot() { return($this->_root); }
        function setRoot($value)
        {
                //TODO: Check here $value for null
                $this->_root=$value;
                //Gets the vars from the root object to get the pointers for the components
                $this->_rootvars=get_object_vars($this->_root);

                //Clears parents list and sets the root as the first parent
                $this->_parents->clear();
                $this->_parents->add($this->_root);

        }
}

/**
 * A class for reading components from an xml stream
 *
 * Inherits from Filer and provides a method to start the read process which will
 * create the components stored on the XML file and will assign all properties.
 *
 * @see Filer
 * @link http://www.php.net/manual/en/function.xml-parse.php
 */
class Reader extends Filer
{
        /**
         * Reads a component and all its children from a stream
         * @param object $root Root component to read
         * @param string $stream XML stream to read from
         */
        function readRootComponent($root,$stream)
        {
                $this->Root=$root;
                xml_parse($this->_xmlparser, $stream);

                $this->_root->ControlState=0;
        }
}

/**
 * A class for storing and managing a list of objects. This class acts as a wrapper over a PHP array.
 *
 * Collection, which stores an array of items, is often used to maintain lists of objects. Collection introduces
 * properties and methods to:
 *
 * Add or delete the objects in the list.
 *
 * Rearrange the objects in the list.
 *
 * Locate and access objects in the list.
 *
 * Sort the objects in the list.
 *
 * @link http://www.php.net/manual/en/ref.array.php
 */
class Collection extends Object
{
        //Items array
        public $items;

        function __construct()
        {
                //Initializes the array
                $this->clear();
        }

         /**
         * Inserts a new item at the end of the list.
         *
         * Call Add to insert a new object at the end of the array. Add returns
         * the index of the new item, where the first item in the list has an
         * index of 0.
         *
         * Note: Add always inserts the Item at the end of the array, even if
         * the internal position pointer of the array is at another position
         *
         * @see delete()
         *
         * @param mixed $item Object to add to the list
         * @return integer Number of items in the collection
         */
        function add($item)
        {
                //Sets the array to the end
                end($this->items);

                //Adds the item as the last one
                $this->items[]=$item;

                return($this->count());
        }

         /**
         * Deletes all items from the list
         *
         * Call Clear to empty the array and set the Count to 0. Clear also
         * frees the memory used to store the Items.
         *
         * @see add(), delete()
         *
         */
        function clear()
        {
                $this->items=array();
        }

         /**
         * Removes the item at the position given by the Index parameter.
         *
         * Call Delete to remove the item at a specific position from the list.
         * The index is zero-based, so the first item has an Index value of 0, the second
         * item has an Index value of 1, and so on. Calling Delete moves up all items in
         * the array that follow the deleted item, and reduces the Count.
         *
         * If the item is not in the list, an ECollectionError exception is raised.
         *
         * @see add(), clear(), remove()
         *
         * @param integer $index Index of the item to delete
         */
        function delete($index)
        {
                //Deletes the item from the array so the rest of items are reordered
                if ($index<$this->count())
                {
                        array_splice($this->items, $index, 1);
                }
                else
                {
                        throw new ECollectionError($index);
                }
        }

         /**
         * Returns the index of the first entry in the Items array with a specified value.
         *
         * Call IndexOf to get the index for an item in the array. Specify the item as the Item parameter.
         *
         * The first item in the array has index 0, the second item has index 1, and so on. If an item is
         * not in the list, IndexOf returns -1. If an item appears more than once in the array, IndexOf returns
         * the index of the first appearance.
         *
         * @param object $item Item to find
         * @return integer Index of the item or -1 if not found
         */
        function indexof($item)
        {
                $result=-1;

                reset($this->items);
                while (list($k,$v)=each($this->items))
                {
                        if ($v===$item)
                        {
                                $result=$k;
                                break;
                        }
                }

                return($result);
        }

        /**
         * Deletes the first reference to the Item parameter from the Items array.
         *
         * Call Remove to remove a specific item from the array when its index is unknown.
         * The value returned is the index of the item in the array before it was removed.
         * After an item is removed, all the items that follow it are moved up in index
         * position and the Count is reduced by one.
         *
         * If the array contains more than one copy of the pointer, only the first copy is deleted.
         *
         * @see delete()
         *
         * @param object $item Item to delete from the list
         * @return integer Index of the item removed or -1 if it's not found
         */
        function remove($item)
        {
                //Finds the pointer
                $index=$this->indexof($item);

                //Deletes the index if it exists
                if ($index>=0)
                {
                        $this->delete($index);
                }

                return($index);
        }

        /**
         * Indicates the number of entries in the list that are in use
         *
         * Call Count to determine the number of entries in the Items array.
         *
         * @see $items
         *
         * @return integer
         */
        function count()
        {
                return(count($this->items));
        }

         /**
         * Returns the last element from the collection.
         *
         * Call this method to get the last item added to the list, if the list is empty,
         * this method returns null
         *
         * @see $items
         *
         * @return object
         */
        function last()
        {
                if ($this->count()>=1)
                {
                        return($this->items[count($this->items)-1]);
                }
                else
                {
                        return(null);
                }
        }

}

global $methodCache;

$methodCache = array();

/**
 * A base class for persistent objects which are the ones which provide the required
 * features to be serialized/unserialized easily.
 *
 * If you want to create a component that has persistance capabilities, you can inherit
 * from this class to get all the mecanisms you need. The internal session handling uses
 * properties and methods found on this class to serialize/unserialize components to the session
 * and recover application state.
 *
 * @see serialize(), unserialize()
 *
 */
class Persistent extends Object
{
                /**
                 * Used to serialize/unserialize. It returns the full path to identify this component.
                 *
                 * @see className(), serialize(), unserialize()
                 *
                 * @return string
                 */
        function readNamePath()
        {
                $result=$this->className();

                if ($this->readOwner()!=null)
                {
                        $s=$this->readOwner()->readNamePath();

                        if ($s!="") $result = $s . "." . $result;

                }

                return($result);
        }

        /**
        * Owner of the component.
        *
        * In Persistent, it always returns null. In Component,
        * it returns the owner of the component if assigned.
        *
        * @return Component
        */
        function readOwner()
        {
                return(null);
        }

        /**
         * Assigns the source properties to this object.
         *
         * This method calls the assignTo method of the source component. If
         * $source is null, an assign error is raised.
         *
         * @see assignTo(), assignError()
         *
         * @param Persistent $source Object to get assigned to this object
         */
        function assign($source)
        {
                if ($source!=null) $source->assignTo($this);
                else $this->assignError(null);
        }

        /**
         * Assigns this object to another object.
         *
         * Override this method to implement the code required to copy one object
         * instance into this one.
         *
         * @see assign(), assignError()
         *
         * @param Persistent $dest Object to assign this object to
         */
        function assignTo($dest)
        {
                $dest->assignError($this);
        }

        function handleUndefinedProperty($propname, $propvalue)
        {
          echo "Error setting property (".$this->className()."::$propname), doesn't exists";
        }

        /**
         * Raises an assignation error.
         *
         * $source can be null, but if not, the class name will be used to show
         * the error and give the user more info.
         *
         * @see assign(), assignTo()
         *
         * @param Persistent $source Component tried to assign
         */
        function assignError($source)
        {
                if ($source!=null) $sourcename=$source->className();
                else $sourcename='null';

                throw new EAssignError($sourcename,$this->className());
        }

        /*

        //get_class_vars doesn't work well in new PHP versions, for the purposes of this
        public function __sleep()
        {
          $vars=get_class_vars(get_class($this));
          $result=array();
          foreach($vars as $key=>$value)
          {
            if ($key[0]=='_')
            {
              if ($this->methodExists('set'.substr($key,1))) $result[]=$key;
            }
            if ($key=='owner') $result[]=$key;
          }
          return($result);
        }
        */

        function newserialize()
        {
          $_SESSION[$this->readNamePath()]=serialize($this);
        }

        function newunserialize($source)
        {
          $cname=get_class($this);
          $start='O:'.strlen($cname).':"'.$cname.'"';
          $source='a'.substr($source,strlen($start));
          $props=unserialize($source);

          foreach($props as $prop=>$value)
          {
            if ($prop=='owner') continue;
            $prop=str_replace(chr(0).'*'.chr(0).'_','*set',$prop);
            if ($prop[0]=='_') $method='set'.substr($prop,1);
            else $method=substr($prop,1);

            if ($this->methodExists($method))
            {
              if ((is_object($value)) && ($value->inheritsFrom('Persistent')))
              {
                if ($value->inheritsFrom('Component'))
                {
                  $propvalue=$value->_name;
                  if (is_object($value->owner))
                  {
                    if ($value->owner!=$this->owner)
                    {
                      $propvalue=$value->owner->name.'.'.$propvalue;
                    }
                  }
                  $this->$method($propvalue);
                }
                else
                {
                  $persistentprop='g'.substr($prop,2);
                  $objectproperty=$this->$persistentprop();
                  $objectproperty->assign($value);
                }
              }
              else $this->$method($value);
            }
          }
        }

        /**
         * Stores this object into the session.
         *
         * It uses PHP reflection
         * to get the published properties that will be stored. Component
         * persistance is achieved by iterating through all published properties
         * (the ones starting with get) and storing that value into the session.
         *
         * Those values are retrieved at the right time to recover the component
         * state.
         *
         * To be serialized, components need an owner to be unique on the session array.
         * If an owner is not assigned, an exception will be raised.
         *
         * @see readOwner(), readNamePath()
         * @link http://www.php.net/manual/en/language.oop5.reflection.php
         * @link http://www.php.net/manual/en/ref.session.php
         *
         */
        function serialize()
        {
                $owner=$this->readOwner();

        if ($owner!=null)
        {

                $_SESSION['insession.'.$this->readNamePath()]=1;

                //$this->newserialize();

                $refclass=new ReflectionClass($this->ClassName());
                $methods=$refclass->getMethods();

                reset($methods);

                while (list($k,$method)=each($methods))
                {
                        $methodname=$method->name;
                        if ($methodname[0] == 's' && $methodname[1] == 'e' && $methodname[2] == 't')   // fast check of: substr($methodname,0,3)=='set'
                        {
                                $propname=substr($methodname, 3);

                                if($propname=='Name')
                                    $propvalue = $this->_name;
                                else
                                    $propvalue=$this->$propname;

                                if (is_object($propvalue))
                                {
                                    if ($propvalue->inheritsFrom('Component'))
                                    {
                                        $apropvalue='';
                                        $aowner=$propvalue->readOwner();
                                        if ($aowner!=null) $apropvalue=$aowner->getName().'.';
                                        $apropvalue.=$propvalue->getName();
                                        $propvalue=$apropvalue;
                                    }
                                    else if ($propvalue->inheritsFrom('Persistent'))
                                    {
                                       $propvalue->serialize();
                                    }
                                }

                                if ((!is_object($propvalue))  && ($this->allowserialize($propname)))
                                {
                                        $defmethod='default'.$propname;

                                        if (method_exists($this,$defmethod))
                                        {
                                            $defvalue=$this->$defmethod();

                                            if (typesafeequal($defvalue,$propvalue))
                                            {
                                                unset($_SESSION[$this->readNamePath().".".$propname]);
                                                continue;
                                            }
                                        }

                                        //TODO: Optimize this
                                        $_SESSION[$this->readNamePath().".".$propname]=$propvalue;
                                }
                        }
                }


                if ($this->inheritsFrom('Component')) $this->serializeChildren();
        }
        else
        {
                global $exceptions_enabled;

                if ($exceptions_enabled)
                {
                        throw new Exception('Cannot serialize a component without an owner');
                }
        }
  }

  /**
  * This method provides an opportunity for the component developer to prevent the
  * serialization/unserialization of a property.
  *
  * Override the filter $propname, and return false if you do not want to allow a
  * property to be serialized.
  *
  * @see serialize()
  *
  * @param string $propname Name of the property
  * @return boolean True if the property can be serialized
  */
  function allowserialize($propname)
  {
    return(true);
  }

  /**
  * This method determines if this object exists in the current session.
  *
  * @see serialize(), readOwner(), readNamePath()
  *
  * @return boolean True if the component exists in the session
  */
  function inSession($name)
  {
    return(isset($_SESSION['insession.'.$this->readNamePath()]));
  }

  /**
   * This method uses PHP reflection to iterate through published properties
   * (the ones starting with get) and retrieve the properties stored by a previous serialize() call.
   *
   * To be unserialized, components need the owner to be unique on the session array.
   * If the owner is notassigned, an exception will be raised.
   *
   *
   * @see serialize(), readOwner(), readNamePath(), Component::readControlState()
   * @link http://www.php.net/manual/en/language.oop5.reflection.php
   * @link http://www.php.net/manual/en/ref.session.php
   *
   */
  function unserialize()
  {
        global $methodCache;

        $owner=$this->readOwner();

        if ($owner!=null)
        {
                if ($this->inheritsFrom('Component')) $this->ControlState=csLoading;

                $namepath=$this->readNamePath();
                //if (isset($_SESSION[$namepath])) $this->newunserialize($_SESSION[$namepath]);

                $myclassName = $this->ClassName();

                if( isset( $methodCache[ $myclassName ] ) )
                {
                    $methods = $methodCache[ $myclassName ];
                }
                else
                {
                    $refclass=new ReflectionClass( $myclassName );
                    $methods=$refclass->getMethods();

                    $methods = array_filter( $methods, 'filterSet' );

                    array_walk( $methods, 'processMethods' );

                    $methodCache[ $myclassName ] = $methods;
                }

                $ourNamePath = $this->readNamePath();

                foreach( $methods as $methodname )
                {
                        $propname=substr($methodname, 3);

                        $fullname = $ourNamePath . '.' . $propname;
                        if (isset($_SESSION[$fullname]))
                        {
                                $this->$methodname($_SESSION[$fullname]);
                        }
                        else
                        {
                            $propname = 'get' . $propname;
                            $ob=$this->$propname();
                            if (is_object($ob))
                            {
                              if ($ob->inheritsFrom('Persistent'))
                              {
                                $ob->unserialize();
                              }
                            }
                        }
                }

                if ($this->inheritsFrom('Component')) $this->ControlState=0;
        }
        else
        {
                global $exceptions_enabled;

                if ($exceptions_enabled)
                {
                        throw new Exception('Cannot unserialize a component without an owner');
                }
        }
  }
}


/**
 * Component is the common ancestor of all component classes.
 *
 * A base class for components that provides owner relationship properties and
 * basic methods for calling events.
 *
 * Non-visible components must inherit from Component and not from Control. The
 * IDE automatically handles the component as iconic.
 *
 * Components are persistent objects that have the following capabilities:
 *
 * IDE integration. The ability to appear on an IDE palette and be manipulated in a form designer.
 *
 * Ownership. The ability to manage other components. If component A owns component B, then A is responsible
 * for destroying B when A is destroyed.
 *
 * Streaming and filing. Enhancements of the persistence features inherited from Persistent.
 *
 * Component does not provide any user interface or display features. These features are provided by
 * two classes that directly descend from Control.
 *
 * Control, in the controls.inc.php unit, is the base class for "visual" components in visual applications.
 *
 * Components that can be visible at runtime are sometimes called "visual components". Other components, which are never
 * visible at runtime, are sometimes called "non-visual components". However it is more common to refer to "visual components" as
 * "controls" and "non-visual components" simply as "components."
 *
 * Do not create instances of Component. Use Component as a base class when declaring non-visual components that
 * can appear on the component palette and be used in the form designer. Properties and methods of Component
 * provide basic behavior that descendant classes inherit as well as behavior that components can override to
 * customize their behavior.
 *
 * @see Persistent
 */
class Component extends Persistent
{
        public $owner;
        public $components;
        public $_name;
        public $lastresourceread="";
        public $reallastresourceread=array();
        public $alreadycreated=false;
        public $_controlstate=0;

        public $_childnames = array();

        public $_tag=0;

        protected $_namepath = '';

        /**
        * Component constructor
        *
        * It creates the component and set $aowner as the Owner of the component,
        * it also creates the Collection to hold components owned by this component
        *
        * @see $components, readOwner(), insertComponent()
        *
        * @param object $aowner The owner of this component
        */
        function __construct($aowner=null)
        {
                //Calls the inherited constructor
                parent::__construct($aowner);

                //List of children
                $this->components=new Collection();

                //Initializes the owner
                $this->owner=null;

                //Initializes the name
                $this->_name="";

                $this->_controlstate=0;

                if ($aowner!=null)
                {
                        //If there is an owner
                        if (is_object($aowner))
                        {
                                //Stores it
                                $this->owner=$aowner;

                                //Adds itself to the list of components from the owner
                                $this->owner->insertComponent($this);
                        }
                        else
                        {
                                throw new Exception("Owner must be an object");
                        }
                }

        }

        /**
        * Initializes the component after the form file has been read into memory.
        *
        * Do not call the Loaded method. The streaming system calls this method after it
        * loads the component�s form from a stream.
        *
        * When the streaming system loads a form or data module from its form file,
        * it first constructs the form component by calling its constructor, then reads
        * its property values from the form file. After reading all the property values
        * for all the components, the streaming system calls the Loaded methods of each
        * component in the order the components were created. This gives the components a
        * chance to initialize any data that depends on the values of other components or
        * other parts of itself.
        *
        * Note: All references to sibling components are resolved by the time Loaded is called.
        * Loaded is the first place that sibling pointers can be used after being streamed in.
        *
        * As for the reading operation, the reader sets the ComponentState in csLoading
        *
        * Warning: Loaded may be called multiple times on inherited forms. It is called every time
        * a level of inheritance is streamed in.
        *
        * @see init(), preinit(), loadedChildren()
        *
        * @link wiki://Component_Writer%27s_Guide_::_Execution_Order
        *
        */
        function loaded()
        {

        }

        /**
         * Calls childrens loaded
         *
         * This method iterates all children and call loaded for each of them.
         * The list used for children is the Components property.
         *
         * @see $components, loaded()
         *
         */
        function loadedChildren()
        {
                //Calls childrens loaded recursively
                reset($this->components->items);
                while (list($k,$v)=each($this->components->items))
                {
                        $v->loaded();
                }
        }

        /**
        * Provides accessibility info to the embedded RPC engine.
        *
        * Override this method to provide accessibility info for the RPC engine.
        * If you use RPC in your component, you can override this method to provide
        * the RPC engine with the accesibility information on the methods you want to publish.
        *
        * This is required to prevent remote execution of methods.
        *
        * @see DBGrid::UpdateRow()
        *
        * @param string $method Name of the method to check accessibility
        * @param integer $defaccessibility Default accesibility if method is not found
        * @return integer Accesibility level
        */
        function readAccessibility($method, $defaccessibility)
        {
                use_unit("rpc/rpc.inc.php");
                return(Accessibility_Fail);
        }

        /**
         * Dumps javascript code for an event
         *
         * This method dumps a javascript named $event. This function is called when generating the
         * page code in the header to create all the functions to hold the javascript code
         * written by the user.
         *
         * This method is interesting for you if you are a component developer, as you can use it
         * to generate javascript code for an event
         *
         * @param string $event Name of the event you want to generate
         */
        function dumpJSEvent($event)
        {
                if ($event!=null)
                {
                        if ($this->owner!=null)
                        {
                        if (!defined($this->owner->Name.'_'.$event))
                        {
                                define($this->owner->Name.'_'.$event,1);
                                echo "function $event(event)\n";
                                echo "{\n\n";
                                echo "var event = event || window.event;\n";            //To get the right event object
                                echo "var params=null;\n";                               //For Ajax calls

                                if ($this->inheritsFrom('CustomPage'))
                                {
                                    $this->$event($this, array());
                                }
                                else
                                {
                                    if ($this->owner!=null) $this->owner->$event($this, array());
                                }
                                echo "\n}\n";
                                echo "\n";
                        }
                        }
                }
        }


        /**
        * Resolves the right reference to an object property
        *
        * This method returns the right object (or the input string if object not found) for an object name.
        * Use on the loaded method for object properties to find the right reference.
        *
        * When properties are loaded from the stream, object properties are set with the Name of the component to
        * which they must link. Those properties are strings on that moment, to get the right reference to the object,
        * you can use this method to make the link.
        *
        * @param mixed $value string or object to set the property to
        *
        * @link wiki://Component_Writer%27s_Guide_::_Adding_properties
        *
        * @see Component::readControlState(), loaded(), init()
        */
        function fixupProperty($value)
        {
                if (($this->ControlState & csDesigning)!=csDesigning)
                {
                        if (!empty($value))
                        {
                                if (!is_object($value))
                                {
                                		if ($this->inheritsFrom('CustomPage')) $form=$this;
                                     else $form=$this->owner;

                                        if (strpos($value,'.'))
                                        {
                                                $pieces=explode('.',$value);
                                                if (count($pieces)==2)
                                                {
                                                        $form=$pieces[0];
                                                        $value=$pieces[1];
                                                }
                                                else if (count($pieces)==3)
                                                {
                                                        $form=$pieces[1];
                                                        $value=$pieces[2];
                                                }

                                                global $$form;

                                                $form=$$form;
                                        }
                                        if (is_object($form->$value))
                                        {
                                                $value=$form->$value;
                                        }
                                }
                        }
                }
                return($value);
        }

        /**
         * Unserializes all children by calling unserialize for all the components
         *
         * This method iterates the components property and calls the unserialize()
         * method of each one, to recover the state of all published properties from
         * the session.
         *
         * This is used to ensure the persistance of the status of the application.
         *
         * @see unserialize()
         *
         */
        function unserializeChildren()
        {
                reset($this->components->items);
                while (list($k,$v)=each($this->components->items))
                {
                        $v->unserialize();
                }
        }


        /**
         * Calls a server event.
         *
         * This method provides you an easy way to fire an
         * event in your component and check if it is assigned.
         *
         * Example: $this->callEvent($this->_onclick, array());
         *
         * You can send any params you want the user of your component to receive.
         * This method is useful if you are a component developer and you can use it
         * to fire your server events easily, as it performs any check is needed to
         * call the right event.
         *
         * @link wiki://Component_Writer%27s_Guide_::_Adding_events
         *
         * @param string $event Name of the event to call
         * @param mixed $params Parameters to send to the event handler
         * @return mixed Calling event result, if the event handler returns something
         */
        function callEvent($event,$params)
        {
                //Prevent event executions for this component
                if (!$this->inheritsFrom('CustomPage'))
                {
                  if (!acl_isallowed($this->className().'::'.$this->Name, "Execute")) return;
                }

                $result=null;
                $ievent="_".$event;

                if ($this->$ievent!=null)
                {
                        $event=$this->$ievent;
                        if (!$this->owner->classNameIs('application'))
                        {
                                return($this->owner->$event($this,$params));
                        }
                        else return($this->$event($this,$params));
                }
                return($result);
        }

        /**
         * Returns the javascript code to generate an ajax call.
         *
         * This method returns the js event attribute to call the server using Ajax.
         * Use xajax to handle everything related to ajax. This method is useful for you if
         * you are a component developer and want to implement ajax easily in your component.
         *
         * @see ajaxCall()
         *
         * @param string $jsevent  javascript event
         * @param string $phpevent php event to call
         * @return string Event attribute to add to your tag
         */
        function generateAjaxEvent($jsevent, $phpevent)
        {
                $result=" $jsevent=\"xajax_ajaxProcess('".$this->owner->Name."','".$this->Name."',null,'$phpevent',xajax.getFormValues('".$this->owner->Name."'))\" ";

                return($result);
        }

        //TODO: Fully implement the param exchange
        /**
         * Dumps the javascript code to make an ajax call to the server.
         *
         * Use this method in your javascript events to generate the required
         * javascript code to perform an ajax call to the server.
         *
         * By default, all components are updated after returning from the server,
         * but to save bandwidth and prevent some components to get updated if are not
         * need, you can use the $comps parameter and specify which components you want
         * to get updated.
         *
         * @link wiki://Component_Writer%27s_Guide_::_Ajax_Integration#Simple_Ajax_using_xajax
         *
         * @see Page::getUseAjax(), Page::getUseAjaxDebug()
         * @example Ajax/Basic/basicajax.php How to use ajaxCall
         *
         * @param string $phpevent php event to call
         * @param array $params values to send to the server
         * @param array $comps Array with the names of the components to get updated
         * @return string Javascript code to execute to perform the ajax call
         */
        function ajaxCall($phpevent, $params=array(), $comps=array())
        {
                $jcomps="";

                reset($comps);
                while(list($key, $val)=each($comps))
                {
                    if ($jcomps!='') $jcomps.=',';
                    $jcomps.='"'.$val.'"';
                }

                $jcomps="[$jcomps]";

                $result =" xajax_ajaxProcess('".$this->owner->Name."','".$this->Name."',params,'$phpevent',xajax.getFormValues('".$this->owner->Name."'),$jcomps);\n ";

                return($result);
        }

        /**
         * Method called before init()
         *
         * The streaming system calls this method before calling init() so if you need
         * to perform a process before, this is the right method to override.
         *
         * You need to know about this method only if you are a component developer
         *
         * @link wiki://Component_Writer%27s_Guide_::_Ajax_Integration#Simple_Ajax_using_xajax
         * @see $components, init(), loaded()
         *
         */
        function preinit()
        {
                //Calls children's init recursively
                reset($this->components->items);
                while (list($k,$v)=each($this->components->items))
                {
                        $v->preinit();
                }
        }

        /**
         * Initializes a component
         *
         * This method is the right method to override if you want to fire events
         * after a server request, because all components have been loaded, all properties
         * have been fixed up and no output has been dump yet.
         *
         * @link wiki://Component_Writer%27s_Guide_::_Ajax_Integration#Simple_Ajax_using_xajax
         * @see $components, preinit(), loaded()
         */
        function init()
        {
                //Copy components to comps, so you can alter components properties
                //on init() methods
                $comps=$this->components->items;
                //Calls children's init recursively
                reset($comps);
                while (list($k,$v)=each($comps))
                {
                        $v->init();
                }
        }

        /**
        * Updates the field on the dataset attached, if any
        *
        * Checks if there is any datafield attached to the component.
        * If so, sets the dataset in edit state and all the fields with
        * the appropiate values so the dataset is able to update the
        * right record.
        *
        * Properties for data-aware components must be named
        *
        * DataField
        *
        * DataSource
        *
        * This is for basic single-field data-aware controls. For more
        * complicated controls like DBGrid, each component must create
        * its own mechanism to update information in the database.
        *
        * @link wiki://Component_Writer%27s_Guide_::_Data-aware_Controls
        * @see hasValidDataField()
        * @param mixed $value Value to use to update the DataField
        *
        *
        */
        function updateDataField($value)
        {
                if ($this->_datafield!="")
                {
                        if ($this->_datasource!=null)
                        {
                                if ($this->_datasource->Dataset!=null)
                                {
                                        //Checks for the index fields
                                        $keyfields=$this->Name."_key";
                                        $keys=$this->input->$keyfields;
                                        // Checks if the keys were posted
                                        if (is_object($keys))
                                        {
                                                $fname=$this->DataField;

                                                //Sets to Edit State
                                                $this->_datasource->Dataset->edit();


                                                $values=$keys->asStringArray();

                                                //Sets the key values
                                                reset($values);
                                                while (list($k,$v)=each($values))
                                                {
                                                        $this->_datasource->Dataset->fieldset($k,$v);
                                                }

                                                //Sets the field value
                                                $this->_datasource->Dataset->fieldset($fname,$value);
                                        }
                                        else $this->_datasource->Dataset->fieldset($this->_datafield,$value);
                                }
                        }
                }
        }

        /**
        * Returns true if a valid data field is attached to the component
        *
        * Use this method if you want to know if there is a valid data field attached
        * to the component. For that, datafield property must be assigned, datasource must be
        * assigned also, and datasource must have a dataset assigned.
        *
        * @link wiki://Component_Writer%27s_Guide_::_Data-aware_Controls
        *
        * @see updateDataField()
        *
        * @return boolean True if the component has a valid data field attached
        *
        */
        function hasValidDataField()
        {
                $result=false;

                if ($this->_datafield!="")
                {
                        if ($this->_datasource!=null)
                        {
                                if ($this->_datasource->Dataset!=null)
                                {
                                        $result=true;
                                }
                        }
                }

                return($result);
        }

        /**
        * This property returns the value of the datafield if any.
        *
        * Use this property to get the value to the attached datafield, if any.
        * If not datatafield assigned, this property returns false.
        *
        * @link wiki://Component_Writer%27s_Guide_::_Data-aware_Controls
        *
        * @see hasValidDataField()
        *
        * @return mixed Value for the data field attached
        */
        function readDataFieldValue()
        {
                $result=false;
                if ($this->hasValidDataField())
                {
                        $fname=$this->DataField;
                        $value=$this->_datasource->Dataset->fieldget($fname);
                        $result=$value;
                }
                return($result);
        }

        /**
        * Dumps hidden field values for the key record
        *
        * This function dumps out the key fields for the current row. This is useful
        * for sending information about the current register.
        *
        * Use this method when developing data-aware components to set a mark to
        * an specific register on the attached dataset. This can be useful to get those
        * values when the form is posted to the server.
        *
        * @link wiki://Component_Writer%27s_Guide_::_Data-aware_Controls
        *
        * @see Dataset::dumpHiddenKeyFields()
        * @param boolean $force If true, hidden keys will be dumped, no matter the state of the dataset
        *
        */
        function dumpHiddenKeyFields($force=false)
        {
                if ($this->_datasource!=null)
                {
                        if ($this->_datasource->Dataset!=null)
                        {
                                if (($this->_datasource->Dataset->State!=dsInsert) || ($force))
                                {
                                    //Dumps the key values for this record so updating is possible in the future
                                    $this->_datasource->Dataset->dumpHiddenKeyFields($this->Name."_key");
                                }
                        }
                }
        }

        /**
         * Serializes all children
         *
         * This method iterates through all the children and calls serialize for each one.
         * Serializing stores published properties on the session with an specific format
         * so it can restore them on the next request, that way, recovering application state
         * and emulating desktop applications.
         *
         * @see $components, serialize()
         *
         */
        function serializeChildren()
        {
                //Calls children's serialize recursively
                reset($this->components->items);
                while (list($k,$v)=each($this->components->items))
                {
                        $v->serialize();
                }
        }

        /**
         * Dumps the javascript code needed by this component
         *
         * If you write components, override this method to dump all javascript
         * required by your component to work.
         *
         * @see dumpHeaderCode()
         *
         */
        function dumpJavascript()
        {
                //Do nothing yet
        }

        /**
         * Dumps header code required
         *
         * If you write components, override this method to dump all header code
         * you need to make your component work.
         *
         * @see dumpJavascript()
         *
         */
        function dumpHeaderCode()
        {
                //Do nothing yet
        }

        /**
         * Dumps the javascript code for all the children
         *
         * @see $components, dumpJavascript()
         */
        function dumpChildrenJavascript()
        {
                //Iterates through components, dumping all javascript
                $this->dumpJavascript();
                reset($this->components->items);
                while (list($k,$v)=each($this->components->items))
                {
                        if ($v->inheritsFrom('Control'))
                        {
                                if ($v->canShow())
                                {
                                        $v->dumpJavascript();
                                }
                        }
                        else $v->dumpJavascript();
                }
        }

        /**
         * Dumps the header code for all the children
         *
         * @see $components, dumpHeaderCode()
         * @link http://www.php.net/manual/en/ref.outcontrol.php
         *
         * @param boolean $return_contents If true, code is returned instead be dumped
         * @return string Children header code if $return_contents is true
         */
        function dumpChildrenHeaderCode($return_contents=false)
        {
                //Iterates through components, dumping all javascript
                reset($this->components->items);

                if ($return_contents) ob_start();
                while (list($k,$v)=each($this->components->items))
                {
                        if ($v->inheritsFrom('Control'))
                        {
                                if ($v->canShow())
                                {
                                        $v->dumpHeaderCode();
                                }
                        }
                        else $v->dumpHeaderCode();
                }
                if ($return_contents)
                {
                        $contents=ob_get_contents();
                        ob_end_clean();
                        return($contents);
                }
        }

        /**
        * Dumps code just after the form tag, useful to dump hidden fields for
        * state retrieving for non visible components
        *
        * This method is useful for component developers and is not intended
        * to be called by an application developer.
        *
        * Component developers may override this method to provide specific code
        *
        */
        function dumpFormItems()
        {
                //Override
        }

        /**
        * This method is called by the page just after dumping the starting form
        * tag.
        *
        * Provides an opportunity for a component developer to dump hidden fields
        * (or other stuff) on that section of the page. Is also used by templates
        * to get that code.
        *
        * @param boolean $return_contents If true, the form items will be returned as string
        * @return mixed If $return_contents is true, it will return a string
        */
        function dumpChildrenFormItems($return_contents=false)
        {
                //Iterates through components, dumping all form items
                reset($this->components->items);

                if ($return_contents) ob_start();
                while (list($k,$v)=each($this->components->items))
                {
                        if ($v->inheritsFrom('Control'))
                        {
                                if ($v->canShow())
                                {
                                        $v->dumpFormItems();
                                }
                        }
                        else $v->dumpFormItems();
                }
                if ($return_contents)
                {
                        $contents=ob_get_contents();
                        ob_end_clean();
                        return($contents);
                }
        }

        /**
         * Loads this component from a string
         *
         * @see readFromResource()
         *
         * @param string $filename  xml file name
         * @param boolean $inherited specifies if we are going to read an inherited resource
         * @param boolean $storelastresource If true, the component stores the name of the last resource read
         */
        function loadResource($filename, $inherited=false, $storelastresource=true)
        {
           global $application;

           //$start=microtime(true);

           if (!isset($_SESSION['comps.'.$this->readNamePath()]) && !$inherited)
           {
                   if ($this->inheritsFrom('Page'))
                   {
                        if ($this->classParent()!='Page')
                        {
                                $varname=$this->classParent();
                                global $$varname;
                                $baseobject=$$varname;
                                $this->loadResource($baseobject->lastresourceread, true);
                        }
                   }
           }

           if ($storelastresource)
           {
            $this->lastresourceread=$filename;
           }
           //TODO: Check here for the path to the resource file
           //$resourcename=basename($filename);
           $resourcename=$filename;
           $l="";

           if ((($application->Language!='')) || (($this->inheritsFrom('Page')) && ($this->Language!='(default)')))
           {
                $resourcename=str_replace('.php',$l.'.xml.php',$filename);
                $this->readFromResource($resourcename);

                $l=".".$application->Language;
                $resourcename=str_replace('.php',$l.'.xml.php',$filename);
                if (file_exists($resourcename))
                {
                        $this->readFromResource($resourcename, false, false);
                }
           }
           else
           {
                   $resourcename=str_replace('.php',$l.'.xml.php',$resourcename);
                   $this->readFromResource($resourcename);
           }
           //$finish=microtime(true);
           //echo 'loading:'.($finish-$start);
        }

        /**
         * Reads a component from a resource file
         *
         * @see Reader, Filer
         *
         * @param string $filename Filename of the resource file
         * @param boolean $createobjects Specifies if create the objects found or just read properties
         */
        function readFromResource($filename="", $createobjects=true)
        {
                $readfromfile=true;

                global $application;

                $path=$application->Name.'.'.$this->className();

                //If there are components in the session, don't read from the resource file
                if (isset($_SESSION['comps.'.$path]))
                {
                        $readfromfile=false;
                }

                //Recover last resources read from the session
                if (isset($_SESSION[$path.'._reallastresourceread']))
                {
                        $this->reallastresourceread=$_SESSION[$path.'._reallastresourceread'];
                }

                //If there is a file to read and has not been read yet
                if (($filename!="") && (!in_array($filename,$this->reallastresourceread)))
                {
                        $this->reallastresourceread[]=$filename;
                        $readfromfile=true;
                }

                if ((!$readfromfile) && (!$this->alreadycreated))
                {
                        $this->alreadycreated=true;
                    global $checkduplicatenames;
                    $form_fields=get_object_vars($this);

                    $checkduplicatenames=false;

                    $this->Name=$this->className();
                    $components=$_SESSION['comps.'.$application->Name.'.'.$this->className()];

                    reset($components);
                    while(list($name, $classparts)=each($components))
                    {
                        $class=$classparts[1];
                        $parent=$classparts[0];
                        $var=new $class($this);
                        //$var->setTag($name);
                        $var->setName($name);
                        if (array_key_exists($name,$form_fields)) $this->$name=$var;
                        if ($parent!='')
                        {
                            if ($parent==$this->Name) $var->parent=$this;
                            else
                            {
                                $var->parent=$var->fixupProperty($parent);
                            }
                        }
                    }

                    $this->unserialize();
                    $this->unserializeChildren();
                    $this->loadedChildren();
                    $this->loaded();
                    $this->preinit();
                    $this->init();
                }
                else
                {
                //Default filename
                if ($filename=="") $filename=strtolower($this->className()).".xml.php";

                if ($filename!="")
                {
                        if (file_exists($filename))
                        {
                                //Reads the component from an xml stream
                                $xml=xml_parser_create("UTF-8");
                                $reader=new Reader($xml);
                                $filelines=file($filename);

                                array_shift($filelines);
                                array_pop($filelines);

                                $file=implode('',$filelines);

                                $reader->createobjects=$createobjects;

                                $reader->readRootComponent($this, $file);
                        }
                        else
                        {
                                global $exceptions_enabled;

                                if ($exceptions_enabled) throw new EResNotFound($filename);
                        }
                }
                }
        }

         /**
         * Inserts a component into the component's collection
         *
         * @see $components, readOwner()
         *
         * @param object $acomponent Component to insert
         */
        function insertComponent($acomponent)
        {
                //Adds a component to the components list
                $acomponent->owner=$this;

                $this->_childnames[ $acomponent->_name ] = $acomponent;

                $this->components->add($acomponent);
        }

        /**
         * Removes a component from the component's collection
         *
         * @see $components, readOwner()
         *
         * @param object $acomponent Component to remove
         */
        function removeComponent($acomponent)
        {
                //Removes a component from the component's list
                $this->components->remove($acomponent);

                unset( $this->_childnames[ $acomponent->_name ] );
        }


        /**
        * Lists all the components owned by this component.
        *
        * Use Components to access any of the components owned by this component,
        * such as the components owned by a form. The Components property is most
        * useful when referring to owned components by number rather than name.
        * It is also used internally for iterative processing of all owned components.
        *
        * Index ranges from 0 to ComponentCount minus 1.
        *
        * @see $components, readOwner()
        *
        *
        * @return Collection
        */
        function readComponents() { return $this->components; }

        /**
        * Indicates the number of components owned by the component.
        *
        * Use ComponentCount to find or verify the number of components owned by
        * a component, or when iterating through the Components list to perform
        * some action on all owned components. ComponentCount is used internally
        * for such iterative procedures.
        *
        * Note: The ComponentCount of a component contains the same number of items
        * as in the Components list for that component, and is always 1 more than the
        * highest Components index, because the first Components index is always 0.
        *
        *
        * @see $components, readOwner()
        *
        * @return integer
        */
        function readComponentCount() { return $this->components->count(); }

        /**
        * A flag to know the state of the control, csLoading, csDesigning
        * Example: To test if the component is rendered inside the IDE:
        * <code>
        * if (($this->ControlState & csDesigning)==csDesigning)
        * {
        *    //Write the design-time code here
        * }
        * </code>
        *
        * @return integer
        */
        function readControlState() { return $this->_controlstate; }
        function writeControlState($value) { $this->_controlstate=$value; }

        /**
        * Specifies the path to uniquely identify a component, qualified by the owner when required.
        *
        *
        * @see readOwner()
        *
        * @return string
        */
        function readNamePath()
        {
                $result='';

                if ($this->Name!='')
                {
                    $result=$this->Name;

                    if ($this->readOwner()!=null)
                    {
                            $s=$this->readOwner()->readNamePath();
                            if ($s!="")
                            {
                                $result = $s . "." . $result;
                            }

                    }
                }
                else
                {
                    $result=$this->className();

                    if ($this->readOwner()!=null)
                    {
                            $s=$this->readOwner()->readNamePath();
                            if ($s!="")
                            {
                                $result = $s . "." . $result;
                            }

                    }
                }

                return($result);

            //return($this->_name);
        }

        /**
        * Indicates the component that is responsible for streaming and freeing this component.
        *
        * Use Owner to find the owner of a component. The Owner of a component is responsible
        * for two things:
        *
        *
        * The memory for the owned component is freed when its owner's memory is freed.
        * This means that when a form is destroyed, all the components on the form are also destroyed.
        *
        *
        * The Owner is responsible for loading and saving the published properties of its owned controls.
        *
        * By default, a form owns all components that are on it. In turn, the form is owned by the
        * application. Thus when the application shuts down and its memory is freed, the memory for all
        * forms (and all their owned components) is also freed. When a form is loaded into memory,
        * it loads all of the components that are on it.
        *
        *
        * The owner of a component is determined by the parameter passed to the constructor when the
        * component is created. For components created in the form designer, the form is automatically
        * assigned as the Owner.
        *
        * Warning: If a component has an Owner other than a form or data module, it will not be saved or
        * loaded with its Owner.
        *
        * @link wiki://Developer%27s_Guide_::_Owner_Parent
        * @see readComponents(), readComponentCount()
        *
        *
        * @return Component
        */
        function readOwner() { return($this->owner); }

        //Published properties

        /**
        * Specifies the name for the component. The name is used as an identifier and should be unique.
        *
        * Use Name to change the name of a component to reflect its purpose in the current application.
        * By default, the IDE assigns sequential names based on the type of the component, such as 'Button1', 'Button2',
        * and so on.
        *
        * @see readOwner(), ENameDuplicated
        *
        * @return string
        */
        function getName() { return $this->_name; }
        function setName($value)
        {
                global $checkduplicatenames;

                if ($checkduplicatenames)
                {
                    //TODO: If there is an owner, checks that there are no other components with the same name
                    if ($value!=$this->_name)
                    {
                        if ($this->owner!=null)
                            {
                                if (!$this->owner->classNameIs('application'))
                                    {
                                            if( isset( $this->owner->_childnames[ $value ] ) )
                                                throw new ENameDuplicated($value);

                                            if( $this->_name )
                                                unset( $this->owner->_childnames[ $this->_name ] );

                                            $this->_name=$value;
                                    }
                                    else $this->_name=$value;
                            }
                            else $this->_name=$value;
                    }
                }
                else
                {
                    $this->_name=$value;
                }

                if( $this->owner != null )
                    $this->owner->_childnames[ $value ] = $this;
        }
        function defaultName() { return(""); }

        /**
        * A versatile property of every Component that can be used in any way you want
        *
        * Tag has no predefined meaning. The Tag property is provided for the convenience
        * of developers. It can be used for storing an additional value.
        *
        * <code>
        * <?php
        *      function Button1Click($sender, $params)
        *      {
        *               //All three buttons OnClick event is assigned to this
        *               //event handler, and to check which one has been pressed
        *               //you can use $sender and Tag property
        *               switch($sender->Tag)
        *               {
        *                       case 1: echo "Button 1 clicked!"; break;
        *                       case 2: echo "Button 2 clicked!"; break;
        *                       case 3: echo "Button 3 clicked!"; break;
        *               }
        *      }
        *
        * ?>
        * </code>
        * @return mixed
        */
        function getTag() { return $this->_tag; }
        function setTag($value) { $this->_tag=$value; }
        function defaultTag() { return 0; }
}

/**
* Helper function to filter the array of methods for an specific component, not to be called directly
*
* @param string $method Method name to filter
* @return boolean true if method starts with 'set'
*/
function filterSet( $method )
{
    $methodname = $method->name;

    return ($methodname[0] == 's' && $methodname[1] == 'e' && $methodname[2] == 't');
}

/**
* Helper function to filter the array of methods for an specific component, not to be called directly
*
* @param object $method Method to filter
* @param mixed $key Not used
*/
function processMethods( &$method, $key )
{
    $method = $method->name;
}

?>