PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 All 36 releases
vikbooking / libraries / system / rssfeeds.php

rssfeeds.php in VikBooking Hotel Booking Engine & PMS trunk, at libraries/system/rssfeeds.php

451 lines 9.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking - Libraries
4 * @subpackage system
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2020 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * Helper class used to manage settings related to RSS feeds.
16 *
17 * @since 1.3.9
18 */
19 class VikBookingRssFeeds
20 {
21 /**
22 * Hook used to manipulate the RSS channels.
23 *
24 * @param array $channels A list of RSS permalinks.
25 * @param boolean $published True to return only the published channels.
26 *
27 * @return array The channels to use for RSS subscription.
28 */
29 public static function getChannels(array $channels = array(), $published = true)
30 {
31 // subscribe reader to the following channels
32 $default = array(
33 'https://vikwp.com/rss/news/',
34 'https://vikwp.com/rss/promo/',
35 'https://vikwp.com/rss/tips/',
36 );
37
38 // allow channels manipulation only to PRO users
39 if (VikBookingLicense::isPro() && $published)
40 {
41 $user = JFactory::getUser();
42
43 // get channels configuration
44 $config = get_user_meta($user->id, 'vikbooking_rss_urls', true);
45
46 // make sure we have a configuration
47 if (is_array($config))
48 {
49 // take only the active channels
50 $default = array_intersect($default, $config);
51 }
52 }
53
54 // apply filters only in case we need the final URI
55 if ($published)
56 {
57 // build query string for each channel
58 $default = array_map(function($url)
59 {
60 // create URI
61 $url = new JUri($url);
62
63 // append format and type
64 $url->setVar('format', 'feed');
65 $url->setVar('type', 'rss');
66
67 // apply tag filter (8: vikbooking, 12: vbo-lite, 16: vbo-pro)
68 $tags = array(8);
69
70 if (VikBookingLicense::isPro())
71 {
72 // PRO tag
73 $tags[] = 16;
74 }
75 else
76 {
77 // LITE tag
78 $tags[] = 12;
79 }
80
81 $url->setVar('filter_tag', $tags);
82
83 // take language from WP locale
84 $langtag = JFactory::getLanguage()->getTag();
85
86 // look for language part
87 if (preg_match("/^([a-z]{2,})[\-_][a-z]{2,}$/i", $langtag, $match))
88 {
89 // Append language to URI.
90 // In case the language is not supported, the system
91 // will fallback to the default one.
92 $url->setVar('lang', end($match));
93 }
94
95 // take only the channel string
96 return (string) $url;
97 }, $default);
98 }
99
100 // merge default channels with existing ones
101 return array_merge($channels, $default);
102 }
103
104 /**
105 * Downloads the latest feed and display it, if any.
106 *
107 * @return void
108 */
109 public static function download()
110 {
111 $app = JFactory::getApplication();
112 $user = JFactory::getUser();
113
114 // make sure that all the following conditions are verified
115 $conditions = (
116 // we are not doing AJAX
117 !wp_doing_ajax()
118 // we are in the back-end
119 && $app->isClient('administrator')
120 // the user is an administrator
121 && $user->authorise('core.admin', 'com_vikbooking')
122 // the dashboard should display the RSS feeds
123 && static::isDashboard()
124 // the initial setup was at least started
125 && static::hasMinimumSetup()
126 );
127
128 // validate conditions flag
129 if ($conditions)
130 {
131 // instantiate RSS reader
132 $rss = VikBookingBuilder::setupRssReader();
133
134 try
135 {
136 // prepare download options
137 $options = array(
138 // take only one item
139 'limit' => 1,
140 // take only visible feeds
141 'new' => true,
142 // take oldest feed
143 'order' => 'asc',
144 );
145
146 // try to download the feed
147 $feed = $rss->download($options);
148
149 if ($feed)
150 {
151 // opt-in missing, ask the user to agree to our terms
152 echo JLayoutHelper::render('html.rss.feed', array('feed' => $feed));
153 }
154 }
155 catch (JRssOptInException $e)
156 {
157 // opt-in missing, ask the user to agree to our terms
158 echo JLayoutHelper::render('html.rss.optin');
159 }
160 catch (Throwable $e)
161 {
162 // service declined, go ahead silently
163 }
164 }
165 }
166
167 /**
168 * Displays the configuration fieldset to manage the opt-in.
169 *
170 * @param mixed $forms The HTML to display.
171 * @param mixed $view The current view instance.
172 *
173 * @return mixed The HTML to display.
174 *
175 * @return mixed The HTML to display.
176 */
177 public static function config($forms, $view)
178 {
179 $app = JFactory::getApplication();
180 $user = JFactory::getUser();
181
182 if (!is_array($forms))
183 {
184 $forms = array();
185 }
186
187 // make sure we are under VikBooking
188 if ($app->input->get('option') != 'com_vikbooking')
189 {
190 // do not go ahead
191 return $forms;
192 }
193
194 // instantiate RSS reader
195 $rss = VikBookingBuilder::setupRssReader();
196
197 // set up configuration array
198 $config = array();
199
200 try
201 {
202 $config['optin'] = $rss->optedIn();
203 }
204 catch (Exception $e)
205 {
206 $config['optin'] = false;
207 }
208
209 // get published channels
210 $config['channels'] = $rss->getChannels();
211
212 // take only the host and path because the query string might vary
213 $config['channels'] = array_map(function($url)
214 {
215 $url = new JUri($url);
216 $url->setQuery('');
217 return (string) $url;
218 }, $config['channels']);
219
220 // load all supported channels
221 $list = apply_filters('vikbooking_fetch_rss_channels', array(), false);
222
223 $channels = array();
224
225 // iterate channels to fetch a readable label
226 foreach ($list as $url)
227 {
228 $url = new JUri($url);
229
230 // get path without trailing slash
231 $key = trim($url->toString(array('host', 'path')), '/');
232 // explode paths
233 $chunks = explode('/', $key);
234 // take only the last
235 $key = array_pop($chunks);
236
237 // prepend path recursively in case of non-unique path
238 while (isset($channels[$key]) && $chunks)
239 {
240 $key = array_pop($chunks) . ' ' . $key;
241 }
242
243 // remove query from URL
244 $url->setQuery('');
245
246 // register channel
247 $channels[$key] = (string) $url;
248 }
249
250 // get display dashboard from user meta
251 $config['dashboard'] = static::isDashboard();
252
253 // prepare layout data
254 $data = array(
255 'rss' => $rss,
256 'config' => $config,
257 'channels' => $channels,
258 );
259
260 // include sub-fieldset to enable RSS configuration
261 $layout = new JLayoutFile('html.rss.config');
262 // render layout
263 $html = $layout->render($data);
264
265 // create an apposite fieldset for RSS
266 $forms['RSS'] = $html;
267
268 return $forms;
269 }
270
271 /**
272 * Saves the opt-in choice made by the user.
273 *
274 * @return void
275 */
276 public static function save()
277 {
278 $app = JFactory::getApplication();
279 $user = JFactory::getUser();
280
281 // make sure we are under VikBooking
282 if ($app->input->get('option') != 'com_vikbooking')
283 {
284 // do not go ahead
285 return;
286 }
287
288 // instantiate RSS reader
289 $rss = VikBookingBuilder::setupRssReader();
290
291 try
292 {
293 $status = $rss->optedIn();
294 }
295 catch (Exception $e)
296 {
297 $status = false;
298 }
299
300 $input = JFactory::getApplication()->input;
301
302 // get user choice
303 $choice = $input->getBool('rss_optin_status', false);
304
305 // check whether the choice changed
306 if ($choice != $status)
307 {
308 // update choice
309 $rss->optIn($choice);
310 }
311
312 // recover display dashboard from request
313 $dashboard = $input->get('rss_display_dashboard', 0, 'uint');
314
315 // update dashboard visibility
316 update_user_meta($user->id, 'vikbooking_rss_display_dashboard', $dashboard);
317
318 // allow channels manipulation only to PRO users
319 if (VikBookingLicense::isPro())
320 {
321 // recover specified channels from request
322 $channels = $input->get('rss_channel_url', array(), 'string');
323
324 // update channels configuration
325 update_user_meta($user->id, 'vikbooking_rss_urls', $channels);
326 }
327 }
328
329 /**
330 * Adjusts the RSS class to the plugin needs.
331 * Executes before using it.
332 *
333 * @param JRssReader $rss The RSS reader handler.
334 *
335 * @return void
336 */
337 public static function ready(&$rss)
338 {
339 /**
340 * Filters the HTML that is allowed for a given context.
341 *
342 * @since 3.5.0
343 *
344 * @param array $tags An associative array containing the supported tags
345 * and all the related attributes.
346 * @param string $context Context name.
347 */
348 add_filter('wp_kses_allowed_html', function($tags, $context)
349 {
350 // make sure we are filtering a POST context
351 if ($context == 'post')
352 {
353 // add support for input field
354 $tags['input'] = [
355 'type' => true,
356 'name' => true,
357 'id' => true,
358 'class' => true,
359 'value' => true,
360 'style' => true,
361 'disabled' => true,
362 'readonly' => true,
363 ];
364
365 // add support for textarea field
366 $tags['textarea'] = [
367 'name' => true,
368 'id' => true,
369 'class' => true,
370 'style' => true,
371 'rows' => true,
372 'cols' => true,
373 'disabled' => true,
374 'readonly' => true,
375 ];
376
377 // add support for button
378 if (isset($tags['button']))
379 {
380 // just include the use of onclick attribute
381 $tags['button']['onclick'] = true;
382 }
383 else
384 {
385 // define all supported attributes
386 $tags['button'] = [
387 'type' => true,
388 'id' => true,
389 'class' => true,
390 'style' => true,
391 'onclick' => true,
392 'disabled' => true,
393 ];
394 }
395
396 // add support for source under a <video> tag
397 $tags['source'] = [
398 'src' => true,
399 ];
400 }
401
402 return $tags;
403 }, 10, 2);
404 }
405
406 /**
407 * Returns true in case the RSS feeds should be displayed
408 * within the dashboard of VikBooking.
409 *
410 * @return boolean
411 */
412 public static function isDashboard()
413 {
414 $user = JFactory::getUser();
415
416 // get display dashboard from user meta
417 $dashboard = get_user_meta($user->id, 'vikbooking_rss_display_dashboard', true);
418
419 // make sure we have a number
420 if (preg_match("/^[01]$/", (string) $dashboard))
421 {
422 // cast value to boolean
423 $dashboard = (bool) $dashboard;
424 }
425 else
426 {
427 // missing configuration, always show by default
428 $dashboard = true;
429 }
430
431 return $dashboard;
432 }
433
434 /**
435 * Returns true in case a minimum setup has been started.
436 *
437 * @return boolean
438 */
439 public static function hasMinimumSetup()
440 {
441 $dbo = JFactory::getDbo();
442
443 $q = "SELECT `id` FROM `#__vikbooking_rooms`";
444
445 $dbo->setQuery($q);
446 $dbo->execute();
447
448 return ($dbo->getNumRows() > 0);
449 }
450 }
451