Completed
Push — master ( be40dc...524dea )
by Nazar
06:35
created

App::render_blocks()   C

Complexity

Conditions 8
Paths 9

Size

Total Lines 63
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 37
nc 9
nop 1
dl 0
loc 63
rs 6.8825
c 0
b 0
f 0
ccs 32
cts 32
cp 1
crap 8

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