Skip to content

Magic methods evaluating __get instead of __set #2358

@andig

Description

@andig

I'm coming from #2357

Bug report

Sorry to come back- I still can't get this to work. Using .neon now:

parameters:
	universalObjectCratesClasses:
		- Sabre\VObject\Document

with:

use Sabre\VObject\Document;

/**
 * @param Document $vcard
 * @return Document
 */
public function enrichVcard(Document $vcard): Document
{
    if (isset($vcard->FN)) {
        $vcard->FULLNAME = (string)$vcard->FN;
    }
}

now gives:

 ------ --------------------------------------------------------------------------------------------- 
  Line   CardDav/Backend.php                                                                          
 ------ --------------------------------------------------------------------------------------------- 
  253    Property Sabre\VObject\Document::$FULLNAME (Sabre\VObject\Property) does not accept string.  
 ------ --------------------------------------------------------------------------------------------- 

I wondered where the Sabre\VObject\Property came from. This is from the Sabre Document parent class:

/**
 * Using 'get' you will either get a property or component.
 *
 * If there were no child-elements found with the specified name,
 * null is returned.
 *
 * To use this, this may look something like this:
 *
 * $event = $calendar->VEVENT;
 *
 * @param string $name
 * @return Property
 */
public function __get($name)
{
    if ('children' === $name) {
        throw new \RuntimeException('Starting sabre/vobject 4.0 the children property is now protected. You should use the children() method instead');
    }

    $matches = $this->select($name);
    if (0 === count($matches)) {
        return;
    } else {
        $firstMatch = current($matches);
        /* @var $firstMatch Property */
        $firstMatch->setIterator(new ElementList(array_values($matches)));

        return $firstMatch;
    }
}

/**
 * Using the setter method you can add properties or subcomponents.
 *
 * You can either pass a Component, Property
 * object, or a string to automatically create a Property.
 *
 * If the item already exists, it will be removed. If you want to add
 * a new item with the same name, always use the add() method.
 *
 * @param string $name
 * @param mixed  $value
 */
public function __set($name, $value)
{
    $name = strtoupper($name);
    $this->remove($name);
    if ($value instanceof self || $value instanceof Property) {
        $this->add($value);
    } else {
        $this->add($name, $value);
    }
}

__get and __set have different signatures. It seems as if stan is looking at the getter instead of the setter and therefore concludes that it must be a Property?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions