Completed
Push — master ( ba73f2...e6d5b5 )
by Martijn
27s
created
SwaggerGen/Swagger/Type/AbstractRegexType.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -16,61 +16,61 @@
 block discarded – undo
16 16
 class AbstractRegexType extends StringType
17 17
 {
18 18
 
19
-    public const REGEX_DEFAULT_START = '(?:=(';
20
-    public const REGEX_DEFAULT_END = '))?';
19
+	public const REGEX_DEFAULT_START = '(?:=(';
20
+	public const REGEX_DEFAULT_END = '))?';
21 21
 
22
-    /**
23
-     * The raw regular expression to use.
24
-     * Exclude start (`^`) and end (`$`) anchors.
25
-     * @var string
26
-     */
27
-    private $regex;
22
+	/**
23
+	 * The raw regular expression to use.
24
+	 * Exclude start (`^`) and end (`$`) anchors.
25
+	 * @var string
26
+	 */
27
+	private $regex;
28 28
 
29
-    /**
30
-     * Construct and set up the regular expression for this type
31
-     *
32
-     * @param AbstractObject $parent
33
-     * @param string $definition
34
-     * @param string $format Name of the string format
35
-     * @param string $regex Regular expression to use as the format and for default validation
36
-     */
37
-    public function __construct(AbstractObject $parent, $definition, $format, $regex)
38
-    {
39
-        $this->format = $format;
40
-        $this->regex = $regex;
29
+	/**
30
+	 * Construct and set up the regular expression for this type
31
+	 *
32
+	 * @param AbstractObject $parent
33
+	 * @param string $definition
34
+	 * @param string $format Name of the string format
35
+	 * @param string $regex Regular expression to use as the format and for default validation
36
+	 */
37
+	public function __construct(AbstractObject $parent, $definition, $format, $regex)
38
+	{
39
+		$this->format = $format;
40
+		$this->regex = $regex;
41 41
 
42
-        parent::__construct($parent, $definition);
43
-    }
42
+		parent::__construct($parent, $definition);
43
+	}
44 44
 
45
-    /**
46
-     * @throws Exception
47
-     */
48
-    protected function parseDefinition($definition): void
49
-    {
50
-        $definition = self::trim($definition);
45
+	/**
46
+	 * @throws Exception
47
+	 */
48
+	protected function parseDefinition($definition): void
49
+	{
50
+		$definition = self::trim($definition);
51 51
 
52
-        $match = [];
53
-        if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_DEFAULT_START . $this->regex . self::REGEX_DEFAULT_END . self::REGEX_END, $definition, $match) !== 1) {
54
-            throw new Exception('Unparseable ' . $this->format . ' definition: \'' . $definition . '\'');
55
-        }
52
+		$match = [];
53
+		if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_DEFAULT_START . $this->regex . self::REGEX_DEFAULT_END . self::REGEX_END, $definition, $match) !== 1) {
54
+			throw new Exception('Unparseable ' . $this->format . ' definition: \'' . $definition . '\'');
55
+		}
56 56
 
57
-        if (strtolower($match[1]) !== $this->format) {
58
-            throw new Exception('Not a ' . $this->format . ': \'' . $definition . '\'');
59
-        }
57
+		if (strtolower($match[1]) !== $this->format) {
58
+			throw new Exception('Not a ' . $this->format . ': \'' . $definition . '\'');
59
+		}
60 60
 
61
-        $this->pattern = '^' . $this->regex . '$';
62
-        $this->default = isset($match[2]) && $match[2] !== '' ? $this->validateDefault($match[2]) : null;
63
-    }
61
+		$this->pattern = '^' . $this->regex . '$';
62
+		$this->default = isset($match[2]) && $match[2] !== '' ? $this->validateDefault($match[2]) : null;
63
+	}
64 64
 
65
-    protected function validateDefault($value): string
66
-    {
67
-        $value = parent::validateDefault($value);
65
+	protected function validateDefault($value): string
66
+	{
67
+		$value = parent::validateDefault($value);
68 68
 
69
-        if (preg_match('/' . $this->pattern . '/', $value) !== 1) {
70
-            throw new Exception('Invalid ' . $this->format . ' default value');
71
-        }
69
+		if (preg_match('/' . $this->pattern . '/', $value) !== 1) {
70
+			throw new Exception('Invalid ' . $this->format . ' default value');
71
+		}
72 72
 
73
-        return $value;
74
-    }
73
+		return $value;
74
+	}
75 75
 
76 76
 }
Please login to merge, or discard this patch.
SwaggerGen/Swagger/Type/NumberType.php 2 patches
Indentation   +152 added lines, -152 removed lines patch added patch discarded remove patch
@@ -15,157 +15,157 @@
 block discarded – undo
15 15
 class NumberType extends AbstractType
