DCOM-3: Public value property in Base annotation class #612

Closed
doctrinebot opened this Issue Apr 22, 2010 · 5 comments

1 participant

@doctrinebot

Jira issue originally created by user chebba:

1) If our annotation doesn't need any parameters, it stll can accept one ('value').
2) We can intercept set and get of annotation properties via _set and _get methods which is not final, but not for 'value'.
Example of interception

class Annotation extends \Doctrine\Common\Annotations\Annotation
{

    private $someProperty;

    public function **set($name, $value)
    {
        $setMethod = 'set' . ucfirst($name);
        if (method_exists($this, $setMethod)) {
            return $this->{$setMethod}($value);
        }
        return parent::**set($name, $value);
    }

    public function **get($name)
    {
        $getMethod = 'get' . ucfirst($name);
        if (method_exists($this, $getMethod)) {
            return $this->{$getMethod}();
        }
        return parent::**get($name);
    }

    public function getSomeProperty()
    {
        //some logic
        return $this->someProperty;
    }

    protected function setSomeProperty($someProperty)
    {
        //some logic
        $this->someProperty = $someProperty;
    }
}
@doctrinebot

Comment created by @beberlei:

Why is this even relevant? can't you just ignore the value property?

@doctrinebot

Comment created by romanb:

I think there is something not clear here. _get and _set on Annotation are not used to set or get values but to intercept calls to non-existant values.
Annotations are populated through their constructors.

Second, you don't need to extend from Annotation (not in HEAD at least). Any class can be used as an annotation as long as it has a constructor that takes an array with values.

Annotation values are set through the constructor, not through setters or public properties. This allows you to even use immutable classes as annotations:

class MyClass {
     private $a, $b;
     public function **construct(array $values) {
          $this->a = $values['a'];
          $this->b = $values['b'];
     }
    //... only getters...
}
/*** @MyClass(a="Hello", b="World") **/
class Other {
    //...
}

The default "value" will still be in $values['value'] if set. So this should work, too:

class MyClass {
     private $value;
     public function **construct(array $values) {
          $this->value = $values['value'];
     }
    //...
}
/*** @MyClass("Hello World") **/
class Other {
    //...
}
@doctrinebot

Comment created by romanb:

So my suggestion would be: Just don't extend from Doctrine\Common\Annotations\Annotation and you don't have the public $value property.

@doctrinebot

Comment created by chebba:

Oh, i got it. It was my miss, because there was subclass checking in previous versions.
Also, is it a good idea not to have some base class or interface for all annotations, may be it will be better to have an interface with a constructor? based on this restriction
"Any class can be used as an annotation as long as it has a constructor that takes an array with values". Of course using constructors in interfaces not really good, but if we have such restriction...
For example

interface SomeCommonAnnotationInterface
{
    public function **construct(array $values);
}
@doctrinebot

Issue was closed with resolution "Fixed"

@doctrinebot doctrinebot added this to the 2.0.0-BETA2 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment