Completed
Pull Request — master (#41)
by Emanuele
05:27
created

FeatureManager   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 52.17%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 5
dl 0
loc 122
ccs 24
cts 46
cp 0.5217
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A find() 0 11 1
A create() 0 10 2
A update() 0 8 2
A generateCacheKey() 0 4 1
A __construct() 0 4 1
A findParent() 0 7 1
A findOrCreate() 0 17 3
A emptyCache() 0 10 2
1
<?php
2
3
namespace Ae\FeatureBundle\Entity;
4
5
use Doctrine\Common\Cache\Cache;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\NoResultException;
8
9
/**
10
 * @author Carlo Forghieri <[email protected]>
11
 */
12
class FeatureManager
13
{
14
    /**
15
     * @var EntityManager
16
     */
17
    protected $em;
18
19 2
    public static function generateCacheKey($parentName, $name)
20
    {
21 2
        return strtolower(sprintf('feature_%s_%s', $parentName, $name));
22
    }
23
24
    /**
25
     * @param EntityManager $em
26
     */
27 4
    public function __construct(EntityManager $em)
28
    {
29 4
        $this->em = $em;
30 4
    }
31
32
    /**
33
     * @param string $name   Feature name
34
     * @param string $parent Parent name
35
     *
36
     * @return Feature
37
     */
38
    public function find($name, $parent)
39
    {
40
        return $this->em
41
            ->createQuery('SELECT f,p FROM AeFeatureBundle:Feature f JOIN f.parent p WHERE f.name = :name AND p.name = :parent')
42
            ->setParameters([
43
                'name' => $name,
44
                'parent' => $parent,
45
            ])
46
            ->useResultCache(true, 3600 * 24, self::generateCacheKey($parent, $name))
47
            ->getSingleResult();
48
    }
49
50
    /**
51
     * @param string $name Feature name
52
     *
53
     * @return Feature
54
     */
55
    public function findParent($name)
56
    {
57
        return $this->em
58
            ->createQuery('SELECT f FROM AeFeatureBundle:Feature f WHERE f.name = :name AND f.parent IS NULL')
59
            ->setParameter('name', $name)
60
            ->getSingleResult();
61
    }
62
63
    /**
64
     * @param string $name   Feature name
65
     * @param string $parent Parent name
66
     *
67
     * @return Feature
68
     */
69
    public function findOrCreate($name, $parent)
70
    {
71
        try {
72
            $feature = $this->find($name, $parent);
73
        } catch (NoResultException $e) {
74
            try {
75
                $parent = $this->findParent($parent);
76
            } catch (NoResultException $e) {
77
                $parent = $this->create($parent);
78
            }
79
            $feature = $this->create($name, $parent);
80
81
            $this->update($feature);
82
        }
83
84
        return $feature;
85
    }
86
87
    /**
88
     * @param string  $name   Feature name
89
     * @param Feature $parent Parent Feature
90
     *
91
     * @return Feature
92
     */
93 1
    public function create($name, Feature $parent = null)
94
    {
95 1
        $feature = new Feature();
96 1
        $feature->setName($name);
97 1
        if ($parent) {
98 1
            $feature->setParent($parent);
99
        }
100
101 1
        return $feature;
102
    }
103
104
    /**
105
     * @param Feature $feature
106
     * @param bool    $andFlush
107
     */
108 2
    public function update(Feature $feature, $andFlush = true)
109
    {
110 2
        $this->em->persist($feature);
111 2
        if ($andFlush) {
112 2
            $this->em->flush();
113 2
            $this->emptyCache($feature->getName(), $feature->getParent()->getName());
114
        }
115 2
    }
116
117
    /**
118
     * @todo Move cache logic to a separate class
119
     *
120
     * @param string $name
121
     * @param string $parent
122
     */
123 2
    public function emptyCache($name, $parent)
124
    {
125 2
        $cache = $this->em
126 2
            ->getConfiguration()
127 2
            ->getResultCacheImpl();
128
129 2
        if ($cache instanceof Cache) {
130 1
            $cache->delete(self::generateCacheKey($parent, $name));
131
        }
132 2
    }
133
}
134