Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
tao_actions_RestTrait
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 7
342
0.00% covered (danger)
0.00%
0 / 1
 getAcceptableMimeTypes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 returnFailure
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 returnSuccess
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 encode
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
42
 getErrorMessage
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 logException
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 getAdvancedLogger
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 201 (original work) Open Assessment Technologies SA;
19 *
20 */
21
22// phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace, Squiz.Classes.ValidClassName.NotCamelCaps
23use oat\oatbox\log\logger\AdvancedLogger;
24use oat\oatbox\log\logger\extender\ContextExtenderInterface;
25use oat\tao\helpers\RestExceptionHandler;
26use oat\tao\model\http\Controller;
27use Psr\Log\LoggerInterface;
28
29trait tao_actions_RestTrait
30{
31    /**
32     * @OA\Schema(
33     *     schema="tao.RestTrait.BaseResponse",
34     *     @OA\Property(
35     *         property="success",
36     *         type="boolean",
37     *         description="Indicates error"
38     *     ),
39     *     @OA\Property(
40     *         property="version",
41     *         type="string",
42     *         description="Build version"
43     *     )
44     * )
45     */
46
47    /**
48     * @var array
49     * @deprecated since 4.3.0
50     */
51    protected $acceptedMimeTypes = ["application/json", "text/xml", "application/xml", "application/rdf+xml"];
52
53    /**
54     * @var NULL|string
55     */
56    protected $responseEncoding = "application/json";
57
58    /**
59     * return http Accepted mimeTypes
60     *
61     * @return array
62     */
63    protected function getAcceptableMimeTypes()
64    {
65        return $this->acceptedMimeTypes;
66    }
67
68    /**
69     * @OA\Schema(
70     *     schema="tao.RestTrait.FailureResponse",
71     *     description="Error response with success=false",
72     *     allOf={
73     *         @OA\Schema(ref="#/components/schemas/tao.RestTrait.BaseResponse")
74     *     },
75     *     @OA\Property(
76     *         property="success",
77     *         type="boolean",
78     *         example=false,
79     *         description="Indicates error"
80     *     ),
81     *     @OA\Property(
82     *         property="errorCode",
83     *         type="integer",
84     *         description="Exception error code"
85     *     ),
86     *     @OA\Property(
87     *         property="errorMsg",
88     *         type="string",
89     *         description="Exception message, not localized"
90     *     )
91     * )
92     *
93     * Return failed Rest response
94     * Set header http by using handle()
95     * If $withMessage is true:
96     *     Send response with success, code, message & version of TAO
97     *
98     * @param Exception $exception
99     * @param $withMessage
100     * @throws common_exception_NotImplemented
101     */
102    protected function returnFailure(Exception $exception, $withMessage = true)
103    {
104        $handler = new RestExceptionHandler();
105        $handler->sendHeader($exception);
106
107        $this->logException($exception);
108
109        $data = [];
110        if ($withMessage) {
111            $data['success']    =  false;
112            $data['errorCode']  =  $exception->getCode();
113            $data['errorMsg']   =  $this->getErrorMessage($exception);
114            $data['version']    = TAO_VERSION;
115        }
116
117        echo $this->encode($data);
118        exit(0);
119    }
120
121    /**
122     * @OA\Schema(
123     *     schema="tao.RestTrait.SuccessResponse",
124     *     description="Response with data and success=true",
125     *     allOf={
126     *         @OA\Schema(ref="#/components/schemas/tao.RestTrait.BaseResponse"),
127     *     },
128     *     @OA\Property(
129     *         property="success",
130     *         type="boolean",
131     *         example=true,
132     *         description="Indicates success"
133     *     ),
134     *     @OA\Property(
135     *         property="data",
136     *         type="object",
137     *         description="Payload"
138     *     )
139     * )
140     *
141     * Return success Rest response
142     * Send response with success, data & version of TAO
143     *
144     * @param array $rawData
145     * @param bool $withMessage
146     * @deprecated use \oat\tao\model\http\HttpJsonResponseTrait::setSuccessJsonResponse, be mindful that this
147     * trait doesn't return the version attribute like the method bellow.
148     * @throws common_exception_NotImplemented
149     */
150    protected function returnSuccess($rawData = [], $withMessage = true)
151    {
152        $data = [];
153        if ($withMessage) {
154            $data['success'] = true;
155            $data['data']    = $rawData;
156            $data['version'] = TAO_VERSION;
157        } else {
158            $data = $rawData;
159        }
160
161        echo $this->encode($data);
162        exit(0);
163    }
164
165    /**
166     * Encode data regarding responseEncoding
167     *
168     * @param $data
169     * @return string
170     * @throws common_exception_NotImplemented
171     */
172    protected function encode($data)
173    {
174        switch ($this->responseEncoding) {
175            case "application/rdf+xml":
176                throw new common_exception_NotImplemented();
177                break;
178            case "text/xml":
179            case "application/xml":
180                return tao_helpers_Xml::from_array($data);
181            case "application/json":
182            default:
183                return json_encode($data);
184        }
185    }
186
187    /**
188     * Generate safe message preventing exposing sensitive date in non develop mode
189     * @param Exception $exception
190     * @return string
191     */
192    protected function getErrorMessage(Exception $exception)
193    {
194        $defaultMessage =  __('Unexpected error. Please contact administrator');
195        if (DEBUG_MODE) {
196            $defaultMessage = $exception->getMessage();
197        }
198        return ($exception instanceof common_exception_UserReadableException) ? $exception->getUserMessage(
199        ) : $defaultMessage;
200    }
201
202    private function logException(Throwable $exception): void
203    {
204        $logger = $this->getAdvancedLogger();
205
206        if ($logger) {
207            $logger->error(
208                $exception->getMessage(),
209                [
210                    ContextExtenderInterface::CONTEXT_EXCEPTION => $exception
211                ]
212            );
213        }
214    }
215
216    private function getAdvancedLogger(): ?LoggerInterface
217    {
218        return $this instanceof Controller
219            ? $this->getPsrContainer()->get(AdvancedLogger::class)
220            : null;
221    }
222}