ClassMetadataFactory   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 127
c 1
b 0
f 1
wmc 17
lcom 1
cbo 2
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getAllMetadata() 0 11 3
B getMetadataFor() 0 24 6
A hasMetadataFor() 0 4 1
A setMetadataFor() 0 4 1
A loadMetadata() 0 12 3
A getClassHierarchy() 0 12 2
1
<?php
2
/**
3
 * This file is part of the Cubiche package.
4
 *
5
 * Copyright (c) Cubiche
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cubiche\Core\Metadata;
12
13
use Cubiche\Core\Metadata\Cache\CacheInterface;
14
use Cubiche\Core\Metadata\Driver\DriverInterface;
15
16
/**
17
 * ClassMetadataFactory class.
18
 *
19
 * @author Ivannis Suárez Jerez <[email protected]>
20
 */
21
class ClassMetadataFactory implements ClassMetadataFactoryInterface
22
{
23
    /**
24
     * @var DriverInterface
25
     */
26
    protected $driver;
27
28
    /**
29
     * @var CacheInterface
30
     */
31
    protected $cache;
32
33
    /**
34
     * @var array
35
     */
36
    protected $loadedMetadata = array();
37
38
    /**
39
     * ClassMetadataFactory constructor.
40
     *
41
     * @param DriverInterface     $driver
42
     * @param CacheInterface|null $cache
43
     */
44
    public function __construct(DriverInterface $driver, CacheInterface $cache = null)
45
    {
46
        $this->driver = $driver;
47
        $this->cache = $cache;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53
    public function getAllMetadata()
54
    {
55
        $metadatas = [];
56
        foreach ($this->driver->getAllClassNames() as $className) {
57
            if (null !== $metadata = $this->getMetadataFor($className)) {
58
                $metadatas[] = $metadata;
59
            }
60
        }
61
62
        return $metadatas;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function getMetadataFor($className)
69
    {
70
        if (isset($this->loadedMetadata[$className])) {
71
            return $this->loadedMetadata[$className];
72
        }
73
74
        if ($this->cache !== null) {
75
            if (($cached = $this->cache->load($className)) !== null) {
76
                $this->loadedMetadata[$className] = $cached;
77
            } else {
78
                foreach ($this->loadMetadata($className) as $loadedClassName) {
79
                    $this->cache->save($this->loadedMetadata[$loadedClassName]);
80
                }
81
            }
82
        } else {
83
            $this->loadMetadata($className);
84
        }
85
86
        if (isset($this->loadedMetadata[$className])) {
87
            return $this->loadedMetadata[$className];
88
        }
89
90
        return;
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function hasMetadataFor($className)
97
    {
98
        return isset($this->loadedMetadata[$className]);
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function setMetadataFor($className, ClassMetadataInterface $metadata)
105
    {
106
        $this->loadedMetadata[$className] = $metadata;
107
    }
108
109
    /**
110
     * Loads the metadata of the class in question and all it's ancestors whose metadata
111
     * is still not loaded.
112
     *
113
     * @param string $className
114
     *
115
     * @return array
116
     */
117
    protected function loadMetadata($className)
118
    {
119
        $classNames = [];
120
        foreach ($this->getClassHierarchy($className) as $class) {
121
            if (null !== $classMetadata = $this->driver->loadMetadataForClass($class)) {
122
                $this->loadedMetadata[$class] = $classMetadata;
123
                $classNames[] = $class;
124
            }
125
        }
126
127
        return $classNames;
128
    }
129
130
    /**
131
     * @param string $className
132
     *
133
     * @return array
134
     */
135
    private function getClassHierarchy($className)
136
    {
137
        $classes = array();
138
        $refl = new \ReflectionClass($className);
139
140
        do {
141
            $classes[] = $refl->getName();
142
            $refl = $refl->getParentClass();
143
        } while (false !== $refl);
144
145
        return array_reverse($classes, false);
146
    }
147
}
148