Passed
Push — dev ( 65b5b3...c36508 )
by Marcin
04:08
created

ResponseBuilder::make()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 11
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
c 11
b 0
f 0
nc 4
nop 9
dl 0
loc 20
ccs 13
cts 13
cp 1
crap 3
rs 9.8666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
declare(strict_types=1);
3
4
namespace MarcinOrlowski\ResponseBuilder;
5
6
/**
7
 * Laravel API Response Builder
8
 *
9
 * @package   MarcinOrlowski\ResponseBuilder
10
 *
11
 * @author    Marcin Orlowski <mail (#) marcinOrlowski (.) com>
12
 * @copyright 2016-2019 Marcin Orlowski
13
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
14
 * @link      https://github.com/MarcinOrlowski/laravel-api-response-builder
15
 */
16
17
use Illuminate\Support\Facades\Config;
18
use Illuminate\Support\Facades\Response;
19
use Symfony\Component\HttpFoundation\Response as HttpResponse;
20
21
22
/**
23
 * Builds standardized HttpResponse response object
24
 */
25
class ResponseBuilder
26
{
27
    /**
28
     * Default HTTP code to be used with success responses
29
     *
30
     * @var int
31
     */
32
    public const DEFAULT_HTTP_CODE_OK = HttpResponse::HTTP_OK;
33
34
    /**
35
     * Default HTTP code to be used with error responses
36
     *
37
     * @var int
38
     */
39
    public const DEFAULT_HTTP_CODE_ERROR = HttpResponse::HTTP_BAD_REQUEST;
40
41
    /**
42
     * Min allowed HTTP code for errorXXX()
43
     *
44
     * @var int
45
     */
46
    public const ERROR_HTTP_CODE_MIN = 400;
47
48
    /**
49
     * Max allowed HTTP code for errorXXX()
50
     *
51
     * @var int
52
     */
53
    public const ERROR_HTTP_CODE_MAX = 599;
54
55
    /**
56
     * Configuration keys
57
     */
58
    public const CONF_KEY_DEBUG_DEBUG_KEY        = 'response_builder.debug.debug_key';
59
    public const CONF_KEY_DEBUG_EX_TRACE_ENABLED = 'response_builder.debug.exception_handler.trace_enabled';
60
    public const CONF_KEY_DEBUG_EX_TRACE_KEY     = 'response_builder.debug.exception_handler.trace_key';
61
    public const CONF_KEY_MAP                    = 'response_builder.map';
62
    public const CONF_KEY_ENCODING_OPTIONS       = 'response_builder.encoding_options';
63
    public const CONF_KEY_CLASSES                = 'response_builder.classes';
64
    public const CONF_KEY_MIN_CODE               = 'response_builder.min_code';
65
    public const CONF_KEY_MAX_CODE               = 'response_builder.max_code';
66
    public const CONF_KEY_RESPONSE_KEY_MAP       = 'response_builder.map';
67
    public const CONF_EXCEPTION_HANDLER_KEY      = 'response_builder.exception_handler';
68
69
    /**
70
     * Default keys to be used by exception handler while adding debug information
71
     */
72
    public const KEY_DEBUG   = 'debug';
73
    public const KEY_TRACE   = 'trace';
74
    public const KEY_CLASS   = 'class';
75
    public const KEY_FILE    = 'file';
76
    public const KEY_LINE    = 'line';
77
    public const KEY_KEY     = 'key';
78
    public const KEY_METHOD  = 'method';
79
    public const KEY_SUCCESS = 'success';
80
    public const KEY_CODE    = 'code';
81
    public const KEY_LOCALE  = 'locale';
82
    public const KEY_MESSAGE = 'message';
83
    public const KEY_DATA    = 'data';
84
85
    /**
86
     * Default key to be used by exception handler while processing ValidationException
87
     * to return all the error messages
88
     *
89
     * @var string
90
     */
91
    public const KEY_MESSAGES = 'messages';
92
93
    /**
94
     * Default JSON encoding options. Must be specified as final value (i.e. 271) and NOT
95
     * PHP expression i.e. `JSON_HEX_TAG|JSON_HEX_APOS|...` as such syntax is not yet supported
96
     * by PHP.
97
     *
98
     * 271 = JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_AMP|JSON_HEX_QUOT|JSON_UNESCAPED_UNICODE
99
     *
100
     * @var int
101
     */
102
    public const DEFAULT_ENCODING_OPTIONS = 271;
103
104
    /**
105
     * Reads and validates "classes" config mapping
106
     *
107
     * @return array Classes mapping as specified in configuration or empty array if configuration found
108
     *
109
     * @throws \RuntimeException if "classes" mapping is technically invalid (i.e. not array etc).
110
     */
111 4
    protected static function getClassesMapping(): ?array
112
    {
113 4
        $classes = Config::get(self::CONF_KEY_CLASSES);
114
115 4
        if ($classes !== null) {
116 3
            if (!is_array($classes)) {
117 2
                throw new \RuntimeException(
118 2
                    sprintf('CONFIG: "classes" mapping must be an array (%s given)', gettype($classes)));
119
            }
120
121
            $mandatory_keys = [
122 1
                static::KEY_KEY,
123 1
                static::KEY_METHOD,
124
            ];
125 1
            foreach ($classes as $class_name => $class_config) {
126 1
                foreach ($mandatory_keys as $key_name) {
127 1
                    if (!array_key_exists($key_name, $class_config)) {
128 1
                        throw new \RuntimeException("CONFIG: Missing '{$key_name}' for '{$class_name}' class mapping");
129
                    }
130
                }
131
            }
132
        } else {
133 1
            $classes = [];
134
        }
135
136 1
        return $classes;
137
    }
138
139
    /**
140
     * Returns success
141
     *
142
     * @param object|array|null $data          Array of primitives and supported objects to be returned in 'data' node
143
     *                                         of the JSON response, single supported object or @null if there's no
144
     *                                         to be returned.
145
     * @param integer|null      $api_code      API code to be returned or @null to use value of BaseApiCodes::OK().
146
     * @param array|null        $placeholders  Placeholders passed to Lang::get() for message placeholders
147
     *                                         substitution or @null if none.
148
     * @param integer|null      $http_code     HTTP code to be used for HttpResponse sent or @null
149
     *                                         for default DEFAULT_HTTP_CODE_OK.
150
     * @param integer|null      $json_opts     See http://php.net/manual/en/function.json-encode.php for supported
151
     *                                         options or pass @null to use value from your config (or defaults).
152
     *
153
     * @return HttpResponse
154
     */
155 12
    public static function success($data = null, $api_code = null, array $placeholders = null,
156
                                   int $http_code = null, int $json_opts = null): HttpResponse
157
    {
158 12
        return static::buildSuccessResponse($data, $api_code, $placeholders, $http_code, $json_opts);
159
    }
160
161
    /**
162
     * Returns success
163
     *
164
     * @param integer|null $api_code      API code to be returned or @null to use value of BaseApiCodes::OK().
165
     * @param array|null   $placeholders  Placeholders passed to Lang::get() for message placeholders
166
     *                                    substitution or @null if none.
167
     * @param integer|null $http_code     HTTP code to be used for HttpResponse sent or @null
168
     *                                    for default DEFAULT_HTTP_CODE_OK.
169
     *
170
     * @return HttpResponse
171
     */
172 1
    public static function successWithCode(int $api_code = null, array $placeholders = null,
173
                                           int $http_code = null): HttpResponse
174
    {
175 1
        return static::success(null, $api_code, $placeholders, $http_code);
176
    }
177
178
    /**
179
     * Returns success with custom HTTP code
180
     *
181
     * @param integer|null $http_code HTTP return code to be set for this response. If @null is passed, falls back
182
     *                                to DEFAULT_HTTP_CODE_OK.
183
     *
184
     * @return HttpResponse
185
     */
186 4
    public static function successWithHttpCode(int $http_code = null): HttpResponse
187
    {
188 4
        return static::buildSuccessResponse(null, BaseApiCodes::OK(), [], $http_code);
189
    }
190
191
    /**
192
     * @param object|array|null $data          Array of primitives and supported objects to be returned in 'data' node.
193
     *                                         of the JSON response, single supported object or @null if there's no
194
     *                                         to be returned.
195
     * @param integer|null      $api_code      API code to be returned or @null to use value of BaseApiCodes::OK().
196
     * @param array|null        $placeholders  Placeholders passed to Lang::get() for message placeholders
197
     *                                         substitution or @null if none.
198
     * @param integer|null      $http_code     HTTP code to be used for HttpResponse sent or @null
199
     *                                         for default DEFAULT_HTTP_CODE_OK.
200
     * @param integer|null      $json_opts     See http://php.net/manual/en/function.json-encode.php for supported
201
     *                                         options or pass @null to use value from your config (or defaults).
202
     *
203
     * @return HttpResponse
204
     *
205
     * @throws \InvalidArgumentException Thrown when provided arguments are invalid.
206
     */
207 16
    protected static function buildSuccessResponse($data = null, int $api_code = null, array $placeholders = null,
208
                                                   int $http_code = null, int $json_opts = null): HttpResponse
209
    {
210 16
        $http_code = $http_code ?? static::DEFAULT_HTTP_CODE_OK;
211 16
        $api_code = $api_code ?? BaseApiCodes::OK();
212
213 16
        Validator::assertInt('api_code', $api_code);
214 16
        Validator::assertInt('http_code', $http_code);
215 16
        Validator::assertIntRange('http_code', $http_code, 200, 299);
216
217 14
        return static::make(true, $api_code, $api_code, $data, $http_code, $placeholders, null, $json_opts);
218
    }
219
220
    /**
221
     * Builds error Response object. Supports optional arguments passed to Lang::get() if associated error
222
     * message uses placeholders as well as return data payload
223
     *
224
     * @param integer           $api_code      Your API code to be returned with the response object.
225
     * @param array|null        $placeholders  Placeholders passed to Lang::get() for message placeholders
226
     *                                         substitution or @null if none.
227
     * @param object|array|null $data          Array of primitives and supported objects to be returned in 'data' node
228
     *                                         of the JSON response, single supported object or @null if there's no
229
     *                                         to be returned.
230
     * @param integer|null      $http_code     HTTP code to be used for HttpResponse sent or @null
231
     *                                         for default DEFAULT_HTTP_CODE_ERROR.
232
     * @param integer|null      $json_opts     See http://php.net/manual/en/function.json-encode.php for supported
233
     *                                         options or pass @null to use value from your config (or defaults).
234
     *
235
     * @return HttpResponse
236
     */
237 4
    public static function error(int $api_code, array $placeholders = null, $data = null, int $http_code = null,
238
                                 int $encoding_options = null): HttpResponse
239
    {
240 4
        return static::buildErrorResponse($data, $api_code, $http_code, $placeholders, $encoding_options);
241
    }
242
243
    /**
244
     * @param integer           $api_code      Your API code to be returned with the response object.
245
     * @param object|array|null $data          Array of primitives and supported objects to be returned in 'data' node
246
     *                                         of the JSON response, single supported object or @null if there's no
247
     *                                         to be returned.
248
     * @param array|null        $placeholders  Placeholders passed to Lang::get() for message placeholders
249
     *                                         substitution or @null if none.
250
     * @param integer|null      $json_opts     See http://php.net/manual/en/function.json-encode.php for supported
251
     *                                         options or pass @null to use value from your config (or defaults).
252
     *
253
     * @return HttpResponse
254
     */
255 1
    public static function errorWithData(int $api_code, $data, array $placeholders = null,
256
                                         int $json_opts = null): HttpResponse
257
    {
258 1
        return static::buildErrorResponse($data, $api_code, null, $placeholders, $json_opts);
259
    }
260
261
    /**
262
     * @param integer           $api_code      Your API code to be returned with the response object.
263
     * @param object|array|null $data          Array of primitives and supported objects to be returned in 'data' node
264
     *                                         of the JSON response, single supported object or @null if there's no
265
     *                                         to be returned.
266
     * @param integer           $http_code     HTTP code to be used for HttpResponse sent.
267
     * @param array|null        $placeholders  Placeholders passed to Lang::get() for message placeholders
268
     *                                         substitution or @null if none.
269
     * @param integer|null      $json_opts     See http://php.net/manual/en/function.json-encode.php for supported
270
     *                                         options or pass @null to use value from your config (or defaults).
271
     *
272
     * @return HttpResponse
273
     *
274
     * @throws \InvalidArgumentException if http_code is @null
275
     */
276 1
    public static function errorWithDataAndHttpCode(int $api_code, $data, int $http_code, array $placeholders = null,
277
                                                    int $json_opts = null): HttpResponse
278
    {
279 1
        return static::buildErrorResponse($data, $api_code, $http_code, $placeholders, $json_opts);
280
    }
281
282
    /**
283
     * @param integer    $api_code     Your API code to be returned with the response object.
284
     * @param integer    $http_code    HTTP code to be used for HttpResponse sent or @null
285
     *                                 for default DEFAULT_HTTP_CODE_ERROR.
286
     * @param array|null $placeholders Placeholders passed to Lang::get() for message placeholders
287
     *                                 substitution or @null if none.
288
     *
289
     * @return HttpResponse
290
     *
291
     * @throws \InvalidArgumentException if http_code is @null
292
     */
293 1
    public static function errorWithHttpCode(int $api_code, int $http_code, array $placeholders = null): HttpResponse
294
    {
295 1
        return static::buildErrorResponse(null, $api_code, $http_code, $placeholders);
296
    }
297
298
    /**
299
     * @param integer           $api_code  Your API code to be returned with the response object.
300
     * @param string            $message   Custom message to be returned as part of error response
301
     * @param object|array|null $data      Array of primitives and supported objects to be returned in 'data' node
302
     *                                     of the JSON response, single supported object or @null if there's no
303
     *                                     to be returned.
304
     * @param integer|null      $http_code Optional HTTP status code to be used for HttpResponse sent
305
     *                                     or @null for DEFAULT_HTTP_CODE_ERROR
306
     * @param integer|null      $json_opts See http://php.net/manual/en/function.json-encode.php for supported
307
     *                                     options or pass @null to use value from your config (or defaults).
308
     *
309
     * @return HttpResponse
310
     */
311 1
    public static function errorWithMessageAndData(int $api_code, string $message, $data,
312
                                                   int $http_code = null, int $json_opts = null): HttpResponse
313
    {
314 1
        return static::buildErrorResponse($data, $api_code, $http_code, null,
315 1
            $message, null, $json_opts);
316
    }
317
318
    /**
319
     * @param integer           $api_code   Your API code to be returned with the response object.
320
     * @param string            $message    custom message to be returned as part of error response
321
     * @param object|array|null $data       Array of primitives and supported objects to be returned in 'data' node
322
     *                                      of the JSON response, single supported object or @null if there's no
323
     *                                      to be returned.
324
     * @param integer|null      $http_code  HTTP code to be used for HttpResponse sent or @null
325
     *                                      for default DEFAULT_HTTP_CODE_ERROR.
326
     * @param integer|null      $json_opts  See http://php.net/manual/en/function.json-encode.php for supported
327
     *                                      options or pass @null to use value from your config (or defaults).
328
     * @param array|null        $debug_data optional debug data array to be added to returned JSON.
329
     *
330
     * @return HttpResponse
331
     */
332 6
    public static function errorWithMessageAndDataAndDebug(int $api_code, string $message, $data,
333
                                                           int $http_code = null, int $json_opts = null,
334
                                                           array $debug_data = null): HttpResponse
335
    {
336 6
        return static::buildErrorResponse($data, $api_code, $http_code, null,
337 6
            $message, null, $json_opts, $debug_data);
338
    }
339
340
    /**
341
     * @param integer      $api_code  Your API code to be returned with the response object.
342
     * @param string       $message   Custom message to be returned as part of error response
343
     * @param integer|null $http_code HTTP code to be used with final response sent or @null
344
     *                                for default DEFAULT_HTTP_CODE_ERROR.
345
     *
346
     * @return HttpResponse
347
     */
348 1
    public static function errorWithMessage(int $api_code, string $message, int $http_code = null): HttpResponse
349
    {
350 1
        return static::buildErrorResponse(null, $api_code, $http_code, null, $message);
351
    }
352
353
    /**
354
     * Builds error Response object. Supports optional arguments passed to Lang::get() if associated error message
355
     * uses placeholders as well as return data payload
356
     *
357
     * @param object|array|null $data          Array of primitives and supported objects to be returned in 'data' node
358
     *                                         of the JSON response, single supported object or @null if there's no
359
     *                                         to be returned.
360
     * @param integer           $api_code      Your API code to be returned with the response object.
361
     * @param integer|null      $http_code     HTTP code to be used for HttpResponse sent or @null
362
     *                                         for default DEFAULT_HTTP_CODE_ERROR.
363
     * @param array|null        $placeholders  Placeholders passed to Lang::get() for message placeholders
364
     *                                         substitution or @null if none.
365
     * @param string|null       $message       custom message to be returned as part of error response
366
     * @param array|null        $headers       optional HTTP headers to be returned in error response
367
     * @param integer|null      $json_opts     See http://php.net/manual/en/function.json-encode.php for supported
368
     *                                         options or pass @null to use value from your config (or defaults).
369
     * @param array|null        $debug_data    optional debug data array to be added to returned JSON.
370
     *
371
     * @return HttpResponse
372
     *
373
     * @throws \InvalidArgumentException Thrown if $code is not correct, outside the range, equals OK code etc.
374
     *
375
     * @noinspection MoreThanThreeArgumentsInspection
376
     */
377 18
    protected static function buildErrorResponse($data, int $api_code, int $http_code = null,
378
                                                 array $placeholders = null,
379
                                                 string $message = null, array $headers = null,
380
                                                 int $json_opts = null,
381
                                                 array $debug_data = null): HttpResponse
382
    {
383 18
        $http_code = $http_code ?? static::DEFAULT_HTTP_CODE_ERROR;
384 18
        $headers = $headers ?? [];
385
386 18
        Validator::assertInt('api_code', $api_code);
387
388 18
        $code_ok = BaseApiCodes::OK();
389 18
        if ($api_code !== $code_ok) {
390 16
            Validator::assertIntRange('api_code', $api_code, BaseApiCodes::getMinCode(), BaseApiCodes::getMaxCode());
391
        }
392 18
        if ($api_code === $code_ok) {
393 2
            throw new \InvalidArgumentException(
394 2
                "Error response cannot use api_code of value  {$code_ok} which is reserved for OK");
395
        }
396
397 16
        Validator::assertInt('http_code', $http_code);
398 16
        Validator::assertIntRange('http_code', $http_code, static::ERROR_HTTP_CODE_MIN, static::ERROR_HTTP_CODE_MAX);
399
400 15
        $msg_or_api_code = $message ?? $api_code;
401
402 15
        return static::make(false, $api_code, $msg_or_api_code, $data, $http_code,
403 15
            $placeholders, $headers, $json_opts, $debug_data);
404
    }
405
406
    /**
407
     * @param boolean           $success         @true if response reports successful operation, @false otherwise.
408
     * @param integer           $api_code        Your API code to be returned with the response object.
409
     * @param string|integer    $msg_or_api_code message string or valid API code to get message for
410
     * @param object|array|null $data            optional additional data to be included in response object
411
     * @param integer|null      $http_code       HTTP code for the HttpResponse or @null for either DEFAULT_HTTP_CODE_OK
412
     *                                           or DEFAULT_HTTP_CODE_ERROR depending on the $success.
413
     * @param array|null        $placeholders    Placeholders passed to Lang::get() for message placeholders
414
     *                                           substitution or @null if none.
415
     * @param array|null        $headers         Optional HTTP headers to be returned in the response.
416
     * @param integer|null      $json_opts       See http://php.net/manual/en/function.json-encode.php for supported
417
     *                                           options or pass @null to use value from your config (or defaults).
418
     * @param array|null        $debug_data      Optional debug data array to be added to returned JSON.
419
     *
420
     * @return HttpResponse
421
     *
422
     * @throws \InvalidArgumentException If $api_code is neither a string nor valid integer code.
423
     * @throws \InvalidArgumentException if $data is an object of class that is not configured in "classes" mapping.
424
     *
425
     * @noinspection MoreThanThreeArgumentsInspection
426
     */
427 35
    protected static function make(bool $success, int $api_code, $msg_or_api_code, $data = null,
428
                                   int $http_code = null, array $placeholders = null, array $headers = null,
429
                                   int $json_opts = null, array $debug_data = null): HttpResponse
430
    {
431 35
        $headers = $headers ?? [];
432 35
        $http_code = $http_code ?? ($success ? static::DEFAULT_HTTP_CODE_OK : static::DEFAULT_HTTP_CODE_ERROR);
433 35
        $json_opts = $json_opts ?? Config::get(self::CONF_KEY_ENCODING_OPTIONS, static::DEFAULT_ENCODING_OPTIONS);
434
435 35
        Validator::assertInt('encoding_options', $json_opts);
436
437 34
        Validator::assertInt('api_code', $api_code);
438 34
        if (!BaseApiCodes::isCodeValid($api_code)) {
439 1
            $min = BaseApiCodes::getMinCode();
440 1
            $max = BaseApiCodes::getMaxCode();
441 1
            throw new \InvalidArgumentException("API code value ({$api_code}) is out of allowed range {$min}-{$max}");
442
        }
443
444 33
        return Response::json(
445 33
            static::buildResponse($success, $api_code, $msg_or_api_code, $placeholders, $data, $debug_data),
446 28
            $http_code, $headers, $json_opts);
447
    }
448
449
    /**
450
     * If $msg_or_api_code is integer value, returns human readable message associated with that code (with
451
     * fallback to built-in default string if no api code mapping is set. If $msg_or_api_code is a string,
452
     * returns it unaltered.
453
     *
454
     * @param boolean    $success      @true if response reports successful operation, @false otherwise.
455
     * @param integer    $api_code     Your API code to be returned with the response object.
456
     * @param array|null $placeholders Placeholders passed to Lang::get() for message placeholders
457
     *                                 substitution or @null if none.
458
     *
459
     * @return string
460
     */
461 20
    protected static function getMessageForApiCode(bool $success, int $api_code, array $placeholders = null): string
462
    {
463
        // We got integer value here not a message string, so we need to check if we have the mapping for
464
        // this string already configured.
465 20
        $key = BaseApiCodes::getCodeMessageKey($api_code);
466 20
        if ($key === null) {
467
            // nope, let's get the default one instead, based of
468 2
            $fallback_code = $success ? BaseApiCodes::OK() : BaseApiCodes::NO_ERROR_MESSAGE();
469 2
            $key = BaseApiCodes::getCodeMessageKey($fallback_code);
470
        }
471
472 20
        $placeholders = $placeholders ?? [];
473 20
        if (!array_key_exists('api_code', $placeholders)) {
474 18
            $placeholders['api_code'] = $api_code;
475
        }
476
477 20
        return \Lang::get($key, $placeholders);
478
    }
479
480
    /**
481
     * Creates standardised API response array. This is final method called in the whole pipeline before we
482
     * return final JSON back to client. If you want to manipulate your response, this is the place to do that.
483
     * If you set APP_DEBUG to true, 'code_hex' field will be additionally added to reported JSON for easier
484
     * manual debugging.
485
     *
486
     * @param boolean           $success         @true if response reports successful operation, @false otherwise.
487
     * @param integer           $api_code        Your API code to be returned with the response object.
488
     * @param string|integer    $msg_or_api_code Message string or valid API code to get message for.
489
     * @param array|null        $placeholders    Placeholders passed to Lang::get() for message placeholders
490
     *                                           substitution or @null if none.
491
     * @param object|array|null $data            API response data if any
492
     * @param array|null        $debug_data      optional debug data array to be added to returned JSON.
493
     *
494
     * @return array response ready to be encoded as json and sent back to client
495
     *
496
     * @throws \RuntimeException in case of missing or invalid "classes" mapping configuration
497
     */
498 33
    protected static function buildResponse(bool $success, int $api_code,
499
                                            $msg_or_api_code, array $placeholders = null,
500
                                            $data = null, array $debug_data = null): array
501
    {
502
        // ensure $data is either @null, array or object of class with configured mapping.
503 33
        $converter = new Converter();
504
505 33
        $data = $converter->convert($data);
506 30
        if ($data !== null && !is_object($data)) {
507
            // ensure we get object in final JSON structure in data node
508 12
            $data = (object)$data;
509
        }
510
511
        // get human readable message for API code or use message string (if given instead of API code)
512 30
        if (is_int($msg_or_api_code)) {
513 20
            $message = self::getMessageForApiCode($success, $msg_or_api_code, $placeholders);
514
        } else {
515 10
            Validator::assertString('message', $msg_or_api_code);
516 8
            $message = $msg_or_api_code;
517
        }
518
519
        /** @noinspection PhpUndefinedClassInspection */
520
        $response = [
521 28
            static::KEY_SUCCESS => $success,
522 28
            static::KEY_CODE    => $api_code,
523 28
            static::KEY_LOCALE  => \App::getLocale(),
524 28
            static::KEY_MESSAGE => $message,
525 28
            static::KEY_DATA    => $data,
526
        ];
527
528 28
        if ($debug_data !== null) {
529 2
            $debug_key = Config::get(static::CONF_KEY_DEBUG_DEBUG_KEY, self::KEY_DEBUG);
530 2
            $response[ $debug_key ] = $debug_data;
531
        }
532
533 28
        return $response;
534
    }
535
536
}
537