EntityManagerMock::fetch()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.584
c 0
b 0
f 0
cc 4
nc 4
nop 2
1
<?php
2
3
namespace ORM\Testing;
4
5
use Mockery as m;
6
use ORM\Entity;
7
use ORM\EntityFetcher;
8
use ORM\EntityManager;
9
use ORM\Exception\NoEntity;
10
use ORM\Testing\EntityFetcherMock\Result;
11
use ORM\Testing\EntityFetcherMock\ResultRepository;
12
use ReflectionClass;
13
14
class EntityManagerMock extends EntityManager
15
{
16
    protected $resultRepository;
17
18
    public function __construct($options = [])
19
    {
20
        static::$emMapping['byClass'] = [];
21
        parent::__construct($options);
22
        $this->resultRepository = new ResultRepository($this);
23
    }
24
25
    /**
26
     * Add an entity to be fetched by primary key
27
     *
28
     * The entity needs to have a primary key if not it will be filled with random values between RANDOM_KEY_MIN and
29
     * RANDOM_KEY_MAX (at the time writing this it is 1000000000 and 1000999999).
30
     *
31
     * You can pass mocks from Entity too but we need to call `Entity::getPrimaryKey()`.
32
     *
33
     * @param Entity $entity
34
     * @codeCoverageIgnore proxy method
35
     */
36
    public function addEntity(Entity $entity)
37
    {
38
        $this->resultRepository->addEntity($entity);
39
    }
40
41
    /**
42
     * Retrieve an entity by $primaryKey
43
     *
44
     * @param string $class
45
     * @param array $primaryKey
46
     * @return Entity|null
47
     * @codeCoverageIgnore proxy method
48
     */
49
    public function retrieve($class, array $primaryKey)
50
    {
51
        return $this->resultRepository->retrieve($class, $primaryKey);
52
    }
53
54
    /**
55
     * Create and add a EntityFetcherMock\Result for $class
56
     *
57
     * As the results are mocked to come from the database they will also get a primary key if they don't have already.
58
     *
59
     * @param $class
60
     * @param Entity ...$entities
61
     * @return Result|m\MockInterface
62
     * @codeCoverageIgnore proxy method
63
     */
64
    public function addResult($class, Entity ...$entities)
65
    {
66
        return $this->resultRepository->addResult($class, ...$entities);
67
    }
68
69
    /**
70
     * Get the results for $class and $query
71
     *
72
     * The EntityFetcherMock\Result gets a quality for matching this query. Only the highest quality will be used.
73
     *
74
     * @param string $class
75
     * @param EntityFetcher $fetcher
76
     * @return array
77
     * @codeCoverageIgnore proxy method
78
     */
79
    public function getResults($class, EntityFetcher $fetcher)
80
    {
81
        return $this->resultRepository->getResults($class, $fetcher);
82
    }
83
84
    /** {@inheritDoc} */
85
    public function fetch($class, $primaryKey = null)
86
    {
87
        $reflection = new ReflectionClass($class);
88
        if (!$reflection->isSubclassOf(Entity::class)) {
89
            throw new NoEntity($class . ' is not a subclass of Entity');
90
        }
91
        /** @var string|Entity $class */
92
93
        if ($primaryKey === null) {
94
            return new EntityFetcherMock($this, $class);
95
        }
96
97
        $primaryKey = $this->buildPrimaryKey($class, (array)$primaryKey);
98
        $checksum = $this->buildChecksum($primaryKey);
99
100
        if (isset($this->map[$class][$checksum])) {
101
            return $this->map[$class][$checksum];
102
        }
103
104
        return $this->retrieve($class, $primaryKey);
0 ignored issues
show
Bug introduced by
It seems like $class can also be of type object<ORM\Entity>; however, ORM\Testing\EntityManagerMock::retrieve() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
105
    }
106
}
107