RepositoryCache::add()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
/**
4
 * Author: Nil Portugués Calderó <[email protected]>
5
 * Date: 26/01/16
6
 * Time: 23:55.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace NilPortugues\Foundation\Infrastructure\Model\Repository\Cache;
12
13
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\Fields;
14
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\Filter;
15
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\Identity;
16
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\Pageable;
17
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\PageRepository;
18
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\ReadRepository;
19
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\Sort;
20
use NilPortugues\Foundation\Domain\Model\Repository\Contracts\WriteRepository;
21
use Stash\Interfaces\PoolInterface;
22
23
class RepositoryCache implements ReadRepository, WriteRepository, PageRepository
24
{
25
    /**
26
     * @var PoolInterface
27
     */
28
    protected $cache;
29
    /**
30
     * @var ReadRepository|WriteRepository|PageRepository
31
     */
32
    protected $repository;
33
    /**
34
     * @var string
35
     */
36
    protected $cacheNamespace;
37
    /**
38
     * @var string
39
     */
40
    protected $cacheNamespaceFindBy;
41
    /**
42
     * @var string
43
     */
44
    protected $cacheNamespacePage;
45
    /**
46
     * @var string
47
     */
48
    protected $cacheNamespaceCount;
49
50
    /**
51
     * @var null
52
     */
53
    protected $cacheTime = null;
54
55
    /**
56
     * RepositoryCache constructor.
57
     *
58
     * @param PoolInterface $cache
59
     * @param mixed         $repository
60
     * @param string        $classFQN
61
     * @param null          $cacheTime
62
     */
63
    public function __construct(PoolInterface $cache, $repository, $classFQN, $cacheTime = null)
64
    {
65
        $this->cache = $cache;
66
        $this->repository = $repository;
67
        $this->cacheTime = ($cacheTime) ? strtotime(sprintf('now + %s seconds', $cacheTime)) : $cacheTime;
0 ignored issues
show
Documentation Bug introduced by
It seems like $cacheTime ? strtotime(s...acheTime)) : $cacheTime can also be of type integer. However, the property $cacheTime is declared as type null. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
68
69
        $this->buildCacheKeys($classFQN);
70
    }
71
72
    /**
73
     * Creates the cache key for the repository.
74
     *
75
     * @param string $classFQN
76
     */
77
    protected function buildCacheKeys($classFQN)