16 16
 {
17 17
 
18
-    /** @noinspection PhpRegExpUnsupportedModifierInspection */
19
-    const REGEX_RANGE = '(?:([[<])(-?(?:\\d*\\.?\\d+|\\d+\\.\\d*))?,(-?(?:\\d*\\.?\\d+|\\d+\\.\\d*))?([\\]>]))?';
20
-    /** @noinspection PhpRegExpUnsupportedModifierInspection */
21
-    const REGEX_DEFAULT = '(?:=(-?(?:\\d*\\.?\\d+|\\d+\\.\\d*)))?';
22
-
23
-    private static $formats = array(
24
-        'float' => 'float',
25
-        'double' => 'double',
26
-    );
27
-    private $format;
28
-    private $default;
29
-    private $maximum;
30
-    private $exclusiveMaximum;
31
-    private $minimum;
32
-    private $exclusiveMinimum;
33
-    private $enum = [];
34
-    private $multipleOf;
35
-
36
-    /**
37
-     * @param string $command The comment command
38
-     * @param string $data Any data added after the command
39
-     * @return AbstractType|boolean
40
-     * @throws Exception
41
-     * @throws Exception
42
-     * @throws Exception
43
-     */
44
-    public function handleCommand($command, $data = null)
45
-    {
46
-        switch (strtolower($command)) {
47
-            case 'default':
48
-                $this->default = $this->validateDefault($data);
49
-                return $this;
50
-
51
-            case 'enum':
52
-                $words = self::wordSplit($data);
53
-                foreach ($words as &$word) {
54
-                    $word = $this->validateDefault($word);
55
-                }
56
-                unset($word);
57
-                $this->enum = array_merge($this->enum, $words);
58
-                return $this;
59
-
60
-            case 'step':
61
-                if (($step = (float)$data) > 0) {
62
-                    $this->multipleOf = $step;
63
-                }
64
-                return $this;
65
-        }
66
-
67
-        return parent::handleCommand($command, $data);
68
-    }
69
-
70
-    /**
71
-     * @throws Exception
72
-     */
73
-    private function validateDefault($value): float
74
-    {
75
-        if (preg_match('~^-?(?:\\d*\\.?\\d+|\\d+\\.\\d*)$~', $value) !== 1) {
76
-            throw new Exception("Invalid number default: '{$value}'");
77
-        }
78
-
79
-        if ($this->maximum) {
80
-            if (($value > $this->maximum) || ($this->exclusiveMaximum && $value == $this->maximum)) {
81
-                throw new Exception("Default number beyond maximum: '{$value}'");
82
-            }
83
-        }
84
-        if ($this->minimum) {
85
-            if (($value < $this->minimum) || ($this->exclusiveMinimum && $value == $this->minimum)) {
86
-                throw new Exception("Default number beyond minimum: '{$value}'");
87
-            }
88
-        }
89
-
90
-        return (float)$value;
91
-    }
92
-
93
-    public function toArray(): array
94
-    {
95
-        return self::arrayFilterNull(array_merge(array(
96
-            'type' => 'number',
97
-            'format' => $this->format,
98
-            'default' => $this->default,
99
-            'minimum' => $this->minimum,
100
-            'exclusiveMinimum' => ($this->exclusiveMinimum && !is_null($this->minimum)) ? true : null,
101
-            'maximum' => $this->maximum,
102
-            'exclusiveMaximum' => ($this->exclusiveMaximum && !is_null($this->maximum)) ? true : null,
103
-            'enum' => $this->enum,
104
-            'multipleOf' => $this->multipleOf,
105
-        ), parent::toArray()));
106
-    }
107
-
108
-    public function __toString()
109
-    {
110
-        return __CLASS__;
111
-    }
112
-
113
-    /**
114
-     * @throws Exception
115
-     */
116
-    protected function parseDefinition($definition): void
117
-    {
118
-        $match = [];
119
-        if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_RANGE . self::REGEX_DEFAULT . self::REGEX_END, $definition, $match) !== 1) {
120
-            throw new Exception("Unparseable number definition: '{$definition}'");
121
-        }
122
-
123
-        $this->parseFormat($definition, $match);
124
-        $this->parseRange($definition, $match);
125
-        $this->parseDefault($definition, $match);
126
-    }
127
-
128
-    /**
129
-     * @param string[] $match
130
-     * @throws Exception
131
-     */
132
-    private function parseFormat($definition, $match): void
133
-    {
134
-        if (!isset(self::$formats[strtolower($match[1])])) {
135
-            throw new Exception("Not a number: '{$definition}'");
136
-        }
137
-        $this->format = self::$formats[strtolower($match[1])];
138
-    }
139
-
140
-    /**
141
-     * @param string[] $match
142
-     * @throws Exception
143
-     */
144
-    private function parseRange($definition, $match): void
145
-    {
146
-        if (!empty($match[2])) {
147
-            if ($match[3] === '' && $match[4] === '') {
148
-                throw new Exception("Empty number range: '{$definition}'");
149
-            }
150
-
151
-            $this->exclusiveMinimum = $match[2] === '<';
152
-            $this->minimum = $match[3] === '' ? null : (float)$match[3];
153
-            $this->maximum = $match[4] === '' ? null : (float)$match[4];
154
-            $this->exclusiveMaximum = isset($match[5]) ? ($match[5] === '>') : null;
155
-            if ($this->minimum && $this->maximum && $this->minimum > $this->maximum) {
156
-                self::swap($this->minimum, $this->maximum);
157
-                self::swap($this->exclusiveMinimum, $this->exclusiveMaximum);
158
-            }
159
-        }
160
-    }
161
-
162
-    /**
163
-     * @param string[] $match
164
-     * @throws Exception
165
-     */
166
-    private function parseDefault($definition, $match): void
167
-    {
168
-        $this->default = isset($match[6]) && $match[6] !== '' ? $this->validateDefault($match[6]) : null;
169
-    }
18
+	/** @noinspection PhpRegExpUnsupportedModifierInspection */
19
+	const REGEX_RANGE = '(?:([[<])(-?(?:\\d*\\.?\\d+|\\d+\\.\\d*))?,(-?(?:\\d*\\.?\\d+|\\d+\\.\\d*))?([\\]>]))?';
20
+	/** @noinspection PhpRegExpUnsupportedModifierInspection */
21
+	const REGEX_DEFAULT = '(?:=(-?(?:\\d*\\.?\\d+|\\d+\\.\\d*)))?';
22
+
23
+	private static $formats = array(
24
+		'float' => 'float',
25
+		'double' => 'double',
26
+	);
27
+	private $format;
28
+	private $default;
29
+	private $maximum;
30
+	private $exclusiveMaximum;
31
+	private $minimum;
32
+	private $exclusiveMinimum;
33
+	private $enum = [];
34
+	private $multipleOf;
35
+
36
+	/**
37
+	 * @param string $command The comment command
38
+	 * @param string $data Any data added after the command
39
+	 * @return AbstractType|boolean
40
+	 * @throws Exception
41
+	 * @throws Exception
42
+	 * @throws Exception
43
+	 */
44
+	public function handleCommand($command, $data = null)
45
+	{
46
+		switch (strtolower($command)) {
47
+			case 'default':
48
+				$this->default = $this->validateDefault($data);
49
+				return $this;
50
+
51
+			case 'enum':
52
+				$words = self::wordSplit($data);
53
+				foreach ($words as &$word) {
54
+					$word = $this->validateDefault($word);
55
+				}
56
+				unset($word);
57
+				$this->enum = array_merge($this->enum, $words);
58
+				return $this;
59
+
60
+			case 'step':
61
+				if (($step = (float)$data) > 0) {
62
+					$this->multipleOf = $step;
63
+				}
64
+				return $this;
65
+		}
66
+
67
+		return parent::handleCommand($command, $data);
68
+	}
69
+
70
+	/**
71
+	 * @throws Exception
72
+	 */
73
+	private function validateDefault($value): float
74
+	{
75
+		if (preg_match('~^-?(?:\\d*\\.?\\d+|\\d+\\.\\d*)$~', $value) !== 1) {
76
+			throw new Exception("Invalid number default: '{$value}'");
77
+		}
78
+
79
+		if ($this->maximum) {
80
+			if (($value > $this->maximum) || ($this->exclusiveMaximum && $value == $this->maximum)) {
81
+				throw new Exception("Default number beyond maximum: '{$value}'");
82
+			}
83
+		}
84
+		if ($this->minimum) {
85
+			if (($value < $this->minimum) || ($this->exclusiveMinimum && $value == $this->minimum)) {
86
+				throw new Exception("Default number beyond minimum: '{$value}'");
87
+			}
88
+		}
89
+
90
+		return (float)$value;
91
+	}
92
+
93
+	public function toArray(): array
94
+	{
95
+		return self::arrayFilterNull(array_merge(array(
96
+			'type' => 'number',
97
+			'format' => $this->format,
98
+			'default' => $this->default,
99
+			'minimum' => $this->minimum,
100
+			'exclusiveMinimum' => ($this->exclusiveMinimum && !is_null($this->minimum)) ? true : null,
101
+			'maximum' => $this->maximum,
102
+			'exclusiveMaximum' => ($this->exclusiveMaximum && !is_null($this->maximum)) ? true : null,
103
+			'enum' => $this->enum,
104
+			'multipleOf' => $this->multipleOf,
105
+		), parent::toArray()));
106
+	}
107
+
108
+	public function __toString()
109
+	{
110
+		return __CLASS__;
111
+	}
112
+
113
+	/**
114
+	 * @throws Exception
115
+	 */
116
+	protected function parseDefinition($definition): void
117
+	{
118
+		$match = [];
119
+		if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_RANGE . self::REGEX_DEFAULT . self::REGEX_END, $definition, $match) !== 1) {
120
+			throw new Exception("Unparseable number definition: '{$definition}'");
121
+		}
122
+
123
+		$this->parseFormat($definition, $match);
124
+		$this->parseRange($definition, $match);
125
+		$this->parseDefault($definition, $match);
126
+	}
127
+
128
+	/**
129
+	 * @param string[] $match
130
+	 * @throws Exception
131
+	 */
132
+	private function parseFormat($definition, $match): void
133
+	{
134
+		if (!isset(self::$formats[strtolower($match[1])])) {
135
+			throw new Exception("Not a number: '{$definition}'");
136
+		}
137
+		$this->format = self::$formats[strtolower($match[1])];
138
+	}
139
+
140
+	/**
141
+	 * @param string[] $match
142
+	 * @throws Exception
143
+	 */
144
+	private function parseRange($definition, $match): void
145
+	{
146
+		if (!empty($match[2])) {
147
+			if ($match[3] === '' && $match[4] === '') {
148
+				throw new Exception("Empty number range: '{$definition}'");
149
+			}
150
+
151
+			$this->exclusiveMinimum = $match[2] === '<';
152
+			$this->minimum = $match[3] === '' ? null : (float)$match[3];
153
+			$this->maximum = $match[4] === '' ? null : (float)$match[4];
154
+			$this->exclusiveMaximum = isset($match[5]) ? ($match[5] === '>') : null;
155
+			if ($this->minimum && $this->maximum && $this->minimum > $this->maximum) {
156
+				self::swap($this->minimum, $this->maximum);
157
+				self::swap($this->exclusiveMinimum, $this->exclusiveMaximum);
158
+			}
159
+		}
160
+	}
161
+
162
+	/**
163
+	 * @param string[] $match
164
+	 * @throws Exception
165
+	 */
166
+	private function parseDefault($definition, $match): void
167
+	{
168
+		$this->default = isset($match[6]) && $match[6] !== '' ? $this->validateDefault($match[6]) : null;
169
+	}
170 170
 
