Completed
Push — cleanup-service ( b0282b...73e309 )
by Romain
02:20
created

Core::instantiate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 Formz 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\Formz\Core;
15
16
use Romm\Formz\Configuration\ConfigurationFactory;
17
use Romm\Formz\Error\FormzMessageInterface;
18
use Romm\Formz\Service\TypoScriptService;
19
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20
use TYPO3\CMS\Core\Cache\Backend\AbstractBackend;
21
use TYPO3\CMS\Core\Cache\CacheManager;
22
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
23
use TYPO3\CMS\Core\SingletonInterface;
24
use TYPO3\CMS\Core\Utility\ArrayUtility;
25
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Core\Utility\MathUtility;
28
use TYPO3\CMS\Core\Utility\PathUtility;
29
use TYPO3\CMS\Extbase\Error\Message;
30
use TYPO3\CMS\Extbase\Object\ObjectManager;
31
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
32
use TYPO3\CMS\Extbase\Service\EnvironmentService;
33
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
34
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
35
36
/**
37
 * Class containing general functions.
38
 */
39
class Core implements SingletonInterface
40
{
41
    const EXTENSION_KEY = 'formz';
42
    const CACHE_IDENTIFIER = 'cache_formz';
43
    const GENERATED_FILES_PATH = 'typo3temp/Formz/';
44
45
    /**
46
     * @var Core
47
     */
48
    protected static $instance;
49
50
    /**
51
     * @var int|null
52
     */
53
    private $currentPageUid = -1;
54
55
    /**
56
     * @var ObjectManagerInterface
57
     */
58
    private $objectManager;
59
60
    /**
61
     * @var TypoScriptService
62
     */
63
    private $typoScriptService;
64
65
    /**
66
     * @var ConfigurationFactory
67
     */
68
    private $configurationFactory;
69
70
    /**
71
     * @var EnvironmentService
72
     */
73
    private $environmentService;
74
75
    /**
76
     * Contains the actual language key.
77
     *
78
     * @var string
79
     */
80
    private $languageKey;
81
82
    /**
83
     * @var array
84
     */
85
    private $extensionConfiguration;
86
87
    /**
88
     * @var FrontendInterface
89
     */
90
    protected $cacheInstance;
91
92
    /**
93
     * @return Core
94
     */
95
    public static function get()
96
    {
97
        if (null === self::$instance) {
98
            /** @var ObjectManager $objectManager */
99
            $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
100
101
            self::$instance = $objectManager->get(self::class);
102
        }
103
104
        return self::$instance;
105
    }
106
107
    /**
108
     * Translation handler. Does the same job as Extbase translation tools,
109
     * expect that if the index to the LLL reference is not found, the index is
110
     * returned (Extbase would have returned an empty string).
111
     *
112
     * @param    string $index        The index to the LLL reference.
113
     * @param    string $extensionKey Key of the extension containing the LLL reference.
114
     * @param    array  $arguments    Arguments passed over to vsprintf.
115
     * @return   string               The translated string.
116
     */
117
    public function translate($index, $extensionKey = null, $arguments = null)
118
    {
119
        $extensionKey = ($extensionKey) ?: self::EXTENSION_KEY;
120
        $result = LocalizationUtility::translate($index, $extensionKey, $arguments);
121
        if ($result === '' && $index !== '') {
122
            $result = $index;
123
        }
124
125
        return $result;
126
    }
127
128
    /**
129
     * Converts an array to a clean JSON string which can be used by JavaScript.
130
     *
131
     * @param array $array
132
     * @return string
133
     */
134
    public function arrayToJavaScriptJson(array $array)
135
    {
136
        return json_encode($array, JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_TAG);
137
    }
138
139
    /**
140
     * Returns the type of backend cache defined in TypoScript at the path:
141
     * `settings.defaultBackendCache`.
142
     *
143
     * @return string
144
     * @throws \Exception
145
     */
146
    public function getBackendCache()
147
    {
148
        $backendCache = $this->getTypoScriptService()
149
            ->getExtensionConfigurationFromPath('settings.defaultBackendCache');
150
151
        if (false === class_exists($backendCache)
152
            && false === in_array(AbstractBackend::class, class_parents($backendCache))
153
        ) {
154
            throw new \Exception(
155
                'The cache class name given in configuration "config.tx_formz.settings.defaultBackendCache" must inherit "' . AbstractBackend::class . '" (current value: "' . (string)$backendCache . '")',
156
                1459251263
157
            );
158
        }
159
160
        return $backendCache;
161
    }
162
163
    /**
164
     * Returns the current page uid, in a frontend or backend context.
165
     *
166
     * Returns null if the uid can't be found (backend module, ajax call, etc.).
167
     *
168
     * @return int|null
169
     */
170
    public function getCurrentPageUid()
171
    {
172
        if (-1 === $this->currentPageUid) {
173
            $id = ($this->environmentService->isEnvironmentInFrontendMode())
174
                ? $this->getPageController()->id
175
                : GeneralUtility::_GP('id');
176
177
            if (false === MathUtility::canBeInterpretedAsInteger($id)
178
                || intval($id) < 0
179
            ) {
180
                $id = null;
181
            }
182
183
            $this->currentPageUid = $id;
184
        }
185
186
        return $this->currentPageUid;
187
    }
188
189
    /**
190
     * Allows you to set manually the current page uid. Useful when editing a
191
     * record, for example.
192
     *
193
     * @param int $uid The uid of the page.
194
     */
195
    public function setCurrentPageUid($uid)
196
    {
197
        $this->currentPageUid = intval($uid);
198
    }
199
200
    /**
201
     * Returns the cache instance for this extension.
202
     *
203
     * @return FrontendInterface
204
     */
205
    public function getCacheInstance()
206
    {
207
        if (null === $this->cacheInstance) {
208
            /** @var $cacheManager CacheManager */
209
            $cacheManager = $this->getObjectManager()->get(CacheManager::class);
210
211
            if ($cacheManager->hasCache(self::CACHE_IDENTIFIER)) {
212
                $this->cacheInstance = $cacheManager->getCache(self::CACHE_IDENTIFIER);
213
            }
214
        }
215
216
        return $this->cacheInstance;
217
    }
218
219
    /**
220
     * @param FrontendInterface $cacheInstance
221
     */
222
    public function setCacheInstance(FrontendInterface $cacheInstance)
223
    {
224
        $this->cacheInstance = $cacheInstance;
225
    }
226
227
    /**
228
     * Generic cache identifier creation for usages in the extension.
229
     *
230
     * @param string $string
231
     * @param string $formClassName
232
     * @param int    $maxLength
233
     * @return string
234
     */
235
    public function getCacheIdentifier($string, $formClassName, $maxLength = 55)
236
    {
237
        $explodedClassName = explode('\\', $formClassName);
238
239
        $identifier = strtolower(
240
            $string .
241
            end($explodedClassName) .
242
            '-' .
243
            sha1($formClassName)
244
        );
245
246
        return substr($identifier, 0, $maxLength);
247
    }
248
249
    /**
250
     * Return the wanted extension configuration.
251
     *
252
     * @param string $configurationName
253
     * @return mixed
254
     */
255
    public function getExtensionConfiguration($configurationName)
256
    {
257
        $result = null;
258
        $extensionConfiguration = $this->getFullExtensionConfiguration();
259
260
        if (null === $configurationName) {
261
            $result = $extensionConfiguration;
262
        } elseif (ArrayUtility::isValidPath($extensionConfiguration, $configurationName, '.')) {
263
            $result = ArrayUtility::getValueByPath($extensionConfiguration, $configurationName, '.');
264
        }
265
266
        return $result;
267
    }
268
269
    /**
270
     * @return array
271
     */
272
    protected function getFullExtensionConfiguration()
273
    {
274
        if (null === $this->extensionConfiguration) {
275
            $this->extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::EXTENSION_KEY]);
276
277
            if (false === $this->extensionConfiguration) {
278
                $this->extensionConfiguration = [];
279
            }
280
        }
