Passed
Push — release-3.2.0 ( 24bcfb...4d8cca )
by Daniel
04:25
created

feeds::get_fields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 17
nc 3
nop 0
dl 0
loc 29
rs 9.7
c 0
b 0
f 0
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
14
/**
15
 * Feeds Block
16
 */
17
class feeds extends block
18
{
19
	/** @var \phpbb\language\language */
20
	protected $translator;
21
22
	/** @var \phpbb\request\request_interface */
23
	protected $request;
24
25
	/** @var \phpbb\template\twig\environment */
26
	protected $twig;
27
28
	/** @var string */
29
	protected $cache_dir;
30
31
	/** @var array */
32
	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'];
33
34
	/** @var array */
35
	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'];
36
37
	/**
38
	 * Constructor
39
	 *
40
	 * @param \phpbb\language\language				$translator			Language object
41
	 * @param \phpbb\request\request_interface		$request			Request object
42
	 * @param \phpbb\template\twig\environment		$twig				Twig environment
43
	 * @param string 								$cache_dir			Path to cache directory
44
	 */
45
	public function __construct(\phpbb\language\language $translator, \phpbb\request\request_interface $request, \phpbb\template\twig\environment $twig, $cache_dir)
46
	{
47
		$this->translator = $translator;
48
		$this->request = $request;
49
		$this->twig = $twig;
50
		$this->cache_dir = $cache_dir;
51
	}
52
53
	/**
54
	 * {@inheritdoc}
55
	 */
56
	public function get_config(array $settings)
57
	{
58
		$template_default = '<a target="_blank" href="{{ item.link }}">{{ item.title }}</a>';
59
		return array(
60
			'legend1'			=> 'SETTINGS',
61
			'feeds'			=> array('lang' => 'FEED_URLS', 'type' => 'multi_input:0', 'default' => []),
62
			'template'		=> array('type' => 'custom', 'default' => $template_default, 'object' => $this, 'method' => 'get_cfg_feeds_template'),
63
			'max'			=> array('lang' => 'MAX_ITEMS', 'validate' => 'int:1', 'type' => 'number:1', 'default' => 5),
64
			'cache'			=> array('lang' => 'CACHE_DURATION', 'validate' => 'int:1', 'type' => 'number:1', 'default' => 6, 'append' => 'HOURS_SHORT'),
65
		);
66
	}
67
68
	/**
69
	 * {@inheritdoc}
70
	 */
71
	public function display(array $bdata, $edit_mode = false)
72
	{
73
		$title = 'FEEDS';
74
		$content = '';
75
		$settings = $bdata['settings'];
76
		$feed_urls = array_filter((array) $settings['feeds']);
77
78
		if (sizeof($feed_urls))
79
		{
80
			try
81
			{
82
				$template = $this->twig->createTemplate($this->get_template($settings['template']));
83
84
				if ($items = $this->get_feed_items($feed_urls, $settings['max'], $settings['cache']))
85
				{
86
					return array(
87
						'title'		=> $title,
88
						'content'	=> $template->render([
89
							'items'	=> $items,
90
						])
91
					);
92
				}
93
94
				$content = $this->translator->lang('FEED_PROBLEMS');
95
			}
96
			catch (\Exception $e)
97
			{
98
				$content = $e->getMessage();
99
			}
100
		}
101
		else
102
		{
103
			$content = $this->translator->lang('FEED_URL_MISSING');
104
		}
105
106
		return array(
107
			'title'		=> $title,
108
			'content'	=> ($edit_mode) ? $content : '',
109
		);
110
	}
111
112
	/**
113
	 * @param array $feed_urls
114
	 * @param int $max
115
	 * @param int $cache
116
	 * @return array
117
	 */
118
	protected function get_feed_items(array $feed_urls, $max, $cache = 0, $items_per_feed = 0)
119
	{
120
		$items = [];
121
		$feed_urls = array_filter(array_map('trim', $feed_urls));
122
123
		if (sizeof($feed_urls))
124
		{
125
			$feed = new \blitze\sitemaker\services\simplepie\feed;
126
			$feed->set_feed_url($feed_urls);
127
			$feed->enable_cache((bool) $cache);
128
			$feed->set_cache_location($this->cache_dir);
129
			$feed->set_cache_duration($cache * 3600);
130
131
			if ($items_per_feed)
132
			{
133
				$feed->set_item_limit($items_per_feed);
134
			}
135
136
			$feed->init();
137
			$feed->handle_content_type();
138
139
			$items = $feed->get_items(0, $max);
140
		}
141
142
		return $items;
143
	}
144
145
	/**
146
	 * @param string $template
147
	 * @return string
148
	 */
149
	public function get_cfg_feeds_template($template)
150
	{
151
		$this->ptemplate->assign_vars([
152
			'template'	=> $template,
153
		]);
154
155
		return $this->ptemplate->render_view('blitze/sitemaker', 'blocks/cfg_feeds_template.html', 'cfg_feeds_template');
156
	}
157
158
	/**
159
	 * Called when editing feed block to get available rss/atom fields
160
	 * @return array
161
	 */
162
	public function get_fields()
163
	{
164
		$this->translator->add_lang('feed_fields', 'blitze/sitemaker');
165
166
		$feeds = $this->request->variable('feeds', array(0 => ''));
167
		$feed_items = $this->get_feed_items($feeds, 0, 0, 1);
168
169
		$data = array('items' => []);
170
		$fields = array('items' => $this->get_field_defaults('items'));
171
172
		foreach ($feed_items as $feed)
173
		{
174
			$feed_data = $feed_fields = [];
175
			$fields['items']['children'] += $this->get_feed_fields($feed, $feed_data);
176
177
			foreach ($this->item_fields as $field)
178
			{
179
				$value = $feed->{$field};
180
				$feed_data[$field] = $value;
181
				$feed_fields[$field] = $this->buildTags($field, $value);
182
			}
183
184
			$data['items'][] = array_filter($feed_data);
185
			$fields['items']['children'] = array_replace_recursive($fields['items']['children'], array_filter($feed_fields));
186
		}
187
188
		return [
189
			'fields'	=> array_filter($fields),
190
			'data'		=> array_filter($data),
191
		];
192
	}
193
194
	/**
195
	 * @param \blitze\sitemaker\services\simplepie\item $feed
196
	 * @return array
197
	 */
198
	protected function get_feed_fields(\blitze\sitemaker\services\simplepie\item $item, array &$data)
199
	{
200
		$feed_props = [];
201
		foreach ($this->feed_fields as $field)
202
		{
203
			$feed_props[$field] = $this->buildTags($field, $item->feed->{$field});
204
			$data['feed'][$field] = $item->feed->{$field};
205
		}
206
207
		$feed_props = array_filter($feed_props);
208
		$data['feed'] = array_filter($data['feed']);
209
210
		$fields = [];
211
		if (sizeof($feed_props))
212
		{
213
			$fields['feed'] = $this->get_field_defaults('feed');
214
			$fields['feed']['children'] = $feed_props;
215
		}
216
217
		return $fields;
218
	}
219
220
	/**
221
	 * @param string $field
222
	 * @param mixed $value
223
	 * @return array|string
224
	 */
225
	protected function buildTags($field, $value)
226
	{
227
		if (empty($value))
228
		{
229
			return '';
230
		}
231
232
		$data = $this->get_field_defaults($field);
233
234
		if ($this->is_array_of_objects($value))
235
		{
236
			$value = array_slice($value, 0, 1);
237
			$this->iterate_props($value, $data);
238
		}
239
		else if (gettype($value) === 'object')
240
		{
241
			$props = array_filter(get_object_vars($value));
242
			$this->iterate_props($props, $data);
243
		}
244
245
		return $data;
246
	}
247
248
	/**
249
	 * @param array $props
250
	 * @param array $data
251
	 * @return void
252
	 */
253
	protected function iterate_props(array $props, array &$data)
254
	{
255
		ksort($props);
256
		foreach ($props as $prop => $value)
257
		{
258
			$data['children'][$prop] = $this->buildTags($prop, $value);
259
		}
260
	}
261
262
	/**
263
	 * @param mixed $value
264
	 * @return bool
265
	 */
266
	protected function is_array_of_objects($value)
267
	{
268
		return (is_array($value) && gettype($value[0]) === 'object');
269
	}
270
271
	/**
272
	 * @param string $field
273
	 * @return array
274
	 */
275
	protected function get_field_defaults($field)
276
	{
277
		$field = (string) $field;
278
		return [
279
			'text'			=> $field,
280
			'displayText'	=> $this->translator->lang(strtoupper($field)),
281
			'children'		=> [],
282
		];
283
	}
284
285
	/**
286
	 * @param string $tpl
287
	 * @return string
288
	 */
289
	protected function get_template($item_tpl)
290
	{
291
		$item_tpl = html_entity_decode(trim($item_tpl));
292
		return "<ul class=\"sm-list\">
293
			{% for item in items %}
294
			<li>
295
				$item_tpl
296
			</li>
297
			{% endfor %}
298
		</ul>";
299
	}
300
}
301