171 171
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -58,7 +58,7 @@  discard block
 block discarded – undo
58 58
                 return $this;
59 59
 
60 60
             case 'step':
61
-                if (($step = (float)$data) > 0) {
61
+                if (($step = (float) $data) > 0) {
62 62
                     $this->multipleOf = $step;
63 63
                 }
64 64
                 return $this;
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
             }
88 88
         }
89 89
 
90
-        return (float)$value;
90
+        return (float) $value;
91 91
     }
92 92
 
93 93
     public function toArray(): array
@@ -149,8 +149,8 @@  discard block
 block discarded – undo
149 149
             }
150 150
 
151 151
             $this->exclusiveMinimum = $match[2] === '<';
152
-            $this->minimum = $match[3] === '' ? null : (float)$match[3];
153
-            $this->maximum = $match[4] === '' ? null : (float)$match[4];
152
+            $this->minimum = $match[3] === '' ? null : (float) $match[3];
153
+            $this->maximum = $match[4] === '' ? null : (float) $match[4];
154 154
             $this->exclusiveMaximum = isset($match[5]) ? ($match[5] === '>') : null;
155 155
             if ($this->minimum && $this->maximum && $this->minimum > $this->maximum) {
156 156
                 self::swap($this->minimum, $this->maximum);
Please login to merge, or discard this patch.
SwaggerGen/Swagger/Type/ArrayType.php 2 patches
Indentation   +177 added lines, -177 removed lines patch added patch discarded remove patch
@@ -16,182 +16,182 @@
 block discarded – undo
16 16
 class ArrayType extends AbstractType
17 17
 {
18 18
 
19
-    /** @noinspection PhpRegExpUnsupportedModifierInspection */
20
-    private const REGEX_ARRAY_CONTENT = '(?:(\[)(.*)\])?';
21
-
22
-    private static $collectionFormats = array(
23
-        'array' => 'csv',
24
-        'csv' => 'csv',
25
-        'ssv' => 'ssv',
26
-        'tsv' => 'tsv',
27
-        'pipes' => 'pipes',
28
-        'multi' => 'multi',
29
-    );
30
-
31
-    /**
32
-     * @var AbstractType
33
-     */
34
-    private $Items;
35
-    private $minItems;
36
-    private $maxItems;
37
-    private $collectionFormat;
38
-
39
-    /**
40
-     * @param string $command The comment command
41
-     * @param string $data Any data added after the command
42
-     * @return AbstractType|boolean
43
-     * @throws Exception
44
-     * @throws Exception
45
-     * @throws Exception
46
-     * @throws Exception
47
-     * @throws Exception
48
-     * @throws Exception
49
-     * @throws Exception
50
-     */
51
-    public function handleCommand($command, $data = null)
52
-    {
53
-        if ($this->Items) {
54
-            $return = $this->Items->handleCommand($command, $data);
55
-            if ($return) {
56
-                return $return;
57
-            }
58
-        }
59
-
60
-        switch (strtolower($command)) {
61
-            case 'min':
62
-                $this->minItems = (int)$data;
63
-                if ($this->minItems < 0) {
64
-                    throw new Exception("Minimum less than zero: '$data'");
65
-                }
66
-                if ($this->maxItems !== null && $this->minItems > $this->maxItems) {
67
-                    throw new Exception("Minimum greater than maximum: '$data'");
68
-                }
69
-                return $this;
70
-
71
-            case 'max':
72
-                $this->maxItems = (int)$data;
73
-                if ($this->minItems !== null && $this->minItems > $this->maxItems) {
74
-                    throw new Exception("Maximum less than minimum: '$data'");
75
-                }
76
-                if ($this->maxItems < 0) {
77
-                    throw new Exception("Maximum less than zero: '$data'");
78
-                }
79
-                return $this;
80
-
81
-            case 'items':
82
-                $this->Items = $this->validateItems($data);
83
-                return $this->Items;
84
-        }
85
-
86
-        return parent::handleCommand($command, $data);
87
-    }
88
-
89
-    /**
90
-     * @throws Exception
91
-     */
92
-    private function validateItems($items)
93
-    {
94
-        if (empty($items)) {
95
-            throw new Exception("Empty items definition: '$items'");
96
-        }
97
-
98
-        return self::typeFactory($this, $items, "Unparseable items definition: '%s'");
99
-    }
100
-
101
-    public function toArray(): array
102
-    {
103
-        return self::arrayFilterNull(array_merge(array(
104
-            'type' => 'array',
105
-            'items' => empty($this->Items) ? null : $this->Items->toArray(),
106
-            'collectionFormat' => $this->collectionFormat === 'csv' ? null : $this->collectionFormat,
107
-            'minItems' => $this->minItems,
108
-            'maxItems' => $this->maxItems,
109
-        ), parent::toArray()));
110
-    }
111
-
112
-    public function __toString()
113
-    {
114
-        return __CLASS__;
115
-    }
116
-
117
-    /**
118
-     * @throws Exception
119
-     */
120
-    protected function parseDefinition($definition): void
121
-    {
122
-        $definition = self::trim($definition);
123
-        $match = [];
124
-        if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_CONTENT . self::REGEX_RANGE . self::REGEX_END, $definition, $match) === 1) {
125
-            $match[1] = strtolower($match[1]);
126
-        } elseif (preg_match(self::REGEX_START . self::REGEX_ARRAY_CONTENT . self::REGEX_RANGE . self::REGEX_END, $definition, $match) === 1) {
127
-            $match[1] = 'array';
128
-        } else {
129
-            throw new Exception('Unparseable array definition: \'' . $definition . '\'');
130
-        }
131
-
132
-        $this->parseFormat($definition, $match);
133
-        $this->parseItems($definition, $match);
134
-        $this->parseRange($definition, $match);
135
-    }
136
-
137
-    /**
138
-     * @param string $definition
139
-     * @param string[] $match
140
-     * @throws Exception
141
-     * @throws Exception
142
-     */
143
-    private function parseFormat($definition, $match): void
144
-    {
145
-        $type = strtolower($match[1]);
146
-        if (!isset(self::$collectionFormats[$type])) {
147
-            throw new Exception("Not an array: '$definition'");
148
-        }
149
-
150
-        if ($type === 'multi') {
151
-            $parent = $this->getParent();
152
-            if (!($parent instanceof Parameter) || !$parent->isMulti()) {
153
-                throw new Exception("Multi array only allowed on query or form parameter: '$definition'");
154
-            }
155
-        }
156
-
157
-        $this->collectionFormat = self::$collectionFormats[$type];
158
-    }
159
-
160
-    /**
161
-     * @param string $definition
162
-     * @param string[] $match
163
-     * @throws Exception
164
-     */
165
-    private function parseItems($definition, $match): void
166
-    {
167
-        if (!empty($match[2])) {
168
-            $this->Items = $this->validateItems($match[2]);
169
-        }
170
-    }
171
-
172
-    /**
173
-     * @param string $definition
174
-     * @param string[] $match
175
-     * @throws Exception
176
-     */
177
-    private function parseRange($definition, $match): void
178
-    {
179
-        if (!empty($match[3])) {
180
-            if ($match[4] === '' && $match[5] === '') {
181
-                throw new Exception("Empty array range: '$definition'");
182
-            }
183
-
184
-            $exclusiveMinimum = $match[3] === '<';
185
-            $this->minItems = $match[4] === '' ? null : (int)$match[4];
186
-            $this->maxItems = $match[5] === '' ? null : (int)$match[5];
187
-            $exclusiveMaximum = isset($match[6]) ? ($match[6] === '>') : null;
188
-            if ($this->minItems && $this->maxItems && $this->minItems > $this->maxItems) {
189
-                self::swap($this->minItems, $this->maxItems);
190
-                self::swap($exclusiveMinimum, $exclusiveMaximum);
191
-            }
192
-            $this->minItems = $this->minItems === null ? null : max(0, $exclusiveMinimum ? $this->minItems + 1 : $this->minItems);
193
-            $this->maxItems = $this->maxItems === null ? null : max(0, $exclusiveMaximum ? $this->maxItems - 1 : $this->maxItems);
194
-        }
195
-    }
19
+	/** @noinspection PhpRegExpUnsupportedModifierInspection */
20
+	private const REGEX_ARRAY_CONTENT = '(?:(\[)(.*)\])?';
21
+
22
+	private static $collectionFormats = array(
23
+		'array' => 'csv',
24
+		'csv' => 'csv',
25
+		'ssv' => 'ssv',
26
+		'tsv' => 'tsv',
27
+		'pipes' => 'pipes',
28
+		'multi' => 'multi',
29
+	);
30
+
31
+	/**
32
+	 * @var AbstractType
33
+	 */
34
+	private $Items;
35
+	private $minItems;
36
+	private $maxItems;
37
+	private $collectionFormat;
38
+
39
+	/**
40
+	 * @param string $command The comment command
41
+	 * @param string $data Any data added after the command
42
+	 * @return AbstractType|boolean
43
+	 * @throws Exception
44
+	 * @throws Exception
45
+	 * @throws Exception
46
+	 * @throws Exception
47
+	 * @throws Exception
48
+	 * @throws Exception
49
+	 * @throws Exception
50
+	 */
51
+	public function handleCommand($command, $data = null)
52
+	{
53
+		if ($this->Items) {
54
+			$return = $this->Items->handleCommand($command, $data);
55
+			if ($return) {
56
+				return $return;
57
+			}
58
+		}
59
+
60
+		switch (strtolower($command)) {
61
+			case 'min':
62
+				$this->minItems = (int)$data;
63
+				if ($this->minItems < 0) {
64
+					throw new Exception("Minimum less than zero: '$data'");
65
+				}
66
+				if ($this->maxItems !== null && $this->minItems > $this->maxItems) {
67
+					throw new Exception("Minimum greater than maximum: '$data'");
68
+				}
69
+				return $this;
70
+
71
+			case 'max':
72
+				$this->maxItems = (int)$data;
73
+				if ($this->minItems !== null && $this->minItems > $this->maxItems) {
74
+					throw new Exception("Maximum less than minimum: '$data'");
75
+				}
76
+				if ($this->maxItems < 0) {
77
+					throw new Exception("Maximum less than zero: '$data'");
78
+				}
79
+				return $this;
80
+
81
+			case 'items':
82
+				$this->Items = $this->validateItems($data);
83
+				return $this->Items;
84
+		}
85
+
86
+		return parent::handleCommand($command, $data);
87
+	}
88
+
89
+	/**
90
+	 * @throws Exception
91
+	 */
92
+	private function validateItems($items)
93
+	{
94
+		if (empty($items)) {
95
+			throw new Exception("Empty items definition: '$items'");
96
+		}
97
+
98
+		return self::typeFactory($this, $items, "Unparseable items definition: '%s'");
99
+	}
100
+
101
+	public function toArray(): array
102
+	{
103
+		return self::arrayFilterNull(array_merge(array(
104
+			'type' => 'array',
105
+			'items' => empty($this->Items) ? null : $this->Items->toArray(),
106
+			'collectionFormat' => $this->collectionFormat === 'csv' ? null : $this->collectionFormat,
107
+			'minItems' => $this->minItems,
108
+			'maxItems' => $this->maxItems,
109
+		), parent::toArray()));
110
+	}
111
+
112
+	public function __toString()
113
+	{
114
+		return __CLASS__;
115
+	}
116
+
117
+	/**
118
+	 * @throws Exception
119
+	 */
120
+	protected function parseDefinition($definition): void
121
+	{
122
+		$definition = self::trim($definition);
123
+		$match = [];
124
+		if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_CONTENT . self::REGEX_RANGE . self::REGEX_END, $definition, $match) === 1) {
125
+			$match[1] = strtolower($match[1]);
126
+		} elseif (preg_match(self::REGEX_START . self::REGEX_ARRAY_CONTENT . self::REGEX_RANGE . self::REGEX_END, $definition, $match) === 1) {
127
+			$match[1] = 'array';
128
+		} else {
129
+			throw new Exception('Unparseable array definition: \'' . $definition . '\'');
130
+		}
131
+
132
+		$this->parseFormat($definition, $match);
133
+		$this->parseItems($definition, $match);
134
+		$this->parseRange($definition, $match);
135
+	}
136
+
137
+	/**
138
+	 * @param string $definition
139
+	 * @param string[] $match
140
+	 * @throws Exception
141
+	 * @throws Exception
142
+	 */
143
+	private function parseFormat($definition, $match): void
144
+	{
145
+		$type = strtolower($match[1]);
146
+		if (!isset(self::$collectionFormats[$type])) {
147
+			throw new Exception("Not an array: '$definition'");
148
+		}
149
+
150
+		if ($type === 'multi') {
151
+			$parent = $this->getParent();
152
+			if (!($parent instanceof Parameter) || !$parent->isMulti()) {
153
+				throw new Exception("Multi array only allowed on query or form parameter: '$definition'");
154
+			}
155
+		}
156
+
157
+		$this->collectionFormat = self::$collectionFormats[$type];
158
+	}
159
+
160
+	/**
161
+	 * @param string $definition
162
+	 * @param string[] $match
163
+	 * @throws Exception
164
+	 */
165
+	private function parseItems($definition, $match): void
166
+	{
167
+		if (!empty($match[2])) {
168
+			$this->Items = $this->validateItems($match[2]);
169
+		}
170
+	}
171
+
172
+	/**
173
+	 * @param string $definition
174
+	 * @param string[] $match
175
+	 * @throws Exception
176
+	 */
177
+	private function parseRange($definition, $match): void
178
+	{
179
+		if (!empty($match[3])) {
180
+			if ($match[4] === '' && $match[5] === '') {
181
+				throw new Exception("Empty array range: '$definition'");
182
+			}
183
+
184
+			$exclusiveMinimum = $match[3] === '<';
185
+			$this->minItems = $match[4] === '' ? null : (int)$match[4];
186
+			$this->maxItems = $match[5] === '' ? null : (int)$match[5];
187
+			$exclusiveMaximum = isset($match[6]) ? ($match[6] === '>') : null;
188
+			if ($this->minItems && $this->maxItems && $this->minItems > $this->maxItems) {
189
+				self::swap($this->minItems, $this->maxItems);
190
+				self::swap($exclusiveMinimum, $exclusiveMaximum);
191
+			}
192
+			$this->minItems = $this->minItems === null ? null : max(0, $exclusiveMinimum ? $this->minItems + 1 : $this->minItems);
193
+			$this->maxItems = $this->maxItems === null ? null : max(0, $exclusiveMaximum ? $this->maxItems - 1 : $this->maxItems);
194
+		}
195
+	}
196 196
 
