Completed
Branch master (ffa084)
by Martijn
06:37 queued 03:03
created

SwaggerGen::parsePhpFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SwaggerGen;
4
5
/**
6
 * Main class of SwaggerGen which serves as a facade for the entire library.
7
 *
8
 * Copyright (c) 2014-2015 Martijn van der Lee
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11
 * of this software and associated documentation files (the "Software"), to deal
12
 * in the Software without restriction, including without limitation the rights
13
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
 * copies of the Software, and to permit persons to whom the Software is
15
 * furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included in
18
 * all copies or substantial portions of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
23
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
 * THE SOFTWARE.
27
 *
28
 * @package    SwaggerGen
29
 * @author     Martijn van der Lee <[email protected]>
30
 * @copyright  2014-2015 Martijn van der Lee
31
 * @license    https://opensource.org/licenses/MIT MIT
32
 */
33
class SwaggerGen
34
{
35
36
	const FORMAT_ARRAY = '';
37
	const FORMAT_JSON = 'json';
38
	const FORMAT_JSON_PRETTY = 'json+';
39
	const FORMAT_YAML = 'yaml';
40
41
	private $host;
42
	private $basePath;
43
	private $dirs = array();
44
	private $defines = array();
45
46
	/**
47
	 * @var TypeRegistry
48
	 */
49
	private $typeRegistry = null;
50
51
	/**
52
	 * Create a new SwaggerGen instance
53
	 * 
54
	 * @param string $host
55
	 * @param string $basePath
56
	 * @param string[] $dirs
57
	 * @param TypeRegistry $typeRegistry
58
	 */
59
	public function __construct($host = '', $basePath = '', $dirs = array(), $typeRegistry = null)
60
	{
61
		$this->host = $host;
62
		$this->basePath = $basePath;
63
		$this->dirs = $dirs;
64
		$this->typeRegistry = $typeRegistry;
65
	}
66
	
67
	/**
68
	 * Set a new type registry
69
	 * 
70
	 * @param TypeRegistry $typeRegistry
71
	 */
72
	public function setTypeRegistry($typeRegistry = null)
73
	{
74
		$this->typeRegistry = $typeRegistry;
75
	}
76
77
	public function define($name, $value = 1)
78
	{
79
		$this->defines[$name] = $value;
80
	}
81
82
	public function undefine($name)
83
	{
84
		unset($this->defines[$name]);
85
	}
86
87
	/**
88
	 * @param string $file
89
	 * @param string[] $dirs
90
	 * @return Php\Entity\Statement[]
91
	 */
92
	private function parsePhpFile($file, $dirs)
93
	{
94
		$Parser = new Parser\Php\Parser();
95
		return $Parser->parse($file, $dirs, $this->defines);
96
	}
97
98
	/**
99
	 * @param string $file
100
	 * @param string[] $dirs
101
	 * @return Php\Entity\Statement[]
102
	 */
103
	private function parseTextFile($file, $dirs)
104
	{
105
		$Parser = new Parser\Text\Parser();
106
		return $Parser->parse($file, $dirs, $this->defines);
107
	}
108
109
	/**
110
	 * @param string $text
111
	 * @param string[] $dirs
112
	 * @return Php\Entity\Statement[]
113
	 */
114
	private function parseText($text, $dirs)
115
	{
116
		$Parser = new Parser\Text\Parser();
117
		return $Parser->parseText($text, $dirs, $this->defines);
118
	}
119
120
	/**
121
	 * Creates Swagger\Swagger object and populates it with statements
122
	 *
123
	 * This effectively converts the linear list of statements into parse-tree
124
	 * like structure, performing some checks (like rejecting unknown
125
	 * subcommands) during the process. Returned Swagger\Swagger object is
126
	 * ready for serialization with {@see Swagger\Swagger::toArray}
127
	 *
128
	 * @param string $host
129
	 * @param string $basePath
130
	 * @param Statement[] $statements
131
	 * @return Swagger\Swagger
132
	 * @throws StatementException
133
	 */
134
	public function parseStatements($host, $basePath, $statements)
135
	{
136
		$swagger = new Swagger\Swagger($host, $basePath, $this->typeRegistry);
137
138
		$stack = array($swagger); /* @var Swagger\AbstractObject[] $stack */
139
		foreach ($statements as $statement) {
140
			try {
141
				$top = end($stack);
142
143
				do {
144
					$result = $top->handleCommand($statement->getCommand(), $statement->getData());
145
146
					if ($result) {
147
						if ($result !== $top) {
148
							// Remove all similar classes from array first!
149
							$classname = get_class($result);
150
							$stack = array_filter($stack, function($class) use($classname) {
151
								return !(is_a($class, $classname));
152
							});
153
154
							$stack[] = $result;
155
						}
156
					} else {
157
						$top = prev($stack);
158
					}
159
				} while (!$result && $top);
160
			} catch (\SwaggerGen\Exception $e) {
161
				throw new \SwaggerGen\StatementException($e->getMessage(), $e->getCode(), $e, $statement);
0 ignored issues
show
Documentation introduced by
$e is of type object<SwaggerGen\Exception>, but the function expects a object<Throwable>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
162
			}
163
164
			if (!$result && !$top) {
165
				$messages = array("Unsupported or unknown command: {$statement->getCommand()} {$statement->getData()}");
166
167
				$stacktrace = array();
168
				foreach ($stack as $object) {
169
					$stacktrace[] = (string) $object;
170
				}
171
				$messages[] = join(", \n", $stacktrace);
172
173
				throw new \SwaggerGen\StatementException(join('. ', $messages), 0, null, $statement);
174
			}
175
		}
176
177
		return $swagger;
178
	}
179
180
	/**
181
	 * Get Swagger 2.x output
182
	 *
183
	 * @param string[] $files
184
	 * @param string[] $dirs
185
	 * @param string $format
186
	 * @return type
187
	 * @throws \SwaggerGen\Exception
188
	 */
189
	public function getSwagger($files, $dirs = array(), $format = self::FORMAT_ARRAY)
190
	{
191
		$dirs = array_merge($this->dirs, $dirs);
192
193
		$statements = array();
194
		foreach ($files as $file) {
195
			switch (pathinfo($file, PATHINFO_EXTENSION)) {
196
				case 'php':
197
					$fileStatements = $this->parsePhpFile($file, $dirs);
198
					break;
199
200
				case 'txt':
201
					$fileStatements = $this->parseTextFile($file, $dirs);
202
					break;
203
204
				default:
205
					$fileStatements = $this->parseText($file, $dirs);
206
					break;
207
			}
208
209
			$statements = array_merge($statements, $fileStatements);
210
		}
211
212
		$output = $this->parseStatements($this->host, $this->basePath, $statements)->toArray();
213
214
		switch ($format) {
215
			case self::FORMAT_JSON:
216
				$output = json_encode($output);
217
				break;
218
219
			case self::FORMAT_JSON_PRETTY:
220
				$flags = (defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0); // Since PHP 5.4.0
221
				$output = json_encode($output, $flags);
222
				break;
223
224
			case self::FORMAT_YAML:
225
				if (!function_exists('yaml_emit')) {
226
					throw new Exception('YAML extension not installed.');
227
				}
228
				array_walk_recursive($output, function(&$value) {
229
					if (is_object($value)) {
230
						$value = (array) $value;
231
					}
232
				});
233
				$output = yaml_emit($output, YAML_UTF8_ENCODING, YAML_LN_BREAK);
234
				break;
235
		}
236
237
		return $output;
238
	}
239
240
}
241