Failed Conditions
Pull Request — develop (#6873)
by
unknown
112:44 queued 47:41
created

DefaultCacheFactory   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 234
Duplicated Lines 21.37 %

Test Coverage

Coverage 81.43%

Importance

Changes 0
Metric Value
dl 50
loc 234
ccs 57
cts 70
cp 0.8143
rs 10
c 0
b 0
f 0
wmc 28

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A buildCollectionHydrator() 0 3 1
A buildEntityHydrator() 0 3 1
B buildCachedCollectionPersister() 23 23 4
A setFileLockRegionDirectory() 0 3 1
B getRegion() 0 28 5
A setTimestampRegion() 0 3 1
A getFileLockRegionDirectory() 0 3 1
A createRegionCache() 0 17 3
A buildQueryCache() 0 8 2
A createCache() 0 3 1
A setRegion() 0 3 1
A getTimestampRegion() 0 10 2
B buildCachedEntityPersister() 22 22 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
4
declare(strict_types=1);
5
6
namespace Doctrine\ORM\Cache;
7
8
use Doctrine\Common\Cache\Cache as CacheAdapter;
9
use Doctrine\Common\Cache\CacheProvider;
10
use Doctrine\Common\Cache\MultiGetCache;
11
use Doctrine\ORM\Cache;
12
use Doctrine\ORM\Cache\Persister\Collection\NonStrictReadWriteCachedCollectionPersister;
13
use Doctrine\ORM\Cache\Persister\Collection\ReadOnlyCachedCollectionPersister;
14
use Doctrine\ORM\Cache\Persister\Collection\ReadWriteCachedCollectionPersister;
15
use Doctrine\ORM\Cache\Persister\Entity\NonStrictReadWriteCachedEntityPersister;
16
use Doctrine\ORM\Cache\Persister\Entity\ReadOnlyCachedEntityPersister;
17
use Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister;
18
use Doctrine\ORM\Cache\Region\DefaultMultiGetRegion;
19
use Doctrine\ORM\Cache\Region\DefaultRegion;
20
use Doctrine\ORM\Cache\Region\FileLockRegion;
21
use Doctrine\ORM\Cache\Region\UpdateTimestampCache;
22
use Doctrine\ORM\EntityManagerInterface;
23
use Doctrine\ORM\Mapping\AssociationMetadata;
24
use Doctrine\ORM\Mapping\CacheMetadata;
25
use Doctrine\ORM\Mapping\CacheUsage;
26
use Doctrine\ORM\Mapping\ClassMetadata;
27
use Doctrine\ORM\Persisters\Collection\CollectionPersister;
28
use Doctrine\ORM\Persisters\Entity\EntityPersister;
29
30
/**
31
 * @since   2.5
32
 * @author  Fabio B. Silva <[email protected]>
33
 */
34
class DefaultCacheFactory implements CacheFactory
35
{
36
    /**
37
     * @var CacheAdapter
38
     */
39
    private $cache;
40
41
    /**
42
     * @var \Doctrine\ORM\Cache\RegionsConfiguration
43
     */
44
    private $regionsConfig;
45
46
    /**
47
     * @var \Doctrine\ORM\Cache\TimestampRegion|null
48
     */
49
    private $timestampRegion;
50
51
    /**
52
     * @var \Doctrine\ORM\Cache\Region[]
53
     */
54
    private $regions = [];
55
56
    /**
57
     * @var string|null
58
     */
59
    private $fileLockRegionDirectory;
60
61
    /**
62
     * @param RegionsConfiguration $cacheConfig
63
     * @param CacheAdapter         $cache
64
     */
65
    public function __construct(RegionsConfiguration $cacheConfig, CacheAdapter $cache)
66
    {
67
        $this->regionsConfig = $cacheConfig;
68
        $this->cache         = $cache;
69
    }
70
71
    /**
72
     * @param string $fileLockRegionDirectory
73
     */
74
    public function setFileLockRegionDirectory($fileLockRegionDirectory)
75
    {
76
        $this->fileLockRegionDirectory = (string) $fileLockRegionDirectory;
77
    }
78 277
79
    /**
80 277
     * @return string
81 277
     */
82 277
    public function getFileLockRegionDirectory()
83
    {
84
        return $this->fileLockRegionDirectory;
85
    }
86
87
    /**
88
     * @param \Doctrine\ORM\Cache\Region $region
89
     */
90
    public function setRegion(Region $region)
91
    {
92
        $this->regions[$region->getName()] = $region;
93
    }
94
95
    /**
96
     * @param \Doctrine\ORM\Cache\TimestampRegion $region
97
     */
98
    public function setTimestampRegion(TimestampRegion $region)
99
    {
100
        $this->timestampRegion = $region;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 View Code Duplication
    public function buildCachedEntityPersister(
107
        EntityManagerInterface $em,
108
        EntityPersister $persister,
109
        ClassMetadata $metadata
110
    )
111
    {
112
        $cache  = $metadata->getCache();
113
        $region = $this->getRegion($cache);
114
        $usage  = $cache->getUsage();
115
116
        switch ($usage) {
117
            case CacheUsage::READ_ONLY:
118
                return new ReadOnlyCachedEntityPersister($persister, $region, $em, $metadata);
119 125
120
            case CacheUsage::READ_WRITE:
121 125
                return new ReadWriteCachedEntityPersister($persister, $region, $em, $metadata);
122 125
123
            case CacheUsage::NONSTRICT_READ_WRITE:
124 125
                return new NonStrictReadWriteCachedEntityPersister($persister, $region, $em, $metadata);
125 116
126
            default:
127
                throw new \InvalidArgumentException(sprintf("Unrecognized access strategy type [%s]", $usage));
128 90
        }
129 88
    }
130
131
    /**
132 2
     * {@inheritdoc}
133 1
     */
134 View Code Duplication
    public function buildCachedCollectionPersister(
135
        EntityManagerInterface $em,
136 1
        CollectionPersister $persister,
137
        AssociationMetadata $association
138
    )
139
    {
140
        $cache  = $association->getCache();
141
        $region = $this->getRegion($cache);
142 79
        $usage  = $cache->getUsage();
143
144 79
        switch ($usage) {
145 79
            case CacheUsage::READ_ONLY:
146
                return new ReadOnlyCachedCollectionPersister($persister, $region, $em, $association);
147 79
148 57
            case CacheUsage::READ_WRITE:
149
                return new ReadWriteCachedCollectionPersister($persister, $region, $em, $association);
150
151 78
            case CacheUsage::NONSTRICT_READ_WRITE:
152 76
                return new NonStrictReadWriteCachedCollectionPersister($persister, $region, $em, $association);
153
154
            default:
155 2
                throw new \InvalidArgumentException(
156 1
                    sprintf("Unrecognized access strategy type [%s]", $usage)
157
                );
158
        }
159 1
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    public function buildQueryCache(EntityManagerInterface $em, $regionName = null)
165 60
    {
166
        $cacheMetadata = new CacheMetadata(
167 60
            CacheUsage::NONSTRICT_READ_WRITE,
168
            $regionName ?: Cache::DEFAULT_QUERY_REGION_NAME
169 60
        );
170
171 60
        return new DefaultQueryCache($em, $this->getRegion($cacheMetadata));
172 60
    }
173
174
    /**
175
     * {@inheritdoc}
176
     */
177
    public function buildCollectionHydrator(EntityManagerInterface $em, AssociationMetadata $association)
178
    {
179
        return new DefaultCollectionHydrator($em);
180
    }
181 115
182
    /**
183 115
     * {@inheritdoc}
184
     */
185
    public function buildEntityHydrator(EntityManagerInterface $em, ClassMetadata $metadata)
186
    {
187
        return new DefaultEntityHydrator($em);
188
    }
189 202
190
    /**
191 202
     * {@inheritdoc}
192
     */
193
    public function getRegion(CacheMetadata $cache)
194
    {
195
        $regionName = $cache->getRegion();
196
197 127
        if (isset($this->regions[$regionName])) {
198
            return $this->regions[$regionName];
199 127
        }
200 23
201
        $cacheAdapter = $this->createRegionCache($regionName);
202
        $lifetime     = $this->regionsConfig->getLifetime($regionName);
203 127
        $region       = ($cacheAdapter instanceof MultiGetCache)
204
            ? new DefaultMultiGetRegion($regionName, $cacheAdapter, $lifetime)
205 127
            : new DefaultRegion($regionName, $cacheAdapter, $lifetime)
206 126
        ;
207
208
        if ($cache->getUsage() === CacheUsage::READ_WRITE) {
209 127
            if ( ! $this->fileLockRegionDirectory) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->fileLockRegionDirectory of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
210 127
                throw new \LogicException(
211
                    'If you want to use a "READ_WRITE" cache an implementation of "Doctrine\ORM\Cache\ConcurrentRegion" is required, ' .
212 127
                    'The default implementation provided by doctrine is "Doctrine\ORM\Cache\Region\FileLockRegion" if you want to use it please provide a valid directory, DefaultCacheFactory#setFileLockRegionDirectory(). '
213 126
                );
214 127
            }
215
216 127
            $directory = $this->fileLockRegionDirectory . DIRECTORY_SEPARATOR . $regionName;
217
            $region    = new FileLockRegion($region, $directory, $this->regionsConfig->getLockLifetime($regionName));
218 1
        }
219 1
220
        return $this->regions[$regionName] = $region;
221 1
    }
222
223
    /**
224
     * @param string $name
225
     *
226
     * @return CacheAdapter
227
     */
228
    private function createRegionCache($name)
229 126
    {
230
        $cacheAdapter = clone $this->cache;
231
232
        if (!$cacheAdapter instanceof CacheProvider) {
233
            return $cacheAdapter;
234
        }
235 190
236
        $namespace = $cacheAdapter->getNamespace();
237 190
238 190
        if ('' !== $namespace) {
239 190
            $namespace .= ':';
240
        }
241 190
242
        $cacheAdapter->setNamespace($namespace . $name);
243
244 190
        return $cacheAdapter;
245
    }
246
247
    /**
248
     * {@inheritdoc}
249
     */
250 277
    public function getTimestampRegion()
251
    {
252 277
        if ($this->timestampRegion === null) {
253
            $name     = Cache::DEFAULT_TIMESTAMP_REGION_NAME;
254
            $lifetime = $this->regionsConfig->getLifetime($name);
255
256
            $this->timestampRegion = new UpdateTimestampCache($name, clone $this->cache, $lifetime);
257
        }
258
259
        return $this->timestampRegion;
260
    }
261
262
    /**
263
     * {@inheritdoc}
264
     */
265
    public function createCache(EntityManagerInterface $em)
266
    {
267
        return new DefaultCache($em);
268
    }
269
}
270