197 197
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -59,7 +59,7 @@  discard block
 block discarded – undo
59 59
 
60 60
         switch (strtolower($command)) {
61 61
             case 'min':
62
-                $this->minItems = (int)$data;
62
+                $this->minItems = (int) $data;
63 63
                 if ($this->minItems < 0) {
64 64
                     throw new Exception("Minimum less than zero: '$data'");
65 65
                 }
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
                 return $this;
70 70
 
71 71
             case 'max':
72
-                $this->maxItems = (int)$data;
72
+                $this->maxItems = (int) $data;
73 73
                 if ($this->minItems !== null && $this->minItems > $this->maxItems) {
74 74
                     throw new Exception("Maximum less than minimum: '$data'");
75 75
                 }
@@ -182,8 +182,8 @@  discard block
 block discarded – undo
182 182
             }
183 183
 
184 184
             $exclusiveMinimum = $match[3] === '<';
185
-            $this->minItems = $match[4] === '' ? null : (int)$match[4];
186
-            $this->maxItems = $match[5] === '' ? null : (int)$match[5];
185
+            $this->minItems = $match[4] === '' ? null : (int) $match[4];
186
+            $this->maxItems = $match[5] === '' ? null : (int) $match[5];
187 187
             $exclusiveMaximum = isset($match[6]) ? ($match[6] === '>') : null;
