blocks   B
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 224
rs 8.3999
c 0
b 0
f 0
ccs 0
cts 118
cp 0
wmc 38

9 Methods

Rating   Name   Duplication   Size   Complexity  
C admin_blocks_update_order() 0 35 7
A admin_blocks_put() 0 6 2
B admin_blocks_get() 0 20 5
A admin_blocks_get_prepare() 0 10 4
C admin_blocks_delete() 0 32 7
A get_block_by_index() 0 12 3
A admin_blocks_types() 0 2 1
C save_block_data() 0 33 8
A admin_blocks_post() 0 2 1
1
<?php
2
/**
3
 * @package    CleverStyle Framework
4
 * @subpackage System module
5
 * @category   modules
6
 * @author     Nazar Mokrynskyi <[email protected]>
7
 * @license    0BSD
8
 */
9
namespace cs\modules\System\api\Controller\admin;
10
use
11
	cs\Config,
12
	cs\ExitException,
13
	cs\Permission,
14
	cs\Text;
15
16
trait blocks {
17
	/**
18
	 * Get array of blocks data or data of specific block if id specified
19
	 *
20
	 * If block id specified - extended form of data will be returned
21
	 *
22
	 * @param \cs\Request $Request
23
	 *
24
	 * @return array
25
	 *
26
	 * @throws ExitException
27
	 */
28
	public static function admin_blocks_get ($Request) {
29
		$Config = Config::instance();
30
		$Text   = Text::instance();
31
		$db_id  = $Config->module('System')->db('texts');
32
		$index  = $Request->route_ids(0);
33
		if (!$index) {
34
			/**
35
			 * @var array $blocks
36
			 */
37
			$blocks = $Config->components['blocks'];
38
			foreach ($blocks as &$block) {
39
				$block = static::admin_blocks_get_prepare($db_id, $Text, $block);
40
			}
41
			return array_values($blocks) ?: [];
42
		}
43
		$block = static::get_block_by_index($index);
44
		if (!$block) {
0 ignored issues
show
introduced by
The condition $block is always false.
Loading history...
45
			throw new ExitException(404);
46
		}
47
		return static::admin_blocks_get_prepare($db_id, $Text, $block);
48
	}
49
	/**
50
	 * @param int   $db_id
51
	 * @param Text  $Text
52
	 * @param array $block
53
	 *
54
	 * @return array
55
	 */
56
	protected static function admin_blocks_get_prepare ($db_id, $Text, $block) {
57
		$block['active']  = (int)$block['active'];
58
		$block['title']   = $Text->process($db_id, $block['title'], true);
59
		$block['content'] = $block['content'] ? $Text->process($db_id, $block['content'], true) : '';
60
		$block['start']   = date('Y-m-d\TH:i', $block['start'] ?: time());
0 ignored issues
show
Bug introduced by
It seems like $block['start'] ?: time() can also be of type string; however, parameter $timestamp of date() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

60
		$block['start']   = date('Y-m-d\TH:i', /** @scrutinizer ignore-type */ $block['start'] ?: time());
Loading history...
61
		$block['expire']  = [
62
			'date'  => date('Y-m-d\TH:i', $block['expire'] ?: time()),
63
			'state' => (int)($block['expire'] != 0)
64
		];
65
		return $block;
66
	}
67
	/**
68
	 * Add new block
69
	 *
70
	 * @param \cs\Request $Request
71
	 *
72
	 * @throws ExitException
73
	 */
74
	public static function admin_blocks_post ($Request) {
75
		static::save_block_data($Request->data);
76
	}
77
	/**
78
	 * Update block's data
79
	 *
80
	 * @param \cs\Request $Request
81
	 *
82
	 * @throws ExitException
83
	 */
84
	public static function admin_blocks_put ($Request) {
85
		$index = $Request->route_ids(0);
86
		if (!$index) {
87
			throw new ExitException(400);
88
		}
89
		static::save_block_data($Request->data, $index);
90
	}
91
	/**
92
	 * Delete block
93
	 *
94
	 * @param \cs\Request $Request
95
	 *
96
	 * @throws ExitException
97
	 */
98
	public static function admin_blocks_delete ($Request) {
99
		$index = $Request->route_ids(0);
100
		if (!$index) {
101
			throw new ExitException(400);
102
		}
103
		$Config     = Config::instance();
104
		$db_id      = $Config->module('System')->db('texts');
105
		$Permission = Permission::instance();
106
		$Text       = Text::instance();
107
		$found      = false;
108
		/**
109
		 * @var array $blocks
110
		 */
111
		$blocks = $Config->components['blocks'];
112
		foreach ($blocks as $i => $block) {
113
			if ($block['index'] == $index) {
114
				unset($Config->components['blocks'][$i]);
115
				$found = $i;
116
				break;
117
			}
118
		}
119
		if ($found === false) {
120
			throw new ExitException(404);
121
		}
122
		$block_permission = $Permission->get(null, 'Block', $index);
123
		if ($block_permission) {
124
			$Permission->del($block_permission[0]['id']);
125
		}
126
		$Text->del($db_id, 'System/Config/blocks/title', $index);
127
		$Text->del($db_id, 'System/Config/blocks/content', $index);
128
		if (!$Config->save()) {
129
			throw new ExitException(500);
130
		}
131
	}
132
	/**
133
	 * Get array of available block types
134
	 */
135
	public static function admin_blocks_types () {
136
		return array_merge(['html', 'raw_html'], _mb_substr(get_files_list(BLOCKS, '/^block\..*?\.php$/i', 'f'), 6, -4));
0 ignored issues
show
Bug introduced by
It seems like _mb_substr(get_files_lis...\.php$/i', 'f'), 6, -4) can also be of type string; however, parameter $array2 of array_merge() does only seem to accept null|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

136
		return array_merge(['html', 'raw_html'], /** @scrutinizer ignore-type */ _mb_substr(get_files_list(BLOCKS, '/^block\..*?\.php$/i', 'f'), 6, -4));
Loading history...
137
	}
138
	/**
139
	 * Update blocks order
140
	 *
141
	 * @param \cs\Request $Request
142
	 *
143
	 * @throws ExitException
144
	 */
145
	public static function admin_blocks_update_order ($Request) {
146
		$order = $Request->data('order');
0 ignored issues
show
Bug introduced by
'order' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::data(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
		$order = $Request->data(/** @scrutinizer ignore-type */ 'order');
Loading history...
147
		if (!is_array($order)) {
148
			throw new ExitException(400);
149
		}
150
		$Config = Config::instance();
151
		/**
152
		 * @var array $blocks
153
		 */
154
		$blocks           = $Config->components['blocks'];
155
		$indexed_blocks   = array_combine(
156
			array_column($blocks, 'index'),
157
			$blocks
158
		);
159
		$new_blocks_order = [];
160
		$all_indexes      = [];
161
		/**
162
		 * @var array[] $order
163
		 */
164
		foreach ($order as $position => $indexes) {
165
			foreach ($indexes as $index) {
166
				$all_indexes[]      = $index;
167
				$block              = $indexed_blocks[$index];
168
				$block['position']  = $position;
169
				$new_blocks_order[] = $block;
170
			}
171
		}
172
		foreach ($blocks as $block) {
173
			if (!in_array($block['index'], $all_indexes)) {
174
				$new_blocks_order[] = $block;
175
			}
176
		}
177
		$Config->components['blocks'] = $new_blocks_order;
178
		if (!$Config->save()) {
179
			throw new ExitException(500);
180
		}
181
	}
182
	/**
183
	 * @param array     $block_new
184
	 * @param false|int $index Index of existing block, if not specified - new block being added
185
	 *
186
	 * @throws ExitException
187
	 */
188
	protected static function save_block_data ($block_new, $index = false) {
189
		$Config = Config::instance();
190
		$db_id  = $Config->module('System')->db('texts');
191
		$Text   = Text::instance();
192
		$block  = [
193
			'position' => 'floating',
194
			'type'     => xap($block_new['type']),
195
			'index'    => intval(substr(round(microtime(true) * 1000), 3), 10)
196
		];
197
		if ($index) {
198
			$block = &static::get_block_by_index($index);
199
			if (!$block) {
0 ignored issues
show
introduced by
The condition $block is always false.
Loading history...
200
				throw new ExitException(404);
201
			}
202
		}
203
		$block['title']   = $Text->set($db_id, 'System/Config/blocks/title', $block['index'], $block_new['title']);
204
		$block['active']  = $block_new['active'];
205
		$block['type']    = $block_new['type'];
206
		$block['start']   = $block_new['start'];
207
		$block['start']   = strtotime($block_new['start']);
208
		$block['expire']  = $block_new['expire']['state'] ? strtotime($block_new['expire']['date']) : 0;
209
		$block['content'] = '';
210
		if ($block['type'] == 'html') {
211
			$block['content'] = $Text->set($db_id, 'System/Config/blocks/content', $block['index'], xap($block_new['content'], true));
0 ignored issues
show
Bug introduced by
It seems like xap($block_new['content'], true) can also be of type string[]; however, parameter $text of cs\Text::set() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

211
			$block['content'] = $Text->set($db_id, 'System/Config/blocks/content', $block['index'], /** @scrutinizer ignore-type */ xap($block_new['content'], true));
Loading history...
212
		} elseif ($block['type'] == 'raw_html') {
213
			$block['content'] = $Text->set($db_id, 'System/Config/blocks/content', $block['index'], $block_new['content']);
214
		}
215
		if (!$index) {
216
			$Config->components['blocks'][] = $block;
217
			Permission::instance()->add('Block', $block['index']);
218
		}
219
		if (!$Config->save()) {
220
			throw new ExitException(500);
221
		}
222
	}
223
	/**
224
	 * @param int $index
225
	 *
226
	 * @return array|false
227
	 */
228
	protected static function &get_block_by_index ($index) {
229
		/**
230
		 * @var array $blocks
231
		 */
232
		$blocks = Config::instance()->components['blocks'];
233
		foreach ($blocks as &$block) {
234
			if ($block['index'] == $index) {
235
				return $block;
236
			}
237
		}
238
		$false = false;
239
		return $false;
240
	}
241
}
242