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

RestApiClient::createRequestException()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 7
c 0
b 0
f 0
nc 2
nop 3
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Aoe\Restler\System\RestApi;
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\Restler\Builder as RestlerBuilder;
31
use Aoe\Restler\System\TYPO3\Cache;
32
use Luracast\Restler\RestException;
33
use TYPO3\CMS\Core\SingletonInterface;
34
use TYPO3\CMS\Core\Utility\GeneralUtility;
35
use TYPO3\CMS\Core\Http\ServerRequest;
36
use stdClass;
37
38
/**
39
 * @package Restler
40
 */
41
class RestApiClient implements SingletonInterface
42
{
43
    private Cache $typo3Cache;
44
45
    private ExtensionConfiguration $extensionConfiguration;
46
47
    private bool $isExecutingRequest = false;
48
49
    private bool $isRequestPrepared = false;
50
51
    private RestApiRequestScope $restApiRequestScope;
52
53 5
    public function __construct(
54
        ExtensionConfiguration $extensionConfiguration,
55
        RestApiRequestScope $restApiRequestScope,
56
        Cache $typo3Cache
57
    ) {
58 5
        $this->extensionConfiguration = $extensionConfiguration;
59 5
        $this->restApiRequestScope = $restApiRequestScope;
60 5
        $this->typo3Cache = $typo3Cache;
61 5
    }
62
63 1
    public function isExecutingRequest(): bool
64
    {
65 1
        return $this->isExecutingRequest;
66
    }
67
68 2
    public function isProductionContextSet(): bool
69
    {
70 2
        return $this->extensionConfiguration->isProductionContextSet();
71
    }
72
73
    /**
74
     * @param array|stdClass $getData
75
     * @param array|stdClass $postData
76
     * @return mixed can be a primitive or array or object
77
     * @throws RestApiRequestException
78
     */
79 3
    public function executeRequest(string $requestMethod, string $requestUri, $getData = null, $postData = null)
80
    {
81 3
        if ($this->isRequestPreparationRequired()) {
82 1
            $this->prepareRequest($requestMethod, $requestUri);
83
        }
84
85
        try {
86 3
            $this->isExecutingRequest = true;
87 3
            $result = $this->createRequest()
88 3
                ->executeRestApiRequest($requestMethod, $requestUri, $getData, $postData);
89 2
            $this->isExecutingRequest = false;
90 2
            return $result;
91 1
        } catch (RestException $restException) {
92 1
            $this->isExecutingRequest = false;
93 1
            $restException = $this->createRequestException($restException, $requestMethod, $requestUri);
94 1
            throw $restException;
95
        }
96
    }
97
98
    /**
99
     * We must create for every REST-API-request a new object, because the object will contain data, which is related to the request
100
     */
101
    protected function createRequest(): RestApiRequest
102
    {
103
        return new RestApiRequest($this->restApiRequestScope, $this->typo3Cache);
104
    }
105
106 1
    protected function createRequestException(RestException $e, string $requestMethod, string $requestUri): RestApiRequestException
107
    {
108 1
        $errorMessage = "internal REST-API-request '" . $requestMethod . ':' . $requestUri . "' could not be processed";
109 1
        if (!$this->isProductionContextSet()) {
110 1
            $errorMessage .= ' (message: ' . $e->getMessage() . ', details: ' . json_encode($e->getDetails(), JSON_THROW_ON_ERROR) . ')';
111
        }
112 1
        return new RestApiRequestException(
113 1
            $errorMessage,
114 1
            RestApiRequestException::EXCEPTION_CODE_REQUEST_COULD_NOT_PROCESSED,
115
            $e
116
        );
117
    }
118
119
    protected function getRestlerBuilder(): RestlerBuilder
120
    {
121
        return GeneralUtility::makeInstance(RestlerBuilder::class);
122
    }
123
124
    /**
125
     * We must prepare the REST-API-request when we are in the 'normal' TYPO3-context (the client, which called this PHP-request, has
126
     * NOT requested an REST-API-endpoint). In this case, we must build the 'original' REST-API-Request (aka Restler-object, which is
127
     * always required), before we can execute any REST-API-request via this PHP-client.
128
     */
129
    protected function isRequestPreparationRequired(): bool
130
    {
131
        return !defined('REST_API_IS_RUNNING') && !$this->isRequestPrepared;
132
    }
133
134
    /**
135
     * build the 'original' REST-API-Request (aka Restler-object, which is always
136
     * required) and store it in the REST-API-Request-Scope (aka Scope-object)
137
     */
138 1
    private function prepareRequest(string $requestMethod, string $requestUri): void
139
    {
140
        // TODO: pass along the post data
141 1
        $originalRestApiRequest = $this->getRestlerBuilder()
142 1
            ->build(new ServerRequest($requestUri, $requestMethod));
143 1
        $this->restApiRequestScope->storeOriginalRestApiRequest($originalRestApiRequest);
144 1
        $this->isRequestPrepared = true;
145 1
    }
146
}
147