188 188
             if ($this->minItems && $this->maxItems && $this->minItems > $this->maxItems) {
189 189
                 self::swap($this->minItems, $this->maxItems);
Please login to merge, or discard this patch.
SwaggerGen/Swagger/Info.php 2 patches
Indentation   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -14,106 +14,106 @@
 block discarded – undo
14 14
 class Info extends AbstractObject
15 15
 {
16 16
 
17
-    /**
18
-     * @var string
19
-     */
20
-    private $title = 'undefined';
21
-
22
-    /**
23
-     * @var string
24
-     */
25
-    private $description;
26
-
27
-    /**
28
-     * @var string
29
-     */
30
-    private $termsofservice;
31
-
32
-    /**
33
-     * @var Contact
34
-     */
35
-    private $contact;
36
-
37
-    /**
38
-     * @var License
39
-     */
40
-    private $license;
41
-
42
-    /**
43
-     * @var string|integer|float
44
-     */
45
-    private $version = 0;
46
-
47
-    /**
48
-     * @param string $command
49
-     * @param string $data
50
-     * @return AbstractObject|boolean
51
-     */
52
-    public function handleCommand($command, $data = null)
53
-    {
54
-        switch (strtolower($command)) {
55
-            case 'title':
56
-            case 'description':
57
-            case 'termsofservice':
58
-            case 'version':
59
-                $this->$command = $data;
60
-                return $this;
61
-
62
-            case 'terms': // alias
63
-            case 'tos': // alias
64
-                $this->termsofservice = $data;
65
-                return $this;
66
-
67
-            case 'contact':
68
-                $name = [];
69
-                $url = null;
70
-                $email = null;
71
-                foreach (self::wordSplit($data) as $word) {
72
-                    if (filter_var($word, FILTER_VALIDATE_URL)) {
73
-                        $url = $word;
74
-                    } elseif (filter_var($word, FILTER_VALIDATE_EMAIL)) {
75
-                        $email = $word;
76
-                    } else {
77
-                        $name[] = $word;
78
-                    }
79
-                }
80
-                $name = implode(' ', array_filter($name));
81
-                $this->contact = new Contact($this, $name, $url, $email);
82
-                return $this->contact;
83
-
84
-            case 'license':
85
-                $name = [];
86
-                $url = null;
87
-                foreach (self::wordSplit($data) as $word) {
88
-                    if (filter_var($word, FILTER_VALIDATE_URL)) {
89
-                        $url = $word;
90
-                    } else {
91
-                        $name[] = $word;
92
-                    }
93
-                }
94
-                $name = implode(' ', array_filter($name));
95
-                $this->license = new License($this, $name, $url);
96
-                return $this->license;
97
-        }
98
-
99
-        return parent::handleCommand($command, $data);
100
-    }
101
-
102
-    public function toArray(): array
103
-    {
104
-        return self::arrayFilterNull(array_merge(array(
105
-            'title' => $this->title,
106
-            'description' => $this->description,
107
-            'termsOfService' => $this->termsofservice,
108
-            'contact' => $this->contact?->toArray(),
109
-            'license' => $this->license?->toArray(),
110
-            'version' => (string)$this->version,
111
-        ), parent::toArray()));
112
-    }
113
-
114
-    public function __toString()
115
-    {
116
-        return __CLASS__ . ' \'' . $this->title . '\'';
117
-    }
17
+	/**
18
+	 * @var string
19
+	 */
20
+	private $title = 'undefined';
21
+
22
+	/**
23
+	 * @var string
24
+	 */
25
+	private $description;
26
+
27
+	/**
28
+	 * @var string
29
+	 */
30
+	private $termsofservice;
31
+
32
+	/**
33
+	 * @var Contact
34
+	 */
35
+	private $contact;
36
+
37
+	/**
38
+	 * @var License
39
+	 */
40
+	private $license;
41
+
42
+	/**
43
+	 * @var string|integer|float
44
+	 */
45
+	private $version = 0;
46
+
47
+	/**
48
+	 * @param string $command
49
+	 * @param string $data
50
+	 * @return AbstractObject|boolean
51
+	 */
52
+	public function handleCommand($command, $data = null)
53
+	{
54
+		switch (strtolower($command)) {
55
+			case 'title':
56
+			case 'description':
57
+			case 'termsofservice':
58
+			case 'version':
59
+				$this->$command = $data;
60
+				return $this;
61
+
62
+			case 'terms': // alias
63
+			case 'tos': // alias
64
+				$this->termsofservice = $data;
65
+				return $this;
66
+
67
+			case 'contact':
68
+				$name = [];
69
+				$url = null;
70
+				$email = null;
71
+				foreach (self::wordSplit($data) as $word) {
72
+					if (filter_var($word, FILTER_VALIDATE_URL)) {
73
+						$url = $word;
74
+					} elseif (filter_var($word, FILTER_VALIDATE_EMAIL)) {
75
+						$email = $word;
76
+					} else {
77
+						$name[] = $word;
78
+					}
79
+				}
80
+				$name = implode(' ', array_filter($name));
81
+				$this->contact = new Contact($this, $name, $url, $email);
82
+				return $this->contact;
83
+
84
+			case 'license':
85
+				$name = [];
86
+				$url = null;
87
+				foreach (self::wordSplit($data) as $word) {
88
+					if (filter_var($word, FILTER_VALIDATE_URL)) {
89
+						$url = $word;
90
+					} else {
91
+						$name[] = $word;
92
+					}
93
+				}
94
+				$name = implode(' ', array_filter($name));
95
+				$this->license = new License($this, $name, $url);
96
+				return $this->license;
97
+		}
98
+
99
+		return parent::handleCommand($command, $data);
100
+	}
101
+
102
+	public function toArray(): array
103
+	{
104
+		return self::arrayFilterNull(array_merge(array(
105
+			'title' => $this->title,
106
+			'description' => $this->description,
107
+			'termsOfService' => $this->termsofservice,
108
+			'contact' => $this->contact?->toArray(),
109
+			'license' => $this->license?->toArray(),
110
+			'version' => (string)$this->version,
111
+		), parent::toArray()));
112
+	}
113
+
114
+	public function __toString()
115
+	{
116
+		return __CLASS__ . ' \'' . $this->title . '\'';
117
+	}
118 118
 
119 119
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -107,7 +107,7 @@
 block discarded – undo
107 107
             'termsOfService' => $this->termsofservice,
108 108
             'contact' => $this->contact?->toArray(),
109 109
             'license' => $this->license?->toArray(),
110
-            'version' => (string)$this->version,
110
+            'version' => (string) $this->version,
111 111
         ), parent::toArray()));