281
282
        return $this->extensionConfiguration;
283
    }
284
285
    /**
286
     * Function called when clearing TYPO3 caches. It will remove the temporary
287
     * asset files created by Formz.
288
     *
289
     * @param array $parameters
290
     */
291
    public function clearCacheCommand($parameters)
292
    {
293
        if (false === in_array($parameters['cacheCmd'], ['all', 'system'])) {
294
            return;
295
        }
296
297
        $files = glob(GeneralUtility::getFileAbsFileName(self::GENERATED_FILES_PATH . '*'));
298
299
        if (false === $files) {
300
            return;
301
        }
302
303
        foreach ($files as $assetCacheFile) {
304
            unlink($assetCacheFile);
305
        }
306
    }
307
308
    /**
309
     * Returns the current language key.
310
     *
311
     * @return string
312
     */
313
    public function getLanguageKey()
314
    {
315
        if (null === $this->languageKey) {
316
            $this->languageKey = 'default';
317
318
            if ($this->environmentService->isEnvironmentInFrontendMode()) {
319
                $pageController = $this->getPageController();
320
321
                if (isset($pageController->config['config']['language'])) {
322
                    $this->languageKey = $pageController->config['config']['language'];
323
                }
324
            } else {
325
                $backendUser = $this->getBackendUser();
326
327
                if (strlen($backendUser->uc['lang']) > 0) {
328
                    $this->languageKey = $backendUser->uc['lang'];
329
                }
330
            }
331
        }
332
333
        return $this->languageKey;
334
    }
335
336
    /**
337
     * Will check if the TypoScript was indeed included, as it contains required
338
     * configuration to make the forms work properly.
339
     *
340
     * @return bool
341
     */
342
    public function isTypoScriptIncluded()
343
    {
344
        return null !== $this->getTypoScriptService()->getExtensionConfigurationFromPath('settings.typoScriptIncluded');
345
    }
346
347
    /**
348
     * @return bool
349
     */
350
    public function isInDebugMode()
351
    {
352
        return (bool)$this->getExtensionConfiguration('debugMode');
353
    }
