Passed
Push — main ( 04a742...5b603f )
by
unknown
04:37 queued 12s
created

Builder::configureRestler()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.1417

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 19
c 2
b 0
f 0
nc 7
nop 1
dl 0
loc 33
ccs 16
cts 19
cp 0.8421
crap 6.1417
rs 9.0111
1
<?php
2
3
namespace Aoe\Restler\System\Restler;
4
5
/***************************************************************
6
 *  Copyright notice
7
 *
8
 *  (c) 2015 AOE GmbH <[email protected]>
9
 *
10
 *  All rights reserved
11
 *
12
 *  This script is part of the TYPO3 project. The TYPO3 project is
13
 *  free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 3 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  The GNU General Public License can be found at
19
 *  http://www.gnu.org/copyleft/gpl.html.
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28
29
use Aoe\Restler\Configuration\ExtensionConfiguration;
30
use Aoe\Restler\System\TYPO3\Cache;
31
use InvalidArgumentException;
32
use Luracast\Restler\Defaults;
33
use Luracast\Restler\Scope;
34
use Psr\Http\Message\ServerRequestInterface;
35
use TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend;
36
use TYPO3\CMS\Core\Cache\CacheManager;
37
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
38
use TYPO3\CMS\Core\SingletonInterface;
39
use TYPO3\CMS\Core\Utility\GeneralUtility;
40
use TYPO3\CMS\Extbase\Object\ObjectManager;
41
42
/**
43
 * @package Restler
44
 */
