Skip to content

Commit

Permalink
Allow applying further filters after DoctrineProxyFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
fsevestre committed May 29, 2018
1 parent 9f80720 commit 53e84ee
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 2 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ $matcher = new TypeMatcher('Doctrine\Common\Collections\Collection');
- `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher`
- `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher`

Except a few exceptions ([`DoctrineProxyFilter`](#doctrineproxyfilter-filter)), matching a filter will stop the chain of
filters (i.e. the next ones will not be applied).


#### `SetNullFilter` (filter)

Expand Down Expand Up @@ -271,14 +274,18 @@ Doctrine proxy class (...\\\_\_CG\_\_\Proxy).
You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class.
**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded
before other filters are applied!**
This filter won't stop the chain of filters (i.e. the next ones may be applied).

```php
use DeepCopy\DeepCopy;
use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
use DeepCopy\Filter\SetNullFilter;
use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
use DeepCopy\Matcher\PropertyNameMatcher;

$copier = new DeepCopy();
$copier->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
$copier->addFilter(new SetNullFilter(), new PropertyNameMatcher('id'));

$copy = $copier->copy($object);

Expand Down
24 changes: 24 additions & 0 deletions fixtures/f009/A.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace DeepCopy\f009;

use Doctrine\Common\Persistence\Proxy;

class A implements Proxy
{
public $foo = 1;

/**
* @inheritdoc
*/
public function __load()
{
}

/**
* @inheritdoc
*/
public function __isInitialized()
{
}
}
13 changes: 13 additions & 0 deletions src/DeepCopy/DeepCopy.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use DateTimeInterface;
use DateTimeZone;
use DeepCopy\Exception\CloneException;
use DeepCopy\Filter\ChainableFilter;
use DeepCopy\Filter\Filter;
use DeepCopy\Matcher\Matcher;
use DeepCopy\TypeFilter\Date\DateIntervalFilter;
Expand Down Expand Up @@ -207,6 +208,8 @@ private function copyObjectProperty($object, ReflectionProperty $property)
return;
}

$filterWasApplied = false;

// Apply the filters
foreach ($this->filters as $item) {
/** @var Matcher $matcher */
Expand All @@ -223,11 +226,21 @@ function ($object) {
}
);

$filterWasApplied = true;

if ($filter instanceof ChainableFilter) {
continue;
}

// If a filter matches, we stop processing this property
return;
}
}

if ($filterWasApplied) {
return;
}

$property->setAccessible(true);
$propertyValue = $property->getValue($object);

Expand Down
10 changes: 10 additions & 0 deletions src/DeepCopy/Filter/ChainableFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace DeepCopy\Filter;

/**
* Defines a filter that will not stop the chain of filters.
*/
interface ChainableFilter extends Filter
{
}
4 changes: 2 additions & 2 deletions src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

namespace DeepCopy\Filter\Doctrine;

use DeepCopy\Filter\Filter;
use DeepCopy\Filter\ChainableFilter;

/**
* @final
*/
class DoctrineProxyFilter implements Filter
class DoctrineProxyFilter implements ChainableFilter
{
/**
* Triggers the magic method __load() on a Doctrine Proxy class to load the
Expand Down
19 changes: 19 additions & 0 deletions tests/DeepCopyTest/DeepCopyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
use DeepCopy\f006;
use DeepCopy\f007;
use DeepCopy\f008;
use DeepCopy\f009;
use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
use DeepCopy\Filter\KeepFilter;
use DeepCopy\Filter\SetNullFilter;
use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
use DeepCopy\Matcher\PropertyNameMatcher;
use DeepCopy\Matcher\PropertyTypeMatcher;
use DeepCopy\TypeFilter\ShallowCopyFilter;
Expand Down Expand Up @@ -424,6 +427,22 @@ public function test_matchers_can_access_to_parent_private_properties()
$this->assertNull($copy->getFoo());
}

/**
* @ticket https://github.com/myclabs/DeepCopy/issues/98
*/
public function test_it_can_apply_two_filters()
{
$object = new f009\A();

$deepCopy = new DeepCopy();
$deepCopy->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
$deepCopy->addFilter(new SetNullFilter(), new PropertyNameMatcher('foo'));

$copy = $deepCopy->copy($object);

$this->assertNull($copy->foo);
}

private function assertEqualButNotSame($expected, $val)
{
$this->assertEquals($expected, $val);
Expand Down

0 comments on commit 53e84ee

Please sign in to comment.