Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.
"Dot" syntax Variable resolution (eliminating '.'
Goto page Previous  1, 2
 
Post new topic   Reply to topic    Smarty Forum Index -> Feature Requests
View previous topic :: View next topic  
Author Message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5613
Location: Toronto, Canada

PostPosted: Thu Mar 30, 2006 2:12 am    Post subject: Reply with quote

Sounds interesting to me -- I'll be checking out your site Smile If you think of it, feel free to drop me a line to direct me to anything specific. Cross-pollination of ideas is usually a good thing.

All the best!
Back to top
View user's profile Send private message
Henkspenk
Smarty Rookie


Joined: 05 Oct 2011
Posts: 6

PostPosted: Wed Oct 05, 2011 5:16 pm    Post subject: Reply with quote

Hi

First of all, thanks for this great post. It helped me a lot with a project I was working on. For now I found only one problem with looping through arrays. That didn;t work, cause it was looping through the ObjectNavigator. For that I found a simple solution which I will post here

Code:
<?php

/**
 * This class handles the "Dot" syntax from Smarty with Setters and Getters
 * Also it brings a fix for looping through arrays and other Iterators which implement IteratorAggregate
 */

class ObjectNavigator implements ArrayAccess, IteratorAggregate, Countable
{
    /**
     * @var mixed
     */             
    private $wrapped = null;
   
    /**
     * Contstruct function
     * @param mixed $wrapped
     */
    function __construct($wrapped)
    {
        $this->wrapped = $wrapped;
    }

    /**
     * Magic call function to handle for example isFuncname functions in the IndexController
     * @param String $name
     * @param Array $arguments
     */
    public function __call($name, $arguments)
    {
        if(is_object($this -> wrapped))
        {
            if(method_exists($this->wrapped, $name))
            {
                $ret = call_user_func_array(array($this -> wrapped, $name), $arguments);

                if (is_array($ret) || (is_object($ret) && !($ret instanceof ArrayAccess)))
                {
                    return new ObjectNavigator($ret);
                }
               
                return $ret;
            }
            else
            {
                throw new Exception('method '. $name .' does not exist in class '. get_class($this -> wrapped));
            }
        }
        else
        {
            throw new Exception('calling method '. $name .' to a non object');
        }
    }
   
    /**
     * this method checks if $wrapped is an array, or Object
     * called when using $variable.attribute in smarty.
     * @param String $name
     * $name would be the attribute in the example above
     */
    public function offsetGet($name)
    {
        $m          = "get$name";

        // is $wrapped and array or does it implement Traversable
        if (is_array($this->wrapped))
        {
            // Return first array value
            if($name == 'first')
            {
                foreach($this->wrapped as $value) { $ret = $value; break; }
            }
            // Return last array value
            else if($name == 'last')
            {
                foreach($this->wrapped as $value) { $ret = $value; }
            }
            // Return array value
            else $ret = $this->wrapped[$name];
        }
        // Checks if function has to be called as for example getPublished()
        else if ($this -> checkName($name))
        {
            $ret = $this -> getPublishedValues($name);
        }
        // Checks if method exists
        else if (method_exists($this->wrapped,$m))
        {
            $ret = $this->wrapped->$m();
        }

        else
        {
            $ret = $this->wrapped->$name;
        }
       
                   
        if (is_array($ret) || (is_object($ret) && !($ret instanceof ArrayAccess)))
        {
            return new ObjectNavigator($ret);
        }
       
        return $ret;
    }
   
    /**
     * This method sets values in an array or object
     * called when using $variable.attribute = value
     * @param String $name
     * @param mixed $value
     * $name would be the attribute in the example above
     */
    public function offsetSet($name,$value)
    {
        $m = "set$name";
           
        if (method_exists($this->wrapped,$m))
        {
            return $this->wrapped->$m($value);
        }
        else
        {
            $this->wrapped->$name = $value;
        }
    }   

    /**
     * This method unsets a value which is for example setted above
     * @param Sting $name
     */
    public function offsetUnset($name)
    {
        $m = "unset$name";
           
        if (method_exists($this->wrapped,$m))
        {
            return $this->wrapped->$m();
        }
        else
        {
            unset($this->wrapped->$name);
        }
    }
   
    /**
     * this method checks if a method exists
     * @param String $name
     */
    public function offsetExists($name)
    {
        return true;
    }

    /**
     * this method loops through an array
     */
    public function getIterator()
    {
        if(is_array($this->wrapped))
        {
            return new ObjectNavigatorIterator($this->wrapped);
        }
        else
        {
            return new ObjectNavigatorIterator(array());
        }
    }

    /**
     * this methode returns the count from for example an array
     * @return int
     */
    public function count()
    {
        return count($this -> wrapped);
    }

    /**
     * @return mixed
     */
    public function getWrapped()
    {
        return $this -> wrapped;
    }
}

?>


The second class which you will need for looping is the ObjectNavigatorIterator Class.

Code:
<?php

class ObjectNavigatorIterator implements Iterator
{
    private $var = array();

    public function __construct($array)
    {
        if (is_array($array)) {
            $this->var = $array;
        }
    }

    public function rewind()
    {
        reset($this->var);
    }
 
    public function current()
    {
        $var = current($this->var);
        if (is_array($var) || (is_object($var) && !($var instanceof ArrayAccess)))
        {
            return new ObjectNavigator($var);
        }
        return $var;
    }
 
    public function key()
    {
        $var = key($this->var);
        return $var;
    }
 
    public function next()
    {
        $var = next($this->var);
        if (is_array($var) || (is_object($var) && !($var instanceof ArrayAccess)))
        {
            return new ObjectNavigator($var);
        }
       
        return $var;
    }
 
    public function valid()
    {
        $key = key($this->var);
        $var = ($key !== NULL && $key !== FALSE);
        return $var;
    }
}

?>


For more info about the Iterator, you can look here:
http://php.net/manual/en/class.iterator.php


EDITED:: Added Count functionality

with kind regards,
Henk
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Feature Requests All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP