public function __call($name, array $arguments)
{
$e = new InvalidMethodCallException("Method {$name} in entity " . get_called_class() . ' is not callable.');
if (strlen($name) < 4) {
throw $e;
}
if (substr($name, 0, 3) === 'get') {
// get<Name>
return $this->get(lcfirst(substr($name, 3)), $arguments);
} elseif (substr($name, 0, 3) === 'set') {
// set<Name>
if (count($arguments) !== 1) {
throw new InvalidMethodCallException("Method {$name} in entity " . get_called_class() . ' expects exactly one argument.');
}
$property = $this->getCurrentReflection()->getEntityProperty($propertyName = lcfirst(substr($name, 3)));
if ($property === null) {
throw new MemberAccessException("Cannot access undefined property '{$propertyName}' in entity " . get_called_class() . '.');
}
if (!$property->isWritable()) {
throw new MemberAccessException("Cannot write to read-only property '{$propertyName}' in entity " . get_called_class() . '.');
}
$this->set($property, reset($arguments));
} elseif (substr($name, 0, 5) === 'addTo' and strlen($name) > 5) {
// addTo<Name>
$this->checkMethodArgumentsCount(1, $arguments, $name);
$this->addToOrRemoveFrom(self::ACTION_ADD, lcfirst(substr($name, 5)), reset($arguments));
} elseif (substr($name, 0, 10) === 'removeFrom' and strlen($name) > 10) {
// removeFrom<Name>
$this->checkMethodArgumentsCount(1, $arguments, $name);
$this->addToOrRemoveFrom(self::ACTION_REMOVE, lcfirst(substr($name, 10)), reset($arguments));
} elseif (substr($name, 0, 9) === 'removeAll' and strlen($name) > 9) {
// removeAll<Name>
$this->checkMethodArgumentsCount(0, $arguments, $name);
$property = lcfirst(substr($name, 9));
foreach ($this->{$property} as $value) {
$this->addToOrRemoveFrom(self::ACTION_REMOVE, $property, $value);
}
} elseif (substr($name, 0, 10) === 'replaceAll' and strlen($name) > 10) {
// replaceAll<Name>
$this->checkMethodArgumentsCount(1, $arguments, $name);
$arg = reset($arguments);
if (!is_array($arg) and (!$arg instanceof Traversable or $arg instanceof Entity)) {
throw new InvalidArgumentException("Argument of method {$name} in entity " . get_called_class() . ' must contain either array or instance of Traversable which is not Entity.');
}
$property = lcfirst(substr($name, 10));
foreach ($this->{$property} as $value) {
$this->addToOrRemoveFrom(self::ACTION_REMOVE, $property, $value);
}
$this->addToOrRemoveFrom(self::ACTION_ADD, $property, reset($arguments));
} else {
throw $e;
}
}