parent_route::get_all_routes()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 19
rs 9.9332
1
<?php
2
3
/**
4
 *
5
 * @package sitemaker
6
 * @copyright (c) 2021 Daniel A. (blitze)
7
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
8
 *
9
 */
10
11
namespace blitze\sitemaker\services\blocks;
12
13
class parent_route
14
{
15
	/** @var \phpbb\cache\driver\driver_interface */
16
	protected $cache;
17
18
	/** @var \phpbb\config\config */
19
	protected $config;
20
21
	/** @var \blitze\sitemaker\services\blocks\factory */
22
	protected $block_factory;
23
24
	/** @var \blitze\sitemaker\model\mapper_factory */
25
	protected $mapper_factory;
26
27
	/** @var string */
28
	protected $php_ext;
29
30
	/** @var bool */
31
	protected $is_sub_route = false;
32
33
	/**
34
	 * Constructor
35
	 *
36
	 * @param \phpbb\cache\driver\driver_interface			$cache					Cache driver interface
37
	 * @param \phpbb\config\config							$config					Config object
38
	 * @param \blitze\sitemaker\services\blocks\factory		$block_factory			Blocks factory object
39
	 * @param \blitze\sitemaker\model\mapper_factory		$mapper_factory			Mapper factory object
40
	 * @param string										$php_ext				phpEx
41
	 */
42
	public function __construct(\phpbb\cache\driver\driver_interface $cache, \phpbb\config\config $config, \blitze\sitemaker\model\mapper_factory $mapper_factory, $php_ext)
43
	{
44
		$this->cache = $cache;
45
		$this->config = $config;
46
		$this->mapper_factory = $mapper_factory;
47
		$this->php_ext = $php_ext;
48
	}
49
50
	/**
51
	 * @param array $routes
52
	 * @param array $route_info
53
	 * @param string $current_route
54
	 * @param string $page_dir
55
	 * @param int $forum_id
56
	 * @param int $style_id
57
	 * @return array
58
	 */
59
	protected function inherit_route_info(array $routes, array $route_info, $current_route, $page_dir, $forum_id, $style_id)
60
	{
61
		// if block does not have own settings, inherit settings from parent route if it exists
62
		// if block has own settings but no blocks, inherit route_id and has_blocks from parent route if it exists
63
		if (empty($route_info['has_blocks']))
64
		{
65
			if ($parent_route_info = $this->get_parent_route($routes, $current_route, $page_dir, $forum_id))
66
			{
67
				$this->is_sub_route = $parent_route_info['has_blocks'];
68
				$route_info['route_id'] = $parent_route_info['route_id'];
69
				$route_info['has_blocks'] = $parent_route_info['has_blocks'];
70
			}
71
		}
72
73
		// fill in missing fields, while forcing route and style props to current route and style
74
		unset($route_info['style'], $route_info['route']);
75
		$route_info += $this->get_default_route_info($current_route, $style_id);
76
77
		return $this->set_display_route_id($style_id, $route_info);
78
	}
79
80
	/**
81
	 * @param string $current_route
82
	 * @param int $style_id
83
	 * @return array
84
	 */
85
	protected function get_default_route_info($current_route, $style_id)
86
	{
87
		return array(
88
			'route_id'		=> 0,
89
			'ext_name'		=> '',
90
			'route'			=> $current_route,
91
			'style'			=> $style_id,
92
			'hide_blocks'	=> false,
93
			'ex_positions'	=> array(),
94
			'has_blocks'	=> false,
95
			'is_sub_route'	=> $this->is_sub_route,
96
		);
97
	}
98
99
	/**
100
	 * @param array $routes
101
	 * @param string $current_route
102
	 * @param string $page_dir
103
	 * @param int $forum_id
104
	 * @return array
105
	 */
106
	protected function get_parent_route(array $routes, $current_route, $page_dir, $forum_id)
107
	{
108
		if ($page_dir)
109
		{
110
			return $this->get_parent_directory_route_info($routes, $page_dir);
111
		}
112
		else if ($forum_id)
113
		{
114
			return $this->get_parent_forum_route_info($forum_id, $routes);
115
		}
116
117
		return $this->get_parent_app_route_info($routes, $current_route);
118
	}
119
120
	/**
121
	 * @param array $routes
122
	 * @param string $page_dir
123
	 * @return null|array
124
	 */
125
	protected function get_parent_directory_route_info(array $routes, $page_dir)
126
	{
127
		$parent_dir = ltrim(dirname($page_dir) . '/index.php', './');
128
		return (isset($routes[$parent_dir])) ? $routes[$parent_dir] : null;
129
	}
130
131
	/**
132
	 * @param int $forum_id
133
	 * @param array $routes
134
	 * @return null|array
135
	 */
136
	protected function get_parent_forum_route_info($forum_id, array $routes)
137
	{
138
		$forumslist = (array) make_forum_select(false, false, true, false, false, false, true);
139
140
		do
141
		{
142
			$forum_id = &$forumslist[$forum_id]['parent_id'];
143
			$route = "viewforum.{$this->php_ext}?f={$forum_id}";
144
145
			if ($this->route_has_blocks($routes, $route))
146
			{
147
				return $routes[$route];
148
			}
149
		} while ($forum_id);
150
151
		// make all forums child route of app.php/forum
152
		$route = 'app.' . $this->php_ext . '/forum';
153
		return $this->route_has_blocks($routes, $route) ? $routes[$route] : null;
154
	}
155
156
	/**
157
	 * @param array $routes
158
	 * @param string $route
159
	 * @return bool
160
	 */
161
	protected function route_has_blocks(array $routes, $route)
162
	{
163
		return isset($routes[$route]) && $routes[$route]['has_blocks'];
164
	}
165
166
	/**
167
	 * @param array $routes_data
168
	 * @param string $current_route
169
	 * @return null|array
170
	 */
171
	protected function get_parent_app_route_info(array $routes_data, $current_route)
172
	{
173
		$routes = array_keys($routes_data);
174
175
		// We add the current route to the list and sort it in ascending order
176
		// Its parent will likely come before it in the list
177
		// Eg if current route is 'app.php/content/news' the route list might be:
178
		// ['app.php/content', 'app.php/content/category/cars', 'app.php/content/news', 'index.php']
179
		$routes[] = $current_route;
180
		sort($routes);
181
182
		// We find the position of the current route in the list
183
		$index = (int) array_search($current_route, $routes);
184
185
		// we use it as our starting point and walk backwords to find the immediate parent
186
		// in this case 'app.php/content'
187
		for ($i = $index - 1; $i >= 0; $i--)
188
		{
189
			if (strpos($current_route, $routes[$i]) !== false)
190
			{
191
				return $routes_data[$routes[$i]];
192
			}
193
		}
194
195
		return null;
196
	}
197
198
	/**
199
	 * We get blocks to display by route id and style id, so we update the route id here,
200
	 * to show blocks from default route if current route or it's parent has no blocks
201
	 *
202
	 * @param int $style_id
203
	 * @param array $route_info
204
	 * @return array
205
	 */
206
	protected function set_display_route_id($style_id, array $route_info)
207
	{
208
		if (!$route_info['has_blocks'] && ($default = $this->get_inherited_route_info($style_id)))
209
		{
210
			$route_info['route_id'] = $default['route_id'];
211
			$route_info['style'] = $default['style'];
212
		}
213
214
		return $route_info;
215
	}
216
217
	/**
218
	 * @param int $current_style_id
219
	 * @return int
220
	 */
221
	protected function get_inherited_route_info($current_style_id)
222
	{
223
		[$route, $style_id] = array_filter(explode(':', $this->config['sitemaker_default_layout'])) + array('', $current_style_id);
224
		$routes = $this->get_all_routes();
225
226
		return (isset($routes[$style_id]) && isset($routes[$style_id][$route])) ? $routes[$style_id][$route] : 0;
227
	}
228
229
	/**
230
	 * @return array|mixed
231
	 */
232
	protected function get_all_routes()
233
	{
234
		if (($all_routes = $this->cache->get('sitemaker_block_routes')) === false)
235
		{
236
			$route_mapper = $this->mapper_factory->create('routes');
237
			$collection = $route_mapper->find();
238
239
			$all_routes = array();
240
			foreach ($collection as $entity)
241
			{
242
				$route = $entity->get_route();
243
				$style = $entity->get_style();
244
				$all_routes[$style][$route] = $entity->to_array();
245
			}
246
247
			$this->cache->put('sitemaker_block_routes', $all_routes);
248
		}
249
250
		return $all_routes;
251
	}
252
}
253