Location: PHPKode > scripts > DutchPIPE - Avatar worlds on websites > dutchpipe-avatar-worlds-on-websites/dpuniverse/std/DpProperties.php
<?php
/**
 * The DutchPIPE property and coinherit system which all objects extend on
 *
 * DutchPIPE version 0.4; PHP version 5
 *
 * LICENSE: This source file is subject to version 1.0 of the DutchPIPE license.
 * If you did not receive a copy of the DutchPIPE license, you can obtain one at
 * http://dutchpipe.org/license/1_0.txt or by sending a note to
 * hide@address.com, in which case you will be mailed a copy immediately.
 *
 * @package    DutchPIPE
 * @subpackage dpuniverse_std
 * @author     Lennert Stock <hide@address.com>
 * @copyright  2007 Lennert Stock
 * @license    http://dutchpipe.org/license/1_0.txt  DutchPIPE License
 * @version    Subversion: $Id: DpProperties.php 278 2007-08-19 22:52:25Z ls $
 * @link       http://dutchpipe.org/manual/package/DutchPIPE
 */

/**
 * The DutchPIPE property and coinherit system which all objects extend on
 *
 * @package    DutchPIPE
 * @subpackage dpuniverse_std
 * @author     Lennert Stock <hide@address.com>
 * @copyright  2007 Lennert Stock
 * @license    http://dutchpipe.org/license/1_0.txt  DutchPIPE License
 * @version    Release: 0.2.1
 * @link       http://dutchpipe.org/manual/package/DutchPIPE
 */
class DpProperties
{
    /**
     * Generic property array for dynamic, simple vars
     *
     * @var         type
     * @access      private
     */
    private $mProperties = array();

    /**
     * Coinherited objects (for simulated coinherits)
     */
    private $mCoinherits;

    /**
     * Sets the value of a DutchPIPE property using PHP member overloading
     *
     * @access     private
     * @param      string    $nm        name of property
     * @param      string    $val       value of property
     */
    public function __set($nm, $val)
    {
        //echo "__set($nm, $val) called... ";
        /*
         * If a special array is given as constructed by the new_dp_property()
         * method, initializes a new DutchPIPE property
         */
        if (is_array($val) && 4 === count($val)
                && 'new_dp_property' === $val[0]) {
            //echo "Initialized new property $nm.\n";

            if (!isset($this->mProperties[$nm]) &&
                    !is_null($this->mCoinherits)) {
                foreach ($this->mCoinherits as $coinherit) {
                    if (isset($coinherit->{$nm})) {
                        $coinherit->{'set' . ucfirst($nm)}($val);
                        return;
                    }
                }
            }

            $this->mProperties[$nm] = array($val[1], $val[2], $val[3]);
            return;
        }

        /*
         * If $nm is 'foo' and the method 'setFoo()' is defined,
         * $this->foo = ... will use that method to set the value;
         */
        if (method_exists($this, ($setter = 'set' . ucfirst($nm)))) {
            if (func_num_args() <= 2) {
                /*
                 * All member setters and most setter method calls will have
                 * only one argument and this is the fastest way to handle the
                 * call.
                 */
                $this->{$setter}($val);
            } else {
                /*
                 * Handle method setters with multiple arguments
                 */
                $args = func_get_args();
                call_user_func_array(array(&$this, $setter),
                    array_slice($args, 1));
            }

            return;
        }

        if (isset($this->mProperties[$nm])) {
            /* If no setter is defined, just stores the new value */
            if (is_null($this->mProperties[$nm][1])) {
                $this->mProperties[$nm][0] = $val;
                return;
            }
            /* If the setter is FALSE this property is read-only */
            if (FALSE === $this->mProperties[$nm][1]) {
                return;
            }

            /* Use the setter function */
            if (func_num_args() <= 2) {
                $this->{$this->mProperties[$nm][1]}($val);
            } else {
                $args = func_get_args();
                call_user_func_array(array(&$this, $this->mProperties[$nm][1]),
                    array_slice($args, 1));
            }
            return;
        }

        if (isset($this->mCoinherits) && !is_null($this->mCoinherits)) {
                foreach ($this->mCoinherits as $coinherit) {
                    if (isset($coinherit->{$nm})) {
                    $coinherit->{$nm} = $val;
                    return;
                }
            }
        }

        // echo dp_text("Invalid __set, %s not defined.\n", $nm);
        // Should throw error in future.
    }

