function testIt()
 {
     $dummy = new DummyObjectX();
     $dummy->foo = null;
     $res = PHPTAL_Context::path($dummy, 'method');
     $this->assertEquals('__call', $res);
     $res = phptal_path($dummy, 'foo');
     $this->assertEquals(null, $res);
 }
 /**
  * Handles variable accesses for the tal path resolver
  *
  * @param string $var   The variable name to check
  *
  * @return Mixed    An object/array if the path is not over or a boolean
  *
  * @todo    replace the PHPTAL_Context::path() with custom code
  */
 public function __get($var)
 {
     // When the iterator item is empty we just let the tal
     // expression consume by continuously returning this
     // same object which should evaluate to true for 'last'
     if (is_null($this->data)) {
         return $this;
     }
     // Find the requested variable
     $value = PHPTAL_Context::path($this->data, $var, true);
     // Check if it's an object or an array
     if (is_array($value) || is_object($value)) {
         // Move the context to the requested variable and return
         $this->data = $value;
         $this->addVarName($var);
         return $this;
     }
     // get a hash of the variable contents
     $hash = md5($value);
     // compute a path for the variable to use as dictionary key
     $path = $this->branch . $this->getVarPath() . $var;
     // If we don't know about this var store in the dictionary
     if (!isset($this->cache[$path])) {
         if (!isset($this->dict[$path])) {
             $this->dict[$path] = $hash;
             $res = $this->branch === 'F';
         } else {
             // Check if the value has changed
             if ($this->dict[$path] !== $hash) {
                 $this->dict[$path] = $hash;
                 $res = true;
             } else {
                 $res = false;
             }
         }
         $this->cache[$path] = $res;
     }
     return $this->cache[$path];
 }
Example #3
0
 /**
  * Resolve TALES path starting from the first path element.
  * The TALES path : object/method1/10/method2
  * will call : $ctx->path($ctx->object, 'method1/10/method2')
  *
  * This function is very important for PHPTAL performance.
  *
  * This function will become non-static in the future
  *
  * @param mixed  $base    first element of the path ($ctx)
  * @param string $path    rest of the path
  * @param bool   $nothrow is used by phptal_exists(). Prevents this function from
  * throwing an exception when a part of the path cannot be resolved, null is
  * returned instead.
  *
  * @access private
  * @return mixed
  */
 public static function path($base, $path, $nothrow = false)
 {
     if ($base === null) {
         if ($nothrow) {
             return null;
         }
         PHPTAL_Context::pathError($base, $path, $path);
     }
     foreach (explode('/', $path) as $current) {
         // object handling
         if (is_object($base)) {
             // look for method. Both method_exists and is_callable are required because of __call() and protected methods
             if (method_exists($base, $current) && is_callable(array($base, $current))) {
                 $base = $base->{$current}();
                 continue;
             }
             // look for property
             if (property_exists($base, $current)) {
                 $base = $base->{$current};
                 continue;
             }
             if ($base instanceof ArrayAccess && $base->offsetExists($current)) {
                 $base = $base->offsetGet($current);
                 continue;
             }
             if ($base instanceof Countable && ($current === 'length' || $current === 'size')) {
                 $base = count($base);
                 continue;
             }
             // look for isset (priority over __get)
             if (method_exists($base, '__isset')) {
                 if ($base->__isset($current)) {
                     $base = $base->{$current};
                     continue;
                 }
             } elseif (method_exists($base, '__get')) {
                 $tmp = $base->{$current};
                 if (null !== $tmp) {
                     $base = $tmp;
                     continue;
                 }
             }
             // magic method call
             if (method_exists($base, '__call')) {
                 try {
                     $base = $base->__call($current, array());
                     continue;
                 } catch (BadMethodCallException $e) {
                 }
             }
             if ($nothrow) {
                 return null;
             }
             PHPTAL_Context::pathError($base, $path, $current);
         }
         // array handling
         if (is_array($base)) {
             // key or index
             if (array_key_exists((string) $current, $base)) {
                 $base = $base[$current];
                 continue;
             }
             // virtual methods provided by phptal
             if ($current == 'length' || $current == 'size') {
                 $base = count($base);
                 continue;
             }
             if ($nothrow) {
                 return null;
             }
             PHPTAL_Context::pathError($base, $path, $current);
         }
         // string handling
         if (is_string($base)) {
             // virtual methods provided by phptal
             if ($current == 'length' || $current == 'size') {
                 $base = strlen($base);
                 continue;
             }
             // access char at index
             if (is_numeric($current)) {
                 $base = $base[$current];
                 continue;
             }
         }
         // if this point is reached, then the part cannot be resolved
         if ($nothrow) {
             return null;
         }
         PHPTAL_Context::pathError($base, $path, $current);
     }
     return $base;
 }
Example #4
0
 function testZeroIndex()
 {
     $data = array(1, 0, 3);
     $result = PHPTAL_Context::path($data, '0');
     $this->assertEquals(1, $result);
 }