Completed
Push — master ( 0607d7...b07c2b )
by Pavel
02:16
created

Generator::splitRoutesIntoSections()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 26
rs 8.439
cc 6
eloc 16
nc 12
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
		$sections = $this->splitRoutesIntoSections($router);
59
60
		if (!file_exists($this->api_dir) && !is_dir($this->api_dir)) {
61
			mkdir($this->api_dir);
62
		}
63
64
		/**
65
		 * Create index.html
66
		 */
67
		$this->generateIndex($sections);
68
69
		/**
70
		 * Create *.html for each defined ApiRoute
71
		 */
72
		foreach ($sections as $section_name => $routes) {
73
			if (is_array($routes)) {
74
				foreach ($routes as $file_name => $route) {
75
					$this->generateOne($route, $sections, "$section_name.$file_name");
76
				}
77
			} else {
78
				$this->generateOne($routes, $sections, $section_name);
79
			}
80
		}
81
82
		$this->generateSuccess();
83
	}
84
85
86
	/**
87
	 * @param  ApiRoute $route
88
	 * @param  Request  $request
89
	 * @return void
90
	 */
91
	public function generateTarget(ApiRoute $route, Request $request)
92
	{
93
		$template = $this->createTemplate('api_docu_matched.latte');
94
95
		$template->setParameters([
96
			'route'       => $route,
97
			'request'     => $request,
98
			'httpRequest' => $this->httpRequest
99
		]);
100
101
		if (class_exists('Tracy\Debugger')) {
102
			Debugger::$productionMode = TRUE;
103
		}
104
105
		echo (string) $template;
106
	}
107
108
109
	/**
110
	 * @param  ApiRoute $route
111
	 * @param  array    $sections
112
	 * @param  string   $file_name
113
	 * @return void
114
	 */
115
	public function generateOne(ApiRoute $route, $sections, $file_name)
116
	{
117
		$template = $this->createTemplate('api_docu_one.latte');
118
119
		$template->setParameters([
120
			'route'       => $route,
121
			'sections'    => $sections
122
		]);
123
124
		file_put_contents("{$this->api_dir}/{$file_name}.html", (string) $template);
125
	}
126
127
128
	/**
129
	 * @param  array $sections
130
	 * @return void
131
	 */
132
	public function generateIndex($sections)
133
	{
134
		$template = $this->createTemplate('api_docu_index.latte');
135
136
		$template->setParameters([
137
			'sections' => $sections
138
		]);
139
140
		file_put_contents("{$this->api_dir}/index.html", (string) $template);
141
	}
142
143
144
	/**
145
	 * @return void
146
	 */
147
	public function generateSuccess()
148
	{
149
		$template = $this->createTemplate('api_docu_success.latte');
150
151
		$template->setParameters([
152
			'apiDir' => $this->api_dir
153
		]);
154
155
		if (class_exists('Tracy\Debugger')) {
156
			Debugger::$productionMode = TRUE;
157
		}
158
159
		echo (string) $template;
160
	}
161
162
163
	/**
164
	 * @param  string
165
	 * @return Nette\Application\UI\ITemplate
166
	 */
167
	public function createTemplate($which)
168
	{
169
		$template = $this->templateFactory->createTemplate();
170
		$template->setFile(__DIR__ . '/templates/' . $which);
171
172
		if ($template instanceof Nette\Application\UI\ITemplate) {
173
			$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...
174
		}
175
176
		$template->addFilter('routeMaskStyles', function($mask) {
177
			return str_replace(['<', '>'], ['<span class="apiDocu-mask-param">&lt;', '&gt;</span>'], $mask);
178
		});
179
180
		return $template;
181
	}
182
183
184
	/********************************************************************************
185
	 *                                   INTERNAL                                   *
186
	 ********************************************************************************/
187
188
189
	private function splitRoutesIntoSections(IRouter $router)
190
	{
191
		$routes = [];
192
		$sections = [];
193
		$file_name = 1;
194
195
		if ($router instanceof ApiRoute) {
196
			$routes = [$router];
197
		} else if ($router instanceof \IteratorAggregate) {
198
			$routes = $this->getApiRoutesFromIterator($router);
199
		}
200
201
		foreach ($routes as $route) {
202
			if ($route->getSection()) {
203
				if (empty($sections[$route->getSection()])) {
204
					$sections[$route->getSection()] = [];
205
				}
206
207
				$sections[$route->getSection()][$file_name++] = $route;
208
			} else {
209
				$sections[$file_name++] = $route;
210
			}
211
		}
212
213
		return $sections;
214
	}
215
216
217
	/**
218
	 * Recursively flatten \IteratorAggregate (probably Nette\Application\Routers\RouteList)
219
	 * @param  \IteratorAggregate $i
220
	 * @return array
221
	 */
222
	private function getApiRoutesFromIterator(\IteratorAggregate $i)
223
	{
224
		$return = [];
225
226
		foreach ($i as $router) {
227
			if ($router instanceof ApiRoute) {
228
				$return[] = $router;
229
			} else if ($router instanceof \IteratorAggregate) {
230
				$routes = $this->getApiRoutesFromIterator($router);
231
232
				foreach ($routes as $route) {
233
					$return[] = $route;
234
				}
235
			}
236
		}
237
238
		return $return;
239
	}
240
241
}
242