112 112
     }
113 113
 
Please login to merge, or discard this patch.
SwaggerGen/Swagger/AbstractDocumentableObject.php 1 patch
Indentation   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -14,38 +14,38 @@
 block discarded – undo
14 14
 abstract class AbstractDocumentableObject extends AbstractObject
15 15
 {
16 16
 
17
-    /**
18
-     * External documentation
19
-     * @var ExternalDocumentation
20
-     */
21
-    private $externalDocs;
17
+	/**
18
+	 * External documentation
19
+	 * @var ExternalDocumentation
20
+	 */
21
+	private $externalDocs;
22 22
 
23
-    /**
24
-     * @param string $command
25
-     * @param string $data
26
-     * @return AbstractObject|boolean
27
-     */
28
-    public function handleCommand($command, $data = null)
29
-    {
30
-        switch (strtolower($command)) {
31
-            case 'doc':
32
-            case 'docs':
33
-                $url = self::wordShift($data);
34
-                $this->externalDocs = new ExternalDocumentation($this, $url, $data);
35
-                return $this->externalDocs;
36
-        }
23
+	/**
24
+	 * @param string $command
25
+	 * @param string $data
26
+	 * @return AbstractObject|boolean
27
+	 */
28
+	public function handleCommand($command, $data = null)
29
+	{
30
+		switch (strtolower($command)) {
31
+			case 'doc':
32
+			case 'docs':
33
+				$url = self::wordShift($data);
34
+				$this->externalDocs = new ExternalDocumentation($this, $url, $data);
35
+				return $this->externalDocs;
36
+		}
37 37
 
38
-        return parent::handleCommand($command, $data);
39
-    }
38
+		return parent::handleCommand($command, $data);
39
+	}
40 40
 
41
-    /**
42
-     * @return array
43
-     */
44
-    public function toArray(): array
45
-    {
46
-        return self::arrayFilterNull(array_merge(array(
47
-            'externalDocs' => $this->externalDocs?->toArray(),
48
-        ), parent::toArray()));
49
-    }
41
+	/**
42
+	 * @return array
43
+	 */
44
+	public function toArray(): array
45
+	{
46
+		return self::arrayFilterNull(array_merge(array(
47
+			'externalDocs' => $this->externalDocs?->toArray(),
48
+		), parent::toArray()));
49
+	}
50 50
 
51 51
 }
Please login to merge, or discard this patch.
SwaggerGen/SwaggerGen.php 1 patch
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -38,207 +38,207 @@
 block discarded – undo
38 38
 class SwaggerGen
