Completed
Push — master ( 18e3f4...b9ace2 )
by
unknown
29:38 queued 09:10
created

ReflectionService::__sleep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Extbase\Reflection;
17
18
use TYPO3\CMS\Core\Cache\CacheManager;
19
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
20
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
21
use TYPO3\CMS\Core\Core\Environment;
22
use TYPO3\CMS\Core\Information\Typo3Version;
23
use TYPO3\CMS\Core\SingletonInterface;
24
use TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException;
25
26
/**
27
 * Reflection service for acquiring reflection based information.
28
 * Originally based on the TYPO3.Flow reflection service.
29
 */
30
class ReflectionService implements SingletonInterface
31
{
32
    /**
33
     * @var string
34
     */
35
    private static $cacheEntryIdentifier;
36
37
    /**
38
     * @var FrontendInterface
39
     */
40
    protected $dataCache;
41
42
    /**
43
     * Indicates whether the Reflection cache needs to be updated.
44
     *
45
     * This flag needs to be set as soon as new Reflection information was
46
     * created.
47
     *
48
     * @var bool
49
     */
50
    protected $dataCacheNeedsUpdate = false;
51
52
    /**
53
     * Local cache for Class schemata
54
     *
55
     * @var array
56
     */
57
    protected $classSchemata = [];
58
59
    /**
60
     * @var bool
61
     */
62
    private $cachingEnabled = false;
63
64
    /**
65
     * If not $cacheManager is injected, the reflection service does not
66
     * cache any data, useful for testing this service in unit tests.
67
     *
68
     * @param CacheManager $cacheManager
69
     */
70
    public function __construct(CacheManager $cacheManager = null)
71
    {
72
        if ($cacheManager instanceof CacheManager) {
73
            try {
74
                $this->dataCache = $cacheManager->getCache('extbase');
75
                $this->cachingEnabled = true;
76
            } catch (NoSuchCacheException $ignoredException) {
77
                $this->cachingEnabled = false;
78
            }
79
80
            if ($this->cachingEnabled) {
81
                static::$cacheEntryIdentifier = 'ClassSchemata_' . sha1((string)(new Typo3Version()) . Environment::getProjectPath());
0 ignored issues
show
Bug introduced by
Since $cacheEntryIdentifier is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $cacheEntryIdentifier to at least protected.
Loading history...
82
                if (($classSchemata = $this->dataCache->get(static::$cacheEntryIdentifier)) !== false) {
83
                    $this->classSchemata = $classSchemata;
84
                }
85
            }
86
        }
87
    }
88
89
    public function __destruct()
90
    {
91
        if ($this->dataCacheNeedsUpdate && $this->cachingEnabled) {
92
            $this->dataCache->set(static::$cacheEntryIdentifier, $this->classSchemata);
0 ignored issues
show
Bug introduced by
Since $cacheEntryIdentifier is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $cacheEntryIdentifier to at least protected.
Loading history...
93
        }
94
    }
95
96
    /**
97
     * Returns the class schema for the given class
98
     *
99
     * @param mixed $classNameOrObject The class name or an object
100
     * @return ClassSchema
101
     * @throws \TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException
102
     */
103
    public function getClassSchema($classNameOrObject): ClassSchema
104
    {
105
        $className = is_object($classNameOrObject) ? get_class($classNameOrObject) : $classNameOrObject;
106
        if (isset($this->classSchemata[$className])) {
107
            return $this->classSchemata[$className];
108
        }
109
110
        return $this->buildClassSchema($className);
111
    }
112
113
    /**
114
     * Builds class schemata from classes annotated as entities or value objects
115
     *
116
     * @param string $className
117
     * @throws Exception\UnknownClassException
118
     * @return ClassSchema The class schema
119
     */
120
    protected function buildClassSchema($className): ClassSchema
121
    {
122
        try {
123
            $classSchema = new ClassSchema($className);
124
        } catch (\ReflectionException $e) {
125
            throw new UnknownClassException($e->getMessage() . '. Reflection failed.', 1278450972, $e);
126
        }
127
        $this->classSchemata[$className] = $classSchema;
128
        $this->dataCacheNeedsUpdate = true;
129
        return $classSchema;
130
    }
131
132
    /**
133
     * @internal
134
     */
135
    public function __sleep(): array
136
    {
137
        return [];
138
    }
139
140
    /**
141
     * @internal
142
     */
143
    public function __wakeup(): void
144
    {
145
        $this->dataCache = null;
146
        $this->dataCacheNeedsUpdate = false;
147
        $this->classSchemata = [];
148
        $this->cachingEnabled = false;
149
    }
150
}
151