Completed
Pull Request — master (#124)
by Tim
22:56
created

AbstractCachedRepository::flushCache()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 10
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 12
1
<?php
2
3
/**
4
 * TechDivision\Import\Repositories\EavAttributeOptionValueRepository
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Repositories;
22
23
/**
24
 * Repository implementation to load EAV attribute option value data.
25
 *
26
 * @author    Tim Wagner <[email protected]>
27
 * @copyright 2016 TechDivision GmbH <[email protected]>
28
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
29
 * @link      https://github.com/techdivision/import
30
 * @link      http://www.techdivision.com
31
 */
32
abstract class AbstractCachedRepository extends AbstractRepository implements CachedRepositoryInterface
33
{
34
35
    /**
36
     * The cache for the query results.
37
     *
38
     * @var array
39
     */
40
    protected $cache = array();
41
42
    /**
43
     * References that links to another cache entry.
44
     *
45
     * @var array
46
     */
47
    protected $references = array();
48
49
    /**
50
     * Prepares a unique cache key for the passed query name and params.
51
     *
52
     * @param string $queryName The query name to prepare the cache key for
53
     * @param array  $params    The query params
54
     *
55
     * @return string The prepared cache key
56
     */
57
    public function cacheKey($queryName, array $params)
58
    {
59
        return sprintf('%s-%s', $queryName, implode('-', $params));
60
    }
61
62
    /**
63
     * Query whether or not a cache value for the passed cache key is available.
64
     *
65
     * @param string $cacheKey The cache key to query for
66
     *
67
     * @return boolean TRUE if the a value is available, else FALSE
68
     */
69
    public function isCached($cacheKey)
70
    {
71
        return isset($this->cache[$resolvedCacheKey = $this->resolveReference($cacheKey)]);
72
    }
73
74
    /**
75
     * Inversion of the isCached() method.
76
     *
77
     * @param string $cacheKey The cache key to query for
78
     *
79
     * @return boolean TRUE if the value is not available, else FALSE
80
     */
81
    public function notCached($cacheKey)
82
    {
83
        return !$this->isCached($cacheKey);
84
    }
85
86
    /**
87
     * Add's a cache reference from one key to another.
88
     *
89
     * @param string $from The key to reference from
90
     * @param string $to   The key to reference to
91
     *
92
     * @return void
93
     */
94
    public function addReference($from, $to)
95
    {
96
        $this->references[$from] = $to;
97
    }
98
99
    /**
100
     * Resolve's the cache key recursive.
101
     *
102
     * @param string $from The cache key to resolve
103
     *
104
     * @return The resolved reference
105
     */
106
    protected function resolveReference($from)
107
    {
108
109
        // query whether or not a reference exists
110
        if (isset($this->references[$from])) {
111
            return $this->resolveReference($this->references[$from]);
112
        }
113
114
        // return the passed reference
115
        return $from;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $from; (string) is incompatible with the return type documented by TechDivision\Import\Repo...itory::resolveReference of type TechDivision\Import\Repositories\The.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
116
    }
117
118
    /**
119
     * Add the passed value to the cache.
120
     *
121
     * @param string $cacheKey   The cache key
122
     * @param mixed  $value      The value to cache
123
     * @param array  $references An array with references to add
124
     *
125
     * @return void
126
     */
127
    public function toCache($cacheKey, $value, array $references = array())
128
    {
129
130
        // add the value to the cache
131
        $this->cache[$cacheKey] = $value;
132
133
        // also register the references if given
134
        foreach ($references as $from => $to) {
135
            $this->references[$from] = $to;
136
        }
137
    }
138
139
    /**
140
     * Query whether or not a value for the passed cache key exists. If yes, the value
141
     * will be returned, else an exception will be thrown.
142
     *
143
     * @param string $cacheKey The cache key to return the value for
144
     *
145
     * @return mixed The value for the passed cache key
146
     * @throws \Exception Is thrown, if no value is available
147
     */
148
    public function fromCache($cacheKey)
149
    {
150
151
        // query whether or not a value for the cache key is available
152
        if (isset($this->cache[$resolvedCacheKey = $this->resolveReference($cacheKey)])) {
153
            return $this->cache[$resolvedCacheKey];
154
        }
155
156
        // throw an exception if not
157
        throw new \Exception(sprintf('Can\'t find cached value for key "%s"', $cacheKey));
158
    }
159
160
    /**
161
     * Flush the cache, or the value with the passed key.
162
     *
163
     * @param mixed|null $cacheKey The key of the value to flush
164
     *
165
     * @return void
166
     */
167
    public function flushCache($cacheKey = null)
168
    {
169
170
        // flush the complete cache, if NO cache key has been passed
171
        if ($cacheKey === null) {
172
            $this->references = $this->cache = array();
173
            return;
174
        }
175
176
        // only flush the value with the passed cache key
177
        if (isset($this->cache[$cacheKey = $this->resolveReference($cacheKey)])) {
178
            unset($this->cache[$cacheKey]);
179
        }
180
    }
181
}
182