PluginProbe
Event Post / 6.1.2
Event Post v6.1.2
6.1.2 6.1.1 6.1.0 6.0.1 6.0.0 5.12.0 trunk 3.9 4.0 4.2 4.3 4.4 4.5 5.0 5.1 5.10.0 5.10.1 5.10.2 5.10.3 5.10.4 5.11.0 5.11.1 5.2 5.5 5.6 All 47 releases
← All changes | eventpost.php +1276 -569 5.6 → 6.1.2 View file →
@@ -1,23 +1,23 @@
1 1 <?php
2 -/*
3 - Plugin Name: Event Post
4 - Plugin URI: https://event-post.com?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard
5 - Description: Add calendar and/or geolocation metadata on any posts.
6 - Version: 5.6
7 - Author: N.O.U.S. Open Useful and Simple
8 - Contributors: bastho, sabrinaleroy, unecologeek, agencenous
9 - Author URI: https://apps.avecnous.eu/?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard
10 - License: GPLv2
11 - Text Domain: event-post
12 - Domain Path: /languages/
13 - Tags: Post,posts,event,date,geolocalization,gps,widget,map,openstreetmap,EELV,calendar,agenda,blocks
14 - */
15 -
16 2 /**
3 + * Plugin Name: Event Post
4 + * Plugin URI: https://event-post.com?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard&mtm_source=plugin-uri
5 + * Description: Add calendar and/or geolocation metadata on any posts.
6 + * Version: 6.1.2
7 + * Author: N.O.U.S. Open Useful and Simple
8 + * Contributors: bastho, sabrinaleroy, unecologeek, agencenous
9 + * Author URI: https://apps.avecnous.eu/?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard&mtm_source=author
10 + * License: GPLv2
11 + * Text Domain: event-post
12 + * Domain Path: /languages/
13 + * Tags: Post,posts,event,date,geolocalization,gps,widget,map,openstreetmap,EELV,calendar,agenda,blocks
17 14 *
18 15 * @package event-post
19 16 */
17 +
18 +if ( ! defined( 'ABSPATH' ) ) exit;
19 +
20 20 global $EventPost;
21 21 $EventPost = new EventPost();
22 22
23 23 $EventPost_cache=array();
@@ -41,46 +41,336 @@
41 41 *
42 42 * Add calendar and/or geolocation metadata on posts
43 43 */
44 44 class EventPost {
45 - const META_START = 'event_begin';
46 - const META_END = 'event_end';
47 - const META_COLOR = 'event_color';
48 - const META_ICON = 'event_icon';
49 - // http://codex.wordpress.org/Geodata
50 - const META_ADD = 'geo_address';
51 - const META_LAT = 'geo_latitude';
52 - const META_LONG = 'geo_longitude';
53 - // https://schema.org/eventStatus
54 - const META_STATUS = 'event_status';
55 - // https://schema.org/location
56 - const META_VIRTUAL_LOCATION = 'event_virtual_location';
57 - // https://pending.schema.org/eventAttendanceMode
58 - const META_ATTENDANCE_MODE = 'event_attendance_mode';
45 + /**
46 + * The current version
47 + *
48 + * Must be kept in sync with the `Version:` plugin header above: `bin/bump`
49 + * only rewrites header-style declarations, not this literal.
50 + *
51 + * @var string
52 + */
53 + public $version = '6.1.2';
59 54
55 + // --------------------------------------------------------------------------------
56 + // Post metas
57 +
58 + /**
59 + * The meta name for event start date
60 + *
61 + * @var string
62 + */
63 + public $META_START = 'event_begin';
64 +
65 + /**
66 + * The meta name for event end date
67 + *
68 + * @var string
69 + */
70 + public $META_END = 'event_end';
71 +
72 + /**
73 + * The meta name for event color
74 + *
75 + * @var string
76 + */
77 + public $META_COLOR = 'event_color';
78 +
79 + /**
80 + * The meta name for event icon
81 + *
82 + * @var string
83 + */
84 + public $META_ICON = 'event_icon';
85 +
86 + // --------------------------------------------------------------------------------
87 + // Post metas related to location
88 +
89 + /**
90 + * The meta name for event address
91 + *
92 + * @var string
93 + */
94 + public $META_ADD = 'geo_address';
95 +
96 + /**
97 + * The meta name for event latitude
98 + *
99 + * @var string
100 + *
101 + * @see http://codex.wordpress.org/Geodata
102 + */
103 + public $META_LAT = 'geo_latitude';
104 +
105 + /**
106 + * The meta name for event longitude
107 + *
108 + * @var string
109 + *
110 + * @see http://codex.wordpress.org/Geodata
111 + */
112 + public $META_LONG = 'geo_longitude';
113 +
114 + /**
115 + * The meta name for event location
116 + *
117 + * @var string
118 + *
119 + * @see https://schema.org/location
120 + */
121 + public $META_VIRTUAL_LOCATION = 'event_virtual_location';
122 +
123 + // --------------------------------------------------------------------------------
124 + // Post metas related to status
125 +
126 + /**
127 + * The meta name for event status
128 + *
129 + * @var string
130 + *
131 + * @see https://schema.org/eventStatus
132 + */
133 + public $META_STATUS = 'event_status';
134 +
135 + /**
136 + * The meta name for event attendance mode
137 + *
138 + * @var string
139 + *
140 + * @see https://schema.org/eventAttendanceMode
141 + */
142 + public $META_ATTENDANCE_MODE = 'event_attendance_mode';
143 +
144 + /**
145 + * The meta name for event organizer
146 + *
147 + * @var string
148 + *
149 + * @see https://schema.org/Organization
150 + */
151 + public $META_ORGANIZATION = 'event_organization';
152 +
153 + /**
154 + * The meta name for event organizer
155 + *
156 + * @var string
157 + * @see https://schema.org/Offer
158 + */
159 + public $META_OFFER = 'event_offer';
160 +
161 + // --------------------------------------------------------------------------------
162 + // Usefull variables
163 +
164 + /**
165 + * ID of the current list
166 + *
167 + * @var int
168 + */
60 169 public $list_id;
170 +
171 + /**
172 + * ID of the current map
173 + *
174 + * @var int
175 + */
176 + public $map_id=0;
177 +
178 + /**
179 + * Schema as been outputed or not
180 + *
181 + * @var bool
182 + */
183 + private $is_schema_output=false;
184 +
185 + /**
186 + * Month names
187 + *
188 + * @var array
189 + */
61 190 public $NomDuMois;
191 +
192 + /**
193 + * Week days
194 + *
195 + * @var array
196 + */
62 197 public $Week;
63 - public $settings;
198 +
199 + /**
200 + * Currencies
201 + *
202 + * @var array
203 + */
204 + public $currencies = array();
205 +
206 + /**
207 + * Date format
208 + *
209 + * @var string
210 + */
64 211 public $dateformat;
65 212
213 + /**
214 + * Pagination
215 + *
216 + * @var array
217 + */
66 218 private $pagination;
67 - public $version = '5.3';
68 - public $plugin_path ;
219 +
220 + /**
221 + * Plugin path
222 + *
223 + * @var string
224 + */
225 + public $plugin_path;
226 +
227 + /**
228 + * Script suffix
229 + *
230 + * @var string
231 + */
69 232 private $script_sufix;
70 233
234 + /**
235 + * Settings values
236 + *
237 + * @var array
238 + */
239 + public $settings;
240 +
241 + // --------------------------------------------------------------------------------
242 + // Option values
243 +
244 + /**
245 + * Map interractions (from openlayers)
246 + *
247 + * @var array
248 + */
71 249 public $map_interactions;
250 +
251 + /**
252 + * Fields supported by quick-edit
253 + *
254 + * @var array
255 + */
72 256 public $quick_edit_fields;
73 257
74 - public $Shortcodes;
258 + /**
259 + * Fields supported by bulk-edit
260 + *
261 + * @var array
262 + */
263 + public $bulk_edit_fields;
75 264
265 + /**
266 + * Supported attendance modes
267 + *
268 + * @var array
269 + */
76 270 public $attendance_modes;
271 +
272 + /**
273 + * Supported statuses
274 + *
275 + * @var array
276 + */
77 277 public $statuses;
78 - private $is_schema_output=false;
79 278
279 + /**
280 + * Default list schema (HTML template)
281 + *
282 + * @var string
283 + */
284 + public $default_list_shema;
285 +
286 + /**
287 + * Default timeline schema (HTML template)
288 + *
289 + * @var string
290 + */
291 + public $default_timeline_shema;
292 +
293 + /**
294 + * Current list schema (HTML template)
295 + *
296 + * @var string
297 + */
298 + public $list_shema;
299 +
300 + /**
301 + * Current timeline schema (HTML template)
302 + *
303 + * @var string
304 + */
305 + public $timeline_shema;
306 +
307 + // Map variables
308 + /**
309 + * Map tiles
310 + *
311 + * @var array
312 + */
313 + public $maps;
314 +
315 + /**
316 + * Dirpath for map tiles
317 + *
318 + * @var string
319 + */
320 + public $markpath;
321 +
322 + /**
323 + * Base URL for map tiles
324 + *
325 + * @var string
326 + */
327 + public $markurl;
328 +
329 + // --------------------------------------------------------------------------------
330 + // Classes
331 +
332 + /**
333 + * Taxonomies object
334 + *
335 + * @var \EventPost\Taxonomies
336 + */
337 + public $Taxonomies;
338 +
339 + /**
340 + * Icons object
341 + *
342 + * @var \EventPost\Icons
343 + */
344 + public $DashIcons;
345 +
346 + /**
347 + * Settings object
348 + *
349 + * @var \EventPost\Settings
350 + */
351 + public $Settings;
352 +
353 + /**
354 + * Shortcodes object
355 + *
356 + * @var \EventPost\Shortcodes
357 + */
358 + public $Shortcodes;
359 +
360 + /**
361 + * Allowed tags in main outputs
362 + *
363 + * @var array
364 + */
365 + public $kses_tags;
366 +
367 +
80 368 public function __construct() {
81 369 add_action('init', array(&$this,'init'), 1);
82 - add_action('widgets_init', array(&$this,'widgets_init'), 1);
370 + add_action('init', array(&$this,'widgets_init'), 10);
371 + add_action('init', array(&$this, 'register_widgets'), 30, 1);
372 +
83 373 add_action('save_post', array(&$this, 'save_postdata'));
84 374 add_filter('dashboard_glance_items', array(&$this, 'dashboard_right_now'));
85 375
86 376 // Scripts
@@ -86,8 +376,10 @@
86 376 // Scripts
87 377 add_action( 'admin_init', array(&$this, 'editor_styles'));
88 378 add_action('admin_enqueue_scripts', array(&$this, 'admin_head'));
89 379 add_action('admin_print_scripts', array(&$this, 'admin_scripts'));
380 + add_action('admin_print_scripts', array(&$this, 'load_scripts'), 1);
381 + add_action('wp_enqueue_scripts', array(&$this, 'load_scripts'), 1);
90 382 add_action('wp_enqueue_scripts', array(&$this, 'load_styles'));
91 383
92 384 // Single
93 385 add_filter('the_content', array(&$this, 'display_single'), 9999);
@@ -115,40 +407,37 @@
115 407 add_action('wp_ajax_nopriv_EventPostExport', array(&$this, 'export'));
116 408 add_action('wp_ajax_EventPostFeed', array(&$this, 'feed'));
117 409 add_action('wp_ajax_nopriv_EventPostFeed', array(&$this, 'feed'));
118 410
119 - //
411 + // Internal filters
120 412 add_filter('eventpost_list_shema',array(&$this, 'custom_shema'),10,1);
121 413
122 -
123 - add_action('widgets_init', array(&$this, 'register_widgets'),1,1);
124 -
125 414 // Quick edit
126 415 add_action( 'bulk_edit_custom_box', array( &$this, 'bulk_edit' ), 10, 2 );
127 416 add_action( 'quick_edit_custom_box', array( &$this, 'quick_edit' ), 10, 2 );
128 417 add_action( 'admin_print_scripts-edit.php', array(&$this, 'scripts_edit') );
129 418 add_action( 'wp_ajax_inline-save', array(&$this, 'inline_save'), 1 );
130 - add_action( 'wp_ajax_eventpost_save_bulk', array(&$this, 'save_bulkdatas') );
419 + add_action( 'bulk_edit_posts', array(&$this, 'save_bulkdatas'), 10, 2 );
131 420 add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_color'), 10, 3);
132 421 add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_icon'), 10, 3);
133 422
134 423 $inc_path = plugin_dir_path(__FILE__).'inc/';
135 424 $this->plugin_path = plugin_dir_path(__FILE__);
136 - include_once ($inc_path . 'settings.php');
425 + include_once ($inc_path . 'class-settings.php');
137 426 include_once ($inc_path . 'wrappers.php');
138 - include_once ($inc_path . 'widget.php');
139 - include_once ($inc_path . 'widget.cal.php');
140 - include_once ($inc_path . 'widget.map.php');
141 - include_once ($inc_path . 'multisite.php');
142 - include_once ($inc_path . 'shortcodes.php');
427 + include_once ($inc_path . 'deprecated/widget.php');
428 + include_once ($inc_path . 'deprecated/widget.cal.php');
429 + include_once ($inc_path . 'deprecated/widget.map.php');
430 + include_once ($inc_path . 'class-multisite.php');
431 + include_once ($inc_path . 'class-shortcodes.php');
143 432 include_once ($inc_path . 'openweathermap.php');
144 - include_once ($inc_path . 'children.php');
145 - include_once ($inc_path . 'icons.php');
146 - include_once ($inc_path . 'taxonomies.php');
433 + include_once ($inc_path . 'class-children.php');
434 + include_once ($inc_path . 'class-icons.php');
435 + include_once ($inc_path . 'class-taxonomies.php');
147 436
148 - $this->DashIcons = new EventPost\DashIcons();
437 + $this->DashIcons = new EventPost\Icons();
149 438 $this->Settings = new EventPost\Settings($this->DashIcons);
150 - $this->Categories = new EventPost\Categories($this->DashIcons);
439 + $this->Taxonomies = new EventPost\Taxonomies($this->DashIcons);
151 440 }
152 441
153 442 /**
154 443 * PHP4 constructor
@@ -157,34 +446,15 @@
157 446 $this->__construct();
158 447 }
159 448
160 449 public function init(){
161 - add_rewrite_rule('event-feed/?', admin_url('admin-ajax.php?action=EventPostFeed'), 'top');
162 - add_rewrite_rule('eventpost/([0-9]*)\.(ics|vcs)?', plugins_url('export/ics.php', __FILE__), 'top');
163 - }
164 -
165 - /**
166 - * Init all variables when WP is ready
167 - *
168 - * @action evenpost_init
169 - * @filter eventpost_default_list_shema
170 - * @filter eventpost_list_shema
171 - */
172 - public function widgets_init(){
173 - $this->META_START = 'event_begin';
174 - $this->META_END = 'event_end';
175 - $this->META_COLOR = 'event_color';
176 - $this->META_ICON = 'event_icon';
177 - // http://codex.wordpress.org/Geodata
178 - $this->META_ADD = 'geo_address';
179 - $this->META_LAT = 'geo_latitude';
180 - $this->META_LONG = 'geo_longitude';
181 - // https://schema.org/eventStatus
182 - $this->META_STATUS = 'event_status';
183 - // https://schema.org/location
184 - $this->META_VIRTUAL_LOCATION = 'event_virtual_location';
185 - // https://pending.schema.org/eventAttendanceMode
186 - $this->META_ATTENDANCE_MODE = 'event_attendance_mode';
450 + $admin_url = admin_url('admin-ajax.php?action=EventPostFeed');
451 + $admin_url = str_replace(site_url(), '', $admin_url);
452 + $plugins_url = plugins_url('export/ics.php', __FILE__);
453 + $plugins_url = str_replace(site_url(), '', $plugins_url);
454 + add_rewrite_rule('event-feed/?', $admin_url , 'top');
455 + add_rewrite_rule('eventpost/([0-9]*)\.(ics|vcs)?',$plugins_url, 'top');
456 +
187 457 $this->list_id = 0;
188 458 $this->NomDuMois = array('', __('Jan', 'event-post'), __('Feb', 'event-post'), __('Mar', 'event-post'), __('Apr', 'event-post'), __('May', 'event-post'), __('Jun', 'event-post'), __('Jul', 'event-post'), __('Aug', 'event-post'), __('Sept', 'event-post'), __('Oct', 'event-post'), __('Nov', 'event-post'), __('Dec', 'event-post'));
189 459 $this->Week = array(__('Sunday', 'event-post'), __('Monday', 'event-post'), __('Tuesday', 'event-post'), __('Wednesday', 'event-post'), __('Thursday', 'event-post'), __('Friday', 'event-post'), __('Saturday', 'event-post'));
190 460 $this->attendance_modes = array(
@@ -192,30 +462,21 @@
192 462 'MixedEventAttendanceMode' => _x('Mixed', 'Attendance Mode', 'event-post'),
193 463 'OnlineEventAttendanceMode' => _x('Online', 'Attendance Mode', 'event-post'),
194 464 );
195 465 $this->statuses = array(
196 - 'EventScheduled' =>_x('Scheduled', 'Event Status', 'event-post'),
197 - 'EventCancelled'=>_x('Cancelled', 'Event Status', 'event-post'),
198 - 'EventMovedOnline'=>_x('Moved Online', 'Event Status', 'event-post'),
199 - 'EventPostponed'=>_x('Postoned', 'Event Status', 'event-post'),
200 - 'EventRescheduled'=>_x('Rescheduled', 'Event Status', 'event-post'),
466 + 'EventScheduled' => _x('Scheduled', 'Event Status', 'event-post'),
467 + 'EventCancelled' => _x('Cancelled', 'Event Status', 'event-post'),
468 + 'EventMovedOnline' => _x('Moved Online', 'Event Status', 'event-post'),
469 + 'EventPostponed' => _x('Postoned', 'Event Status', 'event-post'),
470 + 'EventRescheduled' => _x('Rescheduled', 'Event Status', 'event-post'),
471 + 'EventCompleted' => _x('Completed', 'Event Status', 'event-post'),
201 472 );
202 -
473 +
203 474 $this->maps = $this->get_maps();
204 475 $this->settings = $this->get_settings();
205 -
476 +
206 477 do_action('evenpost_init', $this);
207 478
208 - $this->Shortcodes = new EventPost_Shortcodes();
209 -
210 - if(function_exists('register_block_type')){
211 - $block_path = plugin_dir_path(__FILE__).'inc/blocks/';
212 - include_once ($block_path . 'eventslist.php');
213 - include_once ($block_path . 'eventstimeline.php');
214 - include_once ($block_path . 'eventsmap.php');
215 - include_once ($block_path . 'eventscalendar.php');
216 - }
217 -
218 479 // Edit
219 480 add_action('add_meta_boxes', array(&$this, 'add_custom_box'));
220 481 foreach($this->settings['posttypes'] as $posttype){
221 482 add_filter('manage_'.$posttype.'_posts_columns', array(&$this, 'columns_head'), 2);
@@ -220,9 +481,9 @@
220 481 foreach($this->settings['posttypes'] as $posttype){
221 482 add_filter('manage_'.$posttype.'_posts_columns', array(&$this, 'columns_head'), 2);
222 483 add_action('manage_'.$posttype.'_posts_custom_column', array(&$this, 'columns_content'), 10, 2);
223 484 }
224 - $this->Categories->add_fields_to_taxonomies($this->settings['posttypes']);
485 + $this->Taxonomies->add_fields_to_taxonomies($this->settings['posttypes']);
225 486
226 487 $this->markpath = '';
227 488 $this->markurl = '';
228 489 if (!empty($this->settings['markpath']) && !empty($this->settings['markurl'])) {
@@ -232,8 +493,10 @@
232 493 // $this->markpath = plugin_dir_path(__FILE__) . 'markers/';
233 494 // $this->markurl = plugins_url('/markers/', __FILE__);
234 495 }
235 496
497 + $this->currencies = include (plugin_dir_path(__FILE__) . 'inc/data/currencies.php');
498 +
236 499 $this->dateformat = str_replace(array('yy', 'mm', 'dd'), array('Y', 'm', 'd'), __('yy-mm-dd', 'event-post'));
237 500
238 501 $this->default_list_shema = apply_filters('eventpost_default_list_shema', array(
239 502 'container' => '<%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>'.
@@ -242,10 +505,11 @@
242 505 '</%type%><!-- .event_loop -->',
243 506 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">'.
244 507 '<a href="%event_link%">'.
245 508 '%event_thumbnail%'.
246 - '<h5>%event_title%</h5>'.
509 + '<h5>%event_title% </h5>'.
247 510 '</a>'.
511 + '%event_price%'.
248 512 '%event_date%'.
249 513 '%event_cat%'.
250 514 '%event_location%'.
251 515 '%event_excerpt%'.
@@ -271,8 +535,9 @@
271 535 <a href="%event_link%">
272 536 %event_thumbnail%
273 537 <h5>%event_title%</h5>
274 538 </a>
539 + %event_price%
275 540 </%child%><!-- .event_item -->'
276 541 ));
277 542 $this->timeline_shema = apply_filters('eventpost_timeline_shema',$this->default_timeline_shema);
278 543
@@ -309,10 +574,42 @@
309 574 ),
310 575 )
311 576 );
312 577
578 + $this->kses_tags = apply_filters('eventpost_kses_tags', json_decode(
579 + file_get_contents(plugin_dir_path(__FILE__).'inc/data/kses-tags.json'),
580 + true
581 + ));
582 +
583 +
313 584 }
314 585
586 + /**
587 + * Init all variables when WP is ready
588 + *
589 + * @action evenpost_init
590 + * @filter eventpost_default_list_shema
591 + * @filter eventpost_list_shema
592 + */
593 + public function widgets_init(){
594 + $this->Shortcodes = new EventPost\Shortcodes();
595 +
596 + if(function_exists('register_block_type')){
597 + $block_path = plugin_dir_path(__FILE__).'inc/blocks/';
598 + include_once ($block_path . 'eventslist.php');
599 + include_once ($block_path . 'eventstimeline.php');
600 + include_once ($block_path . 'eventsmap.php');
601 + include_once ($block_path . 'eventscalendar.php');
602 + include_once ($block_path . 'eventdetails.php');
603 + }
604 +
605 +
606 + // WooCommerce
607 + if (class_exists('WooCommerce') && in_array('product', $this->settings['posttypes'])) {
608 + include_once (plugin_dir_path(__FILE__).'inc/woocommerce.php');
609 + }
610 + }
611 +
315 612 public function register_widgets(){
316 613 register_widget('EventPost_List');
317 614 register_widget('EventPost_Map');
318 615 register_widget('EventPost_Cal');
@@ -319,24 +616,32 @@
319 616 }
320 617
321 618 /**
322 619 * Usefull hexadecimal to decimal converter. Returns an array of RGB from a given hexadecimal color.
620 + *
323 621 * @param string $color
622 + *
324 623 * @return array $color($R, $G, $B)
325 624 */
326 625 public function hex2dec($color = '000000') {
327 626 $tbl_color = array();
328 - if (!strstr('#', $color)){
627 + if(!is_string($color) || empty($color)){
628 + $color = '000000';
629 + }
630 + if (substr($color, 0, 1)!='#'){
329 631 $color = '#' . $color;
330 - }
632 + }
331 633 $tbl_color['R'] = hexdec(substr($color, 1, 2));
332 634 $tbl_color['G'] = hexdec(substr($color, 3, 2));
333 635 $tbl_color['B'] = hexdec(substr($color, 5, 2));
334 636 return $tbl_color;
335 637 }
638 +
336 639 /**
337 640 * Fetch all registered image sizes
641 + *
338 642 * @global array $_wp_additional_image_sizes
643 + *
339 644 * @return array
340 645 */
341 646 function get_thumbnail_sizes(){
342 647 global $_wp_additional_image_sizes;
@@ -349,12 +654,13 @@
349 654
350 655 /**
351 656 * Get blog settings, load and saves default settings if needed. Can be filterred using
352 657 *
353 - * `<?php add_filter('eventpost_getsettings', 'some_function'); ?>`
658 + * @example `<?php add_filter('eventpost_getsettings', 'some_function'); ?>`
354 659 *
355 660 * @action eventpost_getsettings_action
356 661 * @filter eventpost_getsettings
662 + *
357 663 * @return array
358 664 */
359 665 public function get_settings() {
360 666 $ep_settings = $this->Settings->get_settings();
@@ -362,9 +668,11 @@
362 668 }
363 669
364 670 /**
365 671 * Checks if HTML schemas are not empty
672 + *
366 673 * @param array $shema
674 + *
367 675 * @return array
368 676 */
369 677 public function custom_shema($shema){
370 678 if(!empty($this->settings['container_shema'])){
@@ -397,8 +705,9 @@
397 705 * ?>
398 706 * ```
399 707 *
400 708 * @filter eventpost_maps
709 + *
401 710 * @return array of map arrays ['name', 'id', 'urls']
402 711 */
403 712 public function get_maps() {
404 713 $maps = array();
@@ -414,9 +723,10 @@
414 723 return $maps;
415 724 }
416 725
417 726 /**
418 - *
727 + * Get colors
728 + *
419 729 * @return array
420 730 */
421 731 public function get_colors() {
422 732 $colors = array();
@@ -431,10 +741,15 @@
431 741 return $colors;
432 742 }
433 743
434 744 /**
435 - *
436 - * @return color
745 + * Get color of a post
746 + *
747 + * @param int $post_id
748 + * @param bool $default
749 + * @param bool $check_taxo
750 + *
751 + * @return string color
437 752 */
438 753 public function get_post_color($post_id, $default = false, $check_taxo = false) {
439 754 $color = get_post_meta($post_id, $this->META_COLOR,true);
440 755 if($color && !empty($color)){
@@ -441,9 +756,9 @@
441 756 return event_post_format_color($color);
442 757 }else{
443 758 if($check_taxo){
444 759 foreach(event_post_get_all_terms($post_id) as $term){
445 - $taxo_color = $this->Categories->get_taxonomy_color($term->term_id);
760 + $taxo_color = $this->Taxonomies->get_taxonomy_color($term->term_id);
446 761 if($taxo_color){
447 762 return event_post_format_color($taxo_color);
448 763 }
449 764 }
@@ -452,10 +767,15 @@
452 767 return event_post_format_color($default);
453 768 }
454 769
455 770 /**
456 - *
457 - * @return class
771 + * Get icon of a post
772 + *
773 + * @param int $post_id
774 + * @param bool $default
775 + * @param bool $check_taxo
776 + *
777 + * @return string|false icon
458 778 */
459 779 public function get_post_icon($post_id, $default = false, $check_taxo = false) {
460 780 $icon = get_post_meta($post_id, $this->META_ICON,true);
461 781 if($icon && !empty($icon)){
@@ -462,9 +782,9 @@
462 782 return $icon;
463 783 }else{
464 784 if($check_taxo){
465 785 foreach(event_post_get_all_terms($post_id) as $term){
466 - $taxo_icon = $this->Categories->get_taxonomy_icon($term->term_id);
786 + $taxo_icon = $this->Taxonomies->get_taxonomy_icon($term->term_id);
467 787 if($taxo_icon){
468 788 return event_post_format_color($taxo_icon);
469 789 }
470 790 }
@@ -473,10 +793,12 @@
473 793 return $default;
474 794 }
475 795
476 796 /**
477 - *
797 + * Get the URL of a marker
798 + *
478 799 * @param string $color
800 + *
479 801 * @return sring
480 802 */
481 803 public function get_marker($color) {
482 804 if (is_file($this->markpath . $color . '.png')) {
@@ -487,9 +809,9 @@
487 809
488 810 /**
489 811 * Enqueue CSS files
490 812 */
491 - public function load_styles() {
813 + public function load_styles($deps = null) {
492 814 //CSS
493 815 if(!empty($this->settings['customcss'])){
494 816 wp_enqueue_style('event-post-custom', $this->settings['customcss']);
495 817 }
@@ -496,30 +818,28 @@
496 818 elseif(is_file(get_stylesheet_directory().'/event-post.css') || is_file(get_template_directory().'/event-post.css')){
497 819 wp_enqueue_style('event-post-custom', get_theme_file_uri('event-post.css'));
498 820 }
499 821 else{
500 - wp_register_style('event-post', plugins_url('/css/event-post.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/event-post.css" ));
822 + wp_register_style('event-post', plugins_url('/build/front/front.css', __FILE__), $deps, filemtime( "{$this->plugin_path}/build/front/front.css" ));
501 823 wp_enqueue_style('event-post');
502 824 }
503 825
504 826 // Lib scripts
505 - wp_enqueue_style('openlayers', plugins_url('/css/ol.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/ol.css" ));
506 827 wp_enqueue_style('dashicons', includes_url('/css/dashicons.min.css'));
507 828 }
829 +
508 830 /**
509 831 * Enqueue Editor style
510 832 */
511 833 public function editor_styles() {
512 - add_editor_style( plugins_url('/css/event-post.css', __FILE__) );
834 + add_editor_style( plugins_url('/build/front/front.css', __FILE__) );
513 835 }
514 836
515 837 /**
516 838 * Enqueue JS files
517 839 */
518 - public function load_scripts($deps = array('jquery')) {
519 - // JS
520 - wp_enqueue_script('jquery', false, false, false, true);
521 - wp_enqueue_script('event-post', plugins_url('/js/event-post.min.js', __FILE__), $deps, filemtime( "{$this->plugin_path}/js/event-post.min.js" ), true);
840 + public function load_scripts() {
841 + wp_enqueue_script('event-post', plugins_url('/build/front/front.js', __FILE__), array(), filemtime( "{$this->plugin_path}/build/front/front.js" ), true);
522 842 $maps = $this->maps;
523 843 foreach($maps as $m=>$map){
524 844 if(isset($map['api_param']) && $this->settings['tile_api_key']){
525 845 foreach($map['urls'] as $i=>$url){
@@ -526,9 +846,12 @@
526 846 $maps[$m]['urls'][$i] = add_query_arg($map['api_param'], $this->settings['tile_api_key'], $url);
527 847 }
528 848 }
529 849 }
530 - wp_localize_script('event-post', 'eventpost_params', array(
850 + wp_add_inline_script('event-post', 'var EventPost = EventPost || {}; EventPost.front='.wp_json_encode(array(
851 + 'scripts' => array(
852 + 'map' => plugins_url('/build/map/event-map.js', __FILE__)
853 + ),
531 854 'imgpath' => plugins_url('/img/', __FILE__),
532 855 'maptiles' => $maps,
533 856 'defaulttile' => $this->settings['tile'],
534 857 'zoom' => $this->settings['zoom'],
@@ -533,19 +856,18 @@
533 856 'defaulttile' => $this->settings['tile'],
534 857 'zoom' => $this->settings['zoom'],
535 858 'ajaxurl' => admin_url() . 'admin-ajax.php',
536 859 'map_interactions'=>$this->map_interactions,
537 - ));
860 + )), 'before');
538 861 }
539 862 /**
540 863 * Enqueue JS files for maps
541 864 */
542 865 public function load_map_scripts() {
866 + $this->load_styles(array('event-post-map'));
543 867 // JS
544 - wp_enqueue_script('openlayers', plugins_url('/js/ol.js', __FILE__), false, filemtime( "{$this->plugin_path}/js/ol.js" ), true);
545 - $this->load_scripts(array('jquery', 'openlayers'));
546 868 if(is_admin()){
547 - $this->admin_scripts(array('jquery', 'openlayers'));
869 + $this->admin_scripts(array('jquery', 'event-post-map'));
548 870 }
549 871 }
550 872
551 873 /**
@@ -555,11 +877,9 @@
555 877 $page = basename($_SERVER['SCRIPT_NAME']);
556 878 if( $page!='post-new.php' && $page!='edit-tags.php' && !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') && !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings') ){
557 879 return;
558 880 }
559 - wp_enqueue_style('openlayers', plugins_url('/css/ol.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/ol.css" ));
560 - wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/jquery-ui.css" ));
561 - wp_enqueue_style('event-post-admin', plugins_url('/css/event-post-admin.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/event-post-admin.css" ));
881 + wp_enqueue_style('event-post-admin', plugins_url('/build/admin/admin.css', __FILE__), false, filemtime( "{$this->plugin_path}/build/admin/admin.css" ));
562 882 }
563 883
564 884 /**
565 885 * Enqueue JS files in admin
@@ -578,9 +898,9 @@
578 898 wp_enqueue_script('jquery');
579 899 wp_enqueue_script('jquery-effects-core');
580 900 wp_enqueue_script('jquery-effects-shake');
581 901 wp_enqueue_style( 'wp-color-picker');
582 - wp_enqueue_script( 'wp-color-picker');
902 + wp_enqueue_script( 'wp-color-picker');
583 903 if(!is_array($deps)){
584 904 $deps = array('jquery','wp-color-picker');
585 905 }
586 906 if($this->settings['datepicker']=='simple' || !is_admin() || (isset($_GET['page']) && $_GET['page']=='event-settings')){
@@ -586,17 +906,17 @@
586 906 if($this->settings['datepicker']=='simple' || !is_admin() || (isset($_GET['page']) && $_GET['page']=='event-settings')){
587 907 wp_enqueue_script('jquery-ui-datepicker');
588 908 $deps[] = 'jquery-ui-datepicker';
589 909 }
590 - wp_enqueue_script('event-post-admin', plugins_url('/js/event-post-admin.min.js', __FILE__), $deps, filemtime( "{$this->plugin_path}/js/event-post-admin.min.js" ), true);
910 + wp_enqueue_script('event-post-admin', plugins_url('/build/admin/admin.js', __FILE__), $deps, filemtime( "{$this->plugin_path}/build/admin/admin.js" ), true);
591 911 $language = get_bloginfo('language');
592 912 if (strpos($language, '-') > -1) {
593 913 $language = strtolower(substr($language, 0, 2));
594 914 }
595 - wp_localize_script('event-post-admin', 'eventpost', array(
915 + wp_add_inline_script('event-post-admin', 'var EventPost = EventPost || {}; EventPost.admin='.wp_json_encode(array(
596 916 'ajaxurl' => admin_url('admin-ajax.php'),
597 917 'imgpath' => plugins_url('/img/', __FILE__),
598 - 'date_choose' => '<span class="screen-reader-text">'.__('Choose', 'event-post').'</span><i class="dashicons dashicons-calendar-alt"></i>',
918 + 'date_choose' => __('Choose', 'event-post'),
599 919 'date_format' => __('yy-mm-dd', 'event-post'),
600 920 'more_icons' => __('More icons', 'event-post'),
601 921 'pick_a_date'=>__('Pick a date','event-post'),
602 922 'use_current_location'=>__('Use my current location','event-post'),
@@ -602,10 +922,13 @@
602 922 'use_current_location'=>__('Use my current location','event-post'),
603 923 'start_drag'=>__('Click to<br>drag the map<br>and change location','event-post'),
604 924 'empty_address'=>__('Be kind to fill a non empty address:)', 'event-post'),
605 925 'search'=>__('Type an address', 'event-post'),
926 + 'search_button'=>__('Search', 'event-post'),
927 + 'geocoding_attribution'=>__('Geocoding by <a href="https://nominatim.openstreetmap.org/" target="_blank">OpenStreetmap Nominatim</a>', 'event-post'),
606 928 'stop_drag'=>_x('Done','Stop allowing to drag the map', 'event-post'),
607 929 'datepickeri18n'=>array(
930 + // Translators: %1$s is the month name, %2$s is the day number, %3$s is the year, %4$s is the hour, %5$s is the minute
608 931 'order'=>__( '%1$s %2$s, %3$s @ %4$s:%5$s', 'event-post'),
609 932 'day'=>__('Day', 'event-post'),
610 933 'month'=>__('Month', 'event-post'),
611 934 'year'=>__('Day', 'event-post'),
@@ -628,24 +951,24 @@
628 951 'maptiles' => $this->maps,
629 952 'defaulttile' => $this->settings['tile'],
630 953 'palette' => $this->get_theme_palette("hex"),
631 954 'available_images' => $this->get_colors(),
632 - ));
955 + )));
633 956 }
634 957 function scripts_edit() {
635 958 // load only when editing a supported post type
636 959 $current_post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
637 960 if ( in_array( $current_post_type, $this->settings['posttypes'] ) ) {
638 - wp_enqueue_script( 'eventpost-inline-edit', plugins_url( 'js/inline-edit.min.js', __FILE__ ), array( 'jquery', 'inline-edit-post' ), '', true );
639 - wp_localize_script('eventpost-inline-edit', 'eventpost_inline_edit', array(
961 + wp_enqueue_script( 'eventpost-inline-edit', plugins_url( 'build/admin/inline-edit.js', __FILE__ ), array( 'jquery', 'inline-edit-post' ), '', true );
962 + wp_add_inline_script('eventpost-inline-edit', 'var EventPost = EventPost || {}; EventPost.inlineEdit='.wp_json_encode(array(
640 963 'quick'=>$this->quick_edit_fields,
641 964 'bulk'=>$this->bulk_edit_fields,
642 - ));
965 + )));
643 966 }
644 967 }
645 968
646 969 function get_rich_result($event){
647 - /**
970 + /*
648 971 * https://search.google.com/test/rich-results
649 972 {
650 973 "@context": "https://schema.org",
651 974 "@type": "Event",
@@ -697,9 +1020,9 @@
697 1020 $absmin = abs($min);
698 1021 $gmt_offset = sprintf("%s%02d:%02d", $sign, $absmin/60, $absmin%60);
699 1022 $time_format = (is_numeric($event->time_start) && is_numeric($event->time_end) && date('H:i', $event->time_start) != date('H:i', $event->time_end) && date('H:i', $event->time_start) != '00:00' && date('H:i', $event->time_end) != '00:00') ? 'Y-m-d\Th:i:00'.$gmt_offset : 'Y-m-d';
700 1023
701 - return apply_filters('event-post-rich-result', array(
1024 + $rich_data = array(
702 1025 '@context'=>'https://schema.org',
703 1026 '@type'=>'event',
704 1027 'name'=>$event->post_title,
705 1028 'datePublished'=>str_replace(' ', 'T', $event->post_date_gmt).$gmt_offset,
@@ -714,18 +1037,44 @@
714 1037 get_the_post_thumbnail_url($event->ID, 'medium'),
715 1038 get_the_post_thumbnail_url($event->ID, 'large'),
716 1039 get_the_post_thumbnail_url($event->ID, 'full'),
717 1040 ) : null,
718 - 'description'=>$event->post_excerpt,
719 - ), $event);
1041 + 'description'=>$event->description,
1042 + );
1043 + if(!empty($event->organization)){
1044 + $rich_data['organizer'] = array(
1045 + '@type'=>'Organization',
1046 + 'name'=>$event->organization,
1047 + );
1048 + }
1049 + if(!empty($event->offer)){
1050 + $rich_data['offers'] = array(
1051 + '@type'=>'Offer',
1052 + // 'availability'=>$event->availability,
1053 + // 'validFrom'=>date($time_format, $event->time_start),
1054 + );
1055 + if(!empty($event->offer['url'])){
1056 + $rich_data['offers']['url'] = $event->offer['url'];
1057 + }
1058 + if(!empty($event->offer['price'])){
1059 + $rich_data['offers']['price'] = $event->offer['price'];
1060 + }
1061 + if(!empty($event->offer['currency'])){
1062 + $rich_data['offers']['priceCurrency'] = $event->offer['currency'];
1063 + }
1064 + }
1065 +
1066 + return apply_filters('event-post-rich-result', $rich_data, $event);
720 1067 }
721 1068
722 1069 function wpseo_schema_webpage($rich_result){
723 1070 $event = $this->retreive();
724 - if ($event->time_start != '' && $event->time_end != '') {
725 - $rich_result = array_merge($rich_result, $this->get_rich_result($event));
1071 + if ($event != false){
1072 + if ($event->time_start != '' && $event->time_end != '') {
1073 + $rich_result = array_merge($rich_result, $this->get_rich_result($event));
1074 + }
1075 + $this->is_schema_output = true;
726 1076 }
727 - $this->is_schema_output = true;
728 1077 return $rich_result;
729 1078 }
730 1079
731 1080 function get_theme_palette($return = "hex"){
@@ -753,47 +1102,51 @@
753 1102 if (is_single()) {
754 1103 $twitter_label_id=0;
755 1104 $event = $this->retreive();
756 1105 $has_location = $has_time = false;
757 - if ($event->address != '' || ($event->lat != '' && $event->long != '')) {
758 - $twitter_label_id++;
759 - $has_location = true;
760 - ?>
761 -<meta name="geo.placename" content="<?php echo esc_attr($event->address) ?>" />
762 -<meta name="geo.position" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
763 -<meta name="ICBM" content="<?php echo $event->lat ?>;<?php echo esc_attr($event->long) ?>" />
764 -<meta property="place:location:latitude" content="<?php echo esc_attr($event->lat) ?>" />
765 -<meta property="place:location:longitude" content="<?php echo esc_attr($event->long) ?>" />
766 -<meta name="twitter:label<?php echo $twitter_label_id; ?>" content="<?php _e('Location', 'event-post'); ?>"/>
767 -<meta name="twitter:data<?php echo $twitter_label_id; ?>" content="<?php echo esc_attr($event->address) ?>"/>
1106 + if ($event != false) {
1107 + if ($event->address != '' || ($event->lat != '' && $event->long != '')) {
1108 + $twitter_label_id++;
1109 + $has_location = true;
1110 + ?>
1111 +<meta name="geo.placename" content="<?php echo esc_attr($event->address) ?>" />
1112 +<meta name="geo.position" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
1113 +<meta name="ICBM" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
1114 +<meta property="place:location:latitude" content="<?php echo esc_attr($event->lat) ?>" />
1115 +<meta property="place:location:longitude" content="<?php echo esc_attr($event->long) ?>" />
1116 +<meta name="twitter:label<?php echo esc_attr($twitter_label_id); ?>" content="<?php esc_attr_e('Location', 'event-post'); ?>"/>
1117 +<meta name="twitter:data<?php echo esc_attr($twitter_label_id); ?>" content="<?php echo esc_attr($event->address) ?>"/>
768 1118 <?php
769 - }
770 - if ($event->start != '' && $event->end != '') {
771 - $has_time = true;
772 - $twitter_label_id++;
773 - ?>
774 -<meta name="datetime-coverage-start" content="<?php echo date('c', $event->time_start) ?>" />
775 -<meta name="datetime-coverage-end" content="<?php echo date('c', $event->time_end) ?>" />
776 -<meta name="twitter:label<?php echo $twitter_label_id; ?>" content="<?php _e('Date', 'event-post'); ?>"/>
777 -<meta name="twitter:data<?php echo $twitter_label_id; ?>" content="<?php echo esc_attr($this->human_date($event->time_start)) ?>"/>
1119 + }
1120 + if ($event->start != '' && $event->end != '') {
1121 + $has_time = true;
1122 + $twitter_label_id++;
1123 + ?>
1124 +<meta name="datetime-coverage-start" content="<?php echo esc_attr(date('c', $event->time_start)) ?>" />
1125 +<meta name="datetime-coverage-end" content="<?php echo esc_attr(date('c', $event->time_end)) ?>" />
1126 +<meta name="twitter:label<?php echo esc_attr($twitter_label_id); ?>" content="<?php echo esc_attr('Date', 'event-post'); ?>"/>
1127 +<meta name="twitter:data<?php echo esc_attr($twitter_label_id); ?>" content="<?php echo esc_attr($this->human_date($event->time_start)) ?>"/>
778 1128 <?php
1129 + }
1130 + if(($has_location || $has_time) && !$this->is_schema_output){
1131 + $rich_result = $this->get_rich_result($event);
1132 + $this->is_schema_output = true;
1133 + ?>
1134 + <script type="application/ld+json"><?php echo \wp_json_encode($rich_result); ?></script>
1135 + <?php
1136 + }
779 1137 }
780 - if(($has_location || $has_time) && !$this->is_schema_output){
781 - $rich_result = $this->get_rich_result($event);
782 - $this->is_schema_output = true;
783 - ?>
784 - <script type="application/ld+json"><?php echo json_encode($rich_result); ?></script>
785 - <?php
786 - }
787 -
788 1138 }
789 1139 }
790 1140
791 1141 /**
792 - *
1142 + * Cleanups a date
1143 + *
793 1144 * @param type $str
1145 + *
1146 + * @since 5.0.1
1147 + *
794 1148 * @return string
795 - * @since 5.0.1
796 1149 */
797 1150 public function date_cleanup($str){
798 1151 return trim(str_replace(array('0', ' ', ':', '-'), '', $str));
799 1152 }
@@ -798,10 +1151,12 @@
798 1151 return trim(str_replace(array('0', ' ', ':', '-'), '', $str));
799 1152 }
800 1153
801 1154 /**
802 - *
1155 + * Checks if a date is valid or not
1156 + *
803 1157 * @param string $str
1158 + *
804 1159 * @return boolean
805 1160 */
806 1161 public function dateisvalid($str) {
807 1162 return is_string($str) && $this->date_cleanup($str) != '';
@@ -807,11 +1162,13 @@
807 1162 return is_string($str) && $this->date_cleanup($str) != '';
808 1163 }
809 1164
810 1165 /**
811 - *
1166 + * Parse a date from a string
1167 + *
812 1168 * @param string $date
813 1169 * @param string $sep
1170 + *
814 1171 * @return string
815 1172 */
816 1173 public function parsedate($date, $sep = '') {
817 1174 if (!empty($date)) {
@@ -821,11 +1178,27 @@
821 1178 }
822 1179 }
823 1180
824 1181 /**
825 - *
1182 + * Sanitize a coordinate string
1183 + * Only keeps, numbers, dots and commas
1184 + *
1185 + * @param string $str
1186 + *
1187 + * @since 5.9.9
1188 + *
1189 + * @return string
1190 + */
1191 + public function sanitize_coordinate($str){
1192 + return preg_replace('/[^0-9\.,-]/', '', $str);
1193 + }
1194 +
1195 + /**
1196 + * Format a date for humans
1197 + *
826 1198 * @param mixed $date
827 1199 * @param string $format
1200 + *
828 1201 * @return type
829 1202 */
830 1203 public function human_date($date, $format = 'l j F Y') {
831 1204 if($this->settings['dateforhumans']){
@@ -840,11 +1213,13 @@
840 1213 return date_i18n($format, $date);
841 1214 }
842 1215
843 1216 /**
844 - *
1217 + * Returns a range of dates
1218 + *
845 1219 * @param timestamp $time_start
846 1220 * @param timestamp $time_end
1221 + *
847 1222 * @return string
848 1223 */
849 1224 public function delta_date($time_start, $time_end){
850 1225 if(!$time_start || !$time_end){
@@ -850,11 +1225,15 @@
850 1225 if(!$time_start || !$time_end){
851 1226 return;
852 1227 }
853 1228
1229 + // Translators: %1$s, %4$s are opening tags, %2$s and %5$s are closing tag, %3$s is the first date, %6$s is the second date
854 1230 $from_to_days = _x('%1$sfrom%2$s %3$s %4$sto%5$s %6$s', 'Days', 'event-post');
1231 + // Translators: %1$s is the first date, %4$s is the second date, %2$s is an opening tag, %3$s is a closing tag
855 1232 $single_day_at = _x('%1$s%2$s,%3$s %4$s', 'From/To single day at time', 'event-post');
1233 + // Translators: %1$s, %4$s are opening tags, %2$s and %5$s are closing tag, %3$s is the first hour, %6$s is the second hour
856 1234 $from_to_hours = _x('%1$sfrom%2$s %3$s %4$sto%5$s %6$s', 'Hours', 'event-post');
1235 + // Translators: %1$s is an opening tag, %2$s is a closing tag, %3$s is the time
857 1236 $at_time = _x('%1$sat%2$s %3$s', 'Time', 'event-post');
858 1237
859 1238 //Display dates
860 1239 $dates="\t\t\t\t".'<div class="event_date" data-start="' . $this->human_date($time_start) . '" data-end="' . $this->human_date($time_end) . '">';
@@ -909,89 +1288,93 @@
909 1288 return $dates;
910 1289 }
911 1290
912 1291 /**
913 - *
1292 + * Displays a date
1293 + *
914 1294 * @param WP_Post object $post
915 1295 * @param mixed $links
1296 + *
916 1297 * @return string
917 1298 */
918 1299 public function print_date($post = null, $links = 'deprecated', $context='') {
919 1300 $dates = '';
920 1301 $event = $this->retreive($post);
921 - if ($event->start != '' && $event->end != '') {
1302 + if ($event != false){
1303 + if ($event->start != '' && $event->end != '') {
922 1304
923 - $dates.=$this->delta_date($event->time_start, $event->time_end);
924 - if( // Status setting
925 - $this->settings['displaystatus'] == 'both' ||
926 - ($this->settings['displaystatus'] == 'single' && is_single() ) ||
927 - ($this->settings['displaystatus'] == 'list' && !is_single() )
928 - ){
929 - $dates.='<span class="eventpost-status">'.$this->statuses[$event->status].'</span>';
930 - }
931 - $timezone_string = get_option('timezone_string');
932 - $gmt_offset = $gmt = $this->get_gmt_offset();
1305 + $dates.=$this->delta_date($event->time_start, $event->time_end);
1306 + if( // Status setting
1307 + $this->settings['displaystatus'] == 'both' ||
1308 + ($this->settings['displaystatus'] == 'single' && is_single() ) ||
1309 + ($this->settings['displaystatus'] == 'list' && !is_single() )
1310 + ){
1311 + $dates.='<span class="eventpost-status">'.$this->statuses[$event->status].'</span>';
1312 + }
1313 + $timezone_string = get_option('timezone_string');
1314 + $gmt_offset = $gmt = $this->get_gmt_offset();
933 1315
934 - if (
935 - !is_admin()
936 - && ( // Export when setting
937 - $this->settings['export_when'] == 'both' ||
938 - ( $this->settings['export_when'] == 'future' && $this->is_future($event) ) ||
939 - ( $this->settings['export_when'] == 'past' && $this->is_past($event) )
940 - )
941 - && ( // Export setting
942 - $this->settings['export'] == 'both' ||
943 - ($this->settings['export'] == 'single' && is_single() ) ||
944 - ($this->settings['export'] == 'list' && !is_single() )
945 - )
946 - ) {
947 - // Export event
948 - $title = urlencode($post->post_title);
949 - $address = urlencode($post->address);
950 - $desc = urlencode($event->post_excerpt."\n\n".$post->permalink);
951 - $allday = ($post->time_start && $post->time_end && date('H:i:s', $post->time_start) == '00:00:00' && date('H:i:s', $post->time_end) == '00:00:00');
952 - $d_s = date("Ymd", $event->time_start) . ($allday ? '' : 'T' . date("His", $event->time_start));
953 - $d_e = date("Ymd", $event->time_end) . ($allday ? '' : 'T' . date("His", $event->time_end));
954 - $uid = $post->ID . '-' . $post->blog_id;
955 - $url = $event->permalink;
1316 + if (
1317 + !is_admin()
1318 + && ( // Export when setting
1319 + $this->settings['export_when'] == 'both' ||
1320 + ( $this->settings['export_when'] == 'future' && $this->is_future($event) ) ||
1321 + ( $this->settings['export_when'] == 'past' && $this->is_past($event) )
1322 + )
1323 + && ( // Export setting
1324 + $this->settings['export'] == 'both' ||
1325 + ($this->settings['export'] == 'single' && is_single() ) ||
1326 + ($this->settings['export'] == 'list' && !is_single() )
1327 + )
1328 + ) {
1329 + // Export event
1330 + $title = urlencode($post->post_title);
1331 + $address = urlencode($post->address);
1332 + $desc = urlencode($event->description."\n\n".$post->permalink);
1333 + $allday = ($post->time_start && $post->time_end && date('H:i:s', $post->time_start) == '00:00:00' && date('H:i:s', $post->time_end) == '00:00:00');
1334 + $d_s = date("Ymd", $event->time_start) . ($allday ? '' : 'T' . date("His", $event->time_start));
1335 + $d_e = date("Ymd", $event->time_end) . ($allday ? '' : 'T' . date("His", $event->time_end));
1336 + $uid = $post->ID . '-' . $post->blog_id;
1337 + $url = $event->permalink;
956 1338
957 - // format de date ICS
958 - $permalink_structure = get_option( 'permalink_structure' );
959 - if($permalink_structure != ""){
960 - $ics_url = site_url('eventpost/'.$event->ID.'.ics');
961 - $vcs_url = site_url('eventpost/'.$event->ID.'.vcs');
962 - }
963 - else{
964 - $ics_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'ics'), admin_url('admin-ajax.php'));
965 - $vcs_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'vcs'), admin_url('admin-ajax.php'));
1339 + // format de date ICS
1340 + $permalink_structure = get_option( 'permalink_structure' );
1341 + if($permalink_structure != ""){
1342 + $ics_url = site_url('eventpost/'.$event->ID.'.ics');
1343 + $vcs_url = site_url('eventpost/'.$event->ID.'.vcs');
1344 + }
1345 + else{
1346 + $ics_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'ics'), admin_url('admin-ajax.php'));
1347 + $vcs_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'vcs'), admin_url('admin-ajax.php'));
966 1348
967 - }
1349 + }
968 1350
969 - // format de date Google cal
970 - //$google_url = 'https://www.google.com/calendar/event?action=TEMPLATE&amp;text=' . $title . '&amp;dates=' . $d_s . 'Z/' . $d_e . 'Z&amp;details=' . $url . '&amp;ctz='.$timezone_string.'&amp;location=' . $address . '&amp;trp=false&amp;sprop=&amp;sprop=name';
971 - $google_url = add_query_arg(array(
972 - 'action'=>'TEMPLATE',
973 - 'trp'=>'false',
974 - 'sprop'=>'name',
975 - 'text'=>$title,
976 - 'dates'=>$d_s.'/'.$d_e.'', // Removed Z to fix TZ issue
977 - 'location'=>$address,
978 - 'details'=>$desc,
979 - 'gmt'=> urlencode($gmt_offset)
980 - ), 'https://www.google.com/calendar/event');
981 - if(!empty($timezone_string)){
982 - $google_url = add_query_arg(array(
983 - 'ctz'=>$timezone_string,
984 - ), $google_url);
1351 + // format de date Google cal
1352 + //$google_url = 'https://www.google.com/calendar/event?action=TEMPLATE&amp;text=' . $title . '&amp;dates=' . $d_s . 'Z/' . $d_e . 'Z&amp;details=' . $url . '&amp;ctz='.$timezone_string.'&amp;location=' . $address . '&amp;trp=false&amp;sprop=&amp;sprop=name';
1353 + $google_url = add_query_arg(array(
1354 + 'action'=>'TEMPLATE',
1355 + 'trp'=>'false',
1356 + 'sprop'=>'name',
1357 + 'text'=>$title,
1358 + 'dates'=>$d_s.'/'.$d_e.'', // Removed Z to fix TZ issue
1359 + 'location'=>$address,
1360 + 'details'=>$desc,
1361 + 'gmt'=> urlencode($gmt_offset)
1362 + ), 'https://www.google.com/calendar/event');
1363 + if(!empty($timezone_string)){
1364 + $google_url = add_query_arg(array(
1365 + 'ctz'=>$timezone_string,
1366 + ), $google_url);
1367 + }
1368 +
1369 + $dates.='
1370 + <span class="eventpost-date-export">
1371 + <a href="' . $ics_url . '" class="event_link event-export ics" target="_blank" title="' . __('Download ICS file', 'event-post') . '">ical</a>
1372 + <a href="' . $google_url . '" class="event_link event-export gcal" target="_blank" title="' . __('Add to Google calendar', 'event-post') . '">Google</a>
1373 + <a href="' . $vcs_url . '" class="event_link event-export vcs" target="_blank" title="' . __('Add to Outlook', 'event-post') . '">outlook</a>
1374 + <i class="dashicons-before dashicons-calendar"></i>
1375 + </span>';
985 1376 }
986 -
987 - $dates.='
988 - <span class="eventpost-date-export">
989 - <a href="' . $ics_url . '" class="event_link event-export ics" target="_blank" title="' . __('Download ICS file', 'event-post') . '">ical</a>
990 - <a href="' . $google_url . '" class="event_link event-export gcal" target="_blank" title="' . __('Add to Google calendar', 'event-post') . '">Google</a>
991 - <a href="' . $vcs_url . '" class="event_link event-export vcs" target="_blank" title="' . __('Add to Outlook', 'event-post') . '">outlook</a>
992 - <i class="dashicons-before dashicons-calendar"></i>
993 - </span>';
994 1377 }
995 1378 }
996 1379 return apply_filters('eventpost_printdate', $dates);
997 1380 }
@@ -996,10 +1379,12 @@
996 1379 return apply_filters('eventpost_printdate', $dates);
997 1380 }
998 1381
999 1382 /**
1000 - *
1383 + * Outputs location of an event
1384 + *
1001 1385 * @param WP_Post object $post
1386 + *
1002 1387 * @return string
1003 1388 */
1004 1389 public function print_location($post=null, $context='') {
1005 1390 $location = '';
@@ -1010,52 +1395,73 @@
1010 1395 }
1011 1396 if (!isset($post->start)) {
1012 1397 $post = $this->retreive($post);
1013 1398 }
1014 - $address = $post->address;
1015 - $lat = $post->lat;
1016 - $long = $post->long;
1017 - $color = $this->get_post_color($post->ID, $this->settings['default_color'], true);
1018 - $icon = $this->DashIcons->icons[$this->get_post_icon($post->ID, $this->settings['default_icon'], true)];
1019 - $virtual_location = $post->virtual_location;
1020 - $attendance_mode = $post->attendance_mode;
1399 + if ($post != false){
1400 + $this->map_id++;
1401 + $address = $post->address;
1402 + $lat = $post->lat;
1403 + $long = $post->long;
1404 + $color = $this->get_post_color($post->ID, $this->settings['default_color'], true);
1405 + $icon = $this->DashIcons->icons[$this->get_post_icon($post->ID, $this->settings['default_icon'], true)];
1406 + $virtual_location = $post->virtual_location;
1407 + $attendance_mode = $post->attendance_mode;
1021 1408
1022 - if ($this->is_online($post) && $virtual_location) {
1023 - $location.="\t\t\t\t".'<div><a href="'.esc_url($virtual_location).'" class="eventpost-virtual-location-link" target="_blank" rel="noopener">'
1024 - .__('Join link', 'event-post')
1025 - .'</a></div>'
1026 - ."\n";
1027 - }
1028 - if ($this->is_offline($post) && ($address != '' || ($lat != '' && $long != ''))) {
1029 - $location.="\t\t\t\t".'<address';
1030 - if ($lat != '' && $long != '') {
1031 - $location.=' data-id="' . $post->ID . '"
1032 - data-latitude="' . $lat . '"
1033 - data-longitude="' . $long . '"
1034 - data-marker="' . $this->get_marker($color) . '"
1035 - data-iconcode="' .$icon. '"
1036 - data-icon="' . mb_convert_encoding('&#x'.$icon.';', 'UTF-8', 'HTML-ENTITIES'). '"
1037 - data-color="#' . $color. '"';
1409 + if ($this->is_online($post) && $virtual_location) {
1410 + $location.="\t\t\t\t".'<div><a href="'.esc_url($virtual_location).'" class="eventpost-virtual-location-link" target="_blank" rel="noopener">'
1411 + .__('Join link', 'event-post')
1412 + .'</a></div>'
1413 + ."\n";
1038 1414 }
1039 - $location.=' itemprop="adr" class="eventpost-address">'
1040 - . "\n\t\t\t\t\t\t\t".'<span>'
1041 - . "\n".$address
1042 - . "\n\t\t\t\t\t\t\t". '</span>';
1043 - if ($context=='single' && $lat != '' && $long != '') {
1044 - $location.="\n\t\t\t\t\t\t\t".'<a class="event_link gps dashicons-before dashicons-location-alt" href="https://www.openstreetmap.org/?lat=' . $lat .'&amp;lon=' . $long . '&amp;zoom=13" target="_blank" itemprop="geo">' . __('Map', 'event-post') . '</a>';
1415 + if ($this->is_offline($post) && ($address != '' || ($lat != '' && $long != ''))) {
1416 + $location.="\t\t\t\t".'<address';
1417 + if ($lat != '' && $long != '') {
1418 + $geo_attributes = ' data-latitude="' . esc_attr($lat) . '"
1419 + data-longitude="' . esc_attr($long) . '"
1420 + data-marker="' . esc_attr($this->get_marker($color)) . '"
1421 + data-iconcode="' .esc_attr($icon). '"
1422 + data-icon="' . esc_attr(mb_convert_encoding('&#x'.$icon.';', 'UTF-8', 'HTML-ENTITIES')). '"
1423 + data-color="#' . esc_attr($color). '"
1424 + data-id="' . $post->ID . '-'.$this->map_id.'"';
1425 + $location.=' '.$geo_attributes;
1426 + }
1427 + $location.=' itemprop="adr" class="eventpost-address">'
1428 + . "\n\t\t\t\t\t\t\t".'<span>'
1429 + . "\n".$address
1430 + . "\n\t\t\t\t\t\t\t". '</span>';
1431 + if ($context=='single' && $lat != '' && $long != '') {
1432 + $location.="\n\t\t\t\t\t\t\t".'<a class="event_link gps dashicons-before dashicons-location-alt" href="https://www.openstreetmap.org/?lat=' . esc_attr($lat) .'&amp;lon=' . esc_attr($long) . '&amp;zoom=13" target="_blank" itemprop="geo" ' . $geo_attributes . '>' . __('Map', 'event-post') . '</a>';
1433 + }
1434 + $location.="\n\t\t\t\t\t\t".'</address>';
1435 + if (wp_is_mobile() && $lat != '' && $long != '') {
1436 + $location.="\n\t\t\t\t\t\t".'<a class="event_link gps-geo-link" href="geo:' . esc_attr($lat) . ',' . esc_attr($long) . '" target="_blank" itemprop="geo" ' . $geo_attributes . '><i class="dashicons-before dashicons-location"></i> ' . __('Open in app', 'event-post') . '</a>';
1437 + }
1045 1438 }
1046 - $location.="\n\t\t\t\t\t\t".'</address>';
1047 - if (wp_is_mobile() && $lat != '' && $long != '') {
1048 - $location.="\n\t\t\t\t\t\t".'<a class="event_link gps-geo-link" href="geo:' . $lat . ',' . $long . '" target="_blank" itemprop="geo"><i class="dashicons-before dashicons-location"></i> ' . __('Open in app', 'event-post') . '</a>';
1049 - }
1050 1439 }
1440 + return apply_filters('eventpost_printlocation', $location);
1441 + }
1051 1442
1052 - return apply_filters('eventpost_printlocation', $location);
1443 + /**
1444 + * Compute darkness of the color
1445 + *
1446 + * @param string $color
1447 + *
1448 + * @return float
1449 + */
1450 + public function color_darkness($color){
1451 + $color = str_replace('#', '', $color);
1452 + $rgb = array();
1453 + for ($x=0;$x<3;$x++) {
1454 + $rgb[$x] = hexdec(substr($color,(2*$x),2));
1455 + }
1456 + return (max($rgb) + min($rgb)) / 510;
1053 1457 }
1054 1458
1055 1459 /**
1056 - *
1460 + * Outputs categories of an event
1461 + *
1057 1462 * @param WP_Post object $post
1463 + *
1058 1464 * @return string
1059 1465 */
1060 1466 public function print_categories($post=null, $context='') {
1061 1467 if ($post == null)
@@ -1066,21 +1472,36 @@
1066 1472 if (!isset($post->start)) {
1067 1473 $post = $this->retreive($post);
1068 1474 }
1069 1475 $cats = '';
1070 - $categories = $post->categories;
1071 - if ($categories) {
1072 - $cats.="\t\t\t\t".'<span class="event_category"';
1476 + if ($post != false){
1477 + $categories = $post->Taxonomies;
1478 + if ($categories) {
1479 + $cats.="\t\t\t\t".'<span class="event_categories">';
1073 1480
1074 - foreach ($categories as $category) {
1075 - $color = $this->Categories->get_taxonomy_color($category->term_id);
1076 - if ($color != '' && $color) {
1077 - $cats.=' style="color:#' . $color . '"';
1481 + foreach ($categories as $category) {
1482 + $cats.="\t\t\t\t\t".'<span ';
1483 + $classes = array('event-term', 'event_term_category');
1484 + $darkness = 0;
1485 + $color = $this->Taxonomies->get_taxonomy_color($category->term_id);
1486 + if ($color != '' && $color) {
1487 + $cats.=' style="background-color:#' . $color . '"';
1488 +
1489 + $darkness = $this->color_darkness($color);
1490 + if($darkness < 0.5){
1491 + array_push($classes, 'event-post-bg-dark');
1492 + }
1493 + else{
1494 + array_push($classes, 'event-post-bg-light');
1495 + }
1496 +
1497 + }
1498 + $cats.=' class="'.implode(' ', $classes).'">';
1499 + $cats .= $category->name . ' ';
1500 + $cats.='</span>';
1078 1501 }
1079 - $cats.='>';
1080 - $cats .= $category->name . ' ';
1502 + $cats.='</span>';
1081 1503 }
1082 - $cats.='</span>';
1083 1504 }
1084 1505 return $cats;
1085 1506 }
1086 1507
@@ -1085,11 +1506,14 @@
1085 1506 }
1086 1507
1087 1508 /**
1088 1509 * Generate, return or output date event datas
1510 + *
1089 1511 * @param WP_Post object $post
1090 1512 * @param string $class
1513 + *
1091 1514 * @filter eventpost_get_single
1515 + *
1092 1516 * @return string
1093 1517 */
1094 1518 public function get_single($post = null, $class = '', $context='') {
1095 1519 if ($post == null) {
@@ -1094,22 +1518,24 @@
1094 1518 public function get_single($post = null, $class = '', $context='') {
1095 1519 if ($post == null) {
1096 1520 $post = $this->retreive();
1097 1521 }
1098 - $datas_date = $this->print_date($post, null, $context);
1099 - $datas_cat = $this->print_categories($post, $context);
1100 - $datas_loc = $this->print_location($post, $context);
1101 - $classes = array(
1102 - 'event_data',
1103 - 'status-'.$post->status,
1104 - 'location-type-'.$post->attendance_mode,
1105 - $class
1106 - );
1107 - if ($datas_date != '' || $datas_loc != '') {
1108 - $rgb = $this->hex2dec($post->color);
1109 - return '<div class="' . implode(' ', $classes) . '" style="border-left-color:#' . $post->color . ';background:rgba(' . $rgb['R'] . ',' . $rgb['G'] . ',' . $rgb['B'] . ',0.1)" itemscope itemtype="http://microformats.org/profile/hcard">'
1110 - . apply_filters('eventpost_get_single', $datas_date . $datas_cat . $datas_loc, $post)
1111 - . '</div>';
1522 + if ($post != null){
1523 + $datas_date = $this->print_date($post, null, $context);
1524 + $datas_cat = $this->print_categories($post, $context);
1525 + $datas_loc = $this->print_location($post, $context);
1526 + $classes = array(
1527 + 'event_data',
1528 + 'status-'.strtolower(str_replace('Event', '', $post->status)),
1529 + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $post->attendance_mode)),
1530 + $class
1531 + );
1532 + if ($datas_date != '' || $datas_loc != '') {
1533 + $rgb = $this->hex2dec($post->color);
1534 + return '<div class="' . implode(' ', $classes) . '" style="border-left-color:#' . $post->color . ';background:rgba(' . $rgb['R'] . ',' . $rgb['G'] . ',' . $rgb['B'] . ',0.1)" itemscope itemtype="http://microformats.org/profile/hcard">'
1535 + . apply_filters('eventpost_get_single', $datas_date . $datas_cat . $datas_loc, $post)
1536 + . '</div>';
1537 + }
1112 1538 }
1113 1539 return '';
1114 1540 }
1115 1541
@@ -1114,10 +1540,12 @@
1114 1540 }
1115 1541
1116 1542 /**
1117 1543 * Displays dates of a gieven post
1544 + *
1118 1545 * @param WP_Post object $post
1119 1546 * @param string $class
1547 + *
1120 1548 * @return string
1121 1549 */
1122 1550 public function get_singledate($post = null, $class = '', $context='') {
1123 1551 return '<div class="event_data event_date ' . $class . '" itemscope itemtype="http://microformats.org/profile/hcard">' . "\n\t\t".$this->print_date($post, null, $context) . "\n\t\t\t\t\t".'</div><!-- .event_date -->';
@@ -1124,10 +1552,12 @@
1124 1552 }
1125 1553
1126 1554 /**
1127 1555 * Displays coloured terms of a given post
1556 + *
1128 1557 * @param WP_Post object $post
1129 1558 * @param string $class
1559 + *
1130 1560 * @return string
1131 1561 */
1132 1562 public function get_singlecat($post = null, $class = '', $context='') {
1133 1563 return '<div class="event_data event_category ' . $class . '" itemscope itemtype="http://microformats.org/profile/hcard">' . "\n\t\t".$this->print_categories($post, $context) . "\n\t\t\t\t\t".'</div><!-- .event_category -->';
@@ -1134,10 +1564,12 @@
1134 1564 }
1135 1565
1136 1566 /**
1137 1567 * Displays location of a given post
1568 + *
1138 1569 * @param WP_Post object $post
1139 1570 * @param string $class
1571 + *
1140 1572 * @return string
1141 1573 */
1142 1574 public function get_singleloc($post = null, $class = '', $context='') {
1143 1575 return '<div class="event_data event_location ' . $class . '" itemscope itemtype="http://microformats.org/profile/hcard">' . "\n\t\t".$this->print_location($post, $context) . "\n\t\t\t\t\t".'</div><!-- .event_location -->';
@@ -1144,9 +1576,11 @@
1144 1576 }
1145 1577
1146 1578 /**
1147 1579 * Uses `the_content` filter to add event details before or after the content of the current post
1580 + *
1148 1581 * @param string $content
1582 + *
1149 1583 * @return string
1150 1584 */
1151 1585 public function display_single($content) {
1152 1586 if (is_page() || !is_single() || is_home() || !in_the_loop() || !is_main_query()){
@@ -1153,32 +1587,42 @@
1153 1587 return $content;
1154 1588 }
1155 1589
1156 1590 $post = $this->retreive();
1157 - $eventbar = apply_filters('eventpost_contentbar', $this->get_single($post, 'event_single', 'single'), $post);
1158 - if($this->settings['singlepos']=='before'){
1159 - $content=$eventbar.$content;
1591 + if($post != false){
1592 + // If the post is a product, don't display the event bar, use product tab instead
1593 + if($post->post_type=='product'){
1594 + return $content;
1595 + }
1596 +
1597 + $eventbar = apply_filters('eventpost_contentbar', $this->get_single($post, 'event_single', 'single'), $post);
1598 + if($this->settings['singlepos']=='before'){
1599 + $content=$eventbar.$content;
1600 + }
1601 + elseif($this->settings['singlepos']=='after'){
1602 + $content.=$eventbar;
1603 + }
1604 + $this->load_map_scripts();
1160 1605 }
1161 - elseif($this->settings['singlepos']=='after'){
1162 - $content.=$eventbar;
1163 - }
1164 - $this->load_map_scripts();
1165 1606 return $content;
1166 1607 }
1167 1608
1168 1609 /**
1169 1610 * Outputs events details (dates, geoloc, terms) of given post
1611 + *
1170 1612 * @param WP_Post object $post
1171 - * @echoes string
1613 + *
1172 1614 * @return void
1173 1615 */
1174 1616 public function print_single($post = null) {
1175 - echo $this->get_single($post);
1617 + echo wp_kses_post($this->get_single($post));
1176 1618 }
1177 1619
1178 1620 /**
1179 1621 * Alter the post title in order to add icons if needed
1622 + *
1180 1623 * @param string $title
1624 + *
1181 1625 * @return string
1182 1626 */
1183 1627 public function the_title($title, $post_id = null){
1184 1628 if(!$post_id || !in_the_loop() || !$this->settings['loopicons']){
@@ -1191,29 +1635,54 @@
1191 1635 2=>array('<span class="dashicons dashicons-calendar"></span>', '<span class="dashicons dashicons-location"></span>'),
1192 1636 );
1193 1637
1194 1638 $event = $this->retreive($post_id);
1195 - if(!empty($event->start)){
1196 - $title .= ' '.$icons_[$this->settings['loopicons']][0];
1639 + if ($event !== false){
1640 + if(!empty($event->start)){
1641 + $title .= ' '.$icons_[$this->settings['loopicons']][0];
1642 + }
1643 + if(!empty($event->lat) && !empty($event->long)){
1644 + $title .= ' '.$icons_[$this->settings['loopicons']][1];
1645 + }
1197 1646 }
1198 - if(!empty($event->lat) && !empty($event->long)){
1199 - $title .= ' '.$icons_[$this->settings['loopicons']][1];
1200 - }
1201 1647 return $title;
1202 1648 }
1203 1649
1204 1650
1651 + function get_price($event,$html=false){
1652 + $price = '';
1653 + $text_price = $price;
1654 + if($event->post_type == 'product'){
1655 + $product_id = $event->ID;
1656 + $product = wc_get_product($product_id);
1657 + $price = $product->get_price();
1658 + $currency = get_woocommerce_currency_symbol();
1659 + if($product->get_sale_price() != ""){
1660 + $old_price = $product->get_regular_price();
1661 + $text_price = '<span class="event_price"><del>'.$old_price . $currency . '</del> '.$price. $currency. '</span>';
1662 + } else {
1663 + $text_price = '<span class="event_price"> '.$price . $currency.'</span>';
1664 + }
1665 + }
1666 + if ($html == true) {
1667 + return $text_price;
1668 + } else {
1669 + return $price;
1670 + }
1671 + }
1672 +
1205 1673 /**
1206 1674 * Return an HTML list of events
1207 1675 *
1676 + * @param array $atts
1677 + * @param string $id
1678 + * @param string $context
1679 + *
1208 1680 * @filter eventpost_params($defaults, 'list_events')
1209 1681 * @filter eventpost_listevents
1210 1682 * @filter eventpost_item_scheme_entities
1211 1683 * @filter eventpost_item_scheme_values
1212 - *
1213 - * @param array $atts
1214 - * @param string $id
1215 - * @param string $context
1684 + *
1216 1685 * @return string
1217 1686 */
1218 1687 public function list_events($atts, $id = 'event_list', $context='') {
1219 1688 $ep_settings = $this->settings;
@@ -1218,8 +1687,11 @@
1218 1687 public function list_events($atts, $id = 'event_list', $context='') {
1219 1688 $ep_settings = $this->settings;
1220 1689 $defaults = array(
1221 1690 'nb' => 0,
1691 + 'nb_desktop' => 0,
1692 + 'nb_tablet' => 0,
1693 + 'nb_mobile' => 0,
1222 1694 'type' => 'div',
1223 1695 'future' => true,
1224 1696 'past' => false,
1225 1697 'geo' => 0,
@@ -1247,20 +1719,29 @@
1247 1719 'excerpt' => '',
1248 1720 'orderby' => 'meta_value',
1249 1721 'order' => 'ASC',
1250 1722 'class' => '',
1723 + 'align' => '',
1251 1724 'className' => '',
1252 1725 'container_schema' => $this->list_shema['container'],
1253 1726 'item_schema' => $this->list_shema['item'],
1254 1727 'pages' => false,
1255 1728 'paged' => '',
1729 + 'separate_years' => false,
1730 + 'separate_months' => false,
1256 1731 );
1257 1732 // Map UI options
1258 1733 foreach($this->map_interactions as $int_key=>$int_name){
1259 1734 $defaults[$int_key]=true;
1260 1735 }
1261 - $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events'), $atts);
1736 + $atts_old_nb = $defaults['nb'];
1737 + if($id == "event_timeline"){
1738 + $atts_old_nb = intval($atts['nb']);
1739 + $atts['nb'] = -1;
1740 + }
1262 1741
1742 + $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events', $context), $atts);
1743 +
1263 1744 extract($atts);
1264 1745 if (!is_array($events)) {
1265 1746 $events = $this->get_events($atts);
1266 1747 }
@@ -1268,12 +1749,13 @@
1268 1749 $ret = '';
1269 1750 $this->list_id++;
1270 1751 if (sizeof($events) > 0) {
1271 1752 if (!empty($title)) {
1272 - $ret.= html_entity_decode($before_title) . $title . html_entity_decode($after_title);
1753 + $ret .= wp_kses_post($before_title . esc_html($title) . $after_title);
1273 1754 }
1274 1755
1275 - $child = ($type == 'ol' || $type == 'ul') ? 'li' : 'div';
1756 + $type = in_array($type, ['div', 'ul', 'ol']) ? $type : 'div';
1757 + $child = in_array($type, ['ul', 'ol']) ? 'li' : 'div';
1276 1758
1277 1759 $html = '';
1278 1760
1279 1761 if($id=='event_geolist'){
@@ -1284,27 +1766,48 @@
1284 1766 $prev_arrow = "";
1285 1767 $next_arrow = "";
1286 1768 $item_child_style = "";
1287 1769 if($id == "event_timeline"){
1288 - $prev_arrow = '<div class="previous">'.__('« Previous Events', 'event-post')."</div>";
1289 - $next_arrow = '<div class="next">'.__('Next Events »', 'event-post')."</div>";
1290 - $item_child_style = 'width : '.((100/$nb) - 2).'%;';
1291 - $attributes .= ' data-nb="'.$nb.'" data-filter="'.http_build_query($atts).'" ';
1770 + $prev_arrow = '<div class="previous"><span class="screen-reader-text">'.__('« Previous Events', 'event-post')."</span></div>";
1771 + $next_arrow = '<div class="next"><span class="screen-reader-text">'.__('Next Events »', 'event-post')."</span></div>";
1772 + if($atts_old_nb != 0){
1773 + $item_child_style = 'width : '.((100/$atts_old_nb) - 2).'%;';
1774 + }
1775 + $attributes .= ' data-nb="'.$atts_old_nb.'"';
1776 + $attributes .= ' data-nb-desktop="'.intval($atts['nb_desktop'] ?? 0).'"';
1777 + $attributes .= ' data-nb-tablet="'.intval($atts['nb_tablet'] ?? 0).'"';
1778 + $attributes .= ' data-nb-mobile="'.intval($atts['nb_mobile'] ?? 0).'"';
1779 + $attributes .= ' data-filter="'.http_build_query($atts).'" ';
1292 1780 }
1293 1781
1782 + if($id === 'event_timeline'){
1783 + $previous_year = $atts['separate_years'] ? true : false;
1784 + $previous_month = $atts['separate_months'] ? true : false;
1785 + }
1786 +
1294 1787 foreach ($events as $event) {
1295 -
1788 + if($id === 'event_timeline'){
1789 + if($previous_year && $previous_year !== date('Y', $event->time_start)){
1790 + $html.= '<div class="event-timeline-separator event-timeline-year"><span class="event-timeline-year-text">'.date_i18n('Y', $event->time_start).'</span></div>';
1791 + $previous_year = date('Y', $event->time_start);
1792 + }
1793 + if($previous_month && $previous_month !== date('Ym', $event->time_start)){
1794 + $html.= '<div class="event-timeline-separator event-timeline-month"><span class="event-timeline-month-text">'.date_i18n('F', $event->time_start).'</span>'.($previous_year ? '' : ' <span class="event-timeline-year-text">'.date_i18n('Y', $event->time_start).'</span>').'</div>';
1795 + $previous_month = date('Ym', $event->time_start);
1796 + }
1797 + }
1798 + $text_price = $this->get_price($event,true);
1296 1799 $class_item = array(
1297 1800 $this->is_future($event) ? 'event_future' : 'event_past',
1298 - 'status-'.$event->status,
1299 - 'location-type-'.$event->attendance_mode,
1801 + 'status-'.strtolower(str_replace('Event', '', $event->status)),
1802 + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $event->attendance_mode)),
1300 1803 );
1301 1804 $taxonomies= get_taxonomies('','names');
1302 - $post_terms = [];
1303 - $terms = wp_get_post_terms($event->ID, $taxonomies);
1304 - foreach($terms as $term){
1305 - $class_item[] = $term->taxonomy.'-'.$term->name;
1306 - }
1805 + $post_terms = [];
1806 + $terms = wp_get_post_terms($event->ID, $taxonomies);
1807 + foreach($terms as $term){
1808 + $class_item[] = $term->taxonomy.'-'.$term->slug;
1809 + }
1307 1810 if ($ep_settings['emptylink'] == 0 && empty($event->post_content)) {
1308 1811 $event->permalink = '#' . $id . $this->list_id;
1309 1812 }
1310 1813 elseif(empty($event->permalink)){
@@ -1317,8 +1820,9 @@
1317 1820 '%color%',
1318 1821 '%event_link%',
1319 1822 '%event_thumbnail%',
1320 1823 '%event_title%',
1824 + '%event_price%',
1321 1825 '%event_date%',
1322 1826 '%event_cat%',
1323 1827 '%event_location%',
1324 1828 '%event_excerpt%',
@@ -1329,12 +1833,13 @@
1329 1833 $this->get_post_color($event->ID, $this->settings['default_color'],true),
1330 1834 $event->permalink,
1331 1835 $thumbnail == true ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->root_ID, !empty($thumbnail_size) ? $thumbnail_size : 'thumbnail', array('class' => 'attachment-thumbnail wp-post-image event_thumbnail')) . '</span>' : '',
1332 1836 $event->post_title,
1837 + $event->post_type == 'product' ? $text_price : '',
1333 1838 $this->get_singledate($event, '', $context),
1334 1839 $this->get_singlecat($event, '', $context),
1335 1840 $this->get_singleloc($event, '', $context),
1336 - $excerpt == true && $event->post_excerpt!='' ? '<span class="event_exerpt">'.$event->post_excerpt.'</span>' : '',
1841 + $excerpt == true && $event->description!='' ? '<span class="event_exerpt">'.$event->description.'</span>' : '',
1337 1842 $item_child_style,
1338 1843 ), $event), $item_schema
1339 1844 );
1340 1845
@@ -1345,22 +1850,22 @@
1345 1850 }
1346 1851 if($width==''){
1347 1852 $width = '100%';
1348 1853 }
1349 - $attributes .= ' data-tile="'.$tile.'"
1350 - data-width="'.$width.'"
1351 - data-height="'.$height.'"
1352 - data-zoom="'.$zoom.'"
1353 - data-map_position="'.$map_position.'"
1354 - data-latitude="'.$latitude.'"
1355 - data-longitude="'.$longitude.'"
1356 - data-pop_element_schema="'.$pop_element_schema.'"
1357 - data-htmlPop_element_schema="'.esc_attr($htmlPop_element_schema).'"
1358 - data-list="'.$list.'"
1359 - data-disabled-interactions="';
1854 + $attributes .= ' data-tile="'.esc_attr($tile).'"
1855 + data-width="'.esc_attr($width).'"
1856 + data-height="'.esc_attr($height).'"
1857 + data-zoom="'.esc_attr($zoom).'"
1858 + data-map_position="'.esc_attr($map_position).'"
1859 + data-latitude="'.esc_attr($latitude).'"
1860 + data-longitude="'.esc_attr($longitude).'"
1861 + data-pop_element_schema="'.esc_attr($pop_element_schema).'"
1862 + data-htmlPop_element_schema="'.esc_attr($htmlPop_element_schema).'"
1863 + data-list="'.esc_attr($list).'"
1864 + data-disabled-interactions="';
1360 1865 // add data-position avec ma variables
1361 1866 foreach($this->map_interactions as $int_key=>$int_name){
1362 - $attributes.=$atts[$int_key]==false ? $int_key.', ' : '';
1867 + $attributes.=$atts[$int_key]==false ? esc_attr($int_key).', ' : '';
1363 1868 }
1364 1869 $attributes.='" ';
1365 1870 }
1366 1871 $pagination = '';
@@ -1378,8 +1883,20 @@
1378 1883
1379 1884 if($context == 'events_only'){
1380 1885 $ret = $html;
1381 1886 }else{
1887 + $classes = [
1888 + $class,
1889 + $className,
1890 + 'className',
1891 + $id == 'event_geolist' && $list ? ' has-list list-'.esc_attr($list) : ' no-list',
1892 + ];
1893 + if(!empty($align)){
1894 + $classes[] = 'align'.esc_attr($align);
1895 + }
1896 + if($id === 'event_timeline' && ($previous_year || $previous_month)){
1897 + $classes[] = 'has-time-separators';
1898 + }
1382 1899 $ret.=str_replace(
1383 1900 array(
1384 1901 '%type%',
1385 1902 '%id%',
@@ -1394,11 +1911,11 @@
1394 1911 '%number%'
1395 1912 ), array(
1396 1913 $type,
1397 1914 $id,
1398 - $class.($className ? ' '.$className : '').($id == 'event_geolist' && $list ? ' has-list list-'.$list : ' no-list'),
1915 + esc_attr(implode(' ', $classes)),
1399 1916 $id . $this->list_id,
1400 - (!empty($width) ? 'width:' . $width . ';' : '') . (!empty($height) ? 'height:' . $height . ';' : '') . $style,
1917 + (!empty($width) ? 'width:' . esc_attr($width) . ';' : '') . (!empty($height) ? 'height:' . esc_attr($height) . ';' : '') . esc_attr($style),
1401 1918 $attributes,
1402 1919 $html,
1403 1920 $pagination,
1404 1921 $prev_arrow,
@@ -1415,12 +1932,15 @@
1415 1932 }
1416 1933
1417 1934
1418 1935 /**
1419 - * get_events
1936 + * Get events
1937 + *
1420 1938 * @param array $atts
1939 + *
1421 1940 * @filter eventpost_params
1422 1941 * @filter eventpost_get_items
1942 + *
1423 1943 * @return array of post_ids which are events
1424 1944 */
1425 1945 public function get_events($atts) {
1426 1946 if(isset($atts['future'])){
@@ -1588,9 +2108,9 @@
1588 2108 }
1589 2109
1590 2110 $arg['meta_query'] = $meta_query;
1591 2111
1592 - $query_md5 = 'eventpost_' . md5(var_export($requete, true));
2112 + $query_md5 = 'eventpost_' . md5(wp_json_encode($requete, true));
1593 2113 // Check if cache is activated
1594 2114 if ($this->settings['cache'] == 1 && false !== ( $cached_events = get_transient($query_md5) )) {
1595 2115 return apply_filters('eventpost_get_items', is_array($cached_events) ? $cached_events : array(), $requete, $arg);
1596 2116 }
@@ -1605,9 +2125,11 @@
1605 2125 'max_num_pages' => $query->max_num_pages,
1606 2126 );
1607 2127 foreach ($events as $k => $post) {
1608 2128 $event = $this->retreive($post);
1609 - $events[$k] = $event;
2129 + if ($event != false){
2130 + $events[$k] = $event;
2131 + }
1610 2132 }
1611 2133 }
1612 2134 if ($this->settings['cache'] == 1){
1613 2135 set_transient($query_md5, $events, 5 * MINUTE_IN_SECONDS);
@@ -1617,10 +2139,11 @@
1617 2139
1618 2140 /**
1619 2141 * Checks if the given event is in the future or not
1620 2142 *
1621 - * @param object $event
1622 - * @param boolean $exact Future status has to be calculated against time or entire day
2143 + * @param object $event
2144 + * @param boolean $exact Future status has to be calculated against time or entire day
2145 + *
1623 2146 * @return boolean
1624 2147 */
1625 2148 function is_future($event, $exact=false){
1626 2149 $match = current_time('timestamp');
@@ -1633,10 +2156,11 @@
1633 2156
1634 2157 /**
1635 2158 * Checks if the given event is completed or not
1636 2159 *
1637 - * @param object $event
1638 - * @param boolean $exact Past status has to be calculated against time or entire day
2160 + * @param object $event
2161 + * @param boolean $exact Past status has to be calculated against time or entire day
2162 + *
1639 2163 * @return boolean
1640 2164 */
1641 2165 function is_past($event, $exact=false){
1642 2166 $match = current_time('timestamp');
@@ -1648,9 +2172,11 @@
1648 2172 }
1649 2173
1650 2174 /**
1651 2175 * Checks if an event is online
1652 - * @param $event
2176 + *
2177 + * @param $event
2178 + *
1653 2179 * @return boolean
1654 2180 */
1655 2181 function is_online($event){
1656 2182 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OnlineEventAttendanceMode')));
@@ -1657,9 +2183,11 @@
1657 2183 }
1658 2184
1659 2185 /**
1660 2186 * Checks if an event is offline
1661 - * @param $event
2187 + *
2188 + * @param $event
2189 + *
1662 2190 * @return boolean
1663 2191 */
1664 2192 function is_offline($event){
1665 2193 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OfflineEventAttendanceMode')));
@@ -1664,17 +2192,21 @@
1664 2192 function is_offline($event){
1665 2193 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OfflineEventAttendanceMode')));
1666 2194 }
1667 2195
1668 -
1669 2196 /**
1670 - *
2197 + * Populates a WP_Post object with event datas
2198 + *
1671 2199 * @param object $event
2200 + *
1672 2201 * @return object
1673 2202 */
1674 2203 public function retreive($event = null) {
1675 2204 global $EventPost_cache;
1676 2205 $ob = get_post($event);
2206 + if(!$ob){
2207 + return false;
2208 + }
1677 2209 if(is_object($ob) && $ob->start){
1678 2210 return $ob;
1679 2211 }
1680 2212 if(is_object($ob) && isset($EventPost_cache[$ob->ID])){
@@ -1691,26 +2223,37 @@
1691 2223 $ob->root_ID = $ob->ID;
1692 2224 $ob->time_start = !empty($ob->start) ? strtotime($ob->start) : '';
1693 2225 $ob->time_end = !empty($ob->end) ? strtotime($ob->end) : '';
1694 2226 $ob->virtual_location = get_post_meta($ob->ID, $this->META_VIRTUAL_LOCATION, true);
2227 + $ob->virtual_location = esc_url($ob->virtual_location);
2228 + $ob->organization = get_post_meta($ob->ID, $this->META_ORGANIZATION, true);
2229 + $ob->offer = get_post_meta($ob->ID, $this->META_OFFER, true);
2230 + if(empty($ob->offer)){
2231 + $ob->offer = array(
2232 + 'url' => null,
2233 + 'price' => null,
2234 + 'currency' => null,
2235 + );
2236 + }
1695 2237 $ob->address = get_post_meta($ob->ID, $this->META_ADD, true);
1696 - $ob->lat = get_post_meta($ob->ID, $this->META_LAT, true);
1697 - $ob->long = get_post_meta($ob->ID, $this->META_LONG, true);
2238 + $ob->lat = $this->sanitize_coordinate(get_post_meta($ob->ID, $this->META_LAT, true));
2239 + $ob->long = $this->sanitize_coordinate(get_post_meta($ob->ID, $this->META_LONG, true));
1698 2240 $ob->attendance_mode = (null != $att_mod = get_post_meta($ob->ID, $this->META_ATTENDANCE_MODE, true)) ? $att_mod : array_keys($this->attendance_modes)[0];
1699 2241 $ob->status = (null != $status = get_post_meta($ob->ID, $this->META_STATUS, true)) ? $status : array_keys($this->statuses)[0];
1700 2242 $ob->color = $this->get_post_color($ob->ID);
1701 2243 $ob->icon = $this->get_post_icon($ob->ID);
1702 - $ob->categories = get_the_category($ob->ID);
2244 + $ob->Taxonomies = get_the_category($ob->ID);
1703 2245 $ob->permalink = get_permalink($ob->ID);
1704 2246 $ob->blog_id = get_current_blog_id();
1705 -
2247 + $ob->description = $ob->post_excerpt ? $ob->post_excerpt : str_replace('&nbsp;', ' ', preg_replace("/\n+/", "\n", trim(wp_strip_all_tags(excerpt_remove_blocks($ob->post_content)))));
1706 2248 $EventPost_cache[$ob->ID] = apply_filters('eventpost_retreive', $ob);
1707 2249 return $EventPost_cache[$ob->ID];
1708 2250 }
1709 2251
1710 2252 /**
1711 - *
1712 - * @param mixte $_term
2253 + * Fetch terms of a post
2254 + *
2255 + * @param mixed $_term
1713 2256 * @param string $taxonomy
1714 2257 * @param string $post_type
1715 2258 */
1716 2259 public function retreive_term($_term=null, $taxonomy='category', $post_type='post') {
@@ -1754,12 +2297,12 @@
1754 2297 return $term;
1755 2298
1756 2299 }
1757 2300
1758 - /** ADMIN ISSUES * */
2301 + // ADMIN ISSUES
1759 2302
1760 2303 /**
1761 - * add custom boxes in posts edit page
2304 + * Add custom boxes in posts edit page
1762 2305 */
1763 2306 public function add_custom_box() {
1764 2307 foreach($this->settings['posttypes'] as $posttype){
1765 2308 add_meta_box(
@@ -1786,10 +2329,11 @@
1786 2329 );
1787 2330 do_action('eventpost_add_custom_box', $posttype);
1788 2331 }
1789 2332 }
2333 +
1790 2334 /**
1791 - * display the date custom box
2335 + * Displays the date custom box
1792 2336 */
1793 2337 public function inner_custom_box_date() {
1794 2338
1795 2339
@@ -1796,54 +2340,59 @@
1796 2340
1797 2341 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1798 2342 $post_id = get_the_ID();
1799 2343 $event = $this->retreive($post_id);
1800 - $start_date = $event->start;
1801 - $end_date = $event->end;
1802 - $eventcolor = $event->color;
1803 - $eventicon = $event->icon;
2344 + if ($event != false){
2345 + $start_date = $event->start;
2346 + $end_date = $event->end;
2347 + $eventcolor = $event->color;
2348 + $eventicon = $event->icon;
1804 2349
1805 - $language = get_bloginfo('language');
1806 - if (strpos($language, '-') > -1) {
1807 - $language = strtolower(substr($language, 0, 2));
2350 + $language = get_bloginfo('language');
2351 + if (strpos($language, '-') > -1) {
2352 + $language = strtolower(substr($language, 0, 2));
2353 + }
2354 + $colors = $this->get_colors();
2355 + include (plugin_dir_path(__FILE__) . 'views/admin/custombox-date.php');
2356 + do_action ('eventpost_custom_box_date', $event);
1808 2357 }
1809 - $colors = $this->get_colors();
1810 - include (plugin_dir_path(__FILE__) . 'views/admin/custombox-date.php');
1811 - do_action ('eventpost_custom_box_date', $event);
1812 2358 }
2359 +
1813 2360 /**
1814 - * displays the location custom box
2361 + * Displays the location custom box
1815 2362 */
1816 2363 public function inner_custom_box_loc($post) {
1817 2364 $event = $this->retreive($post);
1818 - include (plugin_dir_path(__FILE__) . 'views/admin/custombox-location.php');
1819 - do_action ('eventpost_custom_box_loc', $event);
1820 - $this->load_map_scripts();
2365 + if ($event != false){
2366 + include (plugin_dir_path(__FILE__) . 'views/admin/custombox-location.php');
2367 + do_action ('eventpost_custom_box_loc', $event);
2368 + $this->load_map_scripts();
2369 + }
1821 2370 }
1822 2371
1823 2372 public function icon_color_fields($item_id, $meta_color,$value_color,$meta_icon,$value_icon ){
1824 2373 ?>
1825 2374 <div class="eventpost-misc-pub-section event-color-section">
1826 - <span class="screen-reader-text"><?php _e('Color:', 'event-post'); ?></span>
2375 + <span class="screen-reader-text"><?php esc_html_e('Color:', 'event-post'); ?></span>
1827 2376
1828 2377 <input class="color-field-post eventpost-colorpicker"
1829 2378 type="text"
1830 - name="<?php echo $meta_color; ?>"
1831 - value="<?php echo $value_color; ?>"
1832 - id="color-field<?php echo $item_id; ?>"/>
2379 + name="<?php echo esc_attr($meta_color); ?>"
2380 + value="<?php echo esc_attr($value_color); ?>"
2381 + id="color-field<?php echo esc_attr($item_id); ?>"/>
1833 2382
1834 - <select style="font-family : dashicons;" class="eventpost-iconpicker" name="<?php echo $meta_icon; ?>">
1835 - <option value=""><?php echo __('None','event-post') ?></option>
2383 + <select style="font-family : dashicons;" class="eventpost-iconpicker" name="<?php echo esc_attr($meta_icon); ?>">
2384 + <option value=""><?php esc_attr_e('None','event-post') ?></option>
1836 2385 <?php
1837 2386 foreach($this->DashIcons->icons as $class => $unicode){
1838 2387 ?>
1839 - <option value="<?php echo $class ?>" <?php selected($value_icon, $class, true); ?>>&#x<?php echo $unicode ?>; <?php echo $class ?></option>
2388 + <option value="<?php echo esc_attr($class) ?>" <?php selected($value_icon, $class, true); ?>>&#x<?php esc_attr_e($unicode) ?>; <?php echo esc_html($class) ?></option><?php // phpcs:ignore WordPress.WP.I18n ?>
1840 2389 <?php
1841 2390 }
1842 2391 ?>
1843 2392 </select>
1844 2393 <div class="custom-marker-container">
1845 - <p><?php echo __('An image was found in your custom folder for this color', 'event-post')?> <span class="color-hex"></span> </p>
2394 + <p><?php esc_html_e('An image was found in your custom folder for this color', 'event-post')?> <span class="color-hex"></span> </p>
1846 2395 <img src="" class="image-marker">
1847 2396 </div>
1848 2397 </div>
1849 2398
@@ -1851,12 +2400,13 @@
1851 2400 <?php
1852 2401 }
1853 2402
1854 2403 /**
1855 - *
1856 - * @param string $column_name
1857 - * @param boolean $bulk
1858 - */
2404 + * Quick edit
2405 + *
2406 + * @param string $column_name
2407 + * @param boolean $bulk
2408 + */
1859 2409 function quick_edit( $column_name, $post_type, $bulk=false) {
1860 2410
1861 2411 if ($bulk) {
1862 2412 static $eventpostprintNonceBulk = TRUE;
@@ -1874,17 +2424,17 @@
1874 2424 $fields = $this->quick_edit_fields;
1875 2425 }
1876 2426 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1877 2427 if(isset($fields[$column_name])): ?>
1878 - <fieldset class="inline-edit-col-left inline-edit-<?php echo $column_name; ?>">
2428 + <fieldset class="inline-edit-col-left inline-edit-<?php echo esc_attr($column_name); ?>">
1879 2429 <div class="inline-edit-group">
1880 2430 <?php foreach ($fields[$column_name] as $fieldname=>$fieldlabel): ?>
1881 - <fieldset class="inline-edit-col inline-edit-<?php echo $fieldname; ?>">
1882 - <div class="inline-edit-col column-<?php echo $fieldname; ?>">
2431 + <fieldset class="inline-edit-col inline-edit-<?php echo esc_attr($fieldname); ?>">
2432 + <div class="inline-edit-col column-<?php echo esc_attr($fieldname); ?>">
1883 2433 <label class="inline-edit-group">
1884 - <span class="title"><?php echo $fieldlabel; ?></span>
2434 + <span class="title"><?php echo esc_html($fieldlabel); ?></span>
1885 2435 <span class="input-text-wrap">
1886 - <?php echo $this->inline_field($fieldname, $bulk); ?>
2436 + <?php echo wp_kses($this->inline_field($fieldname, $bulk), $this->kses_tags); ?>
1887 2437 </span>
1888 2438 </label>
1889 2439 </div>
1890 2440 </fieldset>
@@ -1894,14 +2444,16 @@
1894 2444 <?php endif;
1895 2445 }
1896 2446
1897 2447 /**
1898 - *
2448 + * Inline field in bulk edit
2449 + *
1899 2450 * @param type $fieldname
1900 - * @return type
2451 + *
2452 + * @return string
1901 2453 */
1902 2454 function inline_field($fieldname, $bulk){
1903 - return apply_filters('eventpost_inline_field', '<input name="'.$fieldname.'" class="eventpost-inline-'.$fieldname.'" value="" type="text">', $fieldname, $bulk);
2455 + return apply_filters('eventpost_inline_field', '<input name="'.esc_attr($fieldname).'" class="eventpost-inline-'.esc_attr($fieldname).'" value="" type="text">', $fieldname, $bulk);
1904 2456 }
1905 2457
1906 2458 function inline_field_color($html, $fieldname, $bulk){
1907 2459 if($fieldname==$this->META_COLOR){
@@ -1906,13 +2458,13 @@
1906 2458 function inline_field_color($html, $fieldname, $bulk){
1907 2459 if($fieldname==$this->META_COLOR){
1908 2460 $html='';
1909 2461 if($bulk){
1910 - $html.= '<span class="eventpost-bulk-colorpicker-button link">'.__('No Change', 'event-post').'</span>';
2462 + $html.= '<span class="eventpost-bulk-colorpicker-button link">'.esc_html(__('No Change', 'event-post')).'</span>';
1911 2463 }
1912 2464 $html .= '
1913 2465
1914 - <input class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'" type="text" name="'.$fieldname.'" >';
2466 + <input class="eventpost-inline-colorpicker eventpost-inline-'.esc_attr($fieldname).' '.($bulk?'is-bulk':'no-bulk').'" type="color" name="'.esc_attr($fieldname).'" >';
1915 2467 }
1916 2468 return $html;
1917 2469 }
1918 2470 function inline_field_icon($html, $fieldname, $bulk){
@@ -1919,17 +2471,16 @@
1919 2471 if($fieldname==$this->META_ICON){
1920 2472 if($bulk){
1921 2473 $html.= '<span class="eventpost-bulk-icon-button link">'.__('No Change', 'event-post').'</span>';
1922 2474 }
1923 - $html = '<select class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'"
1924 - type="text"
1925 - name="'.$fieldname.'"
1926 - style="font-family : dashicons">
1927 - <option value="">'.__("None", 'event-post').'</option>';
2475 + $html = '<select class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'"
2476 + type="text"
2477 + name="'.$fieldname.'"
2478 + style="font-family : dashicons">
2479 + <option value="">'.__("None", 'event-post').'</option>';
1928 2480 foreach($this->DashIcons->icons as $class => $unicode){
1929 - $html .= '<option value="'.$class.'">&#x'.$unicode.'; '.$class.'</option>';
1930 -
1931 - }
2481 + $html .= '<option value="'.$class.'">&#x'.$unicode.'; '.$class.'</option>';
2482 + }
1932 2483 $html .= '</select>';
1933 2484
1934 2485 }
1935 2486 return $html;
@@ -1936,9 +2487,10 @@
1936 2487 }
1937 2488
1938 2489
1939 2490 /**
1940 - *
2491 + * Bulk edit
2492 + *
1941 2493 * @param type $column_name
1942 2494 * @param type $post_type
1943 2495 */
1944 2496 function bulk_edit($column_name, $post_type){
@@ -1946,17 +2498,20 @@
1946 2498 }
1947 2499
1948 2500 /**
1949 2501 * Saves data from quick-edit via `wp_ajax_inline-save` action
2502 + *
1950 2503 * @return void
1951 2504 */
1952 2505 function inline_save(){
1953 - $post_id = filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT);
2506 + $post_id = absint(filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT));
1954 2507 $this->save_postdata($post_id);
1955 2508 }
1956 2509 /**
1957 2510 * When the post is saved, saves our custom data
2511 + *
1958 2512 * @param int $post_id
2513 + *
1959 2514 * @return void
1960 2515 */
1961 2516 public function save_postdata($post_id) {
1962 2517 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
@@ -1962,36 +2517,60 @@
1962 2517 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
1963 2518 return;
1964 2519 }
1965 2520
1966 - if (!wp_verify_nonce(filter_input(INPUT_POST, 'eventpost_nonce', FILTER_SANITIZE_STRING), plugin_basename(__FILE__))){
2521 + if (!wp_verify_nonce((string) filter_input(INPUT_POST, 'eventpost_nonce'), plugin_basename(__FILE__))){
1967 2522 return;
1968 2523 }
1969 2524
2525 + $post_id = absint($post_id);
2526 + if (!$post_id || !current_user_can('edit_post', $post_id)) {
2527 + return;
2528 + }
2529 +
1970 2530 // Clean color or no color
1971 - if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR, FILTER_SANITIZE_STRING)) {
1972 - update_post_meta($post_id, $this->META_COLOR, $color);
2531 + if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR)) {
2532 + update_post_meta($post_id, $this->META_COLOR, sanitize_text_field($color));
1973 2533 }
1974 2534 // Clean color or no color
1975 - if (false !== $icon = filter_input(INPUT_POST, $this->META_ICON, FILTER_SANITIZE_STRING)) {
1976 - update_post_meta($post_id, $this->META_ICON, $icon);
2535 + if (false !== $icon = filter_input(INPUT_POST, $this->META_ICON)) {
2536 + update_post_meta($post_id, $this->META_ICON, sanitize_text_field($icon));
1977 2537 }
1978 - if (false !== $attendance_mode = filter_input(INPUT_POST, $this->META_ATTENDANCE_MODE, FILTER_SANITIZE_STRING)) {
1979 - update_post_meta($post_id, $this->META_ATTENDANCE_MODE, $attendance_mode);
2538 + if (false !== $attendance_mode = filter_input(INPUT_POST, $this->META_ATTENDANCE_MODE)) {
2539 + update_post_meta($post_id, $this->META_ATTENDANCE_MODE, sanitize_text_field($attendance_mode));
1980 2540 }
1981 - if (false !== $status = filter_input(INPUT_POST, $this->META_STATUS, FILTER_SANITIZE_STRING)) {
1982 - update_post_meta($post_id, $this->META_STATUS, $status);
2541 + if (false !== $status = filter_input(INPUT_POST, $this->META_STATUS)) {
2542 + update_post_meta($post_id, $this->META_STATUS, sanitize_text_field($status));
1983 2543 }
1984 - if (false !== $virtual_location = filter_input(INPUT_POST, $this->META_VIRTUAL_LOCATION, FILTER_SANITIZE_URL)) {
1985 - update_post_meta($post_id, $this->META_VIRTUAL_LOCATION, $virtual_location);
2544 + $virtual_location = filter_input(INPUT_POST, $this->META_VIRTUAL_LOCATION, FILTER_SANITIZE_URL);
2545 + if ($virtual_location !== null && $virtual_location !== false) {
2546 + update_post_meta($post_id, $this->META_VIRTUAL_LOCATION, sanitize_url($virtual_location));
1986 2547 }
2548 + if (false !== $organization = filter_input(INPUT_POST, $this->META_ORGANIZATION)) {
2549 + update_post_meta($post_id, $this->META_ORGANIZATION, sanitize_text_field($organization));
2550 + }
2551 + $offer_url = filter_input(INPUT_POST, "{$this->META_OFFER}_url", FILTER_SANITIZE_URL);
2552 + $offer_price = filter_input(INPUT_POST, "{$this->META_OFFER}_price");
2553 + $offer_currency = filter_input(INPUT_POST, "{$this->META_OFFER}_currency");
2554 + if ($offer_url || ($offer_price && $offer_currency) ) {
2555 + // Format floating
2556 + $offer_price = $offer_price ? str_replace(',', '.', $offer_price) : null;
2557 + update_post_meta($post_id, $this->META_OFFER, array(
2558 + 'url' => $offer_url ? sanitize_text_field($offer_url) : null,
2559 + 'price' => $offer_price ? (float) $offer_price : null,
2560 + 'currency' => $offer_currency ? sanitize_text_field($offer_currency) : null,
2561 + ));
2562 + }
2563 + else{
2564 + delete_post_meta($post_id, $this->META_OFFER);
2565 + }
1987 2566 // Clean date or no date
1988 - if ((false !== $start = filter_input(INPUT_POST, $this->META_START, FILTER_SANITIZE_STRING)) &&
1989 - (false !== $end = filter_input(INPUT_POST, $this->META_END, FILTER_SANITIZE_STRING)) &&
2567 + if ((false !== $start = filter_input(INPUT_POST, $this->META_START)) &&
2568 + (false !== $end = filter_input(INPUT_POST, $this->META_END)) &&
1990 2569 '' != $start &&
1991 2570 '' != $end) {
1992 - update_post_meta($post_id, $this->META_START, substr($start,0,16).':00');
1993 - update_post_meta($post_id, $this->META_END, substr($end,0,16).':00');
2571 + update_post_meta($post_id, $this->META_START, sanitize_text_field(substr($start,0,16).':00'));
2572 + update_post_meta($post_id, $this->META_END, sanitize_text_field(substr($end,0,16).':00'));
1994 2573 }
1995 2574 else {
1996 2575 delete_post_meta($post_id, $this->META_START);
1997 2576 delete_post_meta($post_id, $this->META_END);
@@ -1997,15 +2576,15 @@
1997 2576 delete_post_meta($post_id, $this->META_END);
1998 2577 }
1999 2578
2000 2579 // Clean location or no location
2001 - if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT, FILTER_SANITIZE_STRING)) &&
2002 - (false !== $long = filter_input(INPUT_POST, $this->META_LONG, FILTER_SANITIZE_STRING)) &&
2580 + if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT)) &&
2581 + (false !== $long = filter_input(INPUT_POST, $this->META_LONG)) &&
2003 2582 '' != $lat &&
2004 2583 '' != $long) {
2005 - update_post_meta($post_id, $this->META_ADD, filter_input(INPUT_POST, $this->META_ADD, FILTER_SANITIZE_STRING));
2006 - update_post_meta($post_id, $this->META_LAT, $lat);
2007 - update_post_meta($post_id, $this->META_LONG, $long);
2584 + update_post_meta($post_id, $this->META_ADD, sanitize_text_field(filter_input(INPUT_POST, $this->META_ADD)));
2585 + update_post_meta($post_id, $this->META_LAT, $this->sanitize_coordinate(sanitize_text_field($lat)));
2586 + update_post_meta($post_id, $this->META_LONG, $this->sanitize_coordinate(sanitize_text_field($long)));
2008 2587 }
2009 2588 else {
2010 2589 delete_post_meta($post_id, $this->META_ADD);
2011 2590 delete_post_meta($post_id, $this->META_LAT);
@@ -2016,39 +2595,44 @@
2016 2595 }
2017 2596
2018 2597 /**
2019 2598 * Saves data from bulk-edit
2020 - * Should be used via AJAX
2021 - *
2022 - * outputs JSON
2599 + * Uses bulk_edit_posts hook
2600 + *
2601 + * @see https://developer.wordpress.org/reference/hooks/bulk_edit_posts/
2602 + *
2023 2603 * @return void
2024 2604 */
2025 - function save_bulkdatas() {
2026 - $current_post_type = isset($_POST['post_type']) ? $_POST['post_type'] : 'post';
2605 + function save_bulkdatas(array $post_ids, array $shared_post_data) {
2606 + if (!wp_verify_nonce(filter_input(INPUT_GET, 'eventpost_nonce'), plugin_basename(__FILE__))){
2607 + return;
2608 + }
2609 + $current_post_type = isset($shared_post_data['post_type']) ? $shared_post_data['post_type'] : 'post';
2027 2610 if (in_array($current_post_type, $this->settings['posttypes'])) {
2028 - $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
2029 2611 if (!empty($post_ids) && is_array($post_ids)) {
2030 - foreach ($this->bulk_edit_fields as $sets) {
2031 - foreach ($sets as $fieldname => $fieldlabel) {
2032 - if ((false != $value = filter_input(INPUT_POST, $fieldname))) {
2033 - foreach ($post_ids as $post_id) {
2034 - update_post_meta($post_id, $fieldname, $value);
2612 + foreach ($post_ids as $post_id) {
2613 + if(! current_user_can( 'edit_post', $post_id )){
2614 + continue;
2615 + }
2616 + foreach ($this->bulk_edit_fields as $sets) {
2617 + foreach ($sets as $fieldname => $fieldlabel) {
2618 + if (isset($shared_post_data[$fieldname])) {
2619 + update_post_meta($post_id, $fieldname, $shared_post_data[$fieldname]);
2035 2620 }
2036 2621 }
2037 2622 }
2038 2623 }
2039 2624 }
2040 - wp_send_json(true);
2041 - exit;
2042 2625 }
2043 - wp_send_json(false);
2044 2626 }
2045 2627
2046 2628 /**
2047 - *
2629 + * Displays a date for calendar cell
2630 + *
2048 2631 * @param string $date
2049 2632 * @param string $cat
2050 2633 * @param boolean $display
2634 + *
2051 2635 * @return boolean
2052 2636 */
2053 2637 public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='',$tax_name='' ,$tax_term='') {
2054 2638 $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true,'tax_name' => $tax_name ,'tax_term' => $tax_term));
@@ -2053,21 +2637,26 @@
2053 2637 public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='',$tax_name='' ,$tax_term='') {
2054 2638 $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true,'tax_name' => $tax_name ,'tax_term' => $tax_term));
2055 2639 $nb = count($events);
2056 2640 $ret = "";
2641 + $price = "";
2057 2642 if(!$display && !$nb){
2058 2643 $ret = date('j', $date);
2059 2644 }
2645 + $price = '';
2060 2646 if($nb){
2061 2647 if ($display || $title) {
2062 2648 $ret='<ul>';
2063 2649 foreach ($events as $event) {
2650 + $price = $this->get_price($event, true);
2064 2651 if ($this->settings['emptylink'] == 0 && empty($event->post_content)) {
2065 2652 $event->guid = '#';
2066 2653 }
2067 2654 $ret.='<li>'
2655 + // Translators: %s is the event title
2068 2656 . '<a href="' . $event->permalink . '" title="'.esc_attr(sprintf(__('View event: %s', 'event-post'), $event->post_title)).'">'
2069 2657 . '<h4>' . $event->post_title . '</h4>'
2658 + . '<span class="event_price">' . $price . '</span>'
2070 2659 .$this->get_single($event)
2071 2660 . (!empty($thumbnail) ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->ID, $thumbnail) . '</span>' : '')
2072 2661 .'</a>'
2073 2662 . '</li>';
@@ -2082,8 +2671,9 @@
2082 2671 }
2083 2672 else {
2084 2673 $ret = '<button data-event="'. $tax_term .'" data-date="' . date('Y-m-d', $date).'"'
2085 2674 .' class="'.apply_filters( 'event_post_class_calendar_link', 'eventpost_cal_link' ).'"'.($colored?' style="background-color:#'.$events[0]->color.'"':'')
2675 + // Translators: %1$d is the number of events, %2$s is the date
2086 2676 .' title="'.esc_attr(sprintf(_n('View %1$d event at date %2$s', 'View %1$d events at date %2$s', $nb, 'event-post'), $nb, $this->human_date($date, $this->settings['dateformat']))).'"'
2087 2677 .'>'
2088 2678 . date('j', $date)
2089 2679 . '</button>';
@@ -2088,16 +2678,19 @@
2088 2678 . date('j', $date)
2089 2679 . '</button>';
2090 2680 }
2091 2681 }
2092 -
2093 - return apply_filters('eventpost_display_caldate', $ret, $events, $date, $cat ,$display ,$colored ,$thumbnail ,$title ,$tax_name ,$tax_term );
2682 + return apply_filters('eventpost_display_caldate', $ret, $events, $date, $cat ,$price, $display ,$colored ,$thumbnail ,$title ,$tax_name ,$tax_term );
2094 2683 }
2095 2684
2096 2685
2097 2686 /**
2687 + * Returns a calendar HTML
2688 + *
2098 2689 * @param array $atts
2690 + *
2099 2691 * @filter eventpost_params
2692 + *
2100 2693 * @return string
2101 2694 */
2102 2695 public function calendar($atts) {
2103 2696 extract(shortcode_atts(apply_filters('eventpost_params', array(
@@ -2146,14 +2739,18 @@
2146 2739 . '</caption>';
2147 2740 $ret.='<thead><tr><th colspan="7">';
2148 2741 if ($datepicker == 1) {
2149 2742 $ret.='<div class="eventpost-calendar-header">';
2743 + // Translators: %s is the year
2150 2744 $ret.='<span class="eventpost-cal-year"><button data-date="' . date('Y-n', $prev_year) . '" tabindex="0" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $prev_year)).'" class="eventpost_cal_bt eventpost-cal-bt-prev">&laquo;</button><span class="eventpost-cal-header-text">';
2151 2745 $ret.=$annee;
2746 + // Translators: %s is the year
2152 2747 $ret.='</span><button data-date="' . date('Y-n', $next_year) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $next_year)).'" class="eventpost_cal_bt eventpost-cal-bt-next">&raquo;</button></span>';
2153 - $ret.='<span class="eventpost-cal-month"><button data-date="' . date('Y-n', $prev_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $prev_month)).'" class="eventpost_cal_bt eventpost-cal-bt-prev">&laquo;</button><span class="eventpost-cal-header-text">';
2748 + // Translators: %s is the month name
2749 + $ret.='<span class="eventpost-cal-month"><button data-date="' . date('Y-n', $prev_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $prev_month)).'" class="eventpost_cal_bt eventpost-cal-bt-prev eventpost-cal-bt-prev-month">&laquo;</button><span class="eventpost-cal-header-text">';
2154 2750 $ret.=$this->NomDuMois[abs($mois)];
2155 - $ret.='</span><button data-date="' . date('Y-n', $next_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $next_month)).'" class="eventpost_cal_bt eventpost-cal-bt-next">&raquo;</button> </span>';
2751 + // Translators: %s is the month name
2752 + $ret.='</span><button data-date="' . date('Y-n', $next_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $next_month)).'" class="eventpost_cal_bt eventpost-cal-bt-next eventpost-cal-bt-next-month">&raquo;</button> </span>';
2156 2753 $ret.='<span class="eventpost-cal-today"><button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button></span>';
2157 2754 $ret.='</div>';
2158 2755 }
2159 2756 $ret.='</th></tr><tr class="event_post_cal_days">';
@@ -2194,14 +2791,14 @@
2194 2791 return $ret;
2195 2792 }
2196 2793
2197 2794 /**
2198 - * echoes a list of event, should be called via AJAX
2795 + * Echoes a list of event, should be called via AJAX
2199 2796 *
2200 2797 * @return void
2201 2798 */
2202 2799 public function ajaxlist(){
2203 - echo $this->list_events(array(
2800 + echo wp_kses($this->list_events(array(
2204 2801 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2205 2802 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2206 2803 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2207 2804 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
@@ -2222,19 +2819,19 @@
2222 2819 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2223 2820 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2224 2821 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2225 2822 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2226 - ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2823 + ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type'))), $this->kses_tags);
2227 2824 exit;
2228 2825 }
2229 2826
2230 2827 /**
2231 - * echoes a list of event, should be called via AJAX
2828 + * Echoes a list of event, should be called via AJAX
2232 2829 *
2233 2830 * @return void
2234 2831 */
2235 2832 public function ajaxTimeline(){
2236 - echo $this->list_events(array(
2833 + echo wp_kses($this->list_events(array(
2237 2834 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2238 2835 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2239 2836 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2240 2837 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
@@ -2255,13 +2852,13 @@
2255 2852 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2256 2853 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2257 2854 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2258 2855 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2259 - ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2856 + ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type'))), $this->kses_tags);
2260 2857 exit;
2261 2858 }
2262 2859 /**
2263 - * echoes next page of events, should be called via AJAX
2860 + * Echoes next page of events, should be called via AJAX
2264 2861 *
2265 2862 * @return void
2266 2863 */
2267 2864 public function ajaxGetNextPage(){
@@ -2276,15 +2873,15 @@
2276 2873 }
2277 2874 if(isset($_POST['paged'])){
2278 2875 $query["paged"] = esc_attr($_POST['paged']);
2279 2876 }else{
2280 - $response['message'] = __('Page number missing');
2877 + $response['message'] = __('Page number missing', 'event-post');
2281 2878 }
2282 2879 $query['container_schema'] = $this->timeline_shema['container'];
2283 2880 $query['item_schema'] = $this->timeline_shema['item'];
2284 2881 $html = $this->list_events($query,'event_timeline','events_only');
2285 2882 if($html == ""){
2286 - $response['message'] = __('No more to load');
2883 + $response['message'] = __('No more to load', 'event-post');
2287 2884 }else{
2288 2885 $query["paged"] = $query["paged"] + 1;
2289 2886 $next_html = $this->list_events($query,'event_timeline','events_only');
2290 2887 $response = [
@@ -2293,9 +2890,9 @@
2293 2890 "next_query" => $next_html == "" ? false : true,
2294 2891 ];
2295 2892 }
2296 2893 }else{
2297 - $response['message'] = __('Query missing');
2894 + $response['message'] = __('Query missing', 'event-post');
2298 2895 }
2299 2896 wp_send_json($response);
2300 2897 exit;
2301 2898 }
@@ -2300,14 +2897,15 @@
2300 2897 exit;
2301 2898 }
2302 2899
2303 2900 /**
2304 - * echoes the content of the calendar in ajax context
2901 + * Echoes the content of the calendar in ajax context
2902 + *
2305 2903 * @return void
2306 2904 */
2307 2905 public function ajaxcal() {
2308 2906 $method = isset($_GET['action']) ? INPUT_GET : INPUT_POST;
2309 - echo $this->calendar(array(
2907 + echo wp_kses($this->calendar(array(
2310 2908 'date' => esc_attr(FILTER_INPUT($method, 'date')),
2311 2909 'cat' => esc_attr(FILTER_INPUT($method, 'cat')),
2312 2910 'mondayfirst' => esc_attr(FILTER_INPUT($method, 'mf')),
2313 2911 'datepicker' => esc_attr(FILTER_INPUT($method, 'dp')),
@@ -2315,17 +2913,17 @@
2315 2913 'display_title' => esc_attr(FILTER_INPUT($method, 'display_title')),
2316 2914 'thumbnail' => esc_attr(FILTER_INPUT($method, 'thumbnail')),
2317 2915 'tax_name' => esc_attr(FILTER_INPUT($method, 'tax_name')),
2318 2916 'tax_term' => esc_attr(FILTER_INPUT($method, 'tax_term')),
2319 - ));
2917 + )), $this->kses_tags);
2320 2918 exit();
2321 2919 }
2322 2920
2323 2921 /**
2324 - * echoes the date of the calendar in ajax context
2922 + * Echoes the date of the calendar in ajax context
2325 2923 */
2326 2924 public function ajaxdate() {
2327 - echo $this->display_caldate(
2925 + echo wp_kses($this->display_caldate(
2328 2926 strtotime(esc_attr(FILTER_INPUT(INPUT_GET, 'date'))),
2329 2927 esc_attr(FILTER_INPUT(INPUT_GET, 'cat')),
2330 2928 true,
2331 2929 esc_attr(FILTER_INPUT(INPUT_GET, 'color')),
@@ -2332,19 +2930,19 @@
2332 2930 esc_attr(FILTER_INPUT(INPUT_GET, 'thumbnail')),
2333 2931 esc_attr(FILTER_INPUT(INPUT_GET, 'display_title')),
2334 2932 esc_attr(FILTER_INPUT(INPUT_GET, 'tax_name')),
2335 2933 esc_attr(FILTER_INPUT(INPUT_GET, 'tax_term'))
2336 - );
2934 + ), $this->kses_tags);
2337 2935 exit();
2338 2936 }
2339 2937
2340 2938 /**
2341 - * echoes a date in ajax context
2939 + * Echoes a date in ajax context
2342 2940 */
2343 2941 public function HumanDate() {
2344 2942 if (isset($_REQUEST['date']) && !empty($_REQUEST['date'])) {
2345 2943 $date = strtotime($_REQUEST['date']);
2346 - echo $this->human_date($date, $this->settings['dateformat']).(date('H:i', $date)=='00:00' ? '' : ' '. date($this->settings['timeformat'], $date));
2944 + echo esc_html($this->human_date($date, $this->settings['dateformat']).(date('H:i', $date)=='00:00' ? '' : ' '. date($this->settings['timeformat'], $date)));
2347 2945 exit();
2348 2946 }
2349 2947 }
2350 2948
@@ -2351,8 +2949,9 @@
2351 2949 /**
2352 2950 * Displays a search form
2353 2951 *
2354 2952 * @param type $atts
2953 + *
2355 2954 * @return type
2356 2955 */
2357 2956 public function search($atts) {
2358 2957 $params = shortcode_atts(apply_filters('eventpost_params', array(
@@ -2423,8 +3022,54 @@
2423 3022 }
2424 3023 }
2425 3024
2426 3025 /**
3026 + * Geocodes an address using OpenStreetMap Nominatim API and cache the result in a transient for 30 days
3027 + *
3028 + * @param string $address
3029 + * @param boolean $single_result Whether to return only the first result or all results
3030 + *
3031 + * @return array|false|string The geocoding result(s) or false on failure
3032 + */
3033 + public function geocode(string $address, bool $single_result = false){
3034 + $transient_name = 'eventpost_osquery_' . $address;
3035 + $val = get_transient($transient_name);
3036 + if (false === $val || empty($val) || !is_string($val)) {
3037 + $language = get_bloginfo('language');
3038 + if (strpos($language, '-') > -1) {
3039 + $language = strtolower(substr($language, 0, 2));
3040 + }
3041 + $remote_val = wp_safe_remote_request('https://nominatim.openstreetmap.org/search?q=' . rawurlencode($address) . '&format=json&accept-language=' . $language, [
3042 + 'user-agent' => getenv('HTTP_USER_AGENT') ?? 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url'),
3043 + 'headers' => [
3044 + 'Referer' => get_bloginfo('url'),
3045 + ],
3046 + 'timeout' => 5,
3047 + ]);
3048 + $remote_body = wp_remote_retrieve_body($remote_val);
3049 + if(strstr($remote_body, '<html>')){
3050 + $val = [
3051 + [
3052 + 'lat' => '',
3053 + 'lon' => '',
3054 + 'display_name' => strip_tags($remote_body),
3055 + ]
3056 + ];
3057 + }
3058 + else{
3059 + $val = json_decode($remote_body);
3060 + if($val){
3061 + set_transient($transient_name, $val, 30 * DAY_IN_SECONDS);
3062 + }
3063 + }
3064 + }
3065 + if($single_result && is_array($val) && count($val) > 0){
3066 + $val = $val[0];
3067 + }
3068 + return $val;
3069 + }
3070 +
3071 + /**
2427 3072 * AJAX Get lat long from address
2428 3073 */
2429 3074 public function GetLatLong() {
2430 3075 if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
@@ -2430,31 +3075,22 @@
2430 3075 if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
2431 3076 // verifier le cache
2432 3077 $q = $_REQUEST['q'];
2433 3078 header('Content-Type: application/json');
2434 - $transient_name = 'eventpost_osquery_' . $q;
2435 - $val = get_transient($transient_name);
2436 - if (false === $val || empty($val) || !is_string($val)) {
2437 - $language = get_bloginfo('language');
2438 - if (strpos($language, '-') > -1) {
2439 - $language = strtolower(substr($language, 0, 2));
2440 - }
2441 - $remote_val = wp_safe_remote_request('http://nominatim.openstreetmap.org/search?q=' . urlencode($q) . '&format=json&accept-language=' . $language);
2442 - if(json_decode($remote_val['body'])){
2443 - $val = $remote_val['body'];
2444 - }
2445 - set_transient($transient_name, $val, 30 * DAY_IN_SECONDS);
2446 - }
2447 - echo $val;
3079 + $val = $this->geocode($q);
3080 + wp_send_json( $val );
2448 3081 exit();
2449 3082 }
2450 3083 }
2451 3084
2452 3085 /**
2453 - * alters columns
3086 + * Alters columns
3087 + *
2454 3088 * @param array $defaults
3089 + *
3090 + * @filter eventpost_columns_head
3091 + *
2455 3092 * @return array
2456 - * @filter eventpost_columns_head
2457 3093 */
2458 3094 public function columns_head($defaults) {
2459 3095 $defaults['event'] = __('Event', 'event-post');
2460 3096 $defaults['location'] = __('Location', 'event-post');
@@ -2461,17 +3097,19 @@
2461 3097 return apply_filters('eventpost_columns_head', $defaults);
2462 3098 }
2463 3099
2464 3100 /**
2465 - * echoes content of a row in a given column
3101 + * Echoes content of a row in a given column
3102 + *
2466 3103 * @param string $column_name
2467 3104 * @param int $post_id
3105 + *
2468 3106 * @action eventpost_columns_content
2469 3107 */
2470 3108 public function columns_content($column_name, $post_id) {
2471 3109 if ($column_name == 'location') {
2472 - $lat = get_post_meta($post_id, $this->META_LAT, true);
2473 - $lon = get_post_meta($post_id, $this->META_LONG, true);
3110 + $lat = $this->sanitize_coordinate(get_post_meta($post_id, $this->META_LAT, true));
3111 + $lon = $this->sanitize_coordinate(get_post_meta($post_id, $this->META_LONG, true));
2474 3112
2475 3113 if (!empty($lat) && !empty($lon)) {
2476 3114 add_thickbox();
2477 3115 $color = $this->get_post_color($post_id, $this->settings['default_color'], true);
@@ -2481,18 +3119,18 @@
2481 3119 }
2482 3120 if ($icon == ''){
2483 3121 $icon = 'location';
2484 3122 }
2485 - echo '<a href="https://www.openstreetmap.org/export/embed.html?bbox='.($lon-0.005).'%2C'.($lat-0.005).'%2C'.($lon+0.005).'%2C'.($lat+0.005).'&TB_iframe=true&width=600&height=550" class="thickbox" target="_blank">'
3123 + echo wp_kses( '<a href="https://www.openstreetmap.org/export/embed.html?bbox='.($lon-0.005).'%2C'.($lat-0.005).'%2C'.($lon+0.005).'%2C'.($lat+0.005).'&TB_iframe=true&width=600&height=550" class="thickbox" target="_blank">'
2486 3124 . '<i class="dashicons dashicons-'.$icon.'" style="color:#'.$color.';"></i>'
2487 3125 . '<span class="screen-reader-text">'.__('View on a map', 'event-post').'</span>'
2488 3126 . get_post_meta($post_id, $this->META_ADD, true)
2489 - . '</a> ';
3127 + . '</a> ', $this->kses_tags);
2490 3128 }
2491 3129 $this->column_edit_hidden_fields($post_id, 'location');
2492 3130 }
2493 3131 if ($column_name == 'event') {
2494 - echo $this->print_date($post_id, false);
3132 + echo wp_kses($this->print_date($post_id, false), $this->kses_tags);
2495 3133 $this->column_edit_hidden_fields($post_id, 'event');
2496 3134 }
2497 3135 do_action('eventpost_columns_content', $column_name, $post_id);
2498 3136 }
@@ -2498,20 +3136,25 @@
2498 3136 }
2499 3137
2500 3138 function column_edit_hidden_fields($post_id, $set){
2501 3139 $event = $this->retreive($post_id);
2502 - echo '<div class="hidden">';
2503 - foreach($this->quick_edit_fields[$set] as $fieldname=>$fieldlabel){
2504 - echo'<span class="inline-edit-value '.$fieldname.'">'.esc_attr($event->$fieldname).'</span>';
3140 + $html = '<div class="hidden">';
3141 + if ($event != false){
3142 + foreach($this->quick_edit_fields[$set] as $fieldname=>$fieldlabel){
3143 + $html .= '<span class="inline-edit-value '.$fieldname.'">'.esc_attr($event->$fieldname).'</span>';
3144 + }
2505 3145 }
2506 - echo '</div>';
3146 + $html .= '</div>';
3147 + echo wp_kses($html, $this->kses_tags);
2507 3148 }
2508 3149
2509 - /** ADMIN PAGES **/
3150 + // ADMIN PAGES
2510 3151
2511 3152 /**
2512 - * adds items to the native "right now" dashboard widget
3153 + * Adds items to the native "right now" dashboard widget
3154 + *
2513 3155 * @param array $elements
3156 + *
2514 3157 * @return array
2515 3158 */
2516 3159 public function dashboard_right_now($elements){
2517 3160 $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
@@ -2516,11 +3159,13 @@
2516 3159 public function dashboard_right_now($elements){
2517 3160 $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
2518 3161 $nb_geo = count($this->get_events(array('future'=>1, 'past'=>1, 'geo'=>1, 'nb'=>-1)));
2519 3162 if($nb_date){
3163 + // Translators: %d is the number of events
2520 3164 array_push($elements, '<i class="dashicons dashicons-calendar"></i> <i href="edit.php?post_type=post">'.sprintf(__('%d Events','event-post'), $nb_date)."</i>");
2521 3165 }
2522 3166 if($nb_geo){
3167 + // Translators: %d is the number of geolocalized events
2523 3168 array_push($elements, '<i class="dashicons dashicons-location"></i> <i href="edit.php?post_type=post">'.sprintf(__('%d Geolocalized events','event-post'), $nb_geo)."</i>");
2524 3169 }
2525 3170 return $elements;
2526 3171 }
@@ -2525,19 +3170,21 @@
2525 3170 return $elements;
2526 3171 }
2527 3172
2528 3173 /*
2529 - * feed
3174 + * Feed
2530 3175 * generate ICS or VCS files from a category
2531 3176 */
2532 3177
2533 3178 /**
2534 - *
3179 + * Get a date formatted for ICS
3180 + *
2535 3181 * @param timestamp $timestamp
3182 + *
2536 3183 * @return string
2537 3184 */
2538 3185 public function ics_date($timestamp){
2539 - return date("Ymd",$timestamp).'T'.date("His",$timestamp);
3186 + return date("Ymd",$timestamp).'T'.date("His",$timestamp);
2540 3187 }
2541 3188
2542 3189 public function get_gmt_offset(){
2543 3190 $gmt_offset = get_option('gmt_offset ');
@@ -2551,16 +3198,34 @@
2551 3198 }
2552 3199 return $gmt_offset;
2553 3200 }
2554 3201
3202 + /**
3203 + * Outputs an ICS or VCS file for a given event
3204 + *
3205 + * @param int $event_id
3206 + * @param string $format
3207 + *
3208 + * @return void
3209 + */
2555 3210 private function generate_ics($event_id, $format){
2556 - $export_file = plugin_dir_path(__FILE__).'inc/export/'.$format.'.php';
2557 - if(is_numeric($event_id) && file_exists($export_file)){
2558 - $event = $this->retreive($event_id);
2559 - include $export_file;
2560 - exit;
3211 + $allowed_formats = array('ics', 'vcs');
3212 + $event_id = intval($event_id);
3213 + $format = sanitize_text_field($format);
3214 + if (in_array($format, $allowed_formats)) {
3215 + $export_file = plugin_dir_path(__FILE__) . 'inc/export/' . $format . '.php';
3216 + if (is_numeric($event_id) && file_exists($export_file)) {
3217 + $event = $this->retreive($event_id);
3218 + if($event->post_status != 'publish'){
3219 + wp_die(esc_html__('Event not found.', 'event-post'), 404);
3220 + }
3221 + include $export_file;
3222 + exit;
3223 + }
2561 3224 }
3225 + wp_die(esc_html__('Invalid request.', 'event-post'), 400);
2562 3226 }
3227 +
2563 3228
2564 3229 public function parse_request(){
2565 3230 global $wp;
2566 3231 if (preg_match('#^event-feed#i', $wp->request, $match)) {
@@ -2573,9 +3238,9 @@
2573 3238 }
2574 3239
2575 3240 public function export(){
2576 3241 if(false !== $event_id=\filter_input(INPUT_GET, 'event_id',FILTER_SANITIZE_NUMBER_INT)){
2577 - $format = \filter_input(INPUT_GET, 'format',FILTER_SANITIZE_STRING);
3242 + $format = \filter_input(INPUT_GET, 'format');
2578 3243 $this->generate_ics($event_id, $format);
2579 3244 }
2580 3245 }
2581 3246
@@ -2580,77 +3245,119 @@
2580 3245 }
2581 3246
2582 3247
2583 3248 /**
2584 - * outputs an ICS document
3249 + * Outputs an ICS document
3250 + *
3251 + * Filters can be applied to the criteria used to retrieve events in GET parameters:
3252 + * - cat : category slug
3253 + * - tag : tag slug
3254 + * - tax_name : custom taxonomy name
3255 + * - tax_term : custom taxonomy term slug
3256 + * - nb : number of events to retrieve (default 10)
3257 + * - future : retreive future events
3258 + * - past : retreive past events
3259 + *
3260 + * @return void
2585 3261 */
2586 3262 public function feed(){
2587 - if(false !== $cat=\filter_input(INPUT_GET, 'cat',FILTER_SANITIZE_STRING)){
2588 - $vtz = get_option('timezone_string');
2589 - $gmt = $this->get_gmt_offset();
2590 - date_default_timezone_set($vtz);
2591 - $separator = "\n";
3263 + $criteria = array(
3264 + 'nb'=>10,
3265 + );
3266 + if(false !== $cat=\filter_input(INPUT_GET, 'cat')){
3267 + $criteria['cat'] = sanitize_text_field($cat);
3268 + }
3269 + if(false !== $tag=\filter_input(INPUT_GET, 'tag')){
3270 + $criteria['tag'] = sanitize_text_field($tag);
3271 + }
3272 + if(false !== $tax_name=\filter_input(INPUT_GET, 'tax_name')){
3273 + $criteria['tax_name'] = sanitize_text_field($tax_name);
3274 + }
3275 + if(false !== $tax_term=\filter_input(INPUT_GET, 'tax_term')){
3276 + $criteria['tax_term'] = sanitize_text_field($tax_term);
3277 + }
3278 + if(false !== $nb=\filter_input(INPUT_GET, 'nb', FILTER_SANITIZE_NUMBER_INT)){
3279 + $criteria['nb'] = sanitize_text_field($nb);
3280 + }
3281 + if(false !== $future=\filter_input(INPUT_GET, 'future', FILTER_SANITIZE_NUMBER_INT)){
3282 + $criteria['future'] = sanitize_text_field($future);
3283 + }
3284 + if(false !== $past=\filter_input(INPUT_GET, 'past', FILTER_SANITIZE_NUMBER_INT)){
3285 + $criteria['past'] = sanitize_text_field($past);
3286 + }
3287 + $vtz = get_option('timezone_string');
3288 + $gmt = $this->get_gmt_offset();
3289 + date_default_timezone_set($vtz);
3290 + $separator = "\n";
2592 3291
2593 - header("content-type:text/calendar");
2594 - header("Pragma: public");
2595 - header("Expires: 0");
2596 - header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
2597 - header("Cache-Control: public");
2598 - header("Content-Disposition: attachment; filename=". str_replace('+','-',urlencode(get_option('blogname').'-'.$cat)).".ics;" );
3292 + header("content-type:text/calendar");
3293 + header("Pragma: public");
3294 + header("Expires: 0");
3295 + header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
3296 + header("Cache-Control: public");
3297 + header("Content-Disposition: attachment; filename=". str_replace('+','-',rawurlencode(get_option('blogname').'-'.$cat)).".ics;" );
2599 3298
2600 - $props = array();
3299 + $props = array();
2601 3300
2602 - // General
2603 - $props[] = 'BEGIN:VCALENDAR';
2604 - $props[] = 'PRODID://WordPress//Event-Post-V'. file_get_contents(('VERSION')).'//EN';
2605 - $props[] = 'VERSION:2.0';
3301 + // General
3302 + $props[] = 'BEGIN:VCALENDAR';
3303 + $props[] = 'PRODID://WordPress//Event-Post-V'.$this->version.'//EN';
3304 + $props[] = 'VERSION:2.0';
3305 + // Timezone
3306 + if(!empty($vtz)){
3307 + array_push($props,
3308 + 'BEGIN:VTIMEZONE',
3309 + 'TZID:'.$vtz,
3310 + 'BEGIN:DAYLIGHT',
3311 + 'TZOFFSETFROM:+0100',
3312 + 'TZOFFSETTO:'.($gmt).'00',
3313 + 'DTSTART:19700329T020000',
3314 + 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3',
3315 + 'END:DAYLIGHT',
3316 + 'BEGIN:STANDARD',
3317 + 'TZOFFSETFROM:'.($gmt).'00',
3318 + 'TZOFFSETTO:+0100',
3319 + 'TZNAME:CET',
3320 + 'DTSTART:19701025T030000',
3321 + 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
3322 + 'END:STANDARD',
3323 + 'END:VTIMEZONE'
3324 + );
3325 + }
2606 3326
2607 - // Timezone
2608 - if(!empty($vtz)){
2609 - array_push($props,
2610 - 'BEGIN:VTIMEZONE',
2611 - 'TZID:'.$vtz,
2612 - 'BEGIN:DAYLIGHT',
2613 - 'TZOFFSETFROM:+0100',
2614 - 'TZOFFSETTO:'.($gmt).'00',
2615 - 'DTSTART:19700329T020000',
2616 - 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3',
2617 - 'END:DAYLIGHT',
2618 - 'BEGIN:STANDARD',
2619 - 'TZOFFSETFROM:'.($gmt).'00',
2620 - 'TZOFFSETTO:+0100',
2621 - 'TZNAME:CET',
2622 - 'DTSTART:19701025T030000',
2623 - 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
2624 - 'END:STANDARD',
2625 - 'END:VTIMEZONE'
2626 - );
2627 - }
2628 -
2629 - // Events
2630 - $events=$this->get_events(array('cat'=>$cat,'nb'=>-1));
2631 - foreach ($events as $event) {
2632 - if($event->time_start && $event->time_end){
2633 - array_push($props,
2634 - 'BEGIN:VEVENT',
2635 - 'CREATED:'.$this->ics_date(strtotime($event->post_date)).'Z',
2636 - 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
2637 - 'SUMMARY:'.$event->post_title,
2638 - 'UID:'.md5(site_url()."_eventpost_".$event->ID),
2639 - 'LOCATION:'.str_replace(',','\,',$event->address),
2640 - 'DTSTAMP:'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2641 - 'DTSTART'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2642 - 'DTEND'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_end).(!empty($vtz)?'':'Z'),
2643 - 'DESCRIPTION:'.trim(chunk_split($event->post_excerpt."\\n\\n".$event->permalink, 60, "\n")),
2644 - 'END:VEVENT'
2645 - );
2646 - }
3327 + // Events
3328 + $events=$this->get_events($criteria);
3329 + foreach ($events as $event) {
3330 + if($event->time_start && $event->time_end){
3331 + $description = wordwrap(
3332 + str_replace(
3333 + ['\\', ';', ',', "\r", "\n"],
3334 + ['\\\\', '\;', '\,', '', '\n'],
3335 + wp_strip_all_tags($event->description . "\n\n" . $event->permalink)
3336 + ),
3337 + 70,
3338 + "\n ",
3339 + true
3340 + );
3341 + array_push($props,
3342 + 'BEGIN:VEVENT',
3343 + 'CREATED:'.$this->ics_date(strtotime($event->post_date)).'Z',
3344 + 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
3345 + 'SUMMARY:'.$event->post_title,
3346 + 'UID:'.md5(site_url()."_eventpost_".$event->ID),
3347 + 'LOCATION:'.str_replace(',','\,',$event->address),
3348 + 'DTSTAMP:'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
3349 + 'DTSTART'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
3350 + 'DTEND'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_end).(!empty($vtz)?'':'Z'),
3351 + 'DESCRIPTION:'.$description,
3352 + 'END:VEVENT'
3353 + );
2647 3354 }
3355 + }
2648 3356
2649 - // End
2650 - $props[] = 'END:VCALENDAR';
3357 + // End
3358 + $props[] = 'END:VCALENDAR';
2651 3359
2652 - echo implode($separator, $props);
2653 - exit;
2654 - }
3360 + echo esc_html(implode($separator, $props));
3361 + exit;
2655 3362 }
2656 3363 }