354
355
    /**
356
     * @param string|null $path If a string is given, it will be precessed by the extension relative path and returned.
357
     * @return string
358
     */
359
    public function getExtensionRelativePath($path = null)
360
    {
361
        $relativePath = ExtensionManagementUtility::siteRelPath('formz');
362
363
        if ($this->environmentService->isEnvironmentInBackendMode()) {
364
            $relativePath = '../' . $relativePath;
365
        }
366
367
        return (null !== $path)
368
            ? $relativePath . $path
369
            : $relativePath;
370
    }
371
372
    /**
373
     * @param string $path
374
     * @return string
375
     */
376
    public function getResourceRelativePath($path)
377
    {
378
        $relativePath = rtrim(
379
            PathUtility::getRelativePath(
380
                GeneralUtility::getIndpEnv('TYPO3_DOCUMENT_ROOT'),
381
                GeneralUtility::getFileAbsFileName($path)
382
            ),
383
            '/'
384
        );
385
386
        if ($this->environmentService->isEnvironmentInBackendMode()) {
387
            $relativePath = '../' . $relativePath;
388
        }
389
390
        return $relativePath;
391
    }
392
393
    /**
394
     * Sanitizes a string: lower case with dash separation.
395
     *
396
     * @param string $string
397
     * @return string
398
     */
399
    public function sanitizeString($string)
400
    {
401
        $string = str_replace('_', '-', GeneralUtility::camelCaseToLowerCaseUnderscored($string));
402
403
        while (strpos($string, '--')) {
404
            $string = str_replace('--', '-', $string);
405
        }
406
407
        return $string;
408
    }
409
410
    /**
411
     * Returns the validation name of a message: if it is an instance of
412
     * `FormzMessageInterface`, we can fetch it, otherwise `unknown` is
413
     * returned.
414
     *
415
     * @param Message $message
416
     * @return string
417
     */
418
    public function getMessageValidationName(Message $message)
419
    {
420
        return ($message instanceof FormzMessageInterface)
421
            ? $message->getValidationName()
422
            : 'unknown';
423
    }
424
425
    /**
426
     * Returns the key of a message: if it is an instance of
427
     * `FormzMessageInterface`, we can fetch it, otherwise `unknown` is
428
     * returned.
429
     *
430
     * @param Message $message
431
     * @return string
432
     */
433
    public function getMessageKey(Message $message)
434
    {
435
        return ($message instanceof FormzMessageInterface)
436
            ? $message->getMessageKey()
437
            : 'unknown';
438
    }
439
440
    /**
441
     * Shortcut for object manager `get()` function.
442
     *
443
     * @param string $className
444
     * @return object
445
     */
446
    public static function instantiate($className)
447
    {
448
        $objectManager = self::get()->getObjectManager();
449
450
        return call_user_func_array([$objectManager, 'get'], func_get_args());
451
    }
452
453
    /**
454
     * @return ObjectManagerInterface
455
     */
456
    public function getObjectManager()
457
    {
458
        return $this->objectManager;
459
    }
460
461
    /**
462
     * @param ObjectManagerInterface $objectManager
463
     */
464
    public function injectObjectManager(ObjectManagerInterface $objectManager)
465
    {
466
        $this->objectManager = $objectManager;
467
    }
468
469
    /**
470
     * @return TypoScriptService
471
     */
472
    public function getTypoScriptService()
473
    {
474
        return $this->typoScriptService;
475
    }
476
477
    /**
478
     * @param TypoScriptService $typoScriptService
479
     */
480
    public function injectTypoScriptService(TypoScriptService $typoScriptService)
481
    {
482
        $this->typoScriptService = $typoScriptService;
483
    }
484
485
    /**
486
     * @return ConfigurationFactory
487
     */
488
    public function getConfigurationFactory()
489
    {
490
        return $this->configurationFactory;
491
    }
492
493
    /**
494
     * @param ConfigurationFactory $configurationFactory
495
     */
496
    public function injectConfigurationFactory(ConfigurationFactory $configurationFactory)
497
    {
498
        $this->configurationFactory = $configurationFactory;
499
    }
500
501
    /**
502
     * @return EnvironmentService
503
     */
504
    public function getEnvironmentService()
505
    {
506
        return $this->environmentService;
507
    }
508
509
    /**
510
     * @param EnvironmentService $environmentService
511
     */
512
    public function injectEnvironmentService(EnvironmentService $environmentService)
513
    {
514
        $this->environmentService = $environmentService;
515
    }
516
517
    /**
518
     * Returns the extension key.
519
     *
520
     * @return string
521
     */
522
    public function getExtensionKey()
523
    {
524
        return self::EXTENSION_KEY;
525
    }
526
527
    /**
528
     * @return TypoScriptFrontendController
529
     */
530
    public function getPageController()
531
    {
532
        return $GLOBALS['TSFE'];
533
    }
534
535
    /**
536
     * @return BackendUserAuthentication
537
     */
538
    public function getBackendUser()
539
    {
540
        return $GLOBALS['BE_USER'];
541
    }
542
}
543