45
class Builder implements SingletonInterface
46
{
47
    private ExtensionConfiguration $extensionConfiguration;
48
49
    private CacheManager $cacheManager;
50
51 9
    public function __construct(ExtensionConfiguration $extensionConfiguration, CacheManager $cacheManager)
52
    {
53 9
        $this->extensionConfiguration = $extensionConfiguration;
54 9
        $this->cacheManager = $cacheManager;
55 9
    }
56
57
    /**
58
     * initialize and configure restler-framework and return restler-object
59
     *
60
     * @return RestlerExtended
61
     */
62
    public function build(ServerRequestInterface $request = null)
63
    {
64
        $this->setAutoLoading();
65
        $this->setCacheDirectory();
66
        $this->setServerConfiguration();
67
68
        $restlerObj = $this->createRestlerObject($request);
69
        $this->configureRestler($restlerObj);
70
        $this->addApiClassesByGlobalArray($restlerObj);
71
        return $restlerObj;
72
    }
73
74 1
    protected function createRestlerObject(ServerRequestInterface $request = null): RestlerExtended
75
    {
76 1
        return new RestlerExtended(
77 1
            GeneralUtility::makeInstance(Cache::class),
78 1
            $this->extensionConfiguration->isProductionContextSet(),
79 1
            $this->extensionConfiguration->isCacheRefreshingEnabled(),
80
            $request
81
        );
82
    }
83
84
    /**
85
     * Call all classes, which implements the interface 'Aoe\Restler\System\Restler\ConfigurationInterface'.
86
     * Those classes includes further restler-configurations, e.g.:
87
     *  - add API-classes
88
     *  - add authentication-classes
89
     *  - configure/set properties of several classes inside the restler-framework
90
     *  - configure overwriting of several classes inside the restler-framework
91
     *
92
     * @throws InvalidArgumentException
93
     */
94 4
    private function configureRestler(RestlerExtended $restler)
95
    {
96 4
        $restlerConfigurationClasses = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['restler']['restlerConfigurationClasses'];
97
98 4
        if (!is_array($restlerConfigurationClasses) || $restlerConfigurationClasses === []) {
99 2
            $message = 'No restler-configuration-class found (at least one restler-configuration-class is required)! ';
100 2
            $message .= 'The configuration-class must be registered in ext_localconf.php of your TYPO3-extension like this: ';
101 2
            $message .= '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'restler\'][\'restlerConfigurationClasses\'][] =
102
                \'[YourConfigurationClass]\';';
103 2
            $message .= 'The configuration-class must implement this interface: Aoe\Restler\System\Restler\ConfigurationInterface';
104 2
            throw new InvalidArgumentException($message, 1428562059);
105
        }
106
107
        // append configuration classes from external GLOBAL registration
108 2
        if (is_array($GLOBALS['TYPO3_Restler']['restlerConfigurationClasses'])) {
109 2
            $externalRestlerConfigurationClasses = array_unique($GLOBALS['TYPO3_Restler']['restlerConfigurationClasses']);
110 2
            $restlerConfigurationClasses = array_merge(
111 2
                $restlerConfigurationClasses,
112
                $externalRestlerConfigurationClasses
113
            );
114
        }
115
116 2
        foreach ($restlerConfigurationClasses as $restlerConfigurationClass) {
117
            /** @var ConfigurationInterface $configurationObj */
118 2
            $configurationObj = GeneralUtility::makeInstance($restlerConfigurationClass);
119
120 2
            if (!$configurationObj instanceof ConfigurationInterface) {
121
                $message = 'class "' . $restlerConfigurationClass . '" did not implement the ';
122
                $message .= 'interface "Aoe\Restler\System\Restler\ConfigurationInterface"!';
123
                throw new InvalidArgumentException($message, 1428562081);
124
            }
125
126 2
            $configurationObj->configureRestler($restler);
127
        }
128 2
    }
129
130
    /**
131
     * Add API-Controller-Classes that are registered by global array
132
     */
133 1
    private function addApiClassesByGlobalArray(RestlerExtended $restler)
134
    {
135 1
        $addApiController = $GLOBALS['TYPO3_Restler']['addApiClass'];
136 1
        if (is_array($addApiController)) {
137 1
            foreach ($addApiController as $apiEndpoint => $apiControllers) {
138 1
                $uniqueApiControllers = array_unique($apiControllers);
139 1
                foreach ($uniqueApiControllers as $apiController) {
140 1
                    $restler->addAPIClass($apiController, $apiEndpoint);
141
                }
142
            }
143
        }
144 1
    }
145
146
    /**
147
     * use auto-loading for PHP-classes of restler-framework and Extbase/TYPO3 (use dependency-injection of Extbase)
148
     */
149 1
    private function setAutoLoading()
150
    {
151
        // set auto-loading for Extbase/TYPO3-classes
152 1
        Scope::$resolver = function ($className) {
153
            // @TODO TYPO3 v12:
154
            // Using of ObjectManager will be removed in TYPO3v12. Currently, we must use the ObjectManager here,
155
            // because it can happen, that e.g. the REST-controllers (which 3rd-party-extensions provide), are not
156
            // supporting the new dependency-injection (via symfony) of TYPO3!
157 1
            return GeneralUtility::makeInstance(ObjectManager::class)->get($className);
158
        };
159 1
    }
160
161
    /**
162
     * configure cache-directory (where restler can write cache-files)
163
     */
164 1
    private function setCacheDirectory()
165
    {
166 1
        Defaults::$cacheDirectory = $this->getCache()->getCacheDirectory();
167 1
    }
168
169
    /**
170
     * fix server-port (if not correct set)
171
     */
172 1
    private function setServerConfiguration()
173
    {
174 1
        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' && $_SERVER['SERVER_PORT'] === '80') {
175
            // Fix port for HTTPS
176
            // Otherwise restler will create those urls for online-documentation, when HTTPS is used: https://www.example.com:80
177 1
            $_SERVER['SERVER_PORT'] = '443';
178
        }
179 1
    }
180
181
    /**
182
     * @return SimpleFileBackend
183
     * @throws NoSuchCacheException
184
     */
185 1
    private function getCache()
186
    {
187 1
        return $this->cacheManager->getCache('tx_restler_cache')
188 1
            ->getBackend();
189
    }
190
}
191