yiisoft / yii-core

Yii Framework 3.0 core

Home Page:https://www.yiiframework.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Resolvable magic getters

SamMousa opened this issue · comments

Currently we have 2 kinds of magic getters:

  1. Simple (implemented in yii\base\Component)
  2. ActiveQuery (implemented in yii\db\BaseActiveRecord)

I propose replacing (2) with a generic implementation for resolvable getters. Resolvable getters would be defined as anything that describes an operation that you might want to change before executing.
When using it as a magic getter it would then get resolved with the default settings.
This is 100% analogous to how it currently works for ActiveQueryInterface.

public function __get($name) 
{
    ...
    if (array_key_exists($this->_resolved, $name)) {
        return $this->name;
    }

        $getter = 'get' . $name;
        if (method_exists($this, $getter)) {
            // read property, e.g. getName()
            $value = $this->$getter();
        } else {
            // behavior property
            $this->ensureBehaviors();
            foreach ($this->_behaviors as $behavior) {
                if ($behavior->canGetProperty($name)) {
                    $result = $behavior->$name;
                    break;
                }
            }
        }
        return $this->resolve($name, $result);
}

/**
* Allows child classes who override __get to reuse the resolving part.
*/
protected function resolve(string $name, $resolvable) 
{
    if ($resolvable instanceof Resolvable) {
        $this->_resolved[$name] = $resolvable = $resolvable->resolve($name, $this);
    }
    return $resolvable;
}

Note in the above example error handling is missing (unknown or write-only properties). But the idea is clear.
BaseActiveRecord should then be changed to use this generic approach.

What's the problem you're trying to solve?

Clean up the AR implementation, also laying the groundwork for other kinds of resolvable properties, like virtual fields.
They can benefit from this, as would any cache-able property.

That's pretty low-level and general concept that should be properly described in the guide. Hard to get it from reading phpdoc of PR. I see it as refactoring + more extension points. Correct?

That's correct

Magic setters were removed altogether. Closing.