39 39
 {
40 40
 
41
-    public const FORMAT_ARRAY = '';
42
-    public const FORMAT_JSON = 'json';
43
-    public const FORMAT_JSON_PRETTY = 'json+';
44
-    public const FORMAT_YAML = 'yaml';
45
-
46
-    private string $host;
47
-    private string $basePath;
48
-    private array $dirs;
49
-    private array $defines = [];
50
-
51
-    /**
52
-     * @var TypeRegistry
53
-     */
54
-    private $typeRegistry;
55
-
56
-    /**
57
-     * Create a new SwaggerGen instance
58
-     *
59
-     * @param string $host
60
-     * @param string $basePath
61
-     * @param string[] $dirs
62
-     * @param TypeRegistry $typeRegistry
63
-     */
64
-    public function __construct($host = '', $basePath = '', $dirs = [], $typeRegistry = null)
65
-    {
66
-        $this->host = $host;
67
-        $this->basePath = $basePath;
68
-        $this->dirs = $dirs;
69
-        $this->typeRegistry = $typeRegistry;
70
-    }
71
-
72
-    /**
73
-     * Set a new type registry
74
-     *
75
-     * @param TypeRegistry $typeRegistry
76
-     */
77
-    public function setTypeRegistry($typeRegistry = null): void
78
-    {
79
-        $this->typeRegistry = $typeRegistry;
80
-    }
81
-
82
-    /**
83
-     * @param string $name
84
-     */
85
-    public function define($name, $value = 1): void
86
-    {
87
-        $this->defines[$name] = $value;
88
-    }
89
-
90
-    /**
91
-     * @param string $name
92
-     */
93
-    public function undefine($name): void
94
-    {
95
-        unset($this->defines[$name]);
96
-    }
97
-
98
-    /**
99
-     * Get Swagger 2.x output
100
-     *
101
-     * @param string[] $files
102
-     * @param string[] $dirs
103
-     * @param string $format
104
-     * @return array|false|string
105
-     * @throws Exception
106
-     * @throws StatementException
107
-     */
108
-    public function getSwagger(array $files, array $dirs = [], string $format = self::FORMAT_ARRAY)
109
-    {
110
-        $dirs = array_merge($this->dirs, $dirs);
111
-
112
-        $statements = [];
113
-        foreach ($files as $file) {
114
-            $fileStatements = match (pathinfo($file, PATHINFO_EXTENSION)) {
115
-                'php' => $this->parsePhpFile($file, $dirs),
116
-                'txt' => $this->parseTextFile($file, $dirs),
117
-                default => $this->parseText($file, $dirs),
118
-            };
119
-
120
-            $statements[] = $fileStatements;
121
-        }
122
-        $statements = array_merge(...$statements);
123
-
124
-        $output = $this->parseStatements($this->host, $this->basePath, $statements)->toArray();
125
-
126
-        switch ($format) {
127
-            case self::FORMAT_JSON:
128
-                $output = json_encode($output);
129
-                break;
130
-
131
-            case self::FORMAT_JSON_PRETTY:
132
-                $flags = (defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0); // Since PHP 5.4.0
133
-                $output = json_encode($output, $flags);
134
-                break;
135
-
136
-            case self::FORMAT_YAML:
137
-                if (!function_exists('yaml_emit')) {
138
-                    throw new Exception('YAML extension not installed.');
139
-                }
140
-                array_walk_recursive($output, static function (&$value) {
141
-                    if (is_object($value)) {
142
-                        $value = (array)$value;
143
-                    }
144
-                });
145
-                $output = yaml_emit($output, YAML_UTF8_ENCODING, YAML_LN_BREAK);
146
-                break;
147
-        }
148
-
149
-        return $output;
150
-    }
151
-
152
-    /**
153
-     * @param string $file
154
-     * @param string[] $dirs
155
-     * @return Statement[]
156
-     * @throws Exception
157
-     */
158
-    private function parsePhpFile(string $file, array $dirs): array
159
-    {
160
-        return (new Parser())->parse($file, $dirs, $this->defines);
161
-    }
162
-
163
-    /**
164
-     * @param string $file
165
-     * @param string[] $dirs
166
-     * @return Statement[]
167
-     */
168
-    private function parseTextFile($file, $dirs): array
169
-    {
170
-        return (new TextParser())->parse($file, $dirs, $this->defines);
171
-    }
172
-
173
-    /**
174
-     * @param string $text
175
-     * @param string[] $dirs
176
-     * @return Statement[]
177
-     */
178
-    private function parseText(string $text, array $dirs): array
179
-    {
180
-        return (new TextParser())->parseText($text, $dirs, $this->defines);
181
-    }
182
-
183
-    /**
184
-     * Creates Swagger\Swagger object and populates it with statements
185
-     *
186
-     * This effectively converts the linear list of statements into parse-tree
187
-     * like structure, performing some checks (like rejecting unknown
188
-     * subcommands) during the process. Returned Swagger\Swagger object is
189
-     * ready for serialization with {@see Swagger\Swagger::toArray}
190
-     *
191
-     * @param string $host
192
-     * @param string $basePath
193
-     * @param Statement[] $statements
194
-     * @return Swagger
195
-     * @throws StatementException
196
-     */
197
-    public function parseStatements($host, $basePath, $statements): Swagger
198
-    {
199
-        $swagger = new Swagger($host, $basePath, $this->typeRegistry);
200
-
201
-        $stack = array($swagger);
202
-        /* @var AbstractObject[] $stack */
203
-        foreach ($statements as $statement) {
204
-            try {
205
-                $top = end($stack);
206
-
207
-                do {
208
-                    $result = $top->handleCommand($statement->getCommand(), $statement->getData());
209
-
210
-                    if ($result) {
211
-                        if ($result !== $top) {
212
-                            // Remove all similar classes from array first!
213
-                            $classname = get_class($result);
214
-                            $stack = array_filter($stack, static function ($class) use ($classname) {
215
-                                return !(is_a($class, $classname));
216
-                            });
217
-
218
-                            $stack[] = $result;
219
-                        }
220
-                    } else {
221
-                        $top = prev($stack);
222
-                    }
223
-                } while (!$result && $top);
224
-            } catch (Exception $e) {
225
-                throw new StatementException($e->getMessage(), $e->getCode(), $e, $statement);
226
-            }
227
-
228
-            if (!$result && !$top) {
229
-                $messages = array("Unsupported or unknown command: {$statement->getCommand()} {$statement->getData()}");
230
-
231
-                $stacktrace = [];
232
-                foreach ($stack as $object) {
233
-                    $stacktrace[] = (string)$object;
234
-                }
235
-                $messages[] = implode(', ' . PHP_EOL, $stacktrace);
236
-
237
-                throw new StatementException(implode('. ', $messages), 0, null, $statement);
238
-            }
239
-        }
240
-
241
-        return $swagger;
242
-    }
41
+	public const FORMAT_ARRAY = '';
42
+	public const FORMAT_JSON = 'json';
43
+	public const FORMAT_JSON_PRETTY = 'json+';
44
+	public const FORMAT_YAML = 'yaml';
45
+
46
+	private string $host;
47
+	private string $basePath;
48
+	private array $dirs;
49
+	private array $defines = [];
50
+
51
+	/**
52
+	 * @var TypeRegistry
53
+	 */
54
+	private $typeRegistry;
55
+
56
+	/**
57
+	 * Create a new SwaggerGen instance
58
+	 *
59
+	 * @param string $host
60
+	 * @param string $basePath
61
+	 * @param string[] $dirs
62
+	 * @param TypeRegistry $typeRegistry
63
+	 */
64
+	public function __construct($host = '', $basePath = '', $dirs = [], $typeRegistry = null)
65
+	{
66
+		$this->host = $host;
67
+		$this->basePath = $basePath;
68
+		$this->dirs = $dirs;
69
+		$this->typeRegistry = $typeRegistry;
70
+	}
71
+
72
+	/**
73
+	 * Set a new type registry
74
+	 *
75
+	 * @param TypeRegistry $typeRegistry
76
+	 */
77
+	public function setTypeRegistry($typeRegistry = null): void
78
+	{
79
+		$this->typeRegistry = $typeRegistry;
80
+	}
81
+
82
+	/**
83
+	 * @param string $name
84
+	 */
85
+	public function define($name, $value = 1): void
86
+	{
87
+		$this->defines[$name] = $value;
88
+	}
89
+
90
+	/**
91
+	 * @param string $name
92
+	 */
93
+	public function undefine($name): void
94
+	{
95
+		unset($this->defines[$name]);
96
+	}
97
+
98
+	/**
99
+	 * Get Swagger 2.x output
100
+	 *
101
+	 * @param string[] $files
102
+	 * @param string[] $dirs
103
+	 * @param string $format
104
+	 * @return array|false|string
105
+	 * @throws Exception
106
+	 * @throws StatementException
107
+	 */
108
+	public function getSwagger(array $files, array $dirs = [], string $format = self::FORMAT_ARRAY)
109
+	{
110
+		$dirs = array_merge($this->dirs, $dirs);
111
+
112
+		$statements = [];
113
+		foreach ($files as $file) {
114
+			$fileStatements = match (pathinfo($file, PATHINFO_EXTENSION)) {
115
+				'php' => $this->parsePhpFile($file, $dirs),
116
+				'txt' => $this->parseTextFile($file, $dirs),
117
+				default => $this->parseText($file, $dirs),
118
+			};
119
+
120
+			$statements[] = $fileStatements;
121
+		}
122
+		$statements = array_merge(...$statements);
123
+
124
+		$output = $this->parseStatements($this->host, $this->basePath, $statements)->toArray();
125
+
126
+		switch ($format) {
127
+			case self::FORMAT_JSON:
128
+				$output = json_encode($output);
129
+				break;
130
+
131
+			case self::FORMAT_JSON_PRETTY:
132
+				$flags = (defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0); // Since PHP 5.4.0
133
+				$output = json_encode($output, $flags);
134
+				break;
135
+
136
+			case self::FORMAT_YAML:
137
+				if (!function_exists('yaml_emit')) {
138
+					throw new Exception('YAML extension not installed.');
139
+				}
140
+				array_walk_recursive($output, static function (&$value) {
141
+					if (is_object($value)) {
142
+						$value = (array)$value;
143
+					}
144
+				});
145
+				$output = yaml_emit($output, YAML_UTF8_ENCODING, YAML_LN_BREAK);
146
+				break;
147
+		}
148
+
149
+		return $output;
150
+	}
151
+
152
+	/**
153
+	 * @param string $file
154
+	 * @param string[] $dirs
155
+	 * @return Statement[]
156
+	 * @throws Exception
157
+	 */
158
+	private function parsePhpFile(string $file, array $dirs): array
159
+	{
160
+		return (new Parser())->parse($file, $dirs, $this->defines);
161
+	}
162
+
163
+	/**
164
+	 * @param string $file
165
+	 * @param string[] $dirs
166
+	 * @return Statement[]
167
+	 */
168
+	private function parseTextFile($file, $dirs): array
169
+	{
170
+		return (new TextParser())->parse($file, $dirs, $this->defines);
171
+	}
172
+
173
+	/**
174
+	 * @param string $text
175
+	 * @param string[] $dirs
176
+	 * @return Statement[]
177
+	 */
178
+	private function parseText(string $text, array $dirs): array
179
+	{
180
+		return (new TextParser())->parseText($text, $dirs, $this->defines);
181
+	}
182
+
183
+	/**
184
+	 * Creates Swagger\Swagger object and populates it with statements
185
+	 *
186
+	 * This effectively converts the linear list of statements into parse-tree
187
+	 * like structure, performing some checks (like rejecting unknown
188
+	 * subcommands) during the process. Returned Swagger\Swagger object is
189
+	 * ready for serialization with {@see Swagger\Swagger::toArray}
190
+	 *
191
+	 * @param string $host
192
+	 * @param string $basePath
193
+	 * @param Statement[] $statements
194
+	 * @return Swagger
195
+	 * @throws StatementException
196
+	 */
197
+	public function parseStatements($host, $basePath, $statements): Swagger
198
+	{
199
+		$swagger = new Swagger($host, $basePath, $this->typeRegistry);
200
+
201
+		$stack = array($swagger);
202
+		/* @var AbstractObject[] $stack */
203
+		foreach ($statements as $statement) {
204
+			try {
205
+				$top = end($stack);
206
+
207
+				do {
208
+					$result = $top->handleCommand($statement->getCommand(), $statement->getData());
209
+
210
+					if ($result) {
211
+						if ($result !== $top) {
212
+							// Remove all similar classes from array first!
213
+							$classname = get_class($result);
214
+							$stack = array_filter($stack, static function ($class) use ($classname) {
215
+								return !(is_a($class, $classname));
216
+							});
217
+
218
+							$stack[] = $result;
219
+						}
220
+					} else {
221
+						$top = prev($stack);
222
+					}
223
+				} while (!$result && $top);
224
+			} catch (Exception $e) {
225
+				throw new StatementException($e->getMessage(), $e->getCode(), $e, $statement);
226
+			}
227
+
228
+			if (!$result && !$top) {
229
+				$messages = array("Unsupported or unknown command: {$statement->getCommand()} {$statement->getData()}");
230
+
231
+				$stacktrace = [];
232
+				foreach ($stack as $object) {
233
+					$stacktrace[] = (string)$object;
234
+				}
235
+				$messages[] = implode(', ' . PHP_EOL, $stacktrace);
236
+
237
+				throw new StatementException(implode('. ', $messages), 0, null, $statement);
238
+			}
239
+		}
240
+
241
+		return $swagger;
242
+	}
243 243
 
244 244
 }
