Completed
Push — master ( cfcc09...3dd7ff )
by Nazar
04:14
created

App::render_blocks()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 61
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 50.875

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
eloc 38
c 2
b 0
f 0
nc 9
nop 1
dl 0
loc 61
ccs 4
cts 32
cp 0.125
crap 50.875
rs 7.0047

How to fix   Long Method   

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
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs;
9
use
10
	cs\App\Router;
11
12
/**
13
 * Provides next events:
14
 *  System/App/block_render
15
 *  [
16
 *      'index'           => $index,        //Block index
17
 *      'blocks_array'    => &$blocks_array //Reference to array in form ['top' => '', 'left' => '', 'right' => '', 'bottom' => '']
18
 *  ]
19
 *
20
 *  System/App/render/before
21
 *
22
 *  System/App/execute_router/before
23
 *
24
 *  System/App/execute_router/after
25
 *
26
 *  System/App/render/after
27
 *
28
 * @property string[] $controller_path Path that will be used by controller to render page
29
 *
30
 * @method static $this instance($check = false)
31
 */
32
class App {
33
	use
34
		Singleton,
35
		Router;
36
	const INIT_STATE_METHOD = 'init';
37 12
	protected function init () {
38 12
		$this->init_router();
39 12
	}
40
	/**
41
	 * Executes blocks and module page generation
42
	 *
43
	 * @throws ExitException
44
	 */
45 10
	public function execute () {
46 10
		$Config  = Config::instance();
47 10
		$Request = Request::instance();
48 10
		if (!preg_match('/^[0-9a-z_]+$/i', $Request->method)) {
49
			throw new ExitException(400);
50
		}
51 10
		$this->handle_closed_site(!$Config->core['site_mode'], $Request);
52 8
		if (!$this->check_permission($Request, 'index')) {
53 2
			throw new ExitException(403);
54
		}
55 6
		Event::instance()->fire('System/App/render/before');
56 6
		$this->render($Request);
57 6
		Event::instance()->fire('System/App/render/after');
58 6
		Page::instance()->render();
59 6
	}
60
	/**
61
	 * @param bool    $closed_site
62
	 * @param Request $Request
63
	 *
64
	 * @throws ExitException
65
	 */
66 10
	protected function handle_closed_site ($closed_site, $Request) {
67 10
		if (!$closed_site) {
68 6
			return;
69
		}
70
		/**
71
		 * If site is closed
72
		 */
73 4
		if (!$this->allow_closed_site_request($Request)) {
74 2
			throw new ExitException(
75
				[
76 2
					get_core_ml_text('closed_title'),
77 2
					get_core_ml_text('closed_text')
78
				],
79 2
				503
80
			);
81
		}
82
		/**
83
		 * Warning about closed site for administrator
84
		 */
85 2
		Page::instance()->warning(get_core_ml_text('closed_title'));
86 2
	}
87
	/**
88
	 * Check if visitor is allowed to make current request to closed site
89
	 *
90
	 * @param Request $Request
91
	 *
92
	 * @return bool
93
	 */
94 4
	protected function allow_closed_site_request ($Request) {
95
		return
96 4
			User::instance()->admin() ||
97
			(
98 4
				$Request->api_path &&
99 4
				$Request->current_module == 'System' &&
100 4
				$Request->route == ['profile'] &&
101 4
				$Request->method == 'SIGN_IN'
102
			);
103
	}
104
	/**
105
	 * Check whether user allowed to access to specified label
106
	 *
107
	 * @param Request $Request
108
	 * @param string  $label
109
	 *
110
	 * @return bool
111
	 */
112 8
	protected function check_permission ($Request, $label) {
113 8
		if ($Request->cli_path) {
114
			return true;
115
		}
116 8
		$permission_group = $Request->current_module;
117 8
		if ($Request->admin_path) {
118 2
			$permission_group = "admin/$permission_group";
119 6
		} elseif ($Request->api_path) {
120 4
			$permission_group = "api/$permission_group";
121
		}
122 8
		return User::instance()->get_permission($permission_group, $label);
123
	}
124
	/**
125
	 * @param Request $Request
126
	 *
127
	 * @throws ExitException
128
	 */
129 6
	protected function render ($Request) {
130 6
		$Page = Page::instance();
131 6
		if ($Request->cli_path || $Request->api_path || !$Page->interface) {
132 4
			$this->execute_router($Request);
133
		} else {
134 2
			$this->render_title($Request, $Page);
135 2
			$this->execute_router($Request);
136 2
			$this->render_blocks($Page);
137
		}
138 6
	}
139
	/**
140
	 * Render page title
141
	 *
142
	 * @param Request $Request
143
	 * @param Page    $Page
144
	 */
145 2
	protected function render_title ($Request, $Page) {
146
		/**
147
		 * Add generic Home or Module name title
148
		 */
149 2
		$L = Language::instance();
150 2
		if ($Request->admin_path) {
151
			$Page->title($L->system_admin_administration);
152
		}
153 2
		$Page->title(
154 2
			$L->{$Request->home_page ? 'system_home' : $Request->current_module}
155
		);
156 2
	}
157
	/**
158
	 * Blocks rendering
159
	 *
160
	 * @param Page $Page
161
	 */
162 2
	protected function render_blocks ($Page) {
163 2
		$blocks = Config::instance()->components['blocks'];
164
		/**
165
		 * It is frequent that there is no blocks - so, no need to to anything here
166
		 */
167 2
		if (!$blocks) {
168 2
			return;
169
		}
170
		$blocks_array = [
171
			'top'    => '',
172
			'left'   => '',
173
			'right'  => '',
174
			'bottom' => ''
175
		];
176
		foreach ($blocks as $block) {
177
			/**
178
			 * If there is no need to show block or it was rendered by even handler - skip further processing
179
			 */
180
			if (
181
				!$this->should_block_be_rendered($block) ||
182
				!Event::instance()->fire(
183
					'System/App/block_render',
184
					[
185
						'index'        => $block['index'],
186
						'blocks_array' => &$blocks_array
187
					]
188
				)
189
			) {
190
				/**
191
				 * Block was rendered by event handler
192
				 */
193
				continue;
194
			}
195
			$block['title'] = $this->ml_process($block['title']);
196
			switch ($block['type']) {
197
				default:
198
					$block['content'] = ob_wrapper(
199
						function () use ($block) {
200
							include BLOCKS."/block.$block[type].php";
201
						}
202
					);
203
					break;
204
				case 'html':
205
				case 'raw_html':
206
					$block['content'] = $this->ml_process($block['content']);
207
					break;
208
			}
209
			if ($block['position'] == 'floating') {
210
				$Page->replace(
211
					"<!--block#$block[index]-->",
212
					$block['content']
213
				);
214
			} else {
215
				$blocks_array[$block['position']] .= $block['content'];
216
			}
217
		}
218
		$Page->Top .= $blocks_array['top'];
219
		$Page->Left .= $blocks_array['left'];
220
		$Page->Right .= $blocks_array['right'];
221
		$Page->Bottom .= $blocks_array['bottom'];
222
	}
223
	/**
224
	 * Check whether to render block or not based on its properties (active state, when start to show, when it expires and permissions)
225
	 *
226
	 * @param array $block
227
	 *
228
	 * @return bool
229
	 */
230
	protected function should_block_be_rendered ($block) {
231
		return
232
			$block['active'] &&
233
			$block['start'] <= time() &&
234
			(
235
				!$block['expire'] ||
236
				$block['expire'] >= time()
237
			) &&
238
			User::instance()->get_permission('Block', $block['index']);
239
	}
240
	/**
241
	 * @param string $text
242
	 *
243
	 * @return string
244
	 */
245
	protected function ml_process ($text) {
246
		return Text::instance()->process(Config::instance()->module('System')->db('texts'), $text, true);
247
	}
248
	/**
249
	 * Getter for `controller_path` property (no other properties supported currently)
250
	 *
251
	 * @param string $property
252
	 *
253
	 * @return false|string[]
254
	 */
255 4
	public function __get ($property) {
256 4
		if ($property == 'controller_path') {
257 4
			return $this->controller_path;
258
		}
259
		return false;
260
	}
261
}
262