Completed
Push — master ( 3dd7ff...c8320e )
by Nazar
06:59
created

App::render_blocks()   C

Complexity

Conditions 8
Paths 9

Size

Total Lines 64
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 8

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 8
eloc 38
c 3
b 0
f 1
nc 9
nop 1
dl 0
loc 64
ccs 33
cts 33
cp 1
crap 8
rs 6.8232

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