Completed
Push — master ( 717975...cdab57 )
by Martijn
02:12
created

StringType::validateDefault()   C

Complexity

Conditions 14
Paths 14

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 5.283
c 0
b 0
f 0
cc 14
eloc 13
nc 14
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SwaggerGen\Swagger\Type;
4
5
/**
6
 * Basic strings 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 StringType extends AbstractType
14
{
15
16
	private static $formats = array(
17
		'string' => '',
18
		'byte' => 'byte',
19
		'binary' => 'binary',
20
		'password' => 'password',
21
		'enum' => '',
22
	);
23
24
	/**
25
	 * Name of the type
26
	 * @var string
27
	 */
28
	protected $format = '';
29
	protected $pattern = null;
30
	protected $default = null;
31
	protected $maxLength = null;
32
	protected $minLength = null;
33
	protected $enum = array();
34
35
	protected function parseDefinition($definition)
36
	{
37
		$definition = self::trim($definition);
38
39
		$match = array();
40
		if (preg_match(self::REGEX_START . self::REGEX_FORMAT . self::REGEX_CONTENT . self::REGEX_RANGE . self::REGEX_DEFAULT . self::REGEX_END, $definition, $match) !== 1) {
41
			throw new \SwaggerGen\Exception("Unparseable string definition: '{$definition}'");
42
		}
43
44
		$this->parseFormat($definition, $match);
45
		$this->parseContent($definition, $match);
46
		$this->parseRange($definition, $match);
47
		$this->parseDefault($definition, $match);
48
	}
49
50
	/**
51
	 * @param string $definition
52
	 * @param string[] $match
53
	 */
54
	private function parseFormat($definition, $match)
55
	{
56
		$type = strtolower($match[1]);
57
		if (!isset(self::$formats[$type])) {
58
			throw new \SwaggerGen\Exception("Not a string: '{$definition}'");
59
		}
60
		$this->format = self::$formats[$type];
61
	}
62
63
	/**
64
	 * @param string $definition
65
	 * @param string[] $match
66
	 */
67
	private function parseContent($definition, $match)
0 ignored issues
show
Unused Code introduced by
The parameter $definition is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
	{
69
		if (strtolower($match[1]) === 'enum') {
70
			$this->enum = preg_split('/,/', $match[2]);
71
		} else {
72
			$this->pattern = empty($match[2]) ? null : $match[2];
73
		}
74
	}
75
76
	/**
77
	 * @param string $definition
78
	 * @param string[] $match
79
	 */
80
	private function parseRange($definition, $match)
81
	{
82
83
		if (!empty($match[3])) {
84
			if ($match[1] === 'enum') {
85
				throw new \SwaggerGen\Exception("Range not allowed in enumeration definition: '{$definition}'");
86
			}
87
			if ($match[4] === '' && $match[5] === '') {
88
				throw new \SwaggerGen\Exception("Empty string range: '{$definition}'");
89
			}
90
			$exclusiveMinimum = isset($match[3]) ? ($match[3] == '<') : null;
91
			$this->minLength = $match[4] === '' ? null : $match[4];
92
			$this->maxLength = $match[5] === '' ? null : $match[5];
93
			$exclusiveMaximum = isset($match[6]) ? ($match[6] == '>') : null;
94
			if ($this->minLength !== null && $this->maxLength !== null && $this->minLength > $this->maxLength) {
95
				self::swap($this->minLength, $this->maxLength);
96
				self::swap($exclusiveMinimum, $exclusiveMaximum);
97
			}
98
			$this->minLength = $this->minLength === null ? null : max(0, $exclusiveMinimum ? $this->minLength + 1 : $this->minLength);
99
			$this->maxLength = $this->maxLength === null ? null : max(0, $exclusiveMaximum ? $this->maxLength - 1 : $this->maxLength);
100
		}
101
	}
102
103
	/**
104
	 * @param string $definition
105
	 * @param string[] $match
106
	 */
107
	private function parseDefault($definition, $match)
0 ignored issues
show
Unused Code introduced by
The parameter $definition is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
108
	{
109
		$this->default = isset($match[7]) && $match[7] !== '' ? $this->validateDefault($match[7]) : null;
110
	}
111
112
	/**
113
	 * @param string $command The comment command
114
	 * @param string $data Any data added after the command
115
	 * @return \SwaggerGen\Swagger\Type\AbstractType|boolean
116
	 */
117
	public function handleCommand($command, $data = null)
118
	{
119
		switch (strtolower($command)) {
120
			case 'default':
121
				$this->default = $this->validateDefault($data);
122
				return $this;
123
124
			case 'pattern':
125
				$this->pattern = $data;
126
				return $this;
127
128
			case 'enum':
129
				if ($this->minLength !== null || $this->maxLength !== null) {
130
					throw new \SwaggerGen\Exception("Enumeration not allowed in ranged string: '{$data}'");
131
				}
132
				$words = self::wordSplit($data);
133
				$this->enum = is_array($this->enum) ? array_merge($this->enum, $words) : $words;
134
				return $this;
135
		}
136
137
		return parent::handleCommand($command, $data);
138
	}
139
140
	public function toArray()
141
	{
142
		return self::arrayFilterNull(array(
143
					'type' => 'string',
144
					'format' => empty($this->format) ? null : $this->format,
145
					'pattern' => $this->pattern,
146
					'default' => $this->default,
147
					'minLength' => $this->minLength ? intval($this->minLength) : null,
148
					'maxLength' => $this->maxLength ? intval($this->maxLength) : null,
149
					'enum' => $this->enum,
150
		));
151
	}
152
153
	/**
154
	 * Validate a default string value, depending on subtype
155
	 * 
156
	 * @param string $value the value to validate
157
	 * @return string the value after validation (may be trimmed and such)
158
	 * @throws \SwaggerGen\Exception
159
	 */
160
	protected function validateDefault($value)
161
	{
162
		if (empty($value)) {
163
			$type = $this->format ?: ($this->enum ? 'enum' : 'string');
164
			throw new \SwaggerGen\Exception("Empty {$type} default");
165
		}
166
167
		if (!empty($this->enum) && !in_array($value, $this->enum)) {
168
			throw new \SwaggerGen\Exception("Invalid enum default: '{$value}'");
169
		}
170
171
		if ($this->maxLength !== null && mb_strlen($value) > $this->maxLength) {
172
			$type = $this->format ?: ($this->enum ? 'enum' : 'string');
173
			throw new \SwaggerGen\Exception("Default {$type} length beyond maximum: '{$value}'");
174
		}
175
176
		if ($this->minLength !== null && mb_strlen($value) < $this->minLength) {
177
			$type = $this->format ?: ($this->enum ? 'enum' : 'string');
178
			throw new \SwaggerGen\Exception("Default {$type} length beyond minimum: '{$value}'");
179
		}
180
181
		return $value;
182
	}
183
184
	public function __toString()
185
	{
186
		return __CLASS__;
187
	}
188
189
}
190