Passed
Push — develop ( 4e64c5...c1d6c4 )
by Daniel
09:01
created

feeds   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 276
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 103
dl 0
loc 276
rs 10
c 0
b 0
f 0
wmc 27

12 Methods

Rating   Name   Duplication   Size   Complexity  
A get_feeds_ui() 0 8 1
A get_field_defaults() 0 7 1
A get_config() 0 8 1
A buildTags() 0 21 4
A __construct() 0 6 1
A get_template() 0 7 1
A display() 0 36 5
A get_feed_items() 0 21 3
A get_feed_fields() 0 20 3
A get_fields() 0 31 3
A is_array_of_objects() 0 3 2
A iterate_props() 0 6 2
1
<?php
2
/**
3
 *
4
 * @package sitemaker
5
 * @copyright (c) 2019 Daniel A. (blitze)
6
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
 *
8
 */
9
10
namespace blitze\sitemaker\blocks;
11
12
use blitze\sitemaker\services\blocks\driver\block;
13
use blitze\sitemaker\services\feeds\Feed;
14
15
/**
16
 * Feeds Block
17
 */
18
class feeds extends block
19
{
20
	/** @var \phpbb\language\language */
21
	protected $translator;
22
23
	/** @var \phpbb\request\request_interface */
24
	protected $request;
25
26
	/** @var \phpbb\template\twig\environment */
27
	protected $twig;
28
29
	/** @var string */
30
	protected $phpbb_root_path;
31
32
	/** @var array */
33
	protected $feed_fields = ['title', 'description', 'category', 'categories', 'author', 'authors', 'contributor', 'contributors', 'copyright', 'image_url', 'image_title', 'image_link', 'image_width', 'image_height', 'permalink', 'link', 'links'];
34
35
	/** @var array */
36
	protected $item_fields = ['id', 'title', 'description', 'content', 'category', 'categories', 'author', 'authors', 'contributor', 'contributors', 'copyright', 'date', 'updated_date', 'gmdate', 'updated_gmdate', 'permalink', 'link', 'links', 'enclosure', 'enclosures', 'latitude', 'longitude', 'source'];
37
38
	/**
39
	 * Constructor
40
	 *
41
	 * @param \phpbb\language\language				$translator			Language object
42
	 * @param \phpbb\request\request_interface		$request			Request object
43
	 * @param \phpbb\template\twig\environment		$twig				Twig environment
44
	 * @param string 								$phpbb_root_path	Relative path to phpBB root
45
	 */
46
	public function __construct(\phpbb\language\language $translator, \phpbb\request\request_interface $request, \phpbb\template\twig\environment $twig, $phpbb_root_path)
47
	{
48
		$this->translator = $translator;
49
		$this->request = $request;
50
		$this->twig = $twig;
51
		$this->cache_dir = $phpbb_root_path;
0 ignored issues
show
Bug Best Practice introduced by
The property cache_dir does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
52
	}
53
54
	/**
55
	 * {@inheritdoc}
56
	 */
57
	public function get_config(array $settings)
58
	{
59
		return array(
60
			'legend1'			=> 'SETTINGS',
61
			'feeds'			=> array('type' => 'custom', 'default' => [], 'object' => $this, 'method' => 'get_feeds_ui', 'params' => [$settings['feeds'], $settings['template']]),
62
			'max'			=> array('lang' => 'MAX_ITEMS', 'validate' => 'int:1', 'type' => 'number:1', 'default' => 5),
63
			'cache'			=> array('lang' => 'CACHE_DURATION', 'validate' => 'int:1', 'type' => 'number:1', 'default' => 6, 'append' => 'HOURS_SHORT'),
64
			'template'		=> array('type' => 'hidden', 'default' => '<a target="_blank" href="{{ item.link }}">{{ item.title }}</a>'),
65
		);
66
	}
67
68
	/**
69
	 * {@inheritdoc}
70
	 */
71
	public function display(array $bdata, $edit_mode = false)
72
	{
73
		$settings = $bdata['settings'];
74
		$title = 'FEEDS';
75
		$content = '';
76
77
		if ($settings['feeds'])
78
		{
79
			try
80
			{
81
				$template = $this->twig->createTemplate($this->get_template($settings['template']));
82
				
83
				if ($items = $this->get_feed_items(array_filter((array) $settings['feeds']), $settings['max'], $settings['cache']))
84
				{
85
					return array(
86
						'title'		=> $title,
87
						'content'	=> $template->render([
88
							'items'	=> $items,
89
					]));
90
				}
91
				
92
				$content = $this->translator->lang('FEED_PROBLEMS');
93
			}
94
			catch (\Exception $e)
95
			{
96
				$content = $e->getMessage();
97
			}
98
		}
99
		else
100
		{
101
			$content = $this->translator->lang('FEED_MISSING');
102
		}
103
104
		return array(
105
			'title'		=> $title,
106
			'content'	=> ($edit_mode) ? $content : '',
107
		);
108
	}
109
110
	/**
111
	 * @param array $feed_urls
112
	 * @param int $max
113
	 * @param int $cache
114
	 * @return array
115
	 */
116
	protected function get_feed_items(array $feed_urls, $max, $cache = 0, $items_per_feed = 0)
117
	{
118
		$items = [];
119
		if (sizeof($feed_urls))
120
		{
121
			$feed = new Feed;
122
			$feed->set_feed_url($feed_urls);
123
			$feed->set_cache_location($this->cache_dir);
124
			$feed->set_cache_duration($cache * 3600);
125
126
			if ($items_per_feed) {
127
				$feed->set_item_limit($items_per_feed);
128
			}
129
130
			$feed->init();
131
			$feed->handle_content_type();
132
133
			$items = $feed->get_items(0, $max);
134
		}
135
136
		return $items;
137
	}
138
139
	/**
140
	 * @param mixed $feeds
141
	 * @param string $template
142
	 * @return string
143
	 */
144
	public function get_feeds_ui($feeds, $template)
145
	{
146
		$this->ptemplate->assign_vars([
147
			'feeds'		=> array_filter((array) $feeds),
148
			'template'	=> $template,
149
		]);
150
151
		return $this->ptemplate->render_view('blitze/sitemaker', 'blocks/feeds_settings.html', 'feeds_settings');
152
	}
153
154
	/**
155
	 * Called when editing feed block to get available rss/atom fields
156
	 * @return array
157
	 */
158
	public function get_fields()
159
	{
160
		$feeds = $this->request->variable('feeds', array(0 => ''));
161
162
		$this->translator->add_lang('feed_fields', 'blitze/sitemaker');
163
164
		$feeds = array_filter(array_map('trim', $feeds));
165
		$feed_items = $this->get_feed_items($feeds, 0, 0, 1);
166
167
		$data['items'] = [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
168
		$fields['items'] = $this->get_field_defaults('items');
0 ignored issues
show
Comprehensibility Best Practice introduced by
$fields was never initialized. Although not strictly required by PHP, it is generally a good practice to add $fields = array(); before regardless.
Loading history...
169
170
		foreach ($feed_items as $feed)
171
		{
172
			$feed_data = $feed_fields = [];
173
			$fields['items']['children'] += $this->get_feed_fields($feed, $feed_data);
174
175
			foreach ($this->item_fields as $field)
176
			{
177
				$value = $feed->{$field};
178
				$feed_data[$field] = $value;
179
				$feed_fields[$field] = $this->buildTags($field, $value);
180
			}
181
182
			$data['items'][] = array_filter($feed_data);
183
			$fields['items']['children'] = array_replace_recursive($fields['items']['children'], array_filter($feed_fields));
184
		}
185
186
		return [
187
			'fields'	=> array_filter($fields),
188
			'data'		=> array_filter($data),
189
		];
190
	}
191
192
	/**
193
	 * @param \blitze\sitemaker\services\feeds\Item $feed
194
	 * @return array
195
	 */
196
	protected function get_feed_fields(\blitze\sitemaker\services\feeds\Item $feed, array &$data)
197
	{
198
		$feed_props = [];
199
		foreach ($this->feed_fields as $field)
200
		{
201
			$feed_props[$field] = $this->buildTags($field, $feed->feed->{$field});
202
			$data['feed'][$field] = $feed->feed->{$field};
203
		}
204
205
		$feed_props = array_filter($feed_props);
206
		$data['feed'] = array_filter($data['feed']);
207
208
		$fields = [];
209
		if (sizeof($feed_props))
210
		{
211
			$fields['feed'] = $this->get_field_defaults('feed');
212
			$fields['feed']['children'] = $feed_props;
213
		}
214
215
		return $fields;
216
	}
217
218
	/**
219
	 * @param string $field
220
	 * @param mixed $value
221
	 * @return array
222
	 */
223
	protected function buildTags($field, $value)
224
	{
225
		if (empty($value))
226
		{
227
			return '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the documented return type array.
Loading history...
228
		}
229
230
		$data = $this->get_field_defaults($field);
231
232
		if ($this->is_array_of_objects($value))
233
		{
234
			$value = array_slice($value, 0, 1);
235
			$this->iterate_props($value, $data);
236
		}
237
		else if (gettype($value) === 'object')
238
		{
239
			$props = array_filter(get_object_vars($value));
240
			$this->iterate_props($props, $data);
241
		}
242
243
		return $data;
244
	}
245
246
	/**
247
	 * @param array $props
248
	 * @param array $data
249
	 * @return void
250
	 */
251
	protected function iterate_props(array $props, array &$data)
252
	{
253
		ksort($props);
254
		foreach ($props as $prop => $value)
255
		{
256
			$data['children'][$prop] = $this->buildTags($prop, $value);
257
		}
258
	}
259
260
	/**
261
	 * @param mixed $value
262
	 * @return bool
263
	 */
264
	protected function is_array_of_objects($value)
265
	{
266
		return (is_array($value) && gettype($value[0]) === 'object');
267
	}
268
269
	/**
270
	 * @param string $field
271
	 * @return array
272
	 */
273
	protected function get_field_defaults($field)
274
	{
275
		$field = (string) $field;
276
		return [
277
			'text'			=> $field,
278
			'displayText'	=> $this->translator->lang(strtoupper($field)),
279
			'children'		=> [],
280
		];
281
	}
282
283
	/**
284
	 * @param string $tpl
285
	 * @return string
286
	 */
287
	protected function get_template($item_tpl)
288
	{
289
		$item_tpl = html_entity_decode(trim($item_tpl));
290
		return "<ul class=\"sm-list\">
291
			{% for item in items %}
292
			<li>
293
				$item_tpl
294
			</li>
295
			{% endfor %}
296
		</ul>";
297
	}
298
}
299