    /**
     * Gets the value of a DutchPIPE property using PHP member overloading
     *
     * @access     private
     * @param      string    $nm        name of property
     * @return     mixed     value of property
     */
    public function __get($nm)
    {
        //echo "__get($nm) called\n";

        // Only find dp properties in main object, ordinary members are found
        // without using this method:
        if (isset($this->mProperties[$nm])) {
            if (method_exists($this, 'get' . ucfirst($nm))) {
                if (func_num_args() <= 1) {
                    $rval = $this->{'get' . ucfirst($nm)}();
                } else {
                    $args = func_get_args();
                    $rval = call_user_func_array(array(&$this, 'get' . ucfirst($nm)),
                        array_slice($args, 1));
                }
                return $rval;
            }

            if (is_null($this->mProperties[$nm][2])) {
                return is_array($this->mProperties[$nm][0])
                    ? (array)$this->mProperties[$nm][0]
                    : $this->mProperties[$nm][0];
            }

            if (func_num_args() <= 2) {
                $rval = $this->{$this->mProperties[$nm][2]}();
            } else {
                $args = func_get_args();
                $rval = call_user_func_array(array(&$this,
                    $this->mProperties[$nm][2]), array_slice($args, 1));
            }
            return $rval;
        }

        // Find both dp properties and ordinary members in coinherits:
        if (!is_null($this->mCoinherits)) {
            foreach ($this->mCoinherits as $coinherit) {
                if (isset($coinherit->{$nm})) {
                    return $coinherit->{$nm};
                }
            }
        }

        // echo dp_text("Invalid __get, %s not defined.\n", $nm);
        // Should throw error in future.
        return NULL;
    }

    /**
     * Determines if a property is defined in this object using PHP member overloading
     *
     * @access     private
     * @param      string    $nm        name of property
     * @return     boolean   TRUE if property exists and not NULL, FALSE otherwise
     */
    public function __isset($nm)
    {
        //echo "__isset($nm) called...";

        // Only find dp properties in main object, ordinary members are found
        // without using this method:
        if (isset($this->mProperties[$nm])) {
            //echo "Found $nm\n";
            return TRUE;
        }

        // Find both dp properties and ordinary members in coinherits:
        if (!is_null($this->mCoinherits)) {
            foreach ($this->mCoinherits as $coinherit) {
                if (isset($coinherit->{$nm})) {
                    //echo "Found $nm in coinherit\n";
                    return TRUE;
                }
            }
        }
        //echo "NOT FOUND!\n";
        return FALSE;
    }

    /**
     * Unsets the given DutchPIPE property using PHP member overloading
     *
     * @access     private
     * @param      string    $nm        name of property
     */
    public function __unset($nm)
    {
        //echo "__unset($nm) called\n";

        // Only find dp properties in main object, ordinary members are found
        // without using this method:
        if (isset($this->mProperties[$nm])
                && FALSE !== $this->mProperties[$nm][1]) {
            unset($this->mProperties[$nm]);
            return;
        }

        // Find both dp properties and ordinary members in coinherits:
        if (!is_null($this->mCoinherits)) {
            foreach ($this->mCoinherits as $coinherit) {
                if (isset($coinherit->{$nm})) {
                    unset($coinherit->{$nm});
                    return;
                }
            }
        }
    }