78
    {
79
        $parts = explode('\\', $classFQN);
80
        $classFQN = array_pop($parts);
81
82
        $baseKey = str_replace('\\', '.', strtolower($classFQN));
83
        $this->cacheNamespace = sprintf('/%s/', $baseKey);
84
        $this->cacheNamespaceFindBy = sprintf('/%s/findby/', $baseKey);
85
        $this->cacheNamespacePage = sprintf('/%s/paginated/', $baseKey);
86
        $this->cacheNamespaceCount = sprintf('/%s/count/', $baseKey);
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function find(Identity $id, Fields $fields = null)
93
    {
94
        $key = $this->cacheNamespace.$id->id();
95
        $cachedItem = $this->cache->getItem($key);
96
97
        if (!$cachedItem->isMiss() && null !== ($result = $cachedItem->get())) {
98
            return $result;
99
        }
100
101
        $entity = $this->repository->find($id, $fields);
0 ignored issues
show
Bug introduced by
The method find does only exist in NilPortugues\Foundation\...ontracts\ReadRepository, but not in NilPortugues\Foundation\...ntracts\WriteRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
102
        $cachedItem->set($entity, $this->cacheTime);
0 ignored issues
show
Unused Code introduced by
The call to ItemInterface::set() has too many arguments starting with $this->cacheTime.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
103
104
        return $entity;
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110
    public function findBy(Filter $filter = null, Sort $sort = null, Fields $fields = null)
111
    {
112
        $cachedItem = $this->cache->getItem(
113
            $this->cacheNamespaceFindBy.md5(serialize($filter).serialize($sort).serialize($fields))
114
        );
115
116
        if (!$cachedItem->isMiss() && null !== ($result = $cachedItem->get())) {
117
            return $result;
118
        }
119
120
        $result = $this->repository->findBy($filter, $sort, $fields);
0 ignored issues
show
Bug introduced by
The method findBy does only exist in NilPortugues\Foundation\...ontracts\ReadRepository, but not in NilPortugues\Foundation\...ntracts\WriteRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
121
        $cachedItem->set($result, $this->cacheTime);
0 ignored issues
show
Unused Code introduced by
The call to ItemInterface::set() has too many arguments starting with $this->cacheTime.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
122
123
        return $result;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function add(Identity $value)
130
    {
131
        $entity = $this->repository->add($value);
0 ignored issues
show
Bug introduced by
The method add does only exist in NilPortugues\Foundation\...ntracts\WriteRepository, but not in NilPortugues\Foundation\...ontracts\ReadRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
132
133
        $cachedItem = $this->cache->getItem($this->cacheNamespace.$entity->id());
134
        $cachedItem->set($entity, $this->cacheTime);
0 ignored issues
show
Unused Code introduced by
The call to ItemInterface::set() has too many arguments starting with $this->cacheTime.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
135
136
        return $entity;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    public function remove(Identity $id)
143
    {
144
        $result = $this->repository->remove($id);
0 ignored issues
show
Bug introduced by
The method remove does only exist in NilPortugues\Foundation\...ntracts\WriteRepository, but not in NilPortugues\Foundation\...ontracts\ReadRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
145
146
        $this->cache->getItem($this->cacheNamespace.$id->id())->clear();
147
        $this->cache->getItem($this->cacheNamespacePage)->clear();
148
        $this->cache->getItem($this->cacheNamespaceFindBy)->clear();
149
        $this->cache->getItem($this->cacheNamespaceCount)->clear();
150
151
        return $result;
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 View Code Duplication
    public function findAll(Pageable $pageable = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
158
    {
159
        $cachedItem = $this->cache->getItem($this->cacheNamespacePage.md5(serialize($pageable)));
160
161
        if (!$cachedItem->isMiss() && null !== ($result = $cachedItem->get())) {
162
            return $result;
163
        }
164
165
        $result = $this->repository->findAll($pageable);
0 ignored issues
show
Bug introduced by
The method findAll does only exist in NilPortugues\Foundation\...ontracts\PageRepository, but not in NilPortugues\Foundation\...ntracts\WriteRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
166
        $cachedItem->set($result, $this->cacheTime);
0 ignored issues
show
Unused Code introduced by
The call to ItemInterface::set() has too many arguments starting with $this->cacheTime.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
167
168
        return $result;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174 View Code Duplication
    public function count(Filter $filter = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
175
    {
176
        $cachedItem = $this->cache->getItem($this->cacheNamespaceCount.md5(serialize($filter)));
177
178
        if (!$cachedItem->isMiss() && null !== ($result = $cachedItem->get())) {
179
            return $result;
180
        }
181
182
        $result = $this->repository->count($filter);
0 ignored issues
show
Bug introduced by
The method count does only exist in NilPortugues\Foundation\...ntracts\WriteRepository, but not in NilPortugues\Foundation\...ontracts\PageRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
183
        $cachedItem->set($result, $this->cacheTime);
0 ignored issues
show
Unused Code introduced by
The call to ItemInterface::set() has too many arguments starting with $this->cacheTime.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
184
185
        return $result;
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191
    public function exists(Identity $id)
192
    {
193
        return $this->repository->exists($id);
0 ignored issues
show
Bug introduced by
The method exists does only exist in NilPortugues\Foundation\...ntracts\WriteRepository, but not in NilPortugues\Foundation\...ontracts\PageRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
194
    }
195
196
    /**
197
     * {@inheritdoc}
198
     */
199
    public function addAll(array $values)
200
    {
201
        $result = $this->repository->addAll($values);
0 ignored issues
show
Bug introduced by
The method addAll does only exist in NilPortugues\Foundation\...ntracts\WriteRepository, but not in NilPortugues\Foundation\...ontracts\ReadRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
202
203
        $this->cache->getItem($this->cacheNamespace)->clear();
204
205
        return $result;
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function removeAll(Filter $filter = null)
212
    {
213
        $result = $this->repository->removeAll($filter);
0 ignored issues
show
Bug introduced by
The method removeAll does only exist in NilPortugues\Foundation\...ntracts\WriteRepository, but not in NilPortugues\Foundation\...ontracts\ReadRepository.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
214
215
        $this->cache->getItem($this->cacheNamespace)->clear();
216
217
        return $result;
218
    }
219
}
220