Completed
Push — development ( 63f3ce...83de77 )
by Romain
02:34
created

Core::getObjectService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 Configuration Object project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\ConfigurationObject\Core;
15
16
use Romm\ConfigurationObject\Core\Service\CacheService;
17
use Romm\ConfigurationObject\Core\Service\ObjectService;
18
use Romm\ConfigurationObject\Exceptions\MethodNotFoundException;
19
use Romm\ConfigurationObject\Exceptions\SilentExceptionInterface;
20
use Romm\ConfigurationObject\Service\Items\Parents\ParentsUtility;
21
use Romm\ConfigurationObject\Service\ServiceFactory;
22
use Romm\ConfigurationObject\Validation\ValidatorResolver;
23
use TYPO3\CMS\Core\Cache\CacheManager;
24
use TYPO3\CMS\Core\SingletonInterface;
25
use TYPO3\CMS\Core\Utility\GeneralUtility;
26
use TYPO3\CMS\Extbase\Object\ObjectManager;
27
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
28
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
29
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
30
31
/**
32
 * General functions.
33
 *
34
 * The structure is here to help unit tests to mock correctly what is needed.
35
 */
36
class Core implements SingletonInterface
37
{
38
    /**
39
     * @var Core
40
     */
41
    protected static $instance;
42
43
    /**
44
     * @var ObjectManagerInterface
45
     */
46
    protected $objectManager;
47
48
    /**
49
     * @var ReflectionService
50
     */
51
    protected $reflectionService;
52
53
    /**
54
     * @var ValidatorResolver
55
     */
56
    protected $validatorResolver;
57
58
    /**
59
     * @var CacheManager
60
     */
61
    protected $cacheManager;
62
63
    /**
64
     * @var ParentsUtility
65
     */
66
    protected $parentsUtility;
67
68
    /**
69
     * @var CacheService
70
     */
71
    protected $cacheService;
72
73
    /**
74
     * @var ObjectService
75
     */
76
    protected $objectService;
77
78
    /**
79
     * @var array
80
     */
81
    protected $existingClassList = [];
82
83
    /**
84
     * @var array[]
85
     */
86
    protected $gettablePropertiesOfObjects = [];
87
88
    /**
89
     * @return Core
90
     */
91
    public static function get()
92
    {
93
        if (null === self::$instance) {
94
            /** @var ObjectManager $objectManager */
95
            $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
96
97
            self::$instance = $objectManager->get(self::class);
98
        }
99
100
        return self::$instance;
101
    }
102
103
    /**
104
     * Internal function which will check if the given class exists. This is
105
     * useful because of the calls to undefined class, which can lead to a lack
106
     * of performance due to the auto-loader called if the name of the class
107
     * is not registered yet.
108
     *
109
     * This function will store the already checked class name in local cache.
110
     *
111
     * @param string $className
112
     * @return bool
113
     */
114
    public function classExists($className)
115
    {
116
        if (false === isset($this->existingClassList[$className])) {
117
            $this->existingClassList[$className] = class_exists($className) || interface_exists($className);
118
        }
119
120
        return $this->existingClassList[$className];
121
    }
122
123
    /**
124
     * Returns the list of properties which are accessible for this given
125
     * object.
126
     *
127
     * Properties are stored in local cache to improve performance.
128
     *
129
     * @param object $object
130
     * @return array
131
     */
132
    public function getGettablePropertiesOfObject($object)
133
    {
134
        $className = get_class($object);
135
136
        if (false === isset($this->gettablePropertiesOfObjects[$className])) {
137
            $this->gettablePropertiesOfObjects[$className] = [];
138
            $properties = $this->getReflectionService()->getClassPropertyNames($className);
139
140
            foreach ($properties as $propertyName) {
141
                if (true === $this->isPropertyGettable($object, $propertyName)) {
142
                    $this->gettablePropertiesOfObjects[$className][] = $propertyName;
143
                }
144
            }
145
        }
146
147
        return $this->gettablePropertiesOfObjects[$className];
148
    }
149
150
    /**
151
     * Will check if the property of the given object is gettable. Meaning it
152
     * can be accessed either:
153
     *
154
     * - By the true getter if it does exist;
155
     * - Or by a magic method.
156
     *
157
     * @param object $object
158
     * @param string $propertyName
159
     * @return bool
160
     */
161
    protected function isPropertyGettable($object, $propertyName)
162
    {
163
        $flag = false;
164
165
        if (ObjectAccess::isPropertyGettable($object, $propertyName)) {
166
            $flag = true;
167
            $getterMethodName = 'get' . ucfirst($propertyName);
168
169
            if (false === method_exists($object, $getterMethodName)
170
                && is_callable([$object, $getterMethodName])
171
            ) {
172
                try {
173
                    $object->$getterMethodName();
174
                } catch (\Exception $e) {
175
                    if ($e instanceof MethodNotFoundException
176
                        || false === $e instanceof SilentExceptionInterface
177
                    ) {
178
                        $flag = false;
179
                    }
180
                }
181
            }
182
        }
183
184
        return $flag;
185
    }
186
187
    /**
188
     * @return ServiceFactory
189
     */
190
    public function getServiceFactoryInstance()
191
    {
192
        /** @var ServiceFactory $serviceFactory */
193
        $serviceFactory = GeneralUtility::makeInstance(ServiceFactory::class);
194
195
        return $serviceFactory;
196
    }
197
198
    /**
199
     * @return ObjectManagerInterface
200
     */
201
    public function getObjectManager()
202
    {
203
        return $this->objectManager;
204
    }
205
206
    /**
207
     * @param ObjectManagerInterface $objectManager
208
     */
209
    public function injectObjectManager(ObjectManagerInterface $objectManager)
210
    {
211
        $this->objectManager = $objectManager;
212
    }
213
214
    /**
215
     * @return ReflectionService
216
     */
217
    public function getReflectionService()
218
    {
219
        return $this->reflectionService;
220
    }
221
222
    /**
223
     * @param ReflectionService $reflectionService
224
     */
225
    public function injectReflectionService(ReflectionService $reflectionService)
226
    {
227
        $this->reflectionService = $reflectionService;
228
    }
229
230
    /**
231
     * @return ValidatorResolver
232
     */
233
    public function getValidatorResolver()
234
    {
235
        return $this->validatorResolver;
236
    }
237
238
    /**
239
     * @param ValidatorResolver $validatorResolver
240
     */
241
    public function injectValidatorResolver(ValidatorResolver $validatorResolver)
242
    {
243
        $this->validatorResolver = $validatorResolver;
244
    }
245
246
    /**
247
     * @return CacheManager
248
     */
249
    public function getCacheManager()
250
    {
251
        return $this->cacheManager;
252
    }
253
254
    /**
255
     * @param CacheManager $cacheManager
256
     */
257
    public function injectCacheManager(CacheManager $cacheManager)
258
    {
259
        $this->cacheManager = $cacheManager;
260
    }
261
262
    /**
263
     * @return ObjectService
264
     */
265
    public function getObjectService()
266
    {
267
        return $this->objectService;
268
    }
269
270
    /**
271
     * @param ObjectService $objectService
272
     */
273
    public function injectObjectService(ObjectService $objectService)
274
    {
275
        $this->objectService = $objectService;
276
    }
277
278
    /**
279
     * @return ParentsUtility
280
     */
281
    public function getParentsUtility()
282
    {
283
        return $this->parentsUtility;
284
    }
285
286
    /**
287
     * @param ParentsUtility $parentsUtility
288
     */
289
    public function injectParentsUtility(ParentsUtility $parentsUtility)
290
    {
291
        $this->parentsUtility = $parentsUtility;
292
    }
293
294
    /**
295
     * @return CacheService
296
     */
297
    public function getCacheService()
298
    {
299
        $this->cacheService->registerInternalCache();
300
301
        return $this->cacheService;
302
    }
303
304
    /**
305
     * @param CacheService $cacheService
306
     */
307
    public function injectCacheService(CacheService $cacheService)
308
    {
309
        $this->cacheService = $cacheService;
310
    }
311
}
312