Completed
Push — master ( 8b636b...7c2d20 )
by Martijn
13s
created

SwaggerGen/Swagger/Type/ArrayType.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SwaggerGen\Swagger\Type;
4
5
/**
6
 * Basic array type definition.
7
 *
8
 * @package    SwaggerGen
9
 * @author     Martijn van der Lee <[email protected]>
10
 * @copyright  2014-2015 Martijn van der Lee
11
 * @license    https://opensource.org/licenses/MIT MIT
12
 */
13
class ArrayType extends AbstractType
14
{
15
16
	const REGEX_ARRAY_CONTENT = '(?:(\[)(.*)\])?';
17
18
	private static $classTypes = array(
19
		'integer' => 'Integer',
20
		'int' => 'Integer',
21
		'int32' => 'Integer',
22
		'int64' => 'Integer',
23
		'long' => 'Integer',
24
		'float' => 'Number',
25
		'double' => 'Number',
26
		'string' => 'String',
27
		'uuid' => 'StringUuid',
28
		'byte' => 'String',
29
		'binary' => 'String',
30
		'password' => 'String',
31
		'enum' => 'String',
32
		'boolean' => 'Boolean',
33
		'bool' => 'Boolean',
34
		'array' => 'Array',
35
		'csv' => 'Array',
36
		'ssv' => 'Array',
37
		'tsv' => 'Array',
38
		'pipes' => 'Array',
39
		'date' => 'Date',
40
		'datetime' => 'Date',
41
		'date-time' => 'Date',
42
		'object' => 'Object',
43
	);
44
	private static $collectionFormats = array(
45
		'array' => 'csv',
46
		'csv' => 'csv',
47
		'ssv' => 'ssv',
48
		'tsv' => 'tsv',
49
		'pipes' => 'pipes',
50
		'multi' => 'multi',
51
	);
52
53
	/**
54
	 * @var AbstractType
55
	 */
56
	private $Items = null;
57
	private $minItems = null;
58
	private $maxItems = null;
59
	private $collectionFormat = null;
60
61
	protected function parseDefinition($definition)
62
	{
63
		$definition = self::trim($definition);
64
		$match = array();
65
		if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_CONTENT . self::REGEX_RANGE . self::REGEX_END, $definition, $match) === 1) {
66
			// recognized format
67
		} elseif (preg_match(self::REGEX_START . self::REGEX_ARRAY_CONTENT . self::REGEX_RANGE . self::REGEX_END, $definition, $match) === 1) {
68
			$match[1] = 'array';
69
		} else {
70
			throw new \SwaggerGen\Exception("Unparseable array definition: '{$definition}'");
71
		}
72
73
		$this->parseFormat($definition, $match);
74
		$this->parseItems($definition, $match);
75
		$this->parseRange($definition, $match);
76
	}
77
78
	private function parseFormat($definition, $match)
79
	{
80
		$type = strtolower($match[1]);
81
		if (!isset(self::$collectionFormats[$type])) {
82
			throw new \SwaggerGen\Exception("Not an array: '{$definition}'");
83
		}
84
85
		if ($type === 'multi') {
86
			$parent = $this->getParent();
87
			if (!($parent instanceof \SwaggerGen\Swagger\Parameter) || !$parent->isMulti()) {
88
				throw new \SwaggerGen\Exception("Multi array only allowed on query or form parameter: '{$definition}'");
89
			}
90
		}
91
92
		$this->collectionFormat = self::$collectionFormats[$type];
93
	}
94
95
	private function parseItems($definition, $match)
96
	{
97
		if (!empty($match[2])) {
98
			$this->Items = $this->validateItems($match[2]);
99
		}
100
	}
101
102
	private function parseRange($definition, $match)
