Passed
Branch master (76b039)
by Alex
02:42
created

ResponseParser   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 15
dl 0
loc 163
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A parse() 0 17 4
A callTransformer() 0 9 2
A transformTypes() 0 3 1
A getTransformerMethodName() 0 9 1
A __construct() 0 3 1
A transformNewlines() 0 3 1
A transformRepeatedObject() 0 3 1
A transformShortArray() 0 3 1
A transformVarsOfType() 0 3 1
A transformDecode() 0 3 1
A transformKeyNames() 0 3 1
1
<?php
2
3
namespace AlexWells\ApiDocsGenerator\Parser;
4
5
use AlexWells\ApiDocsGenerator\Exceptions\InvalidTagFormat;
6
use AlexWells\ApiDocsGenerator\Helpers;
7
8
class ResponseParser
9
{
10
    /**
11
     * Steps that should be taken to transform the string from raw to end result.
12
     *
13
     * @var array
14
     */
15
    protected const TRANSFORM_STEPS = ['newlines', 'shortArray', 'keyNames', 'varsOfType', 'types', 'repeatedObject', 'decode'];
16
17
    /**
18
     * Content to be parsed.
19
     *
20
     * @var string
21
     */
22
    protected $content;
23
24
    /**
25
     * ResponseParser constructor.
26
     *
27
     * @param string $content Content to be parsed.
28
     */
29
    public function __construct(string $content)
30
    {
31
        $this->content = $content;
32
    }
33
34
    /**
35
     * Parse the content.
36
     *
37
     * @return array
38
     * @throws InvalidTagFormat
39
     */
40
    public function parse()
41
    {
42
        $content = $this->content;
43
44
        foreach (static::TRANSFORM_STEPS as $step) {
45
            $content = static::callTransformer($step, $content);
46
47
            if($content === null) {
48
                throw new InvalidTagFormat("Response tag format is invalid. Failed at step: $step");
49
            }
50
51
            if(empty($content)) {
52
                return $content;
53
            }
54
        }
55
56
        return $content;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $content returns the type string which is incompatible with the documented return type array.
Loading history...
57
    }
58
59
    /**
60
     * Replace \n and similar symbols with nothing.
61
     *
62
     * @param $content
63
     * @return string
64
     */
65
    protected static function transformNewlines($content)
66
    {
67
        return Helpers::clearNewlines($content);
68
    }
69
70
    /**
71
     * Replace `int[]` with `[ :: int ]`
72
     *
73
     * @param $content
74
     * @return mixed
75
     */
76
    protected static function transformShortArray($content)
77
    {
78
        return preg_replace(Helpers::regexExcludeInQuotes("(\w+)\[\]"), '[ :: $1 ]', $content);
79
    }
80
81
    /**
82
     * Replace `nested: {}` with `"nested": {}`
83
     *
84
     * @param $content
85
     * @return mixed
86
     */
87
    protected static function transformKeyNames($content)
88
    {
89
        return preg_replace(Helpers::regexExcludeInQuotes("(\w+)\s*:[^:]"), '"$1": ', $content);
90
    }
91
92
    /**
93
     * Replace `year :: int` with `"year": {"$ref": "int"}`
94
     *
95
     * @param $content
96
     * @return mixed
97
     */
98
    protected static function transformVarsOfType($content)
99
    {
100
        return preg_replace(Helpers::regexExcludeInQuotes("(\w+)\s*::\s*(\w+)"), '"$1": {"$ref": "$2"}', $content);
101
    }
102
103
    /**
104
     * Replace `:: int` with `{"$ref": "int"}`
105
     *
106
     * @param $content
107
     * @return mixed
108
     */
109
    protected static function transformTypes($content)
110
    {
111
        return preg_replace(Helpers::regexExcludeInQuotes("\s*::\s*(\w+)"), '{"$ref": "$1"}', $content);
112
    }
113
114
    /**
115
     * Replace `:: {}` with `{"$ref": {}}`
116
     *
117
     * @param $content
118
     * @return mixed
119
     */
120
    protected static function transformRepeatedObject($content)
121
    {
122
        return preg_replace(Helpers::regexExcludeInQuotes("::\s*{(.*)}"), '{"$ref": {$1}}', $content);
123
    }
124
125
    /**
126
     * Decode JSON string into PHP 2d array.
127
     *
128
     * @param $content
129
     *
130
     * @return array
131
     */
132
    protected static function transformDecode($content)
133
    {
134
        return json_decode($content, true);
135
    }
136
137
    /**
138
     * Call transformer method by it's partial name.
139
     *
140
     * @param string $name Transformer name
141
     *
142
     * @return string|array
143
     */
144
    protected static function callTransformer($name, $content)
145
    {
146
        $transformer = static::getTransformerMethodName($name);
147
148
        if(! method_exists(static::class, $transformer)) {
149
            return $content;
150
        }
151
152
        return static::$transformer($content);
153
    }
154
155
    /**
156
     * Get method name for transformer by it's partial name.
157
     *
158
     * @param string $name Transformer name
159
     *
160
     * @return string
161
     */
162
    protected static function getTransformerMethodName($name)
163
    {
164
        // Convert snake_case (if present) to camelCase
165
        $name = camel_case($name);
166
167
        // Capitalize first letter
168
        $name = ucfirst($name);
169
170
        return "transform$name";
171
    }
172
}