    /**
     * Handles set and get methods for properties using PHP member overloading
     *
     * @access     private
     * @param      string    $nm        name of property
     */
    public function __call($name, $params)
    {
        //echo "__call($name, $params) called\n";
        //echo "params:\n"; print_r($params);
        if (dp_strlen($name) > 3) {
            $part1 = dp_substr($name, 0, 3);
            $part2 = dp_strtolower(dp_substr($name, 3, 1))
                . (dp_strlen($name) == 4 ? '' : dp_substr($name, 4));

                //echo $part1 . '---' . $part2 . "\n";

            if (isset($this->mProperties[$part2])) {
                if ('set' === $part1) {
                    if (count($params) <= 1) {
                        return $this->__set(dp_strtolower(dp_substr($name, 3,
                            1)) . dp_substr($name, 4), array_pop($params));
                    }
                    call_user_func_array(array(&$this, '__set'),
                        array_merge(array(dp_strtolower(dp_substr($name, 3, 1))
                        . dp_substr($name, 4)), $params));
                    return;
                }
                if ('get' === $part1) {
                    if (empty($params)) {
                        return $this->__get(dp_strtolower(dp_substr($name, 3,
                            1)) . dp_substr($name, 4));
                    }
                    return call_user_func_array(array(&$this, '__get'),
                        array_merge(array(dp_strtolower(dp_substr($name, 3, 1))
                        . dp_substr($name, 4)), $params));
                }
            }
        }

        // Find both dp properties and ordinary members in coinherits:
        if (!is_null($this->mCoinherits)) {
            foreach ($this->mCoinherits as $coinherit) {
                if ((isset($part1)
                        && method_exists($coinherit, 'isDpProperty')
                        && $coinherit->isDpProperty($part2))
                        || method_exists($coinherit, $name)) {
                    return call_user_func_array(array(&$coinherit, $name), $params);
                }
            }
        }

        //echo dp_text("Invalid __call, method %s does not exist.\n", $name);
        return NULL;
    }

    /**
     * Determines if a property is defined in this object
     *
     * Same as isset($ob->{$nm}), except that this method returns TRUE
     * for properties set to NULL.
     *
     * @param      string    $nm        name of property
     * @return     boolean   TRUE if property exists, FALSE otherwise
     */
    final function isDpProperty($nm)
    {
          // First look for property in main object:
        if (isset($this->mProperties[$nm])) {
            return TRUE;
        }

        // ... then search for property in coinherits:
        if (!is_null($this->mCoinherits)) {
            foreach ($this->mCoinherits as $coinherit) {
                if (method_exists($coinherit, 'isDpProperty')
                        && $coinherit->isDpProperty($nm)) {
                    return TRUE;
                }
            }
        }
        return FALSE;
    }

    /**
     * Directly set the value of an existing DutchPIPE property
     *
     * @param      string    $nm        name of property
     * @param      string    $val       value of property
     */
    protected function setDpProperty($nm, $val)
    {
        if (isset($this->mProperties[$nm])) {
            $this->mProperties[$nm][0] = $val;
        }
    }

    /**
     * Directly retrieve the value of an existing DutchPIPE property
     *
     * @param      string    $nm        name of property
     * @return     mixed     value of property
     */
    protected function getDpProperty($nm)
    {
        return !isset($this->mProperties[$nm]) ? NULL
            : $this->mProperties[$nm][0];
    }

    /**
     * "Coinherit" a class located at the given pathname
     *
     * @param      string    $pathname  path to code from universe base path
     */
    function coinherit($pathname)
    {
        if (is_null($this->mCoinherits)) {
            $this->mCoinherits = array();
        } elseif (isset($this->mCoinherit[$pathname])) {
            return;
        }
        require_once(DPUNIVERSE_PREFIX_PATH . $pathname);
        $classname =  explode("/", $pathname);
        $classname = ucfirst(!dp_strlen($classname[sizeof($classname) - 1])
            ? 'index' : dp_substr($classname[sizeof($classname) - 1], 0, -4));
        $object = new $classname($this);

        $this->mCoinherits[$pathname] =& $object;
    }

    /**
     * Removes properties and coinherits
     *
     * Called by DpObject::removeDpObject, unsets all properties and coinherits.
     * This makes sure all object pointers are removed and object can be removed
     * from memory by PHP's cleanup mechanism.
     *
     * @access     private
     * @see        DpObject::removeDpObject
     */
    protected function removeDpProperties()
    {
        if (!is_null($this->mCoinherits)) {
            for ($i = 0, $sz = count($this->mCoinherits); $i < $sz; $i++) {
                $this->mCoinherits[$i] = NULL;
                unset($this->mCoinherits[$i]);
            }
        }
        for ($i = 0, $sz = count($this->mProperties); $i < $sz; $i++) {
            $this->mProperties[$i] = NULL;
            unset($this->mProperties[$i]);
        }
        $this->mCoinherits = NULL;
        unset($this->mCoinherits);
    }
}
Return current item: DutchPIPE - Avatar worlds on websites