Please login to merge, or discard this patch.
SwaggerGen/TypeRegistry.php 2 patches
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -15,59 +15,59 @@
 block discarded – undo
15 15
 class TypeRegistry
16 16
 {
17 17
 
18
-    /**
19
-     * Map of format-name => class-name
20
-     *
21
-     * @var array
22
-     */
23
-    private $formats = [];
18
+	/**
19
+	 * Map of format-name => class-name
20
+	 *
21
+	 * @var array
22
+	 */
23
+	private $formats = [];
24 24
 
25
-    /**
26
-     * Add a type name from classname
27
-     *
28
-     * @param string $classname
29
-     */
30
-    public function add(string $classname): void
31
-    {
32
-        if (is_subclass_of($classname, ICustomType::class)) {
33
-            foreach ($classname::getFormats() as $format) {
34
-                $this->formats[$format] = $classname;
35
-            }
36
-        }
37
-    }
25
+	/**
26
+	 * Add a type name from classname
27
+	 *
28
+	 * @param string $classname
29
+	 */
30
+	public function add(string $classname): void
31
+	{
32
+		if (is_subclass_of($classname, ICustomType::class)) {
33
+			foreach ($classname::getFormats() as $format) {
34
+				$this->formats[$format] = $classname;
35
+			}
36
+		}
37
+	}
38 38
 
39
-    /**
40
-     * Remove type format by explicitly nulling it (disables it)
41
-     *
42
-     * @param string $name
43
-     */
44
-    public function remove($name): void
45
-    {
46
-        $this->formats[$name] = null;
47
-    }
39
+	/**
40
+	 * Remove type format by explicitly nulling it (disables it)
41
+	 *
42
+	 * @param string $name
43
+	 */
44
+	public function remove($name): void
45
+	{
46
+		$this->formats[$name] = null;
47
+	}
48 48
 
49
-    /**
50
-     * Is a type format known?
51
-     *
52
-     * @param $name
53
-     * @return bool
54
-     */
55
-    public function has($name): bool
56
-    {
57
-        return !empty($this->formats[$name]);
58
-    }
49
+	/**
50
+	 * Is a type format known?
51
+	 *
52
+	 * @param $name
53
+	 * @return bool
54
+	 */
55
+	public function has($name): bool
56
+	{
57
+		return !empty($this->formats[$name]);
58
+	}
59 59
 
60
-    /**
61
-     * Get the format class name
62
-     *
63
-     * @param $name
64
-     * @return null|string
65
-     */
66
-    public function get($name): ?string
67
-    {
68
-        return !empty($this->formats[$name])
69
-            ? $this->formats[$name]
70
-            : null;
71
-    }
60
+	/**
61
+	 * Get the format class name
62
+	 *
63
+	 * @param $name
64
+	 * @return null|string
65
+	 */
66
+	public function get($name): ?string
67
+	{
68
+		return !empty($this->formats[$name])
69
+			? $this->formats[$name]
70
+			: null;
71
+	}
72 72
 
73 73
 }
Please login to merge, or discard this patch.
Braces   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -12,8 +12,8 @@  discard block
 block discarded – undo
12 12
  * @copyright  2014-2025 Martijn van der Lee
13 13
  * @license    https://opensource.org/licenses/MIT MIT
14 14
  */
15
-class TypeRegistry
16
-{
15
+class TypeRegistry
16
+{
17 17
 
18 18
     /**
19 19
      * Map of format-name => class-name
@@ -29,8 +29,8 @@  discard block
 block discarded – undo
29 29
      */
30 30
     public function add(string $classname): void
31 31
     {
32
-        if (is_subclass_of($classname, ICustomType::class)) {
33
-            foreach ($classname::getFormats() as $format) {
32
+        if (is_subclass_of($classname, ICustomType::class)) {
33
+            foreach ($classname::getFormats() as $format) {
34 34
                 $this->formats[$format] = $classname;
35 35
             }
36 36
         }
Please login to merge, or discard this patch.
SwaggerGen/Statement.php 1 patch
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -14,61 +14,61 @@
 block discarded – undo
14 14
 class Statement
15 15
 {
16 16
 
17
-    private $command;
18
-    private $data;
19
-    private $file;
20
-    private $line;
17
+	private $command;
18
+	private $data;
19
+	private $file;
20
+	private $line;
21 21
 
22
-    public function __construct($command, $data = null, $file = null, $line = null)
23
-    {
24
-        $this->command = $command;
25
-        $this->data = $data;
26
-        $this->file = $file;
27
-        $this->line = $line;
28
-    }
22
+	public function __construct($command, $data = null, $file = null, $line = null)
23
+	{
24
+		$this->command = $command;
25
+		$this->data = $data;
26
+		$this->file = $file;
27
+		$this->line = $line;
28
+	}
29 29
 
30
-    public function __toString()
31
-    {
32
-        $message = "Command '{$this->command}'";
33
-        $message .= $this->data ? " with data '{$this->data}'" : ' without data';
34
-        $message .= $this->file ? " from static text" : " in file '{$this->file}' on line {$this->line}";
35
-        return $message;
36
-    }
30
+	public function __toString()
31
+	{
32
+		$message = "Command '{$this->command}'";
33
+		$message .= $this->data ? " with data '{$this->data}'" : ' without data';
34
+		$message .= $this->file ? " from static text" : " in file '{$this->file}' on line {$this->line}";
35
+		return $message;
36
+	}
37 37
 
38
-    /**
39
-     * Get the command part of this statement
40
-     * @return string single word, without spaces
41
-     */
42
-    public function getCommand(): string
43
-    {
44
-        return $this->command;
45
-    }
38
+	/**
39
+	 * Get the command part of this statement
40
+	 * @return string single word, without spaces
41
+	 */
42
+	public function getCommand(): string
43
+	{
44
+		return $this->command;
45
+	}
46 46
 
47
-    /**
48
-     * Get the data of this statement
49
-     * @return string|null may contain spaces
50
-     */
51
-    public function getData(): ?string
52
-    {
53
-        return $this->data;
54
-    }
47
+	/**
48
+	 * Get the data of this statement
49
+	 * @return string|null may contain spaces
50
+	 */
51
+	public function getData(): ?string
52
+	{
53
+		return $this->data;
54
+	}
55 55
 
56
-    /**
57
-     * Get the file (if available) where this statement was parsed from
58
-     * @return string|null the full filename or null of from static text
59
-     */
60
-    public function getFile(): ?string
61
-    {
62
-        return $this->file;
63
-    }
56
+	/**
57
+	 * Get the file (if available) where this statement was parsed from
58
+	 * @return string|null the full filename or null of from static text
59
+	 */
60
+	public function getFile(): ?string
61
+	{
62
+		return $this->file;
63
+	}
64 64
 
65
-    /**
66
-     * Get the line number where this statement was found
67
-     * @return int|null the line number
68
-     */
69
-    public function getLine(): ?int
70
-    {
71
-        return $this->line;
72
-    }
65
+	/**
66
+	 * Get the line number where this statement was found
67
+	 * @return int|null the line number
68
+	 */
69
+	public function getLine(): ?int
70
+	{
71
+		return $this->line;
72
+	}
73 73
 
74 74
 }
Please login to merge, or discard this patch.