Completed
Pull Request — master (#26)
by Romain
03:26
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
 * 2018 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\Reflection\ReflectionService;
21
use Romm\ConfigurationObject\Service\Items\Parents\ParentsUtility;
22
use Romm\ConfigurationObject\Service\ServiceFactory;
23
use Romm\ConfigurationObject\Validation\ValidatorResolver;
24
use TYPO3\CMS\Core\Cache\CacheManager;
25
use TYPO3\CMS\Core\SingletonInterface;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Extbase\Object\ObjectManager;
28
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
29
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
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 (!$className) {
117
            return false;
118
        }
119
120
        if (false === isset($this->existingClassList[$className])) {
121
            $this->existingClassList[$className] = class_exists($className) || interface_exists($className);
122
        }
123
124
        return $this->existingClassList[$className];
125
    }
126
127
    /**
128
     * Returns the list of properties which are accessible for this given
129
     * object.
130
     *
131
     * Properties are stored in local cache to improve performance.
132
     *
133
     * @param object $object
134
     * @return array
135
     */
136
    public function getGettablePropertiesOfObject($object)
137
    {
138
        $className = get_class($object);
139
140
        if (false === isset($this->gettablePropertiesOfObjects[$className])) {
141
            $this->gettablePropertiesOfObjects[$className] = [];
142
            $properties = $this->getReflectionService()->getClassPropertyNames($className);
143
144
            foreach ($properties as $propertyName) {
145
                if (true === $this->isPropertyGettable($object, $propertyName)) {
146
                    $this->gettablePropertiesOfObjects[$className][] = $propertyName;
147
                }
148
            }
149
        }
150
151
        return $this->gettablePropertiesOfObjects[$className];
152
    }
153
154
    /**
155
     * Will check if the property of the given object is gettable. Meaning it
156
     * can be accessed either:
157
     *
158
     * - By the true getter if it does exist;
159
     * - Or by a magic method.
160
     *
161
     * @param object $object
162
     * @param string $propertyName
163
     * @return bool
164
     */
165
    protected function isPropertyGettable($object, $propertyName)
166
    {
167
        $flag = false;
168
169
        if (ObjectAccess::isPropertyGettable($object, $propertyName)) {
170
            $flag = true;
171
            $getterMethodName = 'get' . ucfirst($propertyName);
172
173
            if (false === method_exists($object, $getterMethodName)
174
                && is_callable([$object, $getterMethodName])
175
            ) {
176
                try {
177
                    $object->$getterMethodName();
178
                } catch (\Exception $e) {
179
                    if ($e instanceof MethodNotFoundException
180
                        || false === $e instanceof SilentExceptionInterface
181
                    ) {
182
                        $flag = false;
183
                    }
184
                }
185
            }
186
        }
187
188
        return $flag;
189
    }
190
191
    /**
192
     * @return ServiceFactory
193
     */
194
    public function getServiceFactoryInstance()
195
    {
196
        /** @var ServiceFactory $serviceFactory */
197
        $serviceFactory = GeneralUtility::makeInstance(ServiceFactory::class);
198
199
        return $serviceFactory;
200
    }
201
202
    /**
203
     * @return ObjectManagerInterface
204
     */
205
    public function getObjectManager()
206
    {
207
        return $this->objectManager;
208
    }
209
210
    /**
211
     * @param ObjectManagerInterface $objectManager
212
     */
213
    public function injectObjectManager(ObjectManagerInterface $objectManager)
214
    {
215
        $this->objectManager = $objectManager;
216
    }
217
218
    /**
219
     * @return ReflectionService
220
     */
221
    public function getReflectionService()
222
    {
223
        return $this->reflectionService;
224
    }
225
226
    /**
227
     * @param ReflectionService $reflectionService
228
     */
229
    public function injectReflectionService(ReflectionService $reflectionService)
230
    {
231
        $this->reflectionService = $reflectionService;
232
    }
233
234
    /**
235
     * @return ValidatorResolver
236
     */
237
    public function getValidatorResolver()
238
    {
239
        return $this->validatorResolver;
240
    }
241
242
    /**
243
     * @param ValidatorResolver $validatorResolver
244
     */
245
    public function injectValidatorResolver(ValidatorResolver $validatorResolver)
246
    {
247
        $this->validatorResolver = $validatorResolver;
248
    }
249
250
    /**
251
     * @return CacheManager
252
     */
253
    public function getCacheManager()
254
    {
255
        return $this->cacheManager;
256
    }
257
258
    /**
259
     * @param CacheManager $cacheManager
260
     */
261
    public function injectCacheManager(CacheManager $cacheManager)
262
    {
263
        $this->cacheManager = $cacheManager;
264
    }
265
266
    /**
267
     * @return ObjectService
268
     */
269
    public function getObjectService()
270
    {
271
        return $this->objectService;
272
    }
273
274
    /**
275
     * @param ObjectService $objectService
276
     */
277
    public function injectObjectService(ObjectService $objectService)
278
    {
279
        $this->objectService = $objectService;
280
    }
281
282
    /**
283
     * @return ParentsUtility
284
     */
285
    public function getParentsUtility()
286
    {
287
        return $this->parentsUtility;
288
    }
289
290
    /**
291
     * @param ParentsUtility $parentsUtility
292
     */
293
    public function injectParentsUtility(ParentsUtility $parentsUtility)
294
    {
295
        $this->parentsUtility = $parentsUtility;
296
    }
297
298
    /**
299
     * @return CacheService
300
     */
301
    public function getCacheService()
302
    {
303
        $this->cacheService->registerInternalCache();
304
305
        return $this->cacheService;
306
    }
307
308
    /**
309
     * @param CacheService $cacheService
310
     */
311
    public function injectCacheService(CacheService $cacheService)
312
    {
313
        $this->cacheService = $cacheService;
314
    }
315
}
316