Completed
Push — master ( 943dfc...45609c )
by Pavel
02:16
created

Generator::getApiRoutesFromIterator()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
rs 8.8571
cc 5
eloc 10
nc 5
nop 1
1
<?php
2
3
/**
4
 * @copyright   Copyright (c) 2016 ublaboo <[email protected]>
5
 * @author      Pavel Janda <[email protected]>
6
 * @package     Ublaboo
7
 */
8
9
namespace Ublaboo\ApiDocu;
10
11
use Nette;
12
use Nette\Application\Request;
13
use Nette\Application\IRouter;
14
use Ublaboo\ApiRouter\ApiRoute;
15
use Tracy\Debugger;
16
17
class Generator extends Nette\Object
18
{
19
20
	/**
21
	 * @var Nette\Application\UI\ITemplateFactory
22
	 */
23
	private $templateFactory;
24
25
	/**
26
	 * @var Nette\Http\Request
27
	 */
28
	private $httpRequest;
29
30
	/**
31
	 * @var string
32
	 */
33
	private $api_dir;
34
35
36
	/**
37
	 * @param string                                $api_dir
38
	 * @param Nette\Application\UI\ITemplateFactory $templateFactory
39
	 * @param Nette\Http\Request                    $httpRequest
40
	 */
41
	public function __construct(
42
		$api_dir,
43
		Nette\Application\UI\ITemplateFactory $templateFactory,
44
		Nette\Http\Request $httpRequest
45
	) {
46
		$this->api_dir = $api_dir;
47
		$this->templateFactory = $templateFactory;
48
		$this->httpRequest = $httpRequest;
49
	}
50
51
52
	/**
53
	 * @param  IRouter $router
54
	 * @return void
55
	 */
56
	public function generateAll(IRouter $router)
57
	{
58
		$routes = [];
59
		$sections = [];
60
		$file_name = 1;
61
62
		if ($router instanceof ApiRoute) {
63
			$routes = [$router];
64
		} else if ($router instanceof \IteratorAggregate) {
65
			$routes = $this->getApiRoutesFromIterator($router);
66
		}
67
68
		foreach ($routes as $route) {
69
			if ($route->getSection()) {
70
				if (empty($sections[$route->getSection()])) {
71
					$sections[$route->getSection()] = [];
72
				}
73
74
				$sections[$route->getSection()][$file_name++] = $route;
75
			} else {
76
				$sections[$file_name++] = $route;
77
			}
78
		}
79
80
		mkdir($this->api_dir);
81
82
		/**
83
		 * Create index.html
84
		 */
85
		$this->generateIndex($sections);
86
87
		/**
88
		 * Create *.html for each defined ApiRoute
89
		 */
90
		foreach ($sections as $section_name => $routes) {
91
			if (is_array($routes)) {
92
				foreach ($routes as $file_name => $route) {
93
					$this->generateOne($route, $sections, "$section_name.$file_name");
94
				}
95
			} else {
96
				$this->generateOne($routes, $sections, $section_name);
97
			}
98
		}
99
100
		$this->generateSuccess();
101
	}
102
103
104
	/**
105
	 * @param  ApiRoute $route
106
	 * @param  Request  $request
107
	 * @return void
108
	 */
109
	public function generateTarget(ApiRoute $route, Request $request)
110
	{
111
		$template = $this->createTemplate('api_docu_matched.latte');
112
113
		$template->setParameters([
114
			'route'       => $route,
115
			'request'     => $request,
116
			'httpRequest' => $this->httpRequest
117
		]);
118
119
		if (class_exists('Tracy\Debugger')) {
120
			Debugger::$productionMode = TRUE;
121
		}
122
123
		echo (string) $template;
124
	}
125
126
127
	/**
128
	 * @param  ApiRoute $route
129
	 * @param  array    $sections
130
	 * @param  string   $file_name
131
	 * @return void
132
	 */
133
	public function generateOne(ApiRoute $route, $sections, $file_name)
134
	{
135
		$template = $this->createTemplate('api_docu_one.latte');
136
137
		$template->setParameters([
138
			'route'       => $route,
139
			'sections'    => $sections
140
		]);
141
142
		file_put_contents("{$this->api_dir}/{$file_name}.html", (string) $template);
143
	}
144
145
146
	/**
147
	 * @param  array $sections
148
	 * @return void
149
	 */
150
	public function generateIndex($sections)
151
	{
152
		$template = $this->createTemplate('api_docu_index.latte');
153
154
		$template->setParameters([
155
			'sections' => $sections
156
		]);
157
158
		file_put_contents("{$this->api_dir}/index.html", (string) $template);
159
	}
160
161
162
	/**
163
	 * @return void
164
	 */
165
	public function generateSuccess()
166
	{
167
		$template = $this->createTemplate('api_docu_success.latte');
168
169
		$template->setParameters([
170
			'apiDir' => $this->api_dir
171
		]);
172
173
		if (class_exists('Tracy\Debugger')) {
174
			Debugger::$productionMode = TRUE;
175
		}
176
177
		echo (string) $template;
178
	}
179
180
181
	/**
182
	 * @param  string
183
	 * @return Nette\Application\UI\ITemplate
184
	 */
185
	public function createTemplate($which)
186
	{
187
		$template = $this->templateFactory->createTemplate();
188
		$template->setFile(__DIR__ . '/templates/' . $which);
189
190
		if ($template instanceof Nette\Application\UI\ITemplate) {
191
			$template->base_dir = __DIR__ . '/templates';
0 ignored issues
show
Bug introduced by
Accessing base_dir on the interface Nette\Application\UI\ITemplate suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
192
		}
193
194
		$template->addFilter('routeMaskStyles', function($mask) {
195
			return str_replace(['<', '>'], ['<span class="apiDocu-mask-param">&lt;', '&gt;</span>'], $mask);
196
		});
197
198
		return $template;
199
	}
200
201
202
	/********************************************************************************
203
	 *                                   INTERNAL                                   *
204
	 ********************************************************************************/
205
206
207
	/**
208
	 * Recursively flatten \IteratorAggregate (probably Nette\Application\Routers\RouteList)
209
	 * @param  \IteratorAggregate $i
210
	 * @return array
211
	 */
212
	private function getApiRoutesFromIterator(\IteratorAggregate $i)
213
	{
214
		$return = [];
215
216
		foreach ($i as $router) {
217
			if ($router instanceof ApiRoute) {
218
				$return[] = $router;
219
			} else if ($router instanceof \IteratorAggregate) {
220
				$routes = $this->getApiRoutesFromIterator($router);
221
222
				foreach ($routes as $route) {
223
					$return[] = $route;
224
				}
225
			}
226
		}
227
228
		return $return;
229
	}
230
231
}
232