/** * In case of @OneToMany or @ManyToMany or @ManyToOne, this is a general function * for removing a record from a collection * * @param $name * @param Model $model * @param \Closure|ComparatorInterface|null $comparator * @throws \Athem\Exception\InvalidArgument * @throws \Exception * @return $this */ protected function __remove($name, Model $model, $comparator = null) { if (!$this->{$name} instanceof Collection) { throw new \Exception(sprintf('Invalid call of __remove function on property \'%s\' of class/type %s. ' . 'Property type must be Doctrine\\Common\\Collections\\Collection or extended.', $name, is_object($this->{$name}) ? get_class($this->{$name}) : gettype($this->{$name}))); } switch (true) { case $comparator instanceof ComparatorInterface: $this->{$name} = $this->{$name}->filter(function ($m) use($model, $comparator) { return $comparator->compare($m, $model) === 0; }); break; case $comparator instanceof \Closure: $this->{$name} = $this->{$name}->filter(function ($m) use($model, $comparator) { return $comparator($m, $model); }); break; case null === $comparator: $this->{$name} = $this->{$name}->filter(function ($m) use($model) { return $m->getArrayCopy() != $model->getArrayCopy(); }); break; default: throw new \Athem\Exception\InvalidArgument(sprintf('Invalid comparator. Must be of classes: \\Closure or \\Athem\\Stdlib\\ComparatorInterface, but %s found.', is_object($comparator) ? get_class($comparator) : gettype($comparator))); } return $this; }