Search code examples
phpcodeignitertwigphpactiverecord

Twig & PHP ActiveRecord - Cannot access field from join table


I cannot access joined table with PHPActiveRecord/Twig. Here is simplified code. It has two models (Code and User), and each code belongs to one user, so I want to list codes with the name of code's author.

php

// model
class Code extends ActiveRecord\Model {
    static $belongs_to = array(
        array('user'),
    );
}

class User extends ActiveRecord\Model {
    static $has_many = array(
        array('code'),
    );
}


// controller
$codes = Code::all(array('include' => 'user'));
var_dump($codes);      //-> successfully displayed codes list and their authors

$this->twig->display('codelist.twig', $codes);

template.twig

{% for code in codes %}
{{ code.name }}        //-> successfully displayed code's name
{{ code.user.name }}   //-> failed to output user's name with error
{% endfor %}
// error:
// An exception has been thrown during the rendering of a template ("Call to undefined method: user") in "inc/template.twig" at line **.

I saw this page: http://twig.sensiolabs.org/doc/templates.html

Implementation

For convenience sake foo.bar does the following things on the PHP layer:

check if foo is an array and bar a valid element; if not, and if foo is an object, check that bar is a valid property; if not, and if foo is an object, check that bar is a valid method (even if bar is the constructor - use __construct() instead); if not, and if foo is an object, check that getBar is a valid method; if not, and if foo is an object, check that isBar is a valid method; if not, return a null value. foo['bar'] on the other hand only works with PHP arrays:

check if foo is an array and bar a valid element; if not, return a null value.

Although I can access user attribute via $codes[0]->user, why can't I access user attribute in twig templates file?


Solution

  • Thanks to greut, I solved the problem. I replaced function __isset in lib/Model.php in PHPActiveRecord.

    /**
     * Determines if an attribute exists for this {@link Model}.
     *
     * @param string $attribute_name
     * @return boolean
     */
    public function __isset($name)
        {
            // check for getter
            if (method_exists($this, "get_$name"))
            {
                $name = "get_$name";
                $value = $this->$name();
                return $value;
            }
    
            return $this->read_attribute($name);
        }
    

    https://github.com/kla/php-activerecord/issues/156