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

Core::getContextHash()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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