103
	{
104
		if (!empty($match[3])) {
105
			if ($match[4] === '' && $match[5] === '') {
106
				throw new \SwaggerGen\Exception("Empty array range: '{$definition}'");
107
			}
108
109
			$exclusiveMinimum = isset($match[3]) ? ($match[3] == '<') : null;
110
			$this->minItems = $match[4] === '' ? null : intval($match[4]);
111
			$this->maxItems = $match[5] === '' ? null : intval($match[5]);
112
			$exclusiveMaximum = isset($match[6]) ? ($match[6] == '>') : null;
113
			if ($this->minItems && $this->maxItems && $this->minItems > $this->maxItems) {
114
				self::swap($this->minItems, $this->maxItems);
115
				self::swap($exclusiveMinimum, $exclusiveMaximum);
116
			}
117
			$this->minItems = $this->minItems === null ? null : max(0, $exclusiveMinimum ? $this->minItems + 1 : $this->minItems);
118
			$this->maxItems = $this->maxItems === null ? null : max(0, $exclusiveMaximum ? $this->maxItems - 1 : $this->maxItems);
119
		}
120
	}
121
122
	/**
123
	 * @param string $command The comment command
124
	 * @param string $data Any data added after the command
125
	 * @return \SwaggerGen\Swagger\Type\AbstractType|boolean
126
	 */
127
	public function handleCommand($command, $data = null)
128
	{
129
		if ($this->Items) {
130
			$return = $this->Items->handleCommand($command, $data);
131
			if ($return) {
132
				return $return;
133
			}
134
		}
135
136
		switch (strtolower($command)) {
137
			case 'min':
138
				$this->minItems = intval($data);
139
				if ($this->minItems < 0) {
140
					throw new \SwaggerGen\Exception("Minimum less than zero: '{$data}'");
141
				}
142
				if ($this->maxItems !== null && $this->minItems > $this->maxItems) {
143
					throw new \SwaggerGen\Exception("Minimum greater than maximum: '{$data}'");
144
				}
145
				return $this;
146
147
			case 'max':
148
				$this->maxItems = intval($data);
149
				if ($this->minItems !== null && $this->minItems > $this->maxItems) {
150
					throw new \SwaggerGen\Exception("Maximum less than minimum: '{$data}'");
151
				}
152
				if ($this->maxItems < 0) {
153
					throw new \SwaggerGen\Exception("Maximum less than zero: '{$data}'");
154
				}
155
				return $this;
156
157
			case 'items':
158
				$this->Items = $this->validateItems($data);
159
				return $this->Items;
160
		}
161
162
		return parent::handleCommand($command, $data);
163
	}
164
165
	public function toArray()
166
	{
167
		return self::arrayFilterNull(array_merge(array(
168
					'type' => 'array',
169
					'items' => empty($this->Items) ? null : $this->Items->toArray(),
170
					'collectionFormat' => $this->collectionFormat == 'csv' ? null : $this->collectionFormat,
171
					'minItems' => $this->minItems,
172
					'maxItems' => $this->maxItems,
173
								), parent::toArray()));
174
	}
175
176
	private function validateItems($items)
177
	{
178
		if (empty($items)) {
179
			throw new \SwaggerGen\Exception("Empty items definition: '{$items}'");
180
		}
181
182
		$match = array();
183
		if (preg_match('/^([a-z]+)/i', $items, $match) === 1) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
184
			// recognized format
185
		} elseif (preg_match('/^(\[)(?:.*?)\]$/i', $items, $match) === 1) {
186
			$match[1] = 'array';
187
		} elseif (preg_match('/^(\{)(?:.*?)\}$/i', $items, $match) === 1) {
188
			$match[1] = 'object';
189
		} else {
190
			throw new \SwaggerGen\Exception("Unparseable items definition: '{$items}'");
191
		}
192
		$format = strtolower($match[1]);
193
		if (isset(self::$classTypes[$format])) {
194
			$type = self::$classTypes[$format];
195
			$typeClass = "SwaggerGen\\Swagger\\Type\\{$type}Type";
196
			return new $typeClass($this, $items);
197
		}
198
199
		return new ReferenceObjectType($this, $items);
200
	}
201
202
	public function __toString()
203
	{
204
		return __CLASS__;
205
	}
206
207
}
208