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 +1888 -1234 5.2 → 6.1.2 View file →
@@ -1,24 +1,42 @@
1 1 <?php
2 -/*
3 - Plugin Name: Event Post
4 - Plugin URI: http://event-post.com
5 - Description: Add calendar and/or geolocation metadata on posts. For a better experience, we recommand to use it with <a href="https://wordpress.org/plugins/shortcode-ui/" target="_blank">Shortcake (shortcode UI)</a> installed.
6 - Version: 5.2.3
7 - Author: N.O.U.S. Open Useful and Simple
8 - Contributors: bastho, ecolosites
9 - Author URI: https://avecnous.eu
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
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
14 + *
15 + * @package event-post
14 16 */
15 17
18 +if ( ! defined( 'ABSPATH' ) ) exit;
19 +
16 20 global $EventPost;
17 21 $EventPost = new EventPost();
18 22
19 23 $EventPost_cache=array();
20 24
25 +function EventPost(){
26 + global $EventPost;
27 + return $EventPost;
28 +}
29 +function event_post_format_color($color){
30 + return str_replace('#', '', $color);
31 +}
32 +function event_post_get_all_terms($post_id){
33 + $taxonomies= get_taxonomies('','names');
34 +
35 + return wp_get_post_terms($post_id, $taxonomies);
36 +}
37 +
38 +
21 39 /**
22 40 * The main class where everything begins.
23 41 *
24 42 * Add calendar and/or geolocation metadata on posts
@@ -23,43 +41,345 @@
23 41 *
24 42 * Add calendar and/or geolocation metadata on posts
25 43 */
26 44 class EventPost {
27 - const META_START = 'event_begin';
28 - const META_END = 'event_end';
29 - const META_COLOR = 'event_color';
30 - // http://codex.wordpress.org/Geodata
31 - const META_ADD = 'geo_address';
32 - const META_LAT = 'geo_latitude';
33 - const META_LONG = 'geo_longitude';
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';
34 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 + */
35 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 + */
36 190 public $NomDuMois;
191 +
192 + /**
193 + * Week days
194 + *
195 + * @var array
196 + */
37 197 public $Week;
38 - 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 + */
39 211 public $dateformat;
40 212
41 - public $version = '4.5';
213 + /**
214 + * Pagination
215 + *
216 + * @var array
217 + */
218 + private $pagination;
219 +
220 + /**
221 + * Plugin path
222 + *
223 + * @var string
224 + */
225 + public $plugin_path;
226 +
227 + /**
228 + * Script suffix
229 + *
230 + * @var string
231 + */
42 232 private $script_sufix;
43 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 + */
44 249 public $map_interactions;
250 +
251 + /**
252 + * Fields supported by quick-edit
253 + *
254 + * @var array
255 + */
45 256 public $quick_edit_fields;
46 257
258 + /**
259 + * Fields supported by bulk-edit
260 + *
261 + * @var array
262 + */
263 + public $bulk_edit_fields;
264 +
265 + /**
266 + * Supported attendance modes
267 + *
268 + * @var array
269 + */
270 + public $attendance_modes;
271 +
272 + /**
273 + * Supported statuses
274 + *
275 + * @var array
276 + */
277 + public $statuses;
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 + */
47 358 public $Shortcodes;
48 359
360 + /**
361 + * Allowed tags in main outputs
362 + *
363 + * @var array
364 + */
365 + public $kses_tags;
366 +
367 +
49 368 public function __construct() {
50 - load_plugin_textdomain('event-post', false, 'event-post/languages');
369 + add_action('init', array(&$this,'init'), 1);
370 + add_action('init', array(&$this,'widgets_init'), 10);
371 + add_action('init', array(&$this, 'register_widgets'), 30, 1);
51 372
52 - add_action('widgets_init', array(&$this,'init'), 1);
53 373 add_action('save_post', array(&$this, 'save_postdata'));
54 - add_action('admin_menu', array(&$this, 'manage_options'));
55 374 add_filter('dashboard_glance_items', array(&$this, 'dashboard_right_now'));
56 375
57 376 // Scripts
58 377 add_action( 'admin_init', array(&$this, 'editor_styles'));
59 - add_action( 'admin_init', array(&$this, 'register_settings'));
60 378 add_action('admin_enqueue_scripts', array(&$this, 'admin_head'));
61 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);
62 382 add_action('wp_enqueue_scripts', array(&$this, 'load_styles'));
63 383
64 384 // Single
65 385 add_filter('the_content', array(&$this, 'display_single'), 9999);
@@ -65,13 +385,17 @@
65 385 add_filter('the_content', array(&$this, 'display_single'), 9999);
66 386 add_filter('the_title', array(&$this, 'the_title'), 9999, 2);
67 387 add_action('the_event', array(&$this, 'print_single'));
68 388 add_action('wp_head', array(&$this, 'single_header'));
389 + add_action('wpseo_schema_webpage', array(&$this, 'wpseo_schema_webpage'));
69 390
70 391 // Ajax
71 392 add_action('wp_ajax_EventPostGetLatLong', array(&$this, 'GetLatLong'));
72 393 add_action('wp_ajax_EventPostHumanDate', array(&$this, 'HumanDate'));
73 394 add_action('wp_ajax_EventPostList', array(&$this, 'ajaxlist'));
395 + add_action('wp_ajax_EventPostTimeline', array(&$this, 'ajaxTimeline'));
396 + add_action('wp_ajax_EventPostNextPage', array(&$this, 'ajaxGetNextPage'));
397 + add_action('wp_ajax_nopriv_EventPostNextPage', array(&$this, 'ajaxGetNextPage'));
74 398 add_action('wp_ajax_EventPostMap', array(&$this, 'ajaxmap'));
75 399 add_action('wp_ajax_EventPostCalendar', array(&$this, 'ajaxcal'));
76 400 add_action('wp_ajax_nopriv_EventPostCalendar', array(&$this, 'ajaxcal'));
77 401 add_action('wp_ajax_EventPostCalendarDate', array(&$this, 'ajaxdate'));
@@ -77,39 +401,43 @@
77 401 add_action('wp_ajax_EventPostCalendarDate', array(&$this, 'ajaxdate'));
78 402 add_action('wp_ajax_nopriv_EventPostCalendarDate', array(&$this, 'ajaxdate'));
79 403
80 404 // Calendar publishing
405 + add_action('parse_request', array(&$this, 'parse_request'), 100);
406 + add_action('wp_ajax_EventPostExport', array(&$this, 'export'));
407 + add_action('wp_ajax_nopriv_EventPostExport', array(&$this, 'export'));
81 408 add_action('wp_ajax_EventPostFeed', array(&$this, 'feed'));
82 409 add_action('wp_ajax_nopriv_EventPostFeed', array(&$this, 'feed'));
83 410
84 - //
411 + // Internal filters
85 412 add_filter('eventpost_list_shema',array(&$this, 'custom_shema'),10,1);
86 413
87 - // Admin
88 - add_filter('plugin_action_links_event-post/eventpost.php', array( &$this, 'settings_link' ) );
89 - add_filter('plugin_row_meta', array( &$this, 'row_meta' ), 1, 4);
90 -
91 - add_action('widgets_init', array(&$this, 'register_widgets'),1,1);
92 -
93 414 // Quick edit
94 415 add_action( 'bulk_edit_custom_box', array( &$this, 'bulk_edit' ), 10, 2 );
95 416 add_action( 'quick_edit_custom_box', array( &$this, 'quick_edit' ), 10, 2 );
96 417 add_action( 'admin_print_scripts-edit.php', array(&$this, 'scripts_edit') );
97 418 add_action( 'wp_ajax_inline-save', array(&$this, 'inline_save'), 1 );
98 - add_action( 'wp_ajax_eventpost_save_bulk', array(&$this, 'save_bulkdatas') );
419 + add_action( 'bulk_edit_posts', array(&$this, 'save_bulkdatas'), 10, 2 );
99 420 add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_color'), 10, 3);
421 + add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_icon'), 10, 3);
100 422
101 423 $inc_path = plugin_dir_path(__FILE__).'inc/';
424 + $this->plugin_path = plugin_dir_path(__FILE__);
425 + include_once ($inc_path . 'class-settings.php');
102 426 include_once ($inc_path . 'wrappers.php');
103 - include_once ($inc_path . 'widget.php');
104 - include_once ($inc_path . 'widget.cal.php');
105 - include_once ($inc_path . 'widget.map.php');
106 - include_once ($inc_path . 'multisite.php');
107 - 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');
108 432 include_once ($inc_path . 'openweathermap.php');
109 - include_once ($inc_path . 'children.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');
110 436
111 - $this->script_sufix = (defined('WP_DEBUG') && WP_DEBUG) ? '' : '.min';
437 + $this->DashIcons = new EventPost\Icons();
438 + $this->Settings = new EventPost\Settings($this->DashIcons);
439 + $this->Taxonomies = new EventPost\Taxonomies($this->DashIcons);
112 440 }
113 441
114 442 /**
115 443 * PHP4 constructor
@@ -117,41 +445,38 @@
117 445 public function EventPost(){
118 446 $this->__construct();
119 447 }
120 448
121 - /**
122 - * Init all variables when WP is ready
123 - *
124 - * @action evenpost_init
125 - * @filter eventpost_default_list_shema
126 - * @filter eventpost_list_shema
127 - */
128 449 public function init(){
129 - $this->META_START = 'event_begin';
130 - $this->META_END = 'event_end';
131 - $this->META_COLOR = 'event_color';
132 - // http://codex.wordpress.org/Geodata
133 - $this->META_ADD = 'geo_address';
134 - $this->META_LAT = 'geo_latitude';
135 - $this->META_LONG = 'geo_longitude';
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 +
136 457 $this->list_id = 0;
137 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'));
138 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'));
139 -
460 + $this->attendance_modes = array(
461 + 'OfflineEventAttendanceMode' => _x('Physical', 'Attendance Mode', 'event-post'),
462 + 'MixedEventAttendanceMode' => _x('Mixed', 'Attendance Mode', 'event-post'),
463 + 'OnlineEventAttendanceMode' => _x('Online', 'Attendance Mode', 'event-post'),
464 + );
465 + $this->statuses = array(
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'),
472 + );
473 +
140 474 $this->maps = $this->get_maps();
141 475 $this->settings = $this->get_settings();
142 -
476 +
143 477 do_action('evenpost_init', $this);
144 478
145 - $this->Shortcodes = new EventPost_Shortcodes();
146 -
147 - if(function_exists('register_block_type')){
148 - $block_path = plugin_dir_path(__FILE__).'blocks/';
149 - include_once ($block_path . 'eventslist.php');
150 - include_once ($block_path . 'eventsmap.php');
151 - include_once ($block_path . 'eventscalendar.php');
152 - }
153 -
154 479 // Edit
155 480 add_action('add_meta_boxes', array(&$this, 'add_custom_box'));
156 481 foreach($this->settings['posttypes'] as $posttype){
157 482 add_filter('manage_'.$posttype.'_posts_columns', array(&$this, 'columns_head'), 2);
@@ -156,37 +481,66 @@
156 481 foreach($this->settings['posttypes'] as $posttype){
157 482 add_filter('manage_'.$posttype.'_posts_columns', array(&$this, 'columns_head'), 2);
158 483 add_action('manage_'.$posttype.'_posts_custom_column', array(&$this, 'columns_content'), 10, 2);
159 484 }
485 + $this->Taxonomies->add_fields_to_taxonomies($this->settings['posttypes']);
160 486
161 -
487 + $this->markpath = '';
488 + $this->markurl = '';
162 489 if (!empty($this->settings['markpath']) && !empty($this->settings['markurl'])) {
163 490 $this->markpath = ABSPATH.'/'.$this->settings['markpath'];
164 491 $this->markurl = $this->settings['markurl'];
165 492 } else {
166 - $this->markpath = plugin_dir_path(__FILE__) . 'markers/';
167 - $this->markurl = plugins_url('/markers/', __FILE__);
493 + // $this->markpath = plugin_dir_path(__FILE__) . 'markers/';
494 + // $this->markurl = plugins_url('/markers/', __FILE__);
168 495 }
169 496
497 + $this->currencies = include (plugin_dir_path(__FILE__) . 'inc/data/currencies.php');
498 +
170 499 $this->dateformat = str_replace(array('yy', 'mm', 'dd'), array('Y', 'm', 'd'), __('yy-mm-dd', 'event-post'));
171 500
172 501 $this->default_list_shema = apply_filters('eventpost_default_list_shema', array(
502 + 'container' => '<%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>'.
503 + '%list%'.
504 + '%pagination%'.
505 + '</%type%><!-- .event_loop -->',
506 + 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">'.
507 + '<a href="%event_link%">'.
508 + '%event_thumbnail%'.
509 + '<h5>%event_title% </h5>'.
510 + '</a>'.
511 + '%event_price%'.
512 + '%event_date%'.
513 + '%event_cat%'.
514 + '%event_location%'.
515 + '%event_excerpt%'.
516 + '</%child%><!-- .event_item -->'
517 + ));
518 + $this->list_shema = apply_filters('eventpost_list_shema',$this->default_list_shema);
519 +
520 + $this->default_timeline_shema = apply_filters('eventpost_default_timeline_shema', array(
173 521 'container' => '
174 - <%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>%list%
522 + <%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>
523 + %prev_arrow%
524 + <div class="track">
525 + %list%
526 + </div>
527 + %next_arrow%
175 528 </%type%><!-- .event_loop -->',
176 - 'item' => '
177 - <%child% class="event_item %class%" data-color="%color%">
529 + 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">
530 + <div class="anchor" style="background-color:#%color%"></div>
531 + %event_date%
532 + %event_location%
533 + %event_cat%
534 + %event_excerpt%
178 535 <a href="%event_link%">
179 536 %event_thumbnail%
180 537 <h5>%event_title%</h5>
181 538 </a>
182 - %event_date%
183 - %event_cat%
184 - %event_location%
185 - %event_excerpt%
539 + %event_price%
186 540 </%child%><!-- .event_item -->'
187 541 ));
188 - $this->list_shema = apply_filters('eventpost_list_shema',$this->default_list_shema);
542 + $this->timeline_shema = apply_filters('eventpost_timeline_shema',$this->default_timeline_shema);
189 543
190 544 $this->map_interactions=array(
191 545 'DragRotate'=>__('Drag Rotate', 'event-post'),
192 546 'DoubleClickZoom'=>__('Double Click Zoom', 'event-post'),
@@ -203,8 +557,9 @@
203 557 'event'=>array(
204 558 $this->META_START=>__('Begin:', 'event-post'),
205 559 $this->META_END=>__('End:', 'event-post'),
206 560 $this->META_COLOR=>__('Color:', 'event-post'),
561 + $this->META_ICON=>__('Icon:', 'event-post'),
207 562 ),
208 563 'location'=>array(
209 564 $this->META_ADD=>__('Address:', 'event-post'),
210 565 $this->META_LAT=>__('Latitude:', 'event-post'),
@@ -214,14 +569,47 @@
214 569 );
215 570 $this->bulk_edit_fields = apply_filters('eventpost_bulk_edit_fields', array(
216 571 'event'=>array(
217 572 $this->META_COLOR=>__('Color:', 'event-post'),
573 + $this->META_ICON=>__('Icon:', 'event-post'),
218 574 ),
219 575 )
220 576 );
221 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 +
222 584 }
223 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 +
224 612 public function register_widgets(){
225 613 register_widget('EventPost_List');
226 614 register_widget('EventPost_Map');
227 615 register_widget('EventPost_Cal');
@@ -228,24 +616,32 @@
228 616 }
229 617
230 618 /**
231 619 * Usefull hexadecimal to decimal converter. Returns an array of RGB from a given hexadecimal color.
620 + *
232 621 * @param string $color
622 + *
233 623 * @return array $color($R, $G, $B)
234 624 */
235 625 public function hex2dec($color = '000000') {
236 626 $tbl_color = array();
237 - if (!strstr('#', $color)){
627 + if(!is_string($color) || empty($color)){
628 + $color = '000000';
629 + }
630 + if (substr($color, 0, 1)!='#'){
238 631 $color = '#' . $color;
239 - }
632 + }
240 633 $tbl_color['R'] = hexdec(substr($color, 1, 2));
241 634 $tbl_color['G'] = hexdec(substr($color, 3, 2));
242 635 $tbl_color['B'] = hexdec(substr($color, 5, 2));
243 636 return $tbl_color;
244 637 }
638 +
245 639 /**
246 640 * Fetch all registered image sizes
641 + *
247 642 * @global array $_wp_additional_image_sizes
643 + *
248 644 * @return array
249 645 */
250 646 function get_thumbnail_sizes(){
251 647 global $_wp_additional_image_sizes;
@@ -256,119 +652,27 @@
256 652 return $sizes;
257 653 }
258 654
259 655 /**
260 - * Just for localization
261 - */
262 - private function no_use() {
263 - __('Add calendar and/or geolocation metadata on posts', 'event-post');
264 - __('Event Post', 'event-post');
265 - }
266 -
267 - /**
268 656 * Get blog settings, load and saves default settings if needed. Can be filterred using
269 657 *
270 - * `<?php add_filter('eventpost_getsettings', 'some_function'); ?>`
658 + * @example `<?php add_filter('eventpost_getsettings', 'some_function'); ?>`
271 659 *
272 660 * @action eventpost_getsettings_action
273 661 * @filter eventpost_getsettings
662 + *
274 663 * @return array
275 664 */
276 665 public function get_settings() {
277 - $ep_settings = get_option('ep_settings');
278 - $reg_settings=false;
279 - if(!is_array($ep_settings)){
280 - $ep_settings = array();
281 - }
282 - if (!isset($ep_settings['dateformat']) || empty($ep_settings['dateformat'])) {
283 - $ep_settings['dateformat'] = get_option('date_format');
284 - $reg_settings=true;
285 - }
286 - if (!isset($ep_settings['timeformat']) || empty($ep_settings['timeformat'])) {
287 - $ep_settings['timeformat'] = get_option('time_format');
288 - $reg_settings=true;
289 - }
290 - if (!isset($ep_settings['tile']) || empty($ep_settings['tile']) || !isset($this->maps[$ep_settings['tile']])) {
291 - $maps = array_keys($this->maps);
292 - $ep_settings['tile'] = $this->maps[$maps[0]]['id'];
293 - $reg_settings=true;
294 - }
295 - if(!isset($ep_settings['zoom']) || !is_numeric($ep_settings['zoom'])){
296 - $ep_settings['zoom']=12;
297 - $reg_settings=true;
298 - }
299 - if (!isset($ep_settings['cache']) || !is_numeric($ep_settings['cache'])) {
300 - $ep_settings['cache'] = 0;
301 - $reg_settings=true;
302 - }
303 - if (!isset($ep_settings['export']) || empty($ep_settings['export'])) {
304 - $ep_settings['export'] = 'both';
305 - $reg_settings=true;
306 - }
307 - if (!isset($ep_settings['export_when']) || empty($ep_settings['export_when'])) {
308 - $ep_settings['export_when'] = 'future';
309 - $reg_settings=true;
310 - }
311 - if (!isset($ep_settings['dateforhumans'])) {
312 - $ep_settings['dateforhumans'] = 1;
313 - $reg_settings=true;
314 - }
315 - if (!isset($ep_settings['emptylink'])) {
316 - $ep_settings['emptylink'] = 1;
317 - $reg_settings=true;
318 - }
319 - if (!isset($ep_settings['markpath'])) {
320 - $ep_settings['markpath'] = '';
321 - $reg_settings=true;
322 - }
323 - if (!isset($ep_settings['markurl'])) {
324 - $ep_settings['markurl'] = '';
325 - $reg_settings=true;
326 - }
327 - if (!isset($ep_settings['customcss'])) {
328 - $ep_settings['customcss'] = '';
329 - $reg_settings=true;
330 - }
331 - if (!isset($ep_settings['singlepos']) || empty($ep_settings['singlepos'])) {
332 - $ep_settings['singlepos'] = 'after';
333 - $reg_settings=true;
334 - }
335 - if (!isset($ep_settings['loopicons'])) {
336 - $ep_settings['loopicons'] = 1;
337 - $reg_settings=true;
338 - }
339 - if (!isset($ep_settings['adminpos']) || empty($ep_settings['adminpos'])) {
340 - $ep_settings['adminpos'] = 'side';
341 - $reg_settings=true;
342 - }
343 - if (!isset($ep_settings['container_shema']) ) {
344 - $ep_settings['container_shema'] = '';
345 - $reg_settings=true;
346 - }
347 - if (!isset($ep_settings['item_shema']) ) {
348 - $ep_settings['item_shema'] = '';
349 - $reg_settings=true;
350 - }
351 - if(!isset($ep_settings['datepicker']) || !in_array($ep_settings['datepicker'], array('simple', 'native'))){
352 - $ep_settings['datepicker']='simple';
353 - $reg_settings=true;
354 - }
355 - if(!isset($ep_settings['posttypes']) || !is_array($ep_settings['posttypes'])){
356 - $ep_settings['posttypes']=array('post');
357 - $reg_settings=true;
358 - }
359 - do_action_ref_array('eventpost_getsettings_action', array(&$ep_settings, &$reg_settings));
360 -
361 - //Save settings not changed
362 - if($reg_settings===true){
363 - update_option('ep_settings', $ep_settings);
364 - }
666 + $ep_settings = $this->Settings->get_settings();
365 667 return apply_filters('eventpost_getsettings', $ep_settings);
366 668 }
367 669
368 670 /**
369 671 * Checks if HTML schemas are not empty
672 + *
370 673 * @param array $shema
674 + *
371 675 * @return array
372 676 */
373 677 public function custom_shema($shema){
374 678 if(!empty($this->settings['container_shema'])){
@@ -401,8 +705,9 @@
401 705 * ?>
402 706 * ```
403 707 *
404 708 * @filter eventpost_maps
709 + *
405 710 * @return array of map arrays ['name', 'id', 'urls']
406 711 */
407 712 public function get_maps() {
408 713 $maps = array();
@@ -418,9 +723,10 @@
418 723 return $maps;
419 724 }
420 725
421 726 /**
422 - *
727 + * Get colors
728 + *
423 729 * @return array
424 730 */
425 731 public function get_colors() {
426 732 $colors = array();
@@ -435,10 +741,64 @@
435 741 return $colors;
436 742 }
437 743
438 744 /**
439 - *
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
752 + */
753 + public function get_post_color($post_id, $default = false, $check_taxo = false) {
754 + $color = get_post_meta($post_id, $this->META_COLOR,true);
755 + if($color && !empty($color)){
756 + return event_post_format_color($color);
757 + }else{
758 + if($check_taxo){
759 + foreach(event_post_get_all_terms($post_id) as $term){
760 + $taxo_color = $this->Taxonomies->get_taxonomy_color($term->term_id);
761 + if($taxo_color){
762 + return event_post_format_color($taxo_color);
763 + }
764 + }
765 + }
766 + }
767 + return event_post_format_color($default);
768 + }
769 +
770 + /**
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
778 + */
779 + public function get_post_icon($post_id, $default = false, $check_taxo = false) {
780 + $icon = get_post_meta($post_id, $this->META_ICON,true);
781 + if($icon && !empty($icon)){
782 + return $icon;
783 + }else{
784 + if($check_taxo){
785 + foreach(event_post_get_all_terms($post_id) as $term){
786 + $taxo_icon = $this->Taxonomies->get_taxonomy_icon($term->term_id);
787 + if($taxo_icon){
788 + return event_post_format_color($taxo_icon);
789 + }
790 + }
791 + }
792 + }
793 + return $default;
794 + }
795 +
796 + /**
797 + * Get the URL of a marker
798 + *
440 799 * @param string $color
800 + *
441 801 * @return sring
442 802 */
443 803 public function get_marker($color) {
444 804 if (is_file($this->markpath . $color . '.png')) {
@@ -443,15 +803,15 @@
443 803 public function get_marker($color) {
444 804 if (is_file($this->markpath . $color . '.png')) {
445 805 return $this->markurl . $color . '.png';
446 806 }
447 - return plugins_url('/markers/ffffff.png', __FILE__);
807 + return "";
448 808 }
449 809
450 810 /**
451 811 * Enqueue CSS files
452 812 */
453 - public function load_styles() {
813 + public function load_styles($deps = null) {
454 814 //CSS
455 815 if(!empty($this->settings['customcss'])){
456 816 wp_enqueue_style('event-post-custom', $this->settings['customcss']);
457 817 }
@@ -458,48 +818,56 @@
458 818 elseif(is_file(get_stylesheet_directory().'/event-post.css') || is_file(get_template_directory().'/event-post.css')){
459 819 wp_enqueue_style('event-post-custom', get_theme_file_uri('event-post.css'));
460 820 }
461 821 else{
462 - wp_register_style('event-post', plugins_url('/css/eventpost'.$this->script_sufix.'.css', __FILE__), false, $this->version);
463 - wp_enqueue_style('event-post', plugins_url('/css/eventpost'.$this->script_sufix.'.css', __FILE__), false, $this->version);
822 + wp_register_style('event-post', plugins_url('/build/front/front.css', __FILE__), $deps, filemtime( "{$this->plugin_path}/build/front/front.css" ));
823 + wp_enqueue_style('event-post');
464 824 }
465 825
466 826 // Lib scripts
467 - wp_enqueue_style('openlayers', plugins_url('/css/openlayers.css', __FILE__), false, $this->version);
468 827 wp_enqueue_style('dashicons', includes_url('/css/dashicons.min.css'));
469 828 }
829 +
470 830 /**
471 831 * Enqueue Editor style
472 832 */
473 833 public function editor_styles() {
474 - add_editor_style( plugins_url('/css/eventpost'.$this->script_sufix.'.css', __FILE__) );
834 + add_editor_style( plugins_url('/build/front/front.css', __FILE__) );
475 835 }
476 836
477 837 /**
478 838 * Enqueue JS files
479 839 */
480 - public function load_scripts($deps = array('jquery')) {
481 - // JS
482 - wp_enqueue_script('jquery', false, false, false, true);
483 - wp_enqueue_script('event-post', plugins_url('/js/eventpost'.$this->script_sufix.'.js', __FILE__), $deps, $this->version, true);
484 - wp_localize_script('event-post', 'eventpost_params', array(
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);
842 + $maps = $this->maps;
843 + foreach($maps as $m=>$map){
844 + if(isset($map['api_param']) && $this->settings['tile_api_key']){
845 + foreach($map['urls'] as $i=>$url){
846 + $maps[$m]['urls'][$i] = add_query_arg($map['api_param'], $this->settings['tile_api_key'], $url);
847 + }
848 + }
849 + }
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 + ),
485 854 'imgpath' => plugins_url('/img/', __FILE__),
486 - 'maptiles' => $this->maps,
855 + 'maptiles' => $maps,
487 856 'defaulttile' => $this->settings['tile'],
488 857 'zoom' => $this->settings['zoom'],
489 858 'ajaxurl' => admin_url() . 'admin-ajax.php',
490 859 'map_interactions'=>$this->map_interactions,
491 - ));
860 + )), 'before');
492 861 }
493 862 /**
494 863 * Enqueue JS files for maps
495 864 */
496 865 public function load_map_scripts() {
866 + $this->load_styles(array('event-post-map'));
497 867 // JS
498 - wp_enqueue_script('openlayers', plugins_url('/js/OpenLayers.js', __FILE__), false, $this->version, true);
499 - $this->load_scripts(array('jquery', 'openlayers'));
500 868 if(is_admin()){
501 - $this->admin_scripts(array('jquery', 'openlayers'));
869 + $this->admin_scripts(array('jquery', 'event-post-map'));
502 870 }
503 871 }
504 872
505 873 /**
@@ -506,14 +874,12 @@
506 874 * Enqueue CSS files in admin
507 875 */
508 876 public function admin_head() {
509 877 $page = basename($_SERVER['SCRIPT_NAME']);
510 - if( $page!='post-new.php' && !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') && !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings') ){
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') ){
511 879 return;
512 880 }
513 - wp_enqueue_style('openlayers', plugins_url('/css/openlayers.css', __FILE__), false, $this->version);
514 - wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, $this->version);
515 - wp_enqueue_style('event-post-admin', plugins_url('/css/eventpost-admin.css', __FILE__), false, $this->version);
881 + wp_enqueue_style('event-post-admin', plugins_url('/build/admin/admin.css', __FILE__), false, filemtime( "{$this->plugin_path}/build/admin/admin.css" ));
516 882 }
517 883
518 884 /**
519 885 * Enqueue JS files in admin
@@ -519,30 +885,38 @@
519 885 * Enqueue JS files in admin
520 886 */
521 887 public function admin_scripts($deps = array('jquery'), $force=false) {
522 888 $page = basename($_SERVER['SCRIPT_NAME']);
523 - if(!$force && $page!='post-new.php' && !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') && !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings')){
889 + if(!$force &&
890 + $page!='post-new.php' &&
891 + $page!='edit-tags.php' &&
892 + $page!='term.php' &&
893 + !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') &&
894 + !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings')
895 + ){
524 896 return;
525 897 }
526 898 wp_enqueue_script('jquery');
527 899 wp_enqueue_script('jquery-effects-core');
528 900 wp_enqueue_script('jquery-effects-shake');
901 + wp_enqueue_style( 'wp-color-picker');
902 + wp_enqueue_script( 'wp-color-picker');
529 903 if(!is_array($deps)){
530 - $deps = array('jquery');
904 + $deps = array('jquery','wp-color-picker');
531 905 }
532 906 if($this->settings['datepicker']=='simple' || !is_admin() || (isset($_GET['page']) && $_GET['page']=='event-settings')){
533 907 wp_enqueue_script('jquery-ui-datepicker');
534 908 $deps[] = 'jquery-ui-datepicker';
535 909 }
536 - wp_enqueue_script('event-post-admin', plugins_url('/js/eventpost-admin'.$this->script_sufix.'.js', __FILE__), $deps, $this->version, 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);
537 911 $language = get_bloginfo('language');
538 912 if (strpos($language, '-') > -1) {
539 913 $language = strtolower(substr($language, 0, 2));
540 914 }
541 - 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(
542 916 'ajaxurl' => admin_url('admin-ajax.php'),
543 917 'imgpath' => plugins_url('/img/', __FILE__),
544 - 'date_choose' => '<span class="screen-reader-text">'.__('Choose', 'event-post').'</span><i class="dashicons dashicons-calendar-alt"></i>',
918 + 'date_choose' => __('Choose', 'event-post'),
545 919 'date_format' => __('yy-mm-dd', 'event-post'),
546 920 'more_icons' => __('More icons', 'event-post'),
547 921 'pick_a_date'=>__('Pick a date','event-post'),
548 922 'use_current_location'=>__('Use my current location','event-post'),
@@ -548,10 +922,13 @@
548 922 'use_current_location'=>__('Use my current location','event-post'),
549 923 'start_drag'=>__('Click to<br>drag the map<br>and change location','event-post'),
550 924 'empty_address'=>__('Be kind to fill a non empty address:)', 'event-post'),
551 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'),
552 928 'stop_drag'=>_x('Done','Stop allowing to drag the map', 'event-post'),
553 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
554 931 'order'=>__( '%1$s %2$s, %3$s @ %4$s:%5$s', 'event-post'),
555 932 'day'=>__('Day', 'event-post'),
556 933 'month'=>__('Month', 'event-post'),
557 934 'year'=>__('Day', 'event-post'),
@@ -558,8 +935,9 @@
558 935 'hour'=>__('Hour', 'event-post'),
559 936 'minute'=>__('Minute', 'event-post'),
560 937 'ok'=>__('OK', 'event-post'),
561 938 'cancel'=>__('Cancel', 'event-post'),
939 + 'remove'=>__('Remove', 'event-post'),
562 940 'edit'=>__('Edit', 'event-post'),
563 941 'months'=>$this->NomDuMois,
564 942 ),
565 943 'META_START' => $this->META_START,
@@ -566,25 +944,158 @@
566 944 'META_END' => $this->META_END,
567 945 'META_ADD' => $this->META_ADD,
568 946 'META_LAT' => $this->META_LAT,
569 947 'META_LONG' => $this->META_LONG,
948 + 'META_STATUS' => $this->META_STATUS,
949 + 'META_ATTENDANCE_MODE' => $this->META_ATTENDANCE_MODE,
570 950 'lang'=>$language,
571 951 'maptiles' => $this->maps,
572 - 'defaulttile' => $this->settings['tile']
573 - ));
952 + 'defaulttile' => $this->settings['tile'],
953 + 'palette' => $this->get_theme_palette("hex"),
954 + 'available_images' => $this->get_colors(),
955 + )));
574 956 }
575 957 function scripts_edit() {
576 958 // load only when editing a supported post type
577 959 $current_post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
578 960 if ( in_array( $current_post_type, $this->settings['posttypes'] ) ) {
579 - wp_enqueue_script( 'eventpost-inline-edit', plugins_url( 'js/inline-edit.js', __FILE__ ), array( 'jquery', 'inline-edit-post' ), '', true );
580 - 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(
581 963 'quick'=>$this->quick_edit_fields,
582 - 'bulk'=>$this->bulk_edit_fields
583 - ));
964 + 'bulk'=>$this->bulk_edit_fields,
965 + )));
584 966 }
585 967 }
586 968
969 + function get_rich_result($event){
970 + /*
971 + * https://search.google.com/test/rich-results
972 + {
973 + "@context": "https://schema.org",
974 + "@type": "Event",
975 + "name": "The Adventures of Kira and Morrison",
976 + "startDate": "2025-07-21T19:00",
977 + "endDate": "2025-07-21T23:00",
978 + "eventStatus": "https://schema.org/EventScheduled",
979 + "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
980 + "location": {
981 + "@type": "VirtualLocation",
982 + "url": "https://operaonline.stream5.com/"
983 + },
984 + "image": [
985 + "https://example.com/photos/1x1/photo.jpg",
986 + "https://example.com/photos/4x3/photo.jpg",
987 + "https://example.com/photos/16x9/photo.jpg"
988 + ],
989 + "description": "The Adventures of Kira and Morrison is coming to Snickertown in a can’t miss performance.",
990 + "offers": {
991 + "@type": "Offer",
992 + "url": "https://www.example.com/event_offer/12345_201803180430",
993 + "price": "30",
994 + "priceCurrency": "USD",
995 + "availability": "https://schema.org/InStock",
996 + "validFrom": "2024-05-21T12:00"
997 + },
998 + "performer": {
999 + "@type": "PerformingGroup",
1000 + "name": "Kira and Morrison"
1001 + }
1002 + }
1003 + */
1004 + $location_virtual = array(
1005 + '@type'=>'VirtualLocation',
1006 + 'url'=>$event->virtual_location,
1007 + );
1008 + $physical_location = array(
1009 + '@type'=>'place',
1010 + 'name'=>$event->address,
1011 + 'address'=>$event->address,
1012 + 'geo'=>array(
1013 + '@type'=>'GeoCoordinates',
1014 + 'latitude'=>$event->lat,
1015 + 'longitude'=>$event->long,
1016 + ),
1017 + );
1018 + $min = 60 * get_option('gmt_offset');
1019 + $sign = $min < 0 ? "-" : "+";
1020 + $absmin = abs($min);
1021 + $gmt_offset = sprintf("%s%02d:%02d", $sign, $absmin/60, $absmin%60);
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';
1023 +
1024 + $rich_data = array(
1025 + '@context'=>'https://schema.org',
1026 + '@type'=>'event',
1027 + 'name'=>$event->post_title,
1028 + 'datePublished'=>str_replace(' ', 'T', $event->post_date_gmt).$gmt_offset,
1029 + 'dateModified'=>str_replace(' ', 'T', $event->post_modified_gmt).$gmt_offset,
1030 + 'startDate'=>$event->time_start ? date($time_format, $event->time_start) : null,
1031 + 'endDate'=>$event->time_end ? date($time_format, $event->time_end) : null,
1032 + 'eventStatus'=>$event->status,
1033 + 'eventAttendanceMode'=>$event->attendance_mode,
1034 + 'location'=> ($event->attendance_mode == 'MixedEventAttendanceMode') ? array($location_virtual,$physical_location) : ($event->attendance_mode == 'OnlineEventAttendanceMode' ? $location_virtual : $physical_location),
1035 + 'image'=> has_post_thumbnail($event->ID) ? array(
1036 + get_the_post_thumbnail_url($event->ID, 'post-thumbnail'),
1037 + get_the_post_thumbnail_url($event->ID, 'medium'),
1038 + get_the_post_thumbnail_url($event->ID, 'large'),
1039 + get_the_post_thumbnail_url($event->ID, 'full'),
1040 + ) : null,
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);
1067 + }
1068 +
1069 + function wpseo_schema_webpage($rich_result){
1070 + $event = $this->retreive();
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;
1076 + }
1077 + return $rich_result;
1078 + }
1079 +
1080 + function get_theme_palette($return = "hex"){
1081 + $theme_options = wp_get_global_settings();
1082 + $colors = [];
1083 + if(isset($theme_options['color']['palette']['theme'])){
1084 + $colors = $theme_options['color']['palette']['theme'];
1085 + }elseif(isset($theme_options['color']['palette']['default'])){
1086 + $colors = $theme_options['color']['palette']['default'];
1087 + }
1088 + if($return == "hex"){
1089 + $color_hexs = [];
1090 + foreach($colors as $color){
1091 + $color_hexs[] = $color["color"];
1092 + }
1093 + return $color_hexs;
1094 + }
1095 + return $colors;
1096 + }
1097 +
587 1098 /**
588 1099 * Add custom header meta for single events
589 1100 */
590 1101 public function single_header() {
@@ -590,37 +1101,52 @@
590 1101 public function single_header() {
591 1102 if (is_single()) {
592 1103 $twitter_label_id=0;
593 1104 $event = $this->retreive();
594 - if ($event->address != '' || ($event->lat != '' && $event->long != '')) {
595 - $twitter_label_id++;
596 - ?>
597 -<meta name="geo.placename" content="<?php echo esc_attr($event->address) ?>" />
598 -<meta name="geo.position" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
599 -<meta name="ICBM" content="<?php echo $event->lat ?>;<?php echo esc_attr($event->long) ?>" />
600 -<meta property="place:location:latitude" content="<?php echo esc_attr($event->lat) ?>" />
601 -<meta property="place:location:longitude" content="<?php echo esc_attr($event->long) ?>" />
602 -<meta name="twitter:label<?php echo $twitter_label_id; ?>" content="<?php _e('Location', 'event-post'); ?>"/>
603 -<meta name="twitter:data<?php echo $twitter_label_id; ?>" content="<?php echo esc_attr($event->address) ?>"/>
1105 + $has_location = $has_time = false;
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) ?>"/>
604 1118 <?php
605 - }
606 - if ($event->start != '' && $event->end != '') {
607 - $twitter_label_id++;
608 - ?>
609 -<meta name="datetime-coverage-start" content="<?php echo date('c', $event->time_start) ?>" />
610 -<meta name="datetime-coverage-end" content="<?php echo date('c', $event->time_end) ?>" />
611 -<meta name="twitter:label<?php echo $twitter_label_id; ?>" content="<?php _e('Date', 'event-post'); ?>"/>
612 -<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)) ?>"/>
613 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 + }
614 1137 }
615 1138 }
616 1139 }
617 1140
618 1141 /**
619 - *
1142 + * Cleanups a date
1143 + *
620 1144 * @param type $str
1145 + *
1146 + * @since 5.0.1
1147 + *
621 1148 * @return string
622 - * @since 5.0.1
623 1149 */
624 1150 public function date_cleanup($str){
625 1151 return trim(str_replace(array('0', ' ', ':', '-'), '', $str));
626 1152 }
@@ -625,10 +1151,12 @@
625 1151 return trim(str_replace(array('0', ' ', ':', '-'), '', $str));
626 1152 }
627 1153
628 1154 /**
629 - *
1155 + * Checks if a date is valid or not
1156 + *
630 1157 * @param string $str
1158 + *
631 1159 * @return boolean
632 1160 */
633 1161 public function dateisvalid($str) {
634 1162 return is_string($str) && $this->date_cleanup($str) != '';
@@ -634,11 +1162,13 @@
634 1162 return is_string($str) && $this->date_cleanup($str) != '';
635 1163 }
636 1164
637 1165 /**
638 - *
1166 + * Parse a date from a string
1167 + *
639 1168 * @param string $date
640 1169 * @param string $sep
1170 + *
641 1171 * @return string
642 1172 */
643 1173 public function parsedate($date, $sep = '') {
644 1174 if (!empty($date)) {
@@ -648,11 +1178,27 @@
648 1178 }
649 1179 }
650 1180
651 1181 /**
652 - *
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 + *
653 1198 * @param mixed $date
654 1199 * @param string $format
1200 + *
655 1201 * @return type
656 1202 */
657 1203 public function human_date($date, $format = 'l j F Y') {
658 1204 if($this->settings['dateforhumans']){
@@ -667,11 +1213,13 @@
667 1213 return date_i18n($format, $date);
668 1214 }
669 1215
670 1216 /**
671 - *
1217 + * Returns a range of dates
1218 + *
672 1219 * @param timestamp $time_start
673 1220 * @param timestamp $time_end
1221 + *
674 1222 * @return string
675 1223 */
676 1224 public function delta_date($time_start, $time_end){
677 1225 if(!$time_start || !$time_end){
@@ -677,129 +1225,156 @@
677 1225 if(!$time_start || !$time_end){
678 1226 return;
679 1227 }
680 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
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
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
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
1236 + $at_time = _x('%1$sat%2$s %3$s', 'Time', 'event-post');
1237 +
681 1238 //Display dates
682 1239 $dates="\t\t\t\t".'<div class="event_date" data-start="' . $this->human_date($time_start) . '" data-end="' . $this->human_date($time_end) . '">';
683 - if (date('d/m/Y', $time_start) == date('d/m/Y', $time_end)) { // same day
1240 + // Same day
1241 + if (date('Ymd', $time_start) == date('Ymd', $time_end)) {
684 1242 $dates.= "\n\t\t\t\t\t\t\t".'<time itemprop="dtstart" datetime="' . date_i18n('c', $time_start) . '">'
685 1243 . '<span class="date date-single">' . $this->human_date($time_end, $this->settings['dateformat']) . "</span>";
686 1244 if (date('H:i', $time_start) != date('H:i', $time_end) && date('H:i', $time_start) != '00:00' && date('H:i', $time_end) != '00:00') {
687 - $dates.=' <span class="linking_word linking_word-from">' . _x('from', 'Time', 'event-post') . '</span>
688 - <span class="time time-start">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>
689 - <span class="linking_word linking_word-to">' . _x('to', 'Time', 'event-post') . '</span>
690 - <span class="time time-end">' . date_i18n($this->settings['timeformat'], $time_end) . '</span>';
1245 + $dates.= ' '.sprintf(
1246 + $from_to_hours,
1247 + '<span class="linking_word linking_word-from">',
1248 + '</span>',
1249 + '<span class="time time-start">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>',
1250 + '<span class="linking_word linking_word-to">',
1251 + '</span>',
1252 + '<span class="time time-end">' . date_i18n($this->settings['timeformat'], $time_end) . '</span>'
1253 + );
691 1254 }
692 1255 elseif (date('H:i', $time_start) != '00:00') {
693 - $dates.=' <span class="linking_word">' . _x('at', 'Time', 'event-post') . '</span>
694 - <time class="time time-single" itemprop="dtstart" datetime="' . date_i18n('c', $time_start) . '">' . date_i18n($this->settings['timeformat'], $time_start) . '</time>';
1256 + $dates.= ' '.sprintf(
1257 + $at_time,
1258 + '<span class="linking_word">',
1259 + '</span>',
1260 + '<span class="time time-single">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>'
1261 + );
695 1262 }
696 1263 $dates.="\n\t\t\t\t\t\t\t".'</time>';
697 - } else { // not same day
698 - $dates.= '
699 - <span class="linking_word linking_word-from">' . _x('from', 'Date', 'event-post') . '</span>
700 - <time class="date date-start" itemprop="dtstart" datetime="' . date('c', $time_start) . '">' . $this->human_date($time_start, $this->settings['dateformat']);
701 - if (date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00'){
702 - $dates.= ', ' . date_i18n($this->settings['timeformat'], $time_start);
703 - }
704 - $dates.='</time>
705 - <span class="linking_word linking_word-to">' . _x('to', 'Date', 'event-post') . '</span>
706 - <time class="date date-end" itemprop="dtend" datetime="' . date('c', $time_end) . '">' . $this->human_date($time_end, $this->settings['dateformat']);
707 - if (date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00') {
708 - $dates.= ', ' . date_i18n($this->settings['timeformat'], $time_end);
709 - }
710 - $dates.='</time>';
711 1264 }
1265 + // Not same day
1266 + else {
1267 + $dates.= ' '.sprintf(
1268 + $from_to_days,
1269 + '<span class="linking_word linking_word-from">',
1270 + '</span>',
1271 + '<time class="date date-start" itemprop="dtstart" datetime="' . date('c', $time_start) . '">'
1272 + . ((date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00')
1273 + ? sprintf($single_day_at, '<span class="date">'.$this->human_date($time_start, $this->settings['dateformat']).'</span>', '<span class="linking_word">', '</span>', '<span class="time">'.date_i18n($this->settings['timeformat'], $time_start).'</span>')
1274 + : $this->human_date($time_start, $this->settings['dateformat'])
1275 + )
1276 + . '</time>',
1277 + '<span class="linking_word linking_word-to">',
1278 + '</span>',
1279 + '<time class="date date-to" itemprop="dtend" datetime="' . date('c', $time_end) . '">'
1280 + . ((date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00')
1281 + ? sprintf($single_day_at, '<span class="date">'.$this->human_date($time_end, $this->settings['dateformat']).'</span>', '<span class="linking_word">', '</span>', '<span class="time">'.date_i18n($this->settings['timeformat'], $time_end).'</span>')
1282 + : $this->human_date($time_end, $this->settings['dateformat'])
1283 + )
1284 + . '</time>'
1285 + );
1286 + }
712 1287 $dates.="\n\t\t\t\t\t\t".'</div><!-- .event_date -->';
713 1288 return $dates;
714 1289 }
715 1290
716 1291 /**
717 - *
1292 + * Displays a date
1293 + *
718 1294 * @param WP_Post object $post
719 1295 * @param mixed $links
1296 + *
720 1297 * @return string
721 1298 */
722 1299 public function print_date($post = null, $links = 'deprecated', $context='') {
723 1300 $dates = '';
724 1301 $event = $this->retreive($post);
725 - if ($event->start != '' && $event->end != '') {
1302 + if ($event != false){
1303 + if ($event->start != '' && $event->end != '') {
726 1304
727 - $dates.=$this->delta_date($event->time_start, $event->time_end);
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();
728 1315
729 - $timezone_string = get_option('timezone_string');
730 - $gmt_offset = $gmt = $this->get_gmt_offset();
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;
731 1338
732 - if (
733 - !is_admin()
734 - && ( // Export when setting
735 - $this->settings['export_when'] == 'both' ||
736 - ( $this->settings['export_when'] == 'future' && $this->is_future($event) ) ||
737 - ( $this->settings['export_when'] == 'past' && $this->is_past($event) )
738 - )
739 - && ( // Export setting
740 - $this->settings['export'] == 'both' ||
741 - ($this->settings['export'] == 'single' && is_single() ) ||
742 - ($this->settings['export'] == 'list' && !is_single() )
743 - )
744 - ) {
745 - // Export event
746 - $title = urlencode($post->post_title);
747 - $address = urlencode($post->address);
748 - $url = urlencode($post->guid);
749 - $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');
750 - $d_s = date("Ymd", $event->time_start) . ($allday ? '' : 'T' . date("His", $event->time_start));
751 - $d_e = date("Ymd", $event->time_end) . ($allday ? '' : 'T' . date("His", $event->time_end));
752 - $uid = $post->ID . '-' . $post->blog_id;
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'));
753 1348
754 - // format de date ICS
755 - $ics_url = add_query_arg(array(
756 - 't'=>$title,
757 - 'u'=>$uid,
758 - 'sd'=>$d_s,
759 - 'ed'=>$d_e,
760 - 'a'=>$address,
761 - 'd'=>$url,
762 - 'tz'=>$timezone_string,
763 - 'gmt'=>urlencode($gmt_offset)
764 - ), plugins_url('export/ics.php', __FILE__));
1349 + }
765 1350
766 - // format de date Google cal
767 - //$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';
768 - $google_url = add_query_arg(array(
769 - 'action'=>'TEMPLATE',
770 - 'trp'=>'false',
771 - 'sprop'=>'name',
772 - 'text'=>$title,
773 - 'dates'=>$d_s.'/'.$d_e.'', // Removed Z to fix TZ issue
774 - 'location'=>$address,
775 - 'details'=>$url,
776 - 'gmt'=> urlencode($gmt_offset)
777 - ), 'https://www.google.com/calendar/event');
778 - if(!empty($timezone_string)){
779 - $google_url = add_query_arg(array(
780 - 'ctz'=>$timezone_string,
781 - ), $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>';
782 1376 }
783 -
784 - // format de date VCS
785 - $vcs_url = add_query_arg(array(
786 - 't'=>$title,
787 - 'u'=>$uid,
788 - 'sd'=>$d_s,
789 - 'ed'=>$d_e,
790 - 'a'=>$address,
791 - 'd'=>$url,
792 - 'tz'=>$timezone_string,
793 - 'gmt'=>$gmt_offset
794 - ), plugins_url('export/vcs.php', __FILE__));
795 - $dates.='
796 - <span class="eventpost-date-export">
797 - <a href="' . $ics_url . '" class="event_link ics" target="_blank" title="' . __('Download ICS file', 'event-post') . '">ical</a>
798 - <a href="' . $google_url . '" class="event_link gcal" target="_blank" title="' . __('Add to Google calendar', 'event-post') . '">Google</a>
799 - <a href="' . $vcs_url . '" class="event_link vcs" target="_blank" title="' . __('Add to Outlook', 'event-post') . '">outlook</a>
800 - <i class="dashicons-before dashicons-calendar"></i>
801 - </span>';
802 1377 }
803 1378 }
804 1379 return apply_filters('eventpost_printdate', $dates);
805 1380 }
@@ -804,10 +1379,12 @@
804 1379 return apply_filters('eventpost_printdate', $dates);
805 1380 }
806 1381
807 1382 /**
808 - *
1383 + * Outputs location of an event
1384 + *
809 1385 * @param WP_Post object $post
1386 + *
810 1387 * @return string
811 1388 */
812 1389 public function print_location($post=null, $context='') {
813 1390 $location = '';
@@ -818,34 +1395,73 @@
818 1395 }
819 1396 if (!isset($post->start)) {
820 1397 $post = $this->retreive($post);
821 1398 }
822 - $address = $post->address;
823 - $lat = $post->lat;
824 - $long = $post->long;
825 - $color = $post->color;
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;
826 1408
827 - if ($address != '' || ($lat != '' && $long != '')) {
828 - $location.="\t\t\t\t".'<address';
829 - if ($lat != '' && $long != '') {
830 - $location.=' data-id="' . $post->ID . '" data-latitude="' . $lat . '" data-longitude="' . $long . '" data-marker="' . $this->get_marker($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";
831 1414 }
832 - $location.=' itemprop="adr">'
833 - . "\n\t\t\t\t\t\t\t".'<span>'
834 - . "\n".$address
835 - . "\n\t\t\t\t\t\t\t". '</span>';
836 - if ($context=='single' && $lat != '' && $long != '') {
837 - $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 + }
838 1438 }
839 - $location.="\n\t\t\t\t\t\t".'</address>';
840 1439 }
1440 + return apply_filters('eventpost_printlocation', $location);
1441 + }
841 1442
842 - 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;
843 1457 }
844 1458
845 1459 /**
846 - *
1460 + * Outputs categories of an event
1461 + *
847 1462 * @param WP_Post object $post
1463 + *
848 1464 * @return string
849 1465 */
850 1466 public function print_categories($post=null, $context='') {
851 1467 if ($post == null)
@@ -856,20 +1472,36 @@
856 1472 if (!isset($post->start)) {
857 1473 $post = $this->retreive($post);
858 1474 }
859 1475 $cats = '';
860 - $categories = $post->categories;
861 - if ($categories) {
862 - $cats.="\t\t\t\t".'<span class="event_category"';
863 - $color = $post->color;
864 - if ($color != '') {
865 - $cats.=' style="color:#' . $color . '"';
1476 + if ($post != false){
1477 + $categories = $post->Taxonomies;
1478 + if ($categories) {
1479 + $cats.="\t\t\t\t".'<span class="event_categories">';
1480 +
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>';
1501 + }
1502 + $cats.='</span>';
866 1503 }
867 - $cats.='>';
868 - foreach ($categories as $category) {
869 - $cats .= $category->name . ' ';
870 - }
871 - $cats.='</span>';
872 1504 }
873 1505 return $cats;
874 1506 }
875 1507
@@ -874,11 +1506,14 @@
874 1506 }
875 1507
876 1508 /**
877 1509 * Generate, return or output date event datas
1510 + *
878 1511 * @param WP_Post object $post
879 1512 * @param string $class
1513 + *
880 1514 * @filter eventpost_get_single
1515 + *
881 1516 * @return string
882 1517 */
883 1518 public function get_single($post = null, $class = '', $context='') {
884 1519 if ($post == null) {
@@ -883,16 +1518,24 @@
883 1518 public function get_single($post = null, $class = '', $context='') {
884 1519 if ($post == null) {
885 1520 $post = $this->retreive();
886 1521 }
887 - $datas_date = $this->print_date($post, null, $context);
888 - $datas_cat = $this->print_categories($post, $context);
889 - $datas_loc = $this->print_location($post, $context);
890 - if ($datas_date != '' || $datas_loc != '') {
891 - $rgb = $this->hex2dec($post->color);
892 - return '<div class="event_data ' . $class . '" style="border-left-color:#' . $post->color . ';background:rgba(' . $rgb['R'] . ',' . $rgb['G'] . ',' . $rgb['B'] . ',0.1)" itemscope itemtype="http://microformats.org/profile/hcard">'
893 - . apply_filters('eventpost_get_single', $datas_date . $datas_cat . $datas_loc, $post)
894 - . '</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 + }
895 1538 }
896 1539 return '';
897 1540 }
898 1541
@@ -897,10 +1540,12 @@
897 1540 }
898 1541
899 1542 /**
900 1543 * Displays dates of a gieven post
1544 + *
901 1545 * @param WP_Post object $post
902 1546 * @param string $class
1547 + *
903 1548 * @return string
904 1549 */
905 1550 public function get_singledate($post = null, $class = '', $context='') {
906 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 -->';
@@ -907,10 +1552,12 @@
907 1552 }
908 1553
909 1554 /**
910 1555 * Displays coloured terms of a given post
1556 + *
911 1557 * @param WP_Post object $post
912 1558 * @param string $class
1559 + *
913 1560 * @return string
914 1561 */
915 1562 public function get_singlecat($post = null, $class = '', $context='') {
916 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 -->';
@@ -917,10 +1564,12 @@
917 1564 }
918 1565
919 1566 /**
920 1567 * Displays location of a given post
1568 + *
921 1569 * @param WP_Post object $post
922 1570 * @param string $class
1571 + *
923 1572 * @return string
924 1573 */
925 1574 public function get_singleloc($post = null, $class = '', $context='') {
926 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 -->';
@@ -927,9 +1576,11 @@
927 1576 }
928 1577
929 1578 /**
930 1579 * Uses `the_content` filter to add event details before or after the content of the current post
1580 + *
931 1581 * @param string $content
1582 + *
932 1583 * @return string
933 1584 */
934 1585 public function display_single($content) {
935 1586 if (is_page() || !is_single() || is_home() || !in_the_loop() || !is_main_query()){
@@ -936,32 +1587,42 @@
936 1587 return $content;
937 1588 }
938 1589
939 1590 $post = $this->retreive();
940 - $eventbar = apply_filters('eventpost_contentbar', $this->get_single($post, 'event_single', 'single'), $post);
941 - if($this->settings['singlepos']=='before'){
942 - $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();
943 1605 }
944 - elseif($this->settings['singlepos']=='after'){
945 - $content.=$eventbar;
946 - }
947 - $this->load_map_scripts();
948 1606 return $content;
949 1607 }
950 1608
951 1609 /**
952 1610 * Outputs events details (dates, geoloc, terms) of given post
1611 + *
953 1612 * @param WP_Post object $post
954 - * @echoes string
1613 + *
955 1614 * @return void
956 1615 */
957 1616 public function print_single($post = null) {
958 - echo $this->get_single($post);
1617 + echo wp_kses_post($this->get_single($post));
959 1618 }
960 1619
961 1620 /**
962 1621 * Alter the post title in order to add icons if needed
1622 + *
963 1623 * @param string $title
1624 + *
964 1625 * @return string
965 1626 */
966 1627 public function the_title($title, $post_id = null){
967 1628 if(!$post_id || !in_the_loop() || !$this->settings['loopicons']){
@@ -974,29 +1635,54 @@
974 1635 2=>array('<span class="dashicons dashicons-calendar"></span>', '<span class="dashicons dashicons-location"></span>'),
975 1636 );
976 1637
977 1638 $event = $this->retreive($post_id);
978 - if(!empty($event->start)){
979 - $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 + }
980 1646 }
981 - if(!empty($event->lat) && !empty($event->long)){
982 - $title .= ' '.$icons_[$this->settings['loopicons']][1];
983 - }
984 1647 return $title;
985 1648 }
986 1649
987 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 +
988 1673 /**
989 1674 * Return an HTML list of events
990 1675 *
1676 + * @param array $atts
1677 + * @param string $id
1678 + * @param string $context
1679 + *
991 1680 * @filter eventpost_params($defaults, 'list_events')
992 1681 * @filter eventpost_listevents
993 1682 * @filter eventpost_item_scheme_entities
994 1683 * @filter eventpost_item_scheme_values
995 - *
996 - * @param array $atts
997 - * @param string $id
998 - * @param string $context
1684 + *
999 1685 * @return string
1000 1686 */
1001 1687 public function list_events($atts, $id = 'event_list', $context='') {
1002 1688 $ep_settings = $this->settings;
@@ -1001,8 +1687,11 @@
1001 1687 public function list_events($atts, $id = 'event_list', $context='') {
1002 1688 $ep_settings = $this->settings;
1003 1689 $defaults = array(
1004 1690 'nb' => 0,
1691 + 'nb_desktop' => 0,
1692 + 'nb_tablet' => 0,
1693 + 'nb_mobile' => 0,
1005 1694 'type' => 'div',
1006 1695 'future' => true,
1007 1696 'past' => false,
1008 1697 'geo' => 0,
@@ -1009,14 +1698,21 @@
1009 1698 'width' => '',
1010 1699 'height' => '',
1011 1700 'list' => 0,
1012 1701 'zoom' => '',
1702 + 'map_position' => 'false',
1703 + 'latitude' => '',
1704 + 'longitude' => '',
1013 1705 'tile' => $ep_settings['tile'],
1706 + 'pop_element_schema' => 'false',
1707 + 'htmlPop_element_schema' => '',
1014 1708 'title' => '',
1015 1709 'before_title' => '<h3>',
1016 1710 'after_title' => '</h3>',
1017 1711 'cat' => '',
1018 1712 'tag' => '',
1713 + 'tax_name' => '',
1714 + 'tax_term' => '',
1019 1715 'events' => '',
1020 1716 'style' => '',
1021 1717 'thumbnail' => '',
1022 1718 'thumbnail_size' => '',
@@ -1023,39 +1719,95 @@
1023 1719 'excerpt' => '',
1024 1720 'orderby' => 'meta_value',
1025 1721 'order' => 'ASC',
1026 1722 'class' => '',
1723 + 'align' => '',
1724 + 'className' => '',
1027 1725 'container_schema' => $this->list_shema['container'],
1028 1726 'item_schema' => $this->list_shema['item'],
1029 - );
1727 + 'pages' => false,
1728 + 'paged' => '',
1729 + 'separate_years' => false,
1730 + 'separate_months' => false,
1731 + );
1030 1732 // Map UI options
1031 1733 foreach($this->map_interactions as $int_key=>$int_name){
1032 1734 $defaults[$int_key]=true;
1033 1735 }
1034 - $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 + }
1035 1741
1742 + $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events', $context), $atts);
1743 +
1036 1744 extract($atts);
1037 1745 if (!is_array($events)) {
1038 1746 $events = $this->get_events($atts);
1039 1747 }
1748 +
1040 1749 $ret = '';
1041 1750 $this->list_id++;
1042 1751 if (sizeof($events) > 0) {
1043 1752 if (!empty($title)) {
1044 - $ret.= html_entity_decode($before_title) . $title . html_entity_decode($after_title);
1753 + $ret .= wp_kses_post($before_title . esc_html($title) . $after_title);
1045 1754 }
1046 1755
1047 - $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';
1048 1758
1049 1759 $html = '';
1050 1760
1051 - if($id=='event_geolist'){
1052 - $this->load_map_scripts();
1053 - $html.=sprintf('<%1$s class="event_geolist_icon_loader"><p><span class="dashicons dashicons-location-alt"></span></p><p class="screen-reader-text">'.__('An events map', 'event-post').'</p></%1$s>', $type);
1054 - }
1761 + if($id=='event_geolist'){
1762 + $this->load_map_scripts();
1763 + $html.=sprintf('<%1$s class="event_geolist_icon_loader"><p><span class="dashicons dashicons-location-alt"></span></p><p class="screen-reader-text">'.__('An events map', 'event-post').'</p></%1$s>', $type);
1764 + }
1765 + $attributes = '';
1766 + $prev_arrow = "";
1767 + $next_arrow = "";
1768 + $item_child_style = "";
1769 + if($id == "event_timeline"){
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).'" ';
1780 + }
1055 1781
1782 + if($id === 'event_timeline'){
1783 + $previous_year = $atts['separate_years'] ? true : false;
1784 + $previous_month = $atts['separate_months'] ? true : false;
1785 + }
1786 +
1056 1787 foreach ($events as $event) {
1057 - $class_item = $this->is_future($event) ? 'event_future' : 'event_past';
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);
1799 + $class_item = array(
1800 + $this->is_future($event) ? 'event_future' : 'event_past',
1801 + 'status-'.strtolower(str_replace('Event', '', $event->status)),
1802 + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $event->attendance_mode)),
1803 + );
1804 + $taxonomies= get_taxonomies('','names');
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 + }
1058 1810 if ($ep_settings['emptylink'] == 0 && empty($event->post_content)) {
1059 1811 $event->permalink = '#' . $id . $this->list_id;
1060 1812 }
1061 1813 elseif(empty($event->permalink)){
@@ -1068,53 +1820,111 @@
1068 1820 '%color%',
1069 1821 '%event_link%',
1070 1822 '%event_thumbnail%',
1071 1823 '%event_title%',
1824 + '%event_price%',
1072 1825 '%event_date%',
1073 1826 '%event_cat%',
1074 1827 '%event_location%',
1075 - '%event_excerpt%'
1828 + '%event_excerpt%',
1829 + '%style%',
1076 1830 )), apply_filters('eventpost_item_scheme_values', array(
1077 1831 $child,
1078 - $class_item,
1079 - $event->color,
1832 + implode(' ', $class_item),
1833 + $this->get_post_color($event->ID, $this->settings['default_color'],true),
1080 1834 $event->permalink,
1081 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>' : '',
1082 1836 $event->post_title,
1837 + $event->post_type == 'product' ? $text_price : '',
1083 1838 $this->get_singledate($event, '', $context),
1084 1839 $this->get_singlecat($event, '', $context),
1085 1840 $this->get_singleloc($event, '', $context),
1086 - $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>' : '',
1842 + $item_child_style,
1087 1843 ), $event), $item_schema
1088 1844 );
1845 +
1089 1846 }
1090 - $attributes = '';
1091 1847 if($id == 'event_geolist'){
1092 - $attributes = 'data-tile="'.$tile.'" data-width="'.$width.'" data-height="'.$height.'" data-zoom="'.$zoom.'" data-list="'.$list.'" data-disabled-interactions="';
1848 + if($height==''){
1849 + $height = '300px';
1850 + }
1851 + if($width==''){
1852 + $width = '100%';
1853 + }
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="';
1865 + // add data-position avec ma variables
1093 1866 foreach($this->map_interactions as $int_key=>$int_name){
1094 - $attributes.=$atts[$int_key]==false ? $int_key.', ' : '';
1867 + $attributes.=$atts[$int_key]==false ? esc_attr($int_key).', ' : '';
1095 1868 }
1096 - $attributes.='"';
1869 + $attributes.='" ';
1097 1870 }
1098 - $ret.=str_replace(
1099 - array(
1100 - '%type%',
1101 - '%id%',
1102 - '%class%',
1103 - '%listid%',
1104 - '%style%',
1105 - '%attributes%',
1106 - '%list%'
1107 - ), array(
1108 - $type,
1109 - $id,
1110 - $class.($id == 'event_geolist' && $list ? ' has-list list-'.$list : ' no-list'),
1111 - $id . $this->list_id,
1112 - (!empty($width) ? 'width:' . $width . ';' : '') . (!empty($height) ? 'height:' . $height . ';' : '') . $style,
1113 - $attributes,
1114 - $html
1115 - ), $container_schema
1116 - );
1871 + $pagination = '';
1872 + if($pages && $this->pagination){
1873 + global $wp_rewrite;
1874 + $paged = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1875 + $pagination = paginate_links( array(
1876 + 'prev_text' => __('« Previous Events', 'event-post'),
1877 + 'next_text' => __('Next Events »', 'event-post'),
1878 + 'current' => $paged,
1879 + 'total' => $this->pagination['max_num_pages'],
1880 + )
1881 + );
1882 + }
1883 +
1884 + if($context == 'events_only'){
1885 + $ret = $html;
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 + }
1899 + $ret.=str_replace(
1900 + array(
1901 + '%type%',
1902 + '%id%',
1903 + '%class%',
1904 + '%listid%',
1905 + '%style%',
1906 + '%attributes%',
1907 + '%list%',
1908 + '%pagination%',
1909 + '%prev_arrow%',
1910 + '%next_arrow%',
1911 + '%number%'
1912 + ), array(
1913 + $type,
1914 + $id,
1915 + esc_attr(implode(' ', $classes)),
1916 + $id . $this->list_id,
1917 + (!empty($width) ? 'width:' . esc_attr($width) . ';' : '') . (!empty($height) ? 'height:' . esc_attr($height) . ';' : '') . esc_attr($style),
1918 + $attributes,
1919 + $html,
1920 + $pagination,
1921 + $prev_arrow,
1922 + $next_arrow
1923 + ), $container_schema
1924 + );
1925 + }
1926 +
1117 1927 }
1118 1928 elseif(filter_input(INPUT_POST, 'action')=='bulk_do_shortcode'){
1119 1929 return '<div class="event_geolist_icon_loader"><p><span class="dashicons dashicons-calendar"></span></p><p class="screen-reader-text">'.__('An empty list of events', 'event-post').'</p></div>';
1120 1930 }
@@ -1120,16 +1930,35 @@
1120 1930 }
1121 1931 return apply_filters('eventpost_listevents', $ret, $id.$this->list_id, $atts, $events, $context);
1122 1932 }
1123 1933
1934 +
1124 1935 /**
1125 - * get_events
1936 + * Get events
1937 + *
1126 1938 * @param array $atts
1939 + *
1127 1940 * @filter eventpost_params
1128 1941 * @filter eventpost_get_items
1129 - * @return array of post_ids wich are events
1942 + *
1943 + * @return array of post_ids which are events
1130 1944 */
1131 1945 public function get_events($atts) {
1946 + if(isset($atts['future'])){
1947 + $atts['future'] = filter_var( $atts['future'], FILTER_VALIDATE_BOOLEAN);
1948 + }
1949 + if(isset($atts['past'])){
1950 + $atts['past'] = filter_var( $atts['past'], FILTER_VALIDATE_BOOLEAN);
1951 + }
1952 + if(isset($atts['geo'])){
1953 + $atts['geo'] = filter_var( $atts['geo'], FILTER_VALIDATE_BOOLEAN);
1954 + }
1955 + if(isset($atts['pages'])){
1956 + $atts['pages'] = filter_var( $atts['pages'], FILTER_VALIDATE_BOOLEAN);
1957 + }
1958 +
1959 +
1960 +
1132 1961 $requete = (shortcode_atts(apply_filters('eventpost_params', array(
1133 1962 'nb' => 5,
1134 1963 'future' => true,
1135 1964 'past' => false,
@@ -1141,17 +1970,23 @@
1141 1970 'orderbykey' => $this->META_START,
1142 1971 'order' => 'ASC',
1143 1972 'tax_name' => '',
1144 1973 'tax_term' => '',
1974 + 'paged' => 1,
1145 1975 'post_type'=> $this->settings['posttypes']
1146 1976 ), 'get_events'), $atts));
1977 + if(!isset($requete['paged']) || $requete['paged'] == ""){
1978 + $requete['paged'] = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1979 + }
1147 1980 extract($requete);
1148 1981 wp_reset_query();
1149 1982
1983 +
1150 1984 $arg = array(
1151 1985 'post_status' => 'publish',
1152 1986 'post_type' => $post_type,
1153 1987 'posts_per_page' => $nb,
1988 + 'paged' => $paged,
1154 1989 'meta_key' => $orderbykey,
1155 1990 'orderby' => $orderby,
1156 1991 'order' => $order
1157 1992 );
@@ -1166,9 +2001,15 @@
1166 2001 }
1167 2002
1168 2003 // CUSTOM TAXONOMY
1169 2004 if ($tax_name != '' && $tax_term != '') {
1170 - $arg[$tax_name] = $tax_term;
2005 + $arg['tax_query'] = array(
2006 + array(
2007 + 'taxonomy' => $tax_name,
2008 + 'field' => 'slug',
2009 + 'terms' => $tax_term,
2010 + ),
2011 + );
1171 2012 }
1172 2013 // CAT
1173 2014 if ($cat != '') {
1174 2015 if (preg_match('/[a-zA-Z]/i', $cat)) {
@@ -1213,9 +2054,10 @@
1213 2054 $meta_query = array();
1214 2055 $arg['meta_key'] = null;
1215 2056 $arg['orderby'] = null;
1216 2057 $arg['order'] = null;
1217 - } elseif ($future == 1 && $past == 0) {
2058 + }
2059 + elseif ($future == 1 && $past == 0) {
1218 2060 $meta_query[] = array(
1219 2061 'key' => $this->META_END,
1220 2062 'value' => current_time('mysql'),
1221 2063 'compare' => '>=',
@@ -1220,9 +2062,10 @@
1220 2062 'value' => current_time('mysql'),
1221 2063 'compare' => '>=',
1222 2064 //'type'=>'DATETIME'
1223 2065 );
1224 - } elseif ($future == 0 && $past == 1) {
2066 + }
2067 + elseif ($future == 0 && $past == 1) {
1225 2068 $meta_query[] = array(
1226 2069 'key' => $this->META_END,
1227 2070 'value' => current_time('mysql'),
1228 2071 'compare' => '<=',
@@ -1265,9 +2108,9 @@
1265 2108 }
1266 2109
1267 2110 $arg['meta_query'] = $meta_query;
1268 2111
1269 - $query_md5 = 'eventpost_' . md5(var_export($requete, true));
2112 + $query_md5 = 'eventpost_' . md5(wp_json_encode($requete, true));
1270 2113 // Check if cache is activated
1271 2114 if ($this->settings['cache'] == 1 && false !== ( $cached_events = get_transient($query_md5) )) {
1272 2115 return apply_filters('eventpost_get_items', is_array($cached_events) ? $cached_events : array(), $requete, $arg);
1273 2116 }
@@ -1276,16 +2119,22 @@
1276 2119 if ('' === $events) {
1277 2120 global $wpdb;
1278 2121 $query = new WP_Query($arg);
1279 2122 $events = $wpdb->get_col($query->request);
2123 + $this->pagination = array(
2124 + 'found_posts' => $query->found_posts,
2125 + 'max_num_pages' => $query->max_num_pages,
2126 + );
1280 2127 foreach ($events as $k => $post) {
1281 - $event = $this->retreive($post);
1282 - $events[$k] = $event;
2128 + $event = $this->retreive($post);
2129 + if ($event != false){
2130 + $events[$k] = $event;
2131 + }
1283 2132 }
1284 2133 }
1285 2134 if ($this->settings['cache'] == 1){
1286 2135 set_transient($query_md5, $events, 5 * MINUTE_IN_SECONDS);
1287 - }
2136 + }
1288 2137 return apply_filters('eventpost_get_items', $events, $requete, $arg);
1289 2138 }
1290 2139
1291 2140 /**
@@ -1290,10 +2139,11 @@
1290 2139
1291 2140 /**
1292 2141 * Checks if the given event is in the future or not
1293 2142 *
1294 - * @param object $event
1295 - * @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 + *
1296 2146 * @return boolean
1297 2147 */
1298 2148 function is_future($event, $exact=false){
1299 2149 $match = current_time('timestamp');
@@ -1306,10 +2156,11 @@
1306 2156
1307 2157 /**
1308 2158 * Checks if the given event is completed or not
1309 2159 *
1310 - * @param object $event
1311 - * @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 + *
1312 2163 * @return boolean
1313 2164 */
1314 2165 function is_past($event, $exact=false){
1315 2166 $match = current_time('timestamp');
@@ -1319,21 +2170,47 @@
1319 2170 }
1320 2171 return ($event->time_end < $match);
1321 2172 }
1322 2173
2174 + /**
2175 + * Checks if an event is online
2176 + *
2177 + * @param $event
2178 + *
2179 + * @return boolean
2180 + */
2181 + function is_online($event){
2182 + return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OnlineEventAttendanceMode')));
2183 + }
1323 2184
1324 2185 /**
1325 - *
2186 + * Checks if an event is offline
2187 + *
2188 + * @param $event
2189 + *
2190 + * @return boolean
2191 + */
2192 + function is_offline($event){
2193 + return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OfflineEventAttendanceMode')));
2194 + }
2195 +
2196 + /**
2197 + * Populates a WP_Post object with event datas
2198 + *
1326 2199 * @param object $event
2200 + *
1327 2201 * @return object
1328 2202 */
1329 2203 public function retreive($event = null) {
1330 2204 global $EventPost_cache;
1331 - $ob = get_post($event);
1332 - if($ob->start){
2205 + $ob = get_post($event);
2206 + if(!$ob){
2207 + return false;
2208 + }
2209 + if(is_object($ob) && $ob->start){
1333 2210 return $ob;
1334 2211 }
1335 - if(isset($EventPost_cache[$ob->ID])){
2212 + if(is_object($ob) && isset($EventPost_cache[$ob->ID])){
1336 2213 return $EventPost_cache[$ob->ID];
1337 2214 }
1338 2215 $ob->start = get_post_meta($ob->ID, $this->META_START, true);
1339 2216 $ob->end = get_post_meta($ob->ID, $this->META_END, true);
@@ -1338,9 +2215,9 @@
1338 2215 $ob->start = get_post_meta($ob->ID, $this->META_START, true);
1339 2216 $ob->end = get_post_meta($ob->ID, $this->META_END, true);
1340 2217 if (!$this->dateisvalid($ob->start)){
1341 2218 $ob->start = '';
1342 - }
2219 + }
1343 2220 if (!$this->dateisvalid($ob->end)){
1344 2221 $ob->end = '';
1345 2222 }
1346 2223 $ob->root_ID = $ob->ID;
@@ -1345,26 +2222,38 @@
1345 2222 }
1346 2223 $ob->root_ID = $ob->ID;
1347 2224 $ob->time_start = !empty($ob->start) ? strtotime($ob->start) : '';
1348 2225 $ob->time_end = !empty($ob->end) ? strtotime($ob->end) : '';
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 + }
1349 2237 $ob->address = get_post_meta($ob->ID, $this->META_ADD, true);
1350 - $ob->lat = get_post_meta($ob->ID, $this->META_LAT, true);
1351 - $ob->long = get_post_meta($ob->ID, $this->META_LONG, true);
1352 - $ob->color = get_post_meta($ob->ID, $this->META_COLOR, true);
1353 - $ob->categories = get_the_category($ob->ID);
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));
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];
2241 + $ob->status = (null != $status = get_post_meta($ob->ID, $this->META_STATUS, true)) ? $status : array_keys($this->statuses)[0];
2242 + $ob->color = $this->get_post_color($ob->ID);
2243 + $ob->icon = $this->get_post_icon($ob->ID);
2244 + $ob->Taxonomies = get_the_category($ob->ID);
1354 2245 $ob->permalink = get_permalink($ob->ID);
1355 2246 $ob->blog_id = get_current_blog_id();
1356 - if ($ob->color == ''){
1357 - $ob->color = '000000';
1358 - }
1359 -
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)))));
1360 2248 $EventPost_cache[$ob->ID] = apply_filters('eventpost_retreive', $ob);
1361 2249 return $EventPost_cache[$ob->ID];
1362 2250 }
1363 2251
1364 2252 /**
1365 - *
1366 - * @param mixte $_term
2253 + * Fetch terms of a post
2254 + *
2255 + * @param mixed $_term
1367 2256 * @param string $taxonomy
1368 2257 * @param string $post_type
1369 2258 */
1370 2259 public function retreive_term($_term=null, $taxonomy='category', $post_type='post') {
@@ -1408,12 +2297,12 @@
1408 2297 return $term;
1409 2298
1410 2299 }
1411 2300
1412 - /** ADMIN ISSUES * */
2301 + // ADMIN ISSUES
1413 2302
1414 2303 /**
1415 - * add custom boxes in posts edit page
2304 + * Add custom boxes in posts edit page
1416 2305 */
1417 2306 public function add_custom_box() {
1418 2307 foreach($this->settings['posttypes'] as $posttype){
1419 2308 add_meta_box(
@@ -1439,258 +2328,85 @@
1439 2328 )
1440 2329 );
1441 2330 do_action('eventpost_add_custom_box', $posttype);
1442 2331 }
1443 - if(!function_exists('shortcode_ui_register_for_shortcode') && !function_exists('register_block_type')){
1444 - add_meta_box('event_post_sc_edit', __('Events Shortcode editor', 'event-post'), array(&$this, 'inner_custom_box_edit'), 'page');
1445 - }
1446 2332 }
2333 +
1447 2334 /**
1448 - * display the date custom box
2335 + * Displays the date custom box
1449 2336 */
1450 2337 public function inner_custom_box_date() {
2338 +
2339 +
2340 +
1451 2341 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1452 2342 $post_id = get_the_ID();
1453 2343 $event = $this->retreive($post_id);
1454 - $start_date = $event->start;
1455 - $end_date = $event->end;
1456 - $eventcolor = $event->color;
2344 + if ($event != false){
2345 + $start_date = $event->start;
2346 + $end_date = $event->end;
2347 + $eventcolor = $event->color;
2348 + $eventicon = $event->icon;
1457 2349
1458 - $language = get_bloginfo('language');
1459 - if (strpos($language, '-') > -1) {
1460 - $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);
1461 2357 }
1462 - $colors = $this->get_colors();
1463 - ?>
2358 + }
1464 2359
1465 - <div class="eventpost-misc-pub-section">
1466 - <p>
1467 - <label>
1468 - <input type="checkbox" id="event-post-date-all-day" <?php checked( $event->time_start && $event->time_end && date('H:i:s', $event->time_start) == '00:00:00' && date('H:i:s', $event->time_end) == '00:00:00', true, true); ?>>
1469 - <?php _e('All day event', 'event-post') ?>
1470 - </label>
1471 - </p>
1472 - <p>
1473 - <span class="dashicons dashicons-calendar eventpost-edit-icon"></span>
1474 - <label for="<?php echo $this->META_START; ?>_date">
1475 - <?php _e('Begin:', 'event-post') ?>
1476 - <span id="<?php echo $this->META_START; ?>_date_human" class="human_date">
1477 - <?php
1478 - if ($event->time_start != '') {
1479 - echo $this->human_date($event->time_start) . (date('H:i', $event->time_start)=='00:00'?'':date(' H:i', $event->time_start));
1480 - }
1481 - else{
1482 - _e('Pick a date','event-post');
1483 - }
1484 - ?>
1485 - </span>
1486 - <input type="<?php echo ($this->settings['datepicker']=='browser'?'datetime':''); ?>" class="eventpost-datepicker-<?php echo $this->settings['datepicker']; ?>" data-lang="<?php echo $language; ?>" value="<?php echo substr($start_date,0,16) ?>" name="<?php echo $this->META_START; ?>" id="<?php echo $this->META_START; ?>_date"/>
1487 - </label>
1488 - </p>
1489 - <p>
1490 - <span class="dashicons dashicons-calendar eventpost-edit-icon"></span>
1491 - <label for="<?php echo $this->META_END; ?>_date">
1492 - <?php _e('End:', 'event-post') ?>
1493 - <span id="<?php echo $this->META_END; ?>_date_human" class="human_date">
1494 - <?php
1495 - if ($event->time_start != '') {
1496 - echo $this->human_date($event->time_end) . (date('H:i', $event->time_end)=='00:00'?'':date(' H:i', $event->time_end));
1497 - }
1498 - else{
1499 - _e('Pick a date','event-post');
1500 - }
1501 - ?>
1502 - </span>
1503 - <input type="<?php echo ($this->settings['datepicker']=='browser'?'datetime':''); ?>" class="eventpost-datepicker-<?php echo $this->settings['datepicker']; ?>" data-lang="<?php echo $language; ?>" value ="<?php echo substr($end_date,0,16) ?>" name="<?php echo $this->META_END; ?>" id="<?php echo $this->META_END; ?>_date"/>
1504 - </label>
1505 - </p>
1506 - </div>
1507 - <?php if (sizeof($colors) > 0): ?>
1508 - <div class="eventpost-misc-pub-section event-color-section">
1509 - <span class="screen-reader-text"><?php _e('Color:', 'event-post'); ?></span>
1510 - <p>
1511 - <img src="<?php echo $this->markurl.$eventcolor.'.png'; ?>" id="eventpost-color-preview" data-url="<?php echo $this->markurl; ?>">
1512 - <span id="eventpost-color-dropdown">
1513 - <?php foreach ($colors as $color => $file): ?>
1514 - <label style="background:#<?php echo $color ?>" for="<?php echo $this->META_COLOR; ?><?php echo $color ?>" title="<?php echo $file; ?>">
1515 - <img src="<?php echo $this->markurl.$color.'.png'; ?>">
1516 - <input type="radio" value ="<?php echo $color ?>" name="<?php echo $this->META_COLOR; ?>" id="<?php echo $this->META_COLOR; ?><?php echo $color ?>" <?php checked($eventcolor, $color, true); ?>/>
1517 - </label>
1518 - <?php endforeach; ?>
1519 - </span>
1520 - </p>
1521 - </div>
1522 - <?php endif; ?>
1523 - <?php
1524 - do_action ('eventpost_custom_box_date', $event);
1525 - }
1526 2360 /**
1527 - * displays the location custom box
2361 + * Displays the location custom box
1528 2362 */
1529 2363 public function inner_custom_box_loc($post) {
1530 2364 $event = $this->retreive($post);
1531 - ?>
1532 -
1533 - <div class="eventpost-misc-pub-section">
1534 - <label for="<?php echo $this->META_ADD; ?>">
1535 - <?php _e('Address, as it will be displayed:', 'event-post') ?>
1536 - <textarea name="<?php echo $this->META_ADD; ?>" id="<?php echo $this->META_ADD; ?>" class="widefat"><?php echo $event->address; ?></textarea>
1537 - </label>
1538 - </div>
1539 -
1540 - <div id="event_address_searchwrap">
1541 - <span class="dashicons dashicons-location eventpost-edit-icon"></span>
1542 - <?php _e('GPS coordinates:', 'event-post') ?>
1543 - <a id="event_address_search" title="<?php _e('Search or fill exact coordinates', 'event-post') ?>">
1544 - <?php _e('Search / Edit', 'event-post') ?>
1545 - </a>
1546 -
1547 - <div class="misc-pub-section" id="event_address_coords">
1548 - <p>
1549 - <span id="eventaddress_result"></span>
1550 - </p>
1551 - <label for="<?php echo $this->META_LAT; ?>">
1552 - <?php _e('Latitude:', 'event-post') ?>
1553 - <input type="text" value ="<?php echo $event->lat; ?>" name="<?php echo $this->META_LAT; ?>" id="<?php echo $this->META_LAT; ?>" class="widefat"/>
1554 - </label>
1555 -
1556 - <label for="<?php echo $this->META_LONG; ?>">
1557 - <?php _e('Longitude:', 'event-post') ?>
1558 - <input type="text" value ="<?php echo $event->long; ?>" name="<?php echo $this->META_LONG; ?>" id="<?php echo $this->META_LONG; ?>" class="widefat"/>
1559 - </label>
1560 - <p>
1561 - <a id="event_address_unsearch" class="button button-small">
1562 - <span class="dashicons dashicons-yes"></span>
1563 - <?php _e('Done', 'event-post') ?>
1564 - </a>
1565 - </p>
1566 - </div>
1567 - </div>
1568 -
1569 - <div class="eventpost-misc-pub-section">
1570 - <div id="event-post-map-preview" data-marker="<?php echo $this->get_marker($event->color); ?>"></div>
1571 - </div>
1572 - <?php
1573 - do_action ('eventpost_custom_box_loc', $event);
1574 - $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 + }
1575 2370 }
1576 2371
1577 - /**
1578 - * display custombox containing shortcode wizard
1579 - */
1580 - public function inner_custom_box_edit() {
1581 - $ep_settings = $this->settings;
2372 + public function icon_color_fields($item_id, $meta_color,$value_color,$meta_icon,$value_icon ){
1582 2373 ?>
1583 - <?php do_action('before_eventpost_generator'); ?>
1584 - <div class="all">
1585 - <p>
1586 - <label for="ep_sce_type"><?php _e('Type:', 'event-post'); ?>
1587 - <select id="ep_sce_type">
1588 - <option value='list'><?php _e('List', 'event-post') ?></option>
1589 - <option value='map'><?php _e('Map', 'event-post') ?></option>
1590 - </select>
1591 - </label>
1592 - </p>
2374 + <div class="eventpost-misc-pub-section event-color-section">
2375 + <span class="screen-reader-text"><?php esc_html_e('Color:', 'event-post'); ?></span>
1593 2376
1594 - <p>
1595 - <label for="ep_sce_nb"><?php _e('Number of posts', 'event-post'); ?>
1596 - <input id="ep_sce_nb" type="number" value="5" data-att="nb"/>
1597 - <a class="button" id="ep_sce_nball"><?php _e('All', 'event-post'); ?></a>
1598 - </label>
1599 - </p>
2377 + <input class="color-field-post eventpost-colorpicker"
2378 + type="text"
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); ?>"/>
1600 2382
1601 - <p>
1602 - <label for="ep_sce_cat"><?php _e('Only in:', 'event-post'); ?>
1603 - <select id="ep_sce_cat" data-att="cat">
1604 - <option value=''><?php _e('All', '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>
2385 + <?php
2386 + foreach($this->DashIcons->icons as $class => $unicode){
2387 + ?>
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 ?>
1605 2389 <?php
1606 - $cats = get_categories();
1607 - foreach ($cats as $cat) {
1608 - ?>
1609 - <option value="<?php echo $cat->slug; ?>" <?php
1610 - if ($cat->slug == $eventpost_cat) {
1611 - echo'selected';
1612 - }
1613 - ?>><?php echo $cat->cat_name; ?></option>
1614 - <?php } ?>
1615 - </select>
1616 - </label>
1617 - </p>
2390 + }
2391 + ?>
2392 + </select>
2393 + <div class="custom-marker-container">
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>
2395 + <img src="" class="image-marker">
2396 + </div>
2397 + </div>
1618 2398
1619 - <p>
1620 - <label for="ep_sce_future"><?php _e('Future events:', 'event-post'); ?>
1621 - <select id="ep_sce_future" data-att="future">
1622 - <option value='1'><?php _e('Yes', 'event-post') ?></option>
1623 - <option value='0'><?php _e('No', 'event-post') ?></option>
1624 - </select>
1625 - </label>
1626 - <label for="ep_sce_past"><?php _e('Past events:', 'event-post'); ?>
1627 - <select id="ep_sce_past" data-att="past">
1628 - <option value='0'><?php _e('No', 'event-post') ?></option>
1629 - <option value='1'><?php _e('Yes', 'event-post') ?></option>
1630 - </select>
1631 - </label>
1632 - </p>
1633 2399
1634 - <div id="ep_sce_listonly" class="list">
1635 - <p>
1636 - <label for="ep_sce_geo"><?php _e('Only geotagged events:', 'event-post'); ?>
1637 - <select id="ep_sce_geo" data-att="geo">
1638 - <option value='0'><?php _e('No', 'event-post') ?></option>
1639 - <option value='1'><?php _e('Yes', 'event-post') ?></option>
1640 - </select>
1641 - </label>
1642 - </p>
1643 - </div>
1644 - <div id="ep_sce_maponly" class="map">
1645 - <p>
1646 - <label for="ep_sce_tile"><?php _e('Map background', 'event-post'); ?>
1647 - <select id="ep_sce_tile" data-att="tile">
1648 - <?php foreach ($this->maps as $map): ?>
1649 - <option value="<?php
1650 - if ($ep_settings['tile'] != $map['id']) {
1651 - echo $map['id'];
1652 - }
1653 - ?>" <?php selected($ep_settings['tile'], $map['id'], true); ?>>
1654 - <?php echo $map['name']; ?><?php
1655 - if ($ep_settings['tile'] == $map['id']) {
1656 - echo' (default)';
1657 - }
1658 - ?>
1659 - </option>
1660 - <?php endforeach; ?>
1661 - </select>
1662 - </label>
1663 - </p>
1664 - <p>
1665 - <label for="ep_sce_width"><?php _e('Width', 'event-post'); ?>
1666 - <input id="ep_sce_width" type="text" value="500px" data-att="width"/>
1667 - </label>
1668 - </p>
1669 - <p>
1670 - <label for="ep_sce_height"><?php _e('Height', 'event-post'); ?>
1671 - <input id="ep_sce_height" type="text" value="500px" data-att="height"/>
1672 - </label>
1673 - </p>
1674 - </div>
1675 - <?php do_action('after_eventpost_generator'); ?>
1676 - <div id="ep_sce_shortcode">[event_list]</div>
1677 - <a class="button" id="ep_sce_submit"><?php _e('Insert shortcode', 'event-post'); ?></a>
1678 - </div>
1679 - <script>
1680 - var IEbof = false;
1681 - </script>
1682 - <!--[if lt IE 9]>
1683 - <script>IEbof=true;</script>
1684 - <![endif]-->
1685 2400 <?php
1686 2401 }
1687 2402
1688 2403 /**
1689 - *
1690 - * @param string $column_name
1691 - * @param boolean $bulk
1692 - */
2404 + * Quick edit
2405 + *
2406 + * @param string $column_name
2407 + * @param boolean $bulk
2408 + */
1693 2409 function quick_edit( $column_name, $post_type, $bulk=false) {
1694 2410
1695 2411 if ($bulk) {
1696 2412 static $eventpostprintNonceBulk = TRUE;
@@ -1708,17 +2424,17 @@
1708 2424 $fields = $this->quick_edit_fields;
1709 2425 }
1710 2426 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1711 2427 if(isset($fields[$column_name])): ?>
1712 - <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); ?>">
1713 2429 <div class="inline-edit-group">
1714 2430 <?php foreach ($fields[$column_name] as $fieldname=>$fieldlabel): ?>
1715 - <fieldset class="inline-edit-col inline-edit-<?php echo $fieldname; ?>">
1716 - <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); ?>">
1717 2433 <label class="inline-edit-group">
1718 - <span class="title"><?php echo $fieldlabel; ?></span>
2434 + <span class="title"><?php echo esc_html($fieldlabel); ?></span>
1719 2435 <span class="input-text-wrap">
1720 - <?php echo $this->inline_field($fieldname, $bulk); ?>
2436 + <?php echo wp_kses($this->inline_field($fieldname, $bulk), $this->kses_tags); ?>
1721 2437 </span>
1722 2438 </label>
1723 2439 </div>
1724 2440 </fieldset>
@@ -1728,175 +2444,253 @@
1728 2444 <?php endif;
1729 2445 }
1730 2446
1731 2447 /**
1732 - *
2448 + * Inline field in bulk edit
2449 + *
1733 2450 * @param type $fieldname
1734 - * @return type
2451 + *
2452 + * @return string
1735 2453 */
1736 2454 function inline_field($fieldname, $bulk){
1737 - 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);
1738 2456 }
1739 2457
1740 2458 function inline_field_color($html, $fieldname, $bulk){
1741 2459 if($fieldname==$this->META_COLOR){
1742 - $colors = $this->get_colors();
1743 2460 $html='';
1744 2461 if($bulk){
1745 - $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>';
1746 2463 }
1747 - $html .= '<select name="'.$fieldname.'" class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'" >';
2464 + $html .= '
2465 +
2466 + <input class="eventpost-inline-colorpicker eventpost-inline-'.esc_attr($fieldname).' '.($bulk?'is-bulk':'no-bulk').'" type="color" name="'.esc_attr($fieldname).'" >';
2467 + }
2468 + return $html;
2469 + }
2470 + function inline_field_icon($html, $fieldname, $bulk){
2471 + if($fieldname==$this->META_ICON){
1748 2472 if($bulk){
1749 - $html.='<option value="false">— '.__('No Change', 'event-post').' —</option>';
2473 + $html.= '<span class="eventpost-bulk-icon-button link">'.__('No Change', 'event-post').'</span>';
1750 2474 }
1751 - foreach ($colors as $color=>$image_path){
1752 - $html.='<option value="'.$color.'" data-path="'.$image_path.'">'.$color.'</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>';
2480 + foreach($this->DashIcons->icons as $class => $unicode){
2481 + $html .= '<option value="'.$class.'">&#x'.$unicode.'; '.$class.'</option>';
1753 2482 }
1754 - $html.= '</select>';
2483 + $html .= '</select>';
2484 +
1755 2485 }
1756 2486 return $html;
1757 2487 }
1758 2488
2489 +
1759 2490 /**
1760 - *
2491 + * Bulk edit
2492 + *
1761 2493 * @param type $column_name
1762 2494 * @param type $post_type
1763 2495 */
1764 2496 function bulk_edit($column_name, $post_type){
1765 - $this->quick_edit($column_name, $post_type, true);
2497 + $this->quick_edit($column_name, $post_type, true);
1766 2498 }
1767 2499
1768 2500 /**
1769 - *
2501 + * Saves data from quick-edit via `wp_ajax_inline-save` action
2502 + *
2503 + * @return void
1770 2504 */
1771 2505 function inline_save(){
1772 - $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));
1773 2507 $this->save_postdata($post_id);
1774 2508 }
1775 2509 /**
1776 2510 * When the post is saved, saves our custom data
2511 + *
1777 2512 * @param int $post_id
2513 + *
1778 2514 * @return void
1779 2515 */
1780 2516 public function save_postdata($post_id) {
1781 2517 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
1782 2518 return;
1783 - }
2519 + }
1784 2520
1785 - 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__))){
1786 2522 return;
1787 - }
2523 + }
1788 2524
2525 + $post_id = absint($post_id);
2526 + if (!$post_id || !current_user_can('edit_post', $post_id)) {
2527 + return;
2528 + }
2529 +
1789 2530 // Clean color or no color
1790 - if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR, FILTER_SANITIZE_STRING)) {
1791 - 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));
1792 2533 }
2534 + // Clean color or no color
2535 + if (false !== $icon = filter_input(INPUT_POST, $this->META_ICON)) {
2536 + update_post_meta($post_id, $this->META_ICON, sanitize_text_field($icon));
2537 + }
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));
2540 + }
2541 + if (false !== $status = filter_input(INPUT_POST, $this->META_STATUS)) {
2542 + update_post_meta($post_id, $this->META_STATUS, sanitize_text_field($status));
2543 + }
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));
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 + }
1793 2566 // Clean date or no date
1794 - if ((false !== $start = filter_input(INPUT_POST, $this->META_START, FILTER_SANITIZE_STRING)) &&
1795 - (false !== $end = filter_input(INPUT_POST, $this->META_END, FILTER_SANITIZE_STRING)) &&
1796 - '' != $start &&
1797 - '' != $end) {
1798 - update_post_meta($post_id, $this->META_START, substr($start,0,16).':00');
1799 - update_post_meta($post_id, $this->META_END, substr($end,0,16).':00');
2567 + if ((false !== $start = filter_input(INPUT_POST, $this->META_START)) &&
2568 + (false !== $end = filter_input(INPUT_POST, $this->META_END)) &&
2569 + '' != $start &&
2570 + '' != $end) {
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'));
1800 2573 }
1801 - else {
1802 - delete_post_meta($post_id, $this->META_START);
1803 - delete_post_meta($post_id, $this->META_END);
1804 - }
2574 + else {
2575 + delete_post_meta($post_id, $this->META_START);
2576 + delete_post_meta($post_id, $this->META_END);
2577 + }
1805 2578
1806 - // Clean location or no location
1807 - if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT, FILTER_SANITIZE_STRING)) &&
1808 - (false !== $long = filter_input(INPUT_POST, $this->META_LONG, FILTER_SANITIZE_STRING)) &&
1809 - '' != $lat &&
1810 - '' != $long) {
1811 - update_post_meta($post_id, $this->META_ADD, filter_input(INPUT_POST, $this->META_ADD, FILTER_SANITIZE_STRING));
1812 - update_post_meta($post_id, $this->META_LAT, $lat);
1813 - update_post_meta($post_id, $this->META_LONG, $long);
1814 - }
1815 - else {
1816 - delete_post_meta($post_id, $this->META_ADD);
1817 - delete_post_meta($post_id, $this->META_LAT);
1818 - delete_post_meta($post_id, $this->META_LONG);
1819 - }
2579 + // Clean location or no location
2580 + if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT)) &&
2581 + (false !== $long = filter_input(INPUT_POST, $this->META_LONG)) &&
2582 + '' != $lat &&
2583 + '' != $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)));
2587 + }
2588 + else {
2589 + delete_post_meta($post_id, $this->META_ADD);
2590 + delete_post_meta($post_id, $this->META_LAT);
2591 + delete_post_meta($post_id, $this->META_LONG);
2592 + }
1820 2593
1821 2594 $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
1822 2595 }
1823 2596
1824 - function save_bulkdatas() {
1825 - $current_post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
2597 + /**
2598 + * Saves data from bulk-edit
2599 + * Uses bulk_edit_posts hook
2600 + *
2601 + * @see https://developer.wordpress.org/reference/hooks/bulk_edit_posts/
2602 + *
2603 + * @return void
2604 + */
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';
1826 2610 if (in_array($current_post_type, $this->settings['posttypes'])) {
1827 - $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
1828 2611 if (!empty($post_ids) && is_array($post_ids)) {
1829 - foreach ($this->bulk_edit_fields as $sets) {
1830 - foreach ($sets as $fieldname => $fieldlabel) {
1831 - if ((false != $value = filter_input(INPUT_POST, $fieldname))) {
1832 - foreach ($post_ids as $post_id) {
1833 - 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]);
1834 2620 }
1835 2621 }
1836 2622 }
1837 2623 }
1838 2624 }
1839 - wp_send_json(true);
1840 - exit;
1841 2625 }
1842 - wp_send_json(false);
1843 2626 }
1844 2627
1845 2628 /**
1846 - *
2629 + * Displays a date for calendar cell
2630 + *
1847 2631 * @param string $date
1848 2632 * @param string $cat
1849 2633 * @param boolean $display
2634 + *
1850 2635 * @return boolean
1851 2636 */
1852 - public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='') {
1853 - $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true));
2637 + public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='',$tax_name='' ,$tax_term='') {
2638 + $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true,'tax_name' => $tax_name ,'tax_term' => $tax_term));
1854 2639 $nb = count($events);
2640 + $ret = "";
2641 + $price = "";
1855 2642 if(!$display && !$nb){
1856 - return date('j', $date);
2643 + $ret = date('j', $date);
1857 2644 }
1858 - if(!$nb){
1859 - return '';
1860 - }
1861 -
1862 - if ($display || $title) {
1863 - $ret='<ul>';
1864 - foreach ($events as $event) {
1865 - if ($this->settings['emptylink'] == 0 && empty($event->post_content)) {
1866 - $event->guid = '#';
2645 + $price = '';
2646 + if($nb){
2647 + if ($display || $title) {
2648 + $ret='<ul>';
2649 + foreach ($events as $event) {
2650 + $price = $this->get_price($event, true);
2651 + if ($this->settings['emptylink'] == 0 && empty($event->post_content)) {
2652 + $event->guid = '#';
2653 + }
2654 + $ret.='<li>'
2655 + // Translators: %s is the event title
2656 + . '<a href="' . $event->permalink . '" title="'.esc_attr(sprintf(__('View event: %s', 'event-post'), $event->post_title)).'">'
2657 + . '<h4>' . $event->post_title . '</h4>'
2658 + . '<span class="event_price">' . $price . '</span>'
2659 + .$this->get_single($event)
2660 + . (!empty($thumbnail) ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->ID, $thumbnail) . '</span>' : '')
2661 + .'</a>'
2662 + . '</li>';
1867 2663 }
1868 - $ret.='<li>'
1869 - . '<a href="' . $event->permalink . '" title="'.esc_attr(sprintf(__('View event: %s', 'event-post'), $event->post_title)).'">'
1870 - . '<h4>' . $event->post_title . '</h4>'
1871 - .$this->get_single($event)
1872 - . (!empty($thumbnail) ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->ID, $thumbnail) . '</span>' : '')
1873 - .'</a>'
1874 - . '</li>';
2664 + $ret.='</ul>';
1875 2665 }
1876 - $ret.='</ul>';
2666 + if ($display) {
2667 + // return $ret;
2668 + }
2669 + elseif($title) {
2670 + $ret = '<span '.($colored?' style="color:#'.$events[0]->color.'"':'').'>'.date('j', $date).'</span>'.$ret;
2671 + }
2672 + else {
2673 + $ret = '<button data-event="'. $tax_term .'" data-date="' . date('Y-m-d', $date).'"'
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
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']))).'"'
2677 + .'>'
2678 + . date('j', $date)
2679 + . '</button>';
2680 + }
1877 2681 }
1878 - if ($display) {
1879 - return $ret;
1880 - }
1881 - elseif($title) {
1882 - return '<span '.($colored?' style="color:#'.$events[0]->color.'"':'').'>'.date('j', $date).'</span>'.$ret;
1883 - }
1884 - else {
1885 - return '<button data-date="' . date('Y-m-d', $date).'"'
1886 - .' class="eventpost_cal_link"'.($colored?' style="background-color:#'.$events[0]->color.'"':'')
1887 - .' 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']))).'"'
1888 - .'>'
1889 - . date('j', $date)
1890 - . '</button>';
1891 - }
1892 -
2682 + return apply_filters('eventpost_display_caldate', $ret, $events, $date, $cat ,$price, $display ,$colored ,$thumbnail ,$title ,$tax_name ,$tax_term );
1893 2683 }
1894 2684
1895 2685
1896 2686 /**
2687 + * Returns a calendar HTML
2688 + *
1897 2689 * @param array $atts
2690 + *
1898 2691 * @filter eventpost_params
2692 + *
1899 2693 * @return string
1900 2694 */
1901 2695 public function calendar($atts) {
1902 2696 extract(shortcode_atts(apply_filters('eventpost_params', array(
@@ -1905,8 +2699,10 @@
1905 2699 'mondayfirst' => 0, //1 : weeks starts on monday
1906 2700 'datepicker' => 1,
1907 2701 'colored' => 1,
1908 2702 'display_title'=>0,
2703 + 'tax_name' => '',
2704 + 'tax_term' => '',
1909 2705 'thumbnail'=>'',
1910 2706 ), 'calendar'), $atts));
1911 2707
1912 2708 if($date && !preg_match('#[0-9][0-9][0-9][0-9]-[0-9][0-9]?#i', $date)){
@@ -1942,16 +2738,20 @@
1942 2738 . __('A calendar of events', 'event-post')
1943 2739 . '</caption>';
1944 2740 $ret.='<thead><tr><th colspan="7">';
1945 2741 if ($datepicker == 1) {
1946 - $ret.='<div>';
1947 - $ret.='<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">&laquo;</button>&nbsp;';
2742 + $ret.='<div class="eventpost-calendar-header">';
2743 + // Translators: %s is the year
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">';
1948 2745 $ret.=$annee;
1949 - $ret.='&nbsp;<button data-date="' . date('Y-n', $next_year) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $next_year)).'" class="eventpost_cal_bt">&raquo;</button>';
1950 - $ret.='<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">&laquo;</button>&nbsp;';
2746 + // Translators: %s is the year
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>';
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">';
1951 2750 $ret.=$this->NomDuMois[abs($mois)];
1952 - $ret.='&nbsp;<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">&raquo;</button> ';
1953 - $ret.='<button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button>';
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>';
2753 + $ret.='<span class="eventpost-cal-today"><button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button></span>';
1954 2754 $ret.='</div>';
1955 2755 }
1956 2756 $ret.='</th></tr><tr class="event_post_cal_days">';
1957 2757 for ($w = 0; $w < 7; $w++) {
@@ -1974,9 +2774,9 @@
1974 2774 if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour < $cejour){
1975 2775 $td = '<td class="event_post_day_over">'; // Patch ahf
1976 2776 }
1977 2777 $tr_row_content.=$td;
1978 - $tr_row_content.= $this->display_caldate(mktime(0, 0, 0, $mois, $NoJour, $annee), $cat, false, $colored, $thumbnail, $display_title);
2778 + $tr_row_content.= $this->display_caldate(mktime(0, 0, 0, $mois, $NoJour, $annee), $cat, false, $colored, $thumbnail, $display_title ,$tax_name ,$tax_term);
1979 2779 $tr_row_content.='</td>';
1980 2780 } else {
1981 2781 $tr_row_content.='<td></td>';
1982 2782 }
@@ -1990,10 +2790,15 @@
1990 2790 $ret.='</tbody></table>';
1991 2791 return $ret;
1992 2792 }
1993 2793
2794 + /**
2795 + * Echoes a list of event, should be called via AJAX
2796 + *
2797 + * @return void
2798 + */
1994 2799 public function ajaxlist(){
1995 - echo $this->list_events(array(
2800 + echo wp_kses($this->list_events(array(
1996 2801 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
1997 2802 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
1998 2803 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
1999 2804 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
@@ -2013,18 +2818,94 @@
2013 2818 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2014 2819 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2015 2820 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2016 2821 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2017 - ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2822 + 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2823 + ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type'))), $this->kses_tags);
2018 2824 exit;
2019 2825 }
2020 2826
2021 2827 /**
2022 - * echoes the content of the calendar in ajax context
2828 + * Echoes a list of event, should be called via AJAX
2829 + *
2830 + * @return void
2023 2831 */
2832 + public function ajaxTimeline(){
2833 + echo wp_kses($this->list_events(array(
2834 + 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2835 + 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2836 + 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2837 + 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2838 + 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2839 + 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2840 + 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2841 + 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2842 + 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2843 + 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2844 + 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2845 + 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2846 + 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2847 + 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2848 + 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2849 + 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2850 + 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2851 + 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2852 + 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2853 + 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2854 + 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2855 + 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2856 + ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type'))), $this->kses_tags);
2857 + exit;
2858 + }
2859 + /**
2860 + * Echoes next page of events, should be called via AJAX
2861 + *
2862 + * @return void
2863 + */
2864 + public function ajaxGetNextPage(){
2865 + $response = [
2866 + "success" => false,
2867 + "next_query" => false,
2868 + ];
2869 + if(isset($_POST['query'])){
2870 + parse_str($_POST['query'],$query);
2871 + foreach($query as $key => $value){
2872 + $query[$key] = esc_attr($value);
2873 + }
2874 + if(isset($_POST['paged'])){
2875 + $query["paged"] = esc_attr($_POST['paged']);
2876 + }else{
2877 + $response['message'] = __('Page number missing', 'event-post');
2878 + }
2879 + $query['container_schema'] = $this->timeline_shema['container'];
2880 + $query['item_schema'] = $this->timeline_shema['item'];
2881 + $html = $this->list_events($query,'event_timeline','events_only');
2882 + if($html == ""){
2883 + $response['message'] = __('No more to load', 'event-post');
2884 + }else{
2885 + $query["paged"] = $query["paged"] + 1;
2886 + $next_html = $this->list_events($query,'event_timeline','events_only');
2887 + $response = [
2888 + "success" => true,
2889 + "html" => $html,
2890 + "next_query" => $next_html == "" ? false : true,
2891 + ];
2892 + }
2893 + }else{
2894 + $response['message'] = __('Query missing', 'event-post');
2895 + }
2896 + wp_send_json($response);
2897 + exit;
2898 + }
2899 +
2900 + /**
2901 + * Echoes the content of the calendar in ajax context
2902 + *
2903 + * @return void
2904 + */
2024 2905 public function ajaxcal() {
2025 2906 $method = isset($_GET['action']) ? INPUT_GET : INPUT_POST;
2026 - echo $this->calendar(array(
2907 + echo wp_kses($this->calendar(array(
2027 2908 'date' => esc_attr(FILTER_INPUT($method, 'date')),
2028 2909 'cat' => esc_attr(FILTER_INPUT($method, 'cat')),
2029 2910 'mondayfirst' => esc_attr(FILTER_INPUT($method, 'mf')),
2030 2911 'datepicker' => esc_attr(FILTER_INPUT($method, 'dp')),
@@ -2030,34 +2911,38 @@
2030 2911 'datepicker' => esc_attr(FILTER_INPUT($method, 'dp')),
2031 2912 'colored' => esc_attr(FILTER_INPUT($method, 'color')),
2032 2913 'display_title' => esc_attr(FILTER_INPUT($method, 'display_title')),
2033 2914 'thumbnail' => esc_attr(FILTER_INPUT($method, 'thumbnail')),
2034 - ));
2915 + 'tax_name' => esc_attr(FILTER_INPUT($method, 'tax_name')),
2916 + 'tax_term' => esc_attr(FILTER_INPUT($method, 'tax_term')),
2917 + )), $this->kses_tags);
2035 2918 exit();
2036 2919 }
2037 2920
2038 2921 /**
2039 - * echoes the date of the calendar in ajax context
2922 + * Echoes the date of the calendar in ajax context
2040 2923 */
2041 2924 public function ajaxdate() {
2042 - echo $this->display_caldate(
2925 + echo wp_kses($this->display_caldate(
2043 2926 strtotime(esc_attr(FILTER_INPUT(INPUT_GET, 'date'))),
2044 2927 esc_attr(FILTER_INPUT(INPUT_GET, 'cat')),
2045 2928 true,
2046 2929 esc_attr(FILTER_INPUT(INPUT_GET, 'color')),
2047 2930 esc_attr(FILTER_INPUT(INPUT_GET, 'thumbnail')),
2048 - esc_attr(FILTER_INPUT(INPUT_GET, 'display_title'))
2049 - );
2931 + esc_attr(FILTER_INPUT(INPUT_GET, 'display_title')),
2932 + esc_attr(FILTER_INPUT(INPUT_GET, 'tax_name')),
2933 + esc_attr(FILTER_INPUT(INPUT_GET, 'tax_term'))
2934 + ), $this->kses_tags);
2050 2935 exit();
2051 2936 }
2052 2937
2053 2938 /**
2054 - * echoes a date in ajax context
2939 + * Echoes a date in ajax context
2055 2940 */
2056 2941 public function HumanDate() {
2057 2942 if (isset($_REQUEST['date']) && !empty($_REQUEST['date'])) {
2058 2943 $date = strtotime($_REQUEST['date']);
2059 - 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)));
2060 2945 exit();
2061 2946 }
2062 2947 }
2063 2948
@@ -2064,8 +2949,9 @@
2064 2949 /**
2065 2950 * Displays a search form
2066 2951 *
2067 2952 * @param type $atts
2953 + *
2068 2954 * @return type
2069 2955 */
2070 2956 public function search($atts) {
2071 2957 $params = shortcode_atts(apply_filters('eventpost_params', array(
@@ -2091,9 +2977,9 @@
2091 2977 }
2092 2978
2093 2979 // Search form
2094 2980 $this->admin_scripts(null, true);
2095 - wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, $this->version);
2981 + wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, filemtime( "/$block_js" ));
2096 2982 include (plugin_dir_path(__FILE__) . 'views/search-form.php');
2097 2983
2098 2984 // Results
2099 2985 if ($list_id == filter_input(INPUT_GET, 'evenpost_search')) {
@@ -2136,8 +3022,54 @@
2136 3022 }
2137 3023 }
2138 3024
2139 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 + /**
2140 3072 * AJAX Get lat long from address
2141 3073 */
2142 3074 public function GetLatLong() {
2143 3075 if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
@@ -2143,31 +3075,22 @@
2143 3075 if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
2144 3076 // verifier le cache
2145 3077 $q = $_REQUEST['q'];
2146 3078 header('Content-Type: application/json');
2147 - $transient_name = 'eventpost_osquery_' . $q;
2148 - $val = get_transient($transient_name);
2149 - if (false === $val || empty($val) || !is_string($val)) {
2150 - $language = get_bloginfo('language');
2151 - if (strpos($language, '-') > -1) {
2152 - $language = strtolower(substr($language, 0, 2));
2153 - }
2154 - $remote_val = wp_safe_remote_request('http://nominatim.openstreetmap.org/search?q=' . urlencode($q) . '&format=json&accept-language=' . $language);
2155 - if(json_decode($remote_val['body'])){
2156 - $val = $remote_val['body'];
2157 - }
2158 - set_transient($transient_name, $val, 30 * DAY_IN_SECONDS);
2159 - }
2160 - echo $val;
3079 + $val = $this->geocode($q);
3080 + wp_send_json( $val );
2161 3081 exit();
2162 3082 }
2163 3083 }
2164 3084
2165 3085 /**
2166 - * alters columns
3086 + * Alters columns
3087 + *
2167 3088 * @param array $defaults
3089 + *
3090 + * @filter eventpost_columns_head
3091 + *
2168 3092 * @return array
2169 - * @filter eventpost_columns_head
2170 3093 */
2171 3094 public function columns_head($defaults) {
2172 3095 $defaults['event'] = __('Event', 'event-post');
2173 3096 $defaults['location'] = __('Location', 'event-post');
@@ -2174,34 +3097,40 @@
2174 3097 return apply_filters('eventpost_columns_head', $defaults);
2175 3098 }
2176 3099
2177 3100 /**
2178 - * echoes content of a row in a given column
3101 + * Echoes content of a row in a given column
3102 + *
2179 3103 * @param string $column_name
2180 3104 * @param int $post_id
3105 + *
2181 3106 * @action eventpost_columns_content
2182 3107 */
2183 3108 public function columns_content($column_name, $post_id) {
2184 3109 if ($column_name == 'location') {
2185 - $lat = get_post_meta($post_id, $this->META_LAT, true);
2186 - $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));
2187 3112
2188 3113 if (!empty($lat) && !empty($lon)) {
2189 3114 add_thickbox();
2190 - $color = get_post_meta($post_id, $this->META_COLOR, true);
3115 + $color = $this->get_post_color($post_id, $this->settings['default_color'], true);
3116 + $icon = $this->get_post_icon($post_id, $this->settings['default_icon'], true);
2191 3117 if ($color == ''){
2192 3118 $color = '777777';
2193 - }
2194 - 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">'
2195 - . '<i class="dashicons dashicons-location" style="color:#'.$color.';"></i>'
3119 + }
3120 + if ($icon == ''){
3121 + $icon = 'location';
3122 + }
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">'
3124 + . '<i class="dashicons dashicons-'.$icon.'" style="color:#'.$color.';"></i>'
2196 3125 . '<span class="screen-reader-text">'.__('View on a map', 'event-post').'</span>'
2197 3126 . get_post_meta($post_id, $this->META_ADD, true)
2198 - . '</a> ';
3127 + . '</a> ', $this->kses_tags);
2199 3128 }
2200 3129 $this->column_edit_hidden_fields($post_id, 'location');
2201 3130 }
2202 3131 if ($column_name == 'event') {
2203 - echo $this->print_date($post_id, false);
3132 + echo wp_kses($this->print_date($post_id, false), $this->kses_tags);
2204 3133 $this->column_edit_hidden_fields($post_id, 'event');
2205 3134 }
2206 3135 do_action('eventpost_columns_content', $column_name, $post_id);
2207 3136 }
@@ -2207,52 +3136,25 @@
2207 3136 }
2208 3137
2209 3138 function column_edit_hidden_fields($post_id, $set){
2210 3139 $event = $this->retreive($post_id);
2211 - echo '<div class="hidden">';
2212 - foreach($this->quick_edit_fields[$set] as $fieldname=>$fieldlabel){
2213 - 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 + }
2214 3145 }
2215 - echo '</div>';
3146 + $html .= '</div>';
3147 + echo wp_kses($html, $this->kses_tags);
2216 3148 }
2217 3149
2218 - /** ADMIN PAGES **/
3150 + // ADMIN PAGES
2219 3151
2220 3152 /**
2221 - * Settings link on the plugins page
2222 - */
2223 - public function settings_link( $links ) {
2224 - $settings_link = '<a href="options-general.php?page=event-settings">' . __( 'Settings', 'event-post' ) . '</a>';
2225 - // place it before other links
2226 - array_unshift( $links, $settings_link );
2227 - return $links;
2228 - }
2229 - /**
2230 - *
2231 - * @param type $plugin_meta
2232 - * @param type $plugin_file
2233 - * @param type $plugin_data
2234 - * @param type $status
2235 - * @return type
2236 - */
2237 - public function row_meta($plugin_meta, $plugin_file, $plugin_data, $status){
2238 - if($plugin_file=='event-post/eventpost.php'){
2239 - $plugin_link = '<a href="http://event-post.com" target="_blank">' . __( 'Plugin site', 'event-post' ) . '</a>';
2240 - $review_link = '<a href="https://wordpress.org/support/plugin/event-post/reviews/#new-post" target="_blank">' . __( 'Give a note', 'event-post' ) . '</a>';
2241 - array_push($plugin_meta, $plugin_link, $review_link);
2242 - }
2243 - return $plugin_meta;
2244 - }
2245 -
2246 - /**
2247 - * adds menu items
2248 - */
2249 - public function manage_options() {
2250 - add_options_page(__('Events settings', 'event-post'), __('Events', 'event-post'), 'manage_options', 'event-settings', array(&$this, 'manage_settings'));
2251 - }
2252 - /**
2253 - * adds items to the native "right now" dashboard widget
3153 + * Adds items to the native "right now" dashboard widget
3154 + *
2254 3155 * @param array $elements
3156 + *
2255 3157 * @return array
2256 3158 */
2257 3159 public function dashboard_right_now($elements){
2258 3160 $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
@@ -2257,371 +3159,32 @@
2257 3159 public function dashboard_right_now($elements){
2258 3160 $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
2259 3161 $nb_geo = count($this->get_events(array('future'=>1, 'past'=>1, 'geo'=>1, 'nb'=>-1)));
2260 3162 if($nb_date){
3163 + // Translators: %d is the number of events
2261 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>");
2262 3165 }
2263 3166 if($nb_geo){
3167 + // Translators: %d is the number of geolocalized events
2264 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>");
2265 3169 }
2266 3170 return $elements;
2267 3171 }
2268 3172
2269 - /**
2270 - * @action eventpost_register_settings
2271 - */
2272 - public function register_settings(){
2273 - register_setting( 'eventpost-settings', 'ep_settings' );
2274 -
2275 - // Global
2276 - add_settings_section(
2277 - 'eventpost-settings-general',
2278 - '<span class="dashicons dashicons-admin-appearance"></span>&nbsp;'.__('Global settings', 'event-post'),
2279 - array(&$this, 'settings_section_callback'),
2280 - 'eventpost-settings'
2281 - );
2282 - //--
2283 - add_settings_field(
2284 - 'emptylink',
2285 - __('Print link for empty posts', 'event-post'),
2286 - array(&$this, 'settings_field_select_callback'),
2287 - 'eventpost-settings',
2288 - 'eventpost-settings-general',
2289 - array( 'name' => 'emptylink', 'options'=>array(
2290 - 1=>__('Link all posts', 'event-post'),
2291 - 0=>__('Do not link posts with empty content', 'event-post')
2292 - )
2293 - )
2294 - );
2295 - add_settings_field(
2296 - 'singlepos',
2297 - __('Event bar position for single posts', 'event-post'),
2298 - array(&$this, 'settings_field_select_callback'),
2299 - 'eventpost-settings',
2300 - 'eventpost-settings-general',
2301 - array( 'name' => 'singlepos', 'options'=>array(
2302 - 'before'=>__('Before the content', 'event-post'),
2303 - 'after'=>__('After the content', 'event-post'),
2304 - 'none'=>__('Not displayed', 'event-post')
2305 - ) )
2306 - );
2307 - add_settings_field(
2308 - 'loopicons',
2309 - __('Add icons for events in the loop', 'event-post'),
2310 - array(&$this, 'settings_field_select_callback'),
2311 - 'eventpost-settings',
2312 - 'eventpost-settings-general',
2313 - array( 'name' => 'loopicons', 'options'=>array(
2314 - 1=>__('Emojis', 'event-post'),
2315 - 0=>__('Hide', 'event-post'),
2316 - 2=>__('Icons', 'event-post')
2317 - ) )
2318 - );
2319 - add_settings_field(
2320 - 'customcss',
2321 - __('Use this custom CSS file', 'event-post'),
2322 - array(&$this, 'settings_field_default_callback'),
2323 - 'eventpost-settings',
2324 - 'eventpost-settings-general',
2325 - array( 'name' => 'customcss', 'description'=>sprintf(__('Leave empty to use the <a href="%s" target="_blank">default CSS file</a>.', 'event-post'), plugins_url('/css/eventpost'.$this->script_sufix.'css', __FILE__)).'<br>'
2326 - . (is_file(get_stylesheet_directory().'/event-post.css') || is_file(get_template_directory().'/event-post.css')
2327 - ? __('Your theme contains an <code>event-post.css</code> file. It will be used as default stylesheet.', 'event-post')
2328 - : __('You can also add a <code>event-post.css</code> in your theme directory. It will be used as default stylesheet.', 'event-post')))
2329 - );
2330 -
2331 - // Date
2332 - add_settings_section(
2333 - 'eventpost-settings-date',
2334 - '<span class="dashicons dashicons-clock"></span>&nbsp;'.__('Date settings', 'event-post'),
2335 - array(&$this, 'settings_section_callback'),
2336 - 'eventpost-settings'
2337 - );
2338 - //--
2339 - add_settings_field(
2340 - 'dateformat',
2341 - __('Date format', 'event-post'),
2342 - array(&$this, 'settings_field_default_callback'),
2343 - 'eventpost-settings',
2344 - 'eventpost-settings-date',
2345 - array( 'name' => 'dateformat')
2346 - );
2347 - add_settings_field(
2348 - 'timeformat',
2349 - __('Time format', 'event-post'),
2350 - array(&$this, 'settings_field_default_callback'),
2351 - 'eventpost-settings',
2352 - 'eventpost-settings-date',
2353 - array( 'name' => 'timeformat')
2354 - );
2355 - add_settings_field(
2356 - 'export',
2357 - __('Show export buttons on:', 'event-post'),
2358 - array(&$this, 'settings_field_select_callback'),
2359 - 'eventpost-settings',
2360 - 'eventpost-settings-date',
2361 - array( 'name' => 'export', 'options'=>array(
2362 - 'list'=>__('List only', 'event-post'),
2363 - 'single'=>__('Single only', 'event-post'),
2364 - 'both'=>__('Both', 'event-post'),
2365 - 'none'=>__('None', 'event-post'),
2366 - ) )
2367 - );
2368 - add_settings_field(
2369 - 'export_when',
2370 - __('Show export buttons on:', 'event-post'),
2371 - array(&$this, 'settings_field_select_callback'),
2372 - 'eventpost-settings',
2373 - 'eventpost-settings-date',
2374 - array( 'name' => 'export_when', 'options'=>array(
2375 - 'future'=>__('Future only', 'event-post'),
2376 - 'past'=>__('Past only', 'event-post'),
2377 - 'both'=>__('Both', 'event-post'),
2378 - 'none'=>__('None', 'event-post'),
2379 - ) )
2380 - );
2381 - add_settings_field(
2382 - 'dateforhumans',
2383 - __('Relative human dates:', 'event-post'),
2384 - array(&$this, 'settings_field_select_callback'),
2385 - 'eventpost-settings',
2386 - 'eventpost-settings-date',
2387 - array( 'name' => 'dateforhumans',
2388 - 'description'=>__('Replace absolute dates by "today", "yesterday", and "tomorrow".', 'event-post'),
2389 - 'options'=>array(
2390 - 1=>__('Yes', 'event-post'),
2391 - 0=>__('No', 'event-post'),
2392 - ) )
2393 - );
2394 -
2395 - // List
2396 - add_settings_section(
2397 - 'eventpost-settings-list',
2398 - '<span class="dashicons dashicons-editor-ul"></span>&nbsp;'.__('List settings', 'event-post'),
2399 - array(&$this, 'settings_section_callback'),
2400 - 'eventpost-settings'
2401 - );
2402 - //--
2403 - add_settings_field(
2404 - 'container_shema',
2405 - __('Container shema', 'event-post'),
2406 - array(&$this, 'settings_field_textarea_callback'),
2407 - 'eventpost-settings',
2408 - 'eventpost-settings-list',
2409 - array( 'name' => 'container_shema', 'description'=>__('default:','event-post').' <code>'.htmlentities($this->default_list_shema['container']).'</code>')
2410 - );
2411 - add_settings_field(
2412 - 'item_shema',
2413 - __('Container shema', 'event-post'),
2414 - array(&$this, 'settings_field_textarea_callback'),
2415 - 'eventpost-settings',
2416 - 'eventpost-settings-list',
2417 - array( 'name' => 'item_shema', 'description'=>__('default:','event-post').' <code>'.htmlentities($this->default_list_shema['item']).'</code>')
2418 - );
2419 -
2420 - // Map
2421 - add_settings_section(
2422 - 'eventpost-settings-map',
2423 - '<span class="dashicons dashicons-location-alt"></span>&nbsp;'.__('Map settings', 'event-post'),
2424 - array(&$this, 'settings_section_callback'),
2425 - 'eventpost-settings'
2426 - );
2427 - //--
2428 - $maps = array();
2429 - foreach ($this->maps as $map){
2430 - $maps[$map['id']]=$map['name'].(isset($map['urls_retina']) ? ' '.__('(Retina support)', 'event-post') : '');
2431 - }
2432 - add_settings_field(
2433 - 'tile',
2434 - __('Map background', 'event-post'),
2435 - array(&$this, 'settings_field_select_callback'),
2436 - 'eventpost-settings',
2437 - 'eventpost-settings-map',
2438 - array( 'name' => 'tile', 'options'=>$maps)
2439 - );
2440 - add_settings_field(
2441 - 'zoom',
2442 - __('Default zoom', 'event-post'),
2443 - array(&$this, 'settings_field_default_callback'),
2444 - 'eventpost-settings',
2445 - 'eventpost-settings-map',
2446 - array( 'name' => 'zoom')
2447 - );
2448 - add_settings_field(
2449 - 'markpath',
2450 - __('Makers custom directory after <code>ABSPATH/</code>', 'event-post'),
2451 - array(&$this, 'settings_field_default_callback'),
2452 - 'eventpost-settings',
2453 - 'eventpost-settings-map',
2454 - array( 'name' => 'markpath', 'description'=>__('(leave empty for default settings)','event-post'))
2455 - );
2456 - add_settings_field(
2457 - 'markurl',
2458 - __('Makers custom directory URL', 'event-post'),
2459 - array(&$this, 'settings_field_default_callback'),
2460 - 'eventpost-settings',
2461 - 'eventpost-settings-map',
2462 - array( 'name' => 'markurl', 'description'=>__('(leave empty for default settings)','event-post'))
2463 - );
2464 -
2465 - // Admin
2466 - add_settings_section(
2467 - 'eventpost-settings-admin',
2468 - '<span class="dashicons dashicons-admin-generic"></span>&nbsp;'.__('Admin settings', 'event-post'),
2469 - array(&$this, 'settings_section_callback'),
2470 - 'eventpost-settings'
2471 - );
2472 - //--
2473 - add_settings_field(
2474 - 'adminpos',
2475 - __('Position of event details boxes', 'event-post'),
2476 - array(&$this, 'settings_field_select_callback'),
2477 - 'eventpost-settings',
2478 - 'eventpost-settings-admin',
2479 - array( 'name' => 'adminpos', 'options'=>array(
2480 - 'side'=>__('Side', 'event-post'),
2481 - 'normal'=>__('Under the text', 'event-post'),
2482 - ) )
2483 - );
2484 - $post_types = array();
2485 - $posttypes = apply_filters('eventpost_get_post_types', get_post_types(array(), 'objects'));
2486 - foreach($posttypes as $type=>$posttype){
2487 - $post_types[$posttype->name]=$posttype->labels->name;
2488 - }
2489 - add_settings_field(
2490 - 'posttypes',
2491 - __('Wich post types can be events?', 'event-post'),
2492 - array(&$this, 'settings_field_checkbox_callback'),
2493 - 'eventpost-settings',
2494 - 'eventpost-settings-admin',
2495 - array( 'name' => 'posttypes', 'options'=>$post_types)
2496 - );
2497 - add_settings_field(
2498 - 'datepicker',
2499 - __('Datepicker style', 'event-post'),
2500 - array(&$this, 'settings_field_datepicker_callback'),
2501 - 'eventpost-settings',
2502 - 'eventpost-settings-admin',
2503 - array( 'name' => 'datepicker')
2504 - );
2505 - add_settings_field(
2506 - 'cache',
2507 - __('Use cache', 'event-post'),
2508 - array(&$this, 'settings_field_default_callback'),
2509 - 'eventpost-settings',
2510 - 'eventpost-settings-admin',
2511 - array( 'name' => 'cache', 'description'=>__('Use cache for results','event-post'))
2512 - );
2513 -
2514 - do_action('eventpost_register_settings');
2515 - }
2516 - function settings_section_callback( $arg ) {
2517 - echo '<hr>';
2518 - }
2519 -
2520 - function settings_field_default_callback($args){
2521 - ?>
2522 - <input name="ep_settings[<?php echo $args['name']; ?>]" id="<?php echo $args['name']; ?>" value="<?php echo $this->settings[$args['name']]; ?>" class="regular-text"/>
2523 - <?php if(isset($args['description']) && $args['description']): ?>
2524 - <p class="description"><?php echo $args['description']; ?></p>
2525 - <?php endif; ?>
2526 - <?php
2527 - }
2528 - function settings_field_textarea_callback($args){
2529 - ?>
2530 - <textarea name="ep_settings[<?php echo $args['name']; ?>]" id="<?php echo $args['name']; ?>" class="regular-text"><?php echo $this->settings[$args['name']]; ?></textarea>
2531 - <?php if(isset($args['description']) && $args['description']): ?>
2532 - <p class="description"><?php echo $args['description']; ?></p>
2533 - <?php endif; ?>
2534 - <?php
2535 - }
2536 - function settings_field_select_callback($args){
2537 - ?>
2538 - <select name="ep_settings[<?php echo $args['name']; ?>]" id="<?php echo $args['name']; ?>" class="">
2539 - <?php foreach($args['options'] as $value=>$label) : ?>
2540 - <option value="<?php echo $value; ?>" <?php selected($value, $this->settings[$args['name']], true);?>><?php echo $label; ?></option>
2541 - <?php endforeach; ?>
2542 - </select>
2543 - <?php if(isset($args['description']) && $args['description']): ?>
2544 - <p class="description"><?php echo $args['description']; ?></p>
2545 - <?php endif; ?>
2546 - <?php
2547 - }
2548 - function settings_field_checkbox_callback($args){
2549 - ?>
2550 - <?php foreach($args['options'] as $value=>$label) : ?>
2551 - <p>
2552 - <label>
2553 - <input type="checkbox" name="ep_settings[<?php echo $args['name']; ?>][<?php echo $value; ?>]" value="<?php echo $value; ?>" <?php checked(in_array($value, $this->settings[$args['name']]),true, true) ?>>
2554 - <?php echo $label; ?>
2555 - </label>
2556 - </p>
2557 - <?php endforeach; ?>
2558 - <?php if(isset($args['description']) && $args['description']): ?>
2559 - <p class="description"><?php echo $args['description']; ?></p>
2560 - <?php endif; ?>
2561 - <?php
2562 - }
2563 - function settings_field_datepicker_callback($args){
2564 - $now = current_time('mysql');
2565 - $human_date = $this->human_date(current_time('timestamp')) .' '. date($this->settings['timeformat'], current_time('timestamp'));
2566 - ?>
2567 - <div>
2568 - <label>
2569 - <input type="radio" name="ep_settings[datepicker]" id="ep_datepicker_simple" value="simple" <?php checked($this->settings['datepicker'],'simple', true) ?>>
2570 - <?php _e('Simple', 'event-post'); ?>
2571 - </label>
2572 - <p>
2573 - <span id="eventpost_simple_date_human" class="human_date">
2574 - <?php echo $human_date; ?>
2575 - </span>
2576 - <input type="text" class="eventpost-datepicker-simple" id="eventpost_simple_date" value="<?php echo $now; ?>">
2577 - </p>
2578 - </div>
2579 - <div>
2580 - <label>
2581 - <input type="radio" name="ep_settings[datepicker]" id="ep_datepicker_native" value="native" <?php checked($this->settings['datepicker'],'native', true) ?>>
2582 - <?php _e('Native WordPress style', 'event-post'); ?>
2583 - </label>
2584 - <p>
2585 - <span id="eventpost_native_date_human" class="human_date">
2586 - <?php echo $human_date; ?>
2587 - </span>
2588 - <input type="text" class="eventpost-datepicker-native" id="eventpost_native_date" value="<?php echo $now; ?>">
2589 - </p>
2590 - </div>
2591 - <?php
2592 - }
2593 - /**
2594 - * output content of the setting page
2595 - */
2596 - public function manage_settings() {
2597 - $ep_settings = $this->settings;
2598 - ?>
2599 - <div class="wrap">
2600 - <h2><?php _e('Events settings', 'event-post'); ?></h2>
2601 - <form action="options.php" method="post">
2602 - <?php settings_fields( 'eventpost-settings' ); ?>
2603 - <?php do_settings_sections('eventpost-settings'); ?>
2604 - <?php do_action('eventpost_settings_form', $ep_settings); ?>
2605 - <?php submit_button(); ?>
2606 - </form>
2607 - </div>
2608 - <?php
2609 - do_action('eventpost_after_settings_form');
2610 - }
2611 -
2612 3173 /*
2613 - * feed
3174 + * Feed
2614 3175 * generate ICS or VCS files from a category
2615 3176 */
2616 3177
2617 3178 /**
2618 - *
3179 + * Get a date formatted for ICS
3180 + *
2619 3181 * @param timestamp $timestamp
3182 + *
2620 3183 * @return string
2621 3184 */
2622 3185 public function ics_date($timestamp){
2623 - return date("Ymd",$timestamp).'T'.date("His",$timestamp);
3186 + return date("Ymd",$timestamp).'T'.date("His",$timestamp);
2624 3187 }
2625 3188
2626 3189 public function get_gmt_offset(){
2627 3190 $gmt_offset = get_option('gmt_offset ');
@@ -2636,56 +3199,146 @@
2636 3199 return $gmt_offset;
2637 3200 }
2638 3201
2639 3202 /**
2640 - * outputs an ICS document
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
2641 3209 */
3210 + private function generate_ics($event_id, $format){
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 + }
3224 + }
3225 + wp_die(esc_html__('Invalid request.', 'event-post'), 400);
3226 + }
3227 +
3228 +
3229 + public function parse_request(){
3230 + global $wp;
3231 + if (preg_match('#^event-feed#i', $wp->request, $match)) {
3232 + $this->feed();
3233 + exit;
3234 + }
3235 + if (preg_match('#^eventpost/([0-9]*)\.(ics|vcs)#i', $wp->request, $match)) {
3236 + $this->generate_ics($match[1], $match[2]);
3237 + }
3238 + }
3239 +
3240 + public function export(){
3241 + if(false !== $event_id=\filter_input(INPUT_GET, 'event_id',FILTER_SANITIZE_NUMBER_INT)){
3242 + $format = \filter_input(INPUT_GET, 'format');
3243 + $this->generate_ics($event_id, $format);
3244 + }
3245 + }
3246 +
3247 +
3248 + /**
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
3261 + */
2642 3262 public function feed(){
2643 - if(false !== $cat=\filter_input(INPUT_GET, 'cat',FILTER_SANITIZE_STRING)){
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 + }
2644 3287 $vtz = get_option('timezone_string');
2645 - $gmt = $this->get_gmt_offset();
3288 + $gmt = $this->get_gmt_offset();
2646 3289 date_default_timezone_set($vtz);
2647 - $separator = "\n";
3290 + $separator = "\n";
2648 3291
2649 - header("content-type:text/x-icalendar");
3292 + header("content-type:text/calendar");
2650 3293 header("Pragma: public");
2651 3294 header("Expires: 0");
2652 3295 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
2653 3296 header("Cache-Control: public");
2654 - header("Content-Disposition: attachment; filename=". str_replace('+','-',urlencode(get_option('blogname').'-'.$cat)).".ics;" );
3297 + header("Content-Disposition: attachment; filename=". str_replace('+','-',rawurlencode(get_option('blogname').'-'.$cat)).".ics;" );
2655 3298
2656 - $props = array();
3299 + $props = array();
2657 3300
2658 - // General
2659 - $props[] = 'BEGIN:VCALENDAR';
2660 - $props[] = 'PRODID://WordPress//Event-Post V'. file_get_contents(('VERSION')).'//EN';
2661 - $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 + }
2662 3326
2663 - // Timezone
2664 - if(!empty($vtz)){
2665 - array_push($props,
2666 - 'BEGIN:VTIMEZONE',
2667 - 'TZID:'.$vtz,
2668 - 'BEGIN:DAYLIGHT',
2669 - 'TZOFFSETFROM:+0100',
2670 - 'TZOFFSETTO:'.($gmt).'00',
2671 - 'DTSTART:19700329T020000',
2672 - 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3',
2673 - 'END:DAYLIGHT',
2674 - 'BEGIN:STANDARD',
2675 - 'TZOFFSETFROM:'.($gmt).'00',
2676 - 'TZOFFSETTO:+0100',
2677 - 'TZNAME:CET',
2678 - 'DTSTART:19701025T030000',
2679 - 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
2680 - 'END:STANDARD',
2681 - 'END:VTIMEZONE'
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
2682 3340 );
2683 - }
2684 -
2685 - // Events
2686 - $events=$this->get_events(array('cat'=>$cat,'nb'=>-1));
2687 - foreach ($events as $event) {
2688 3341 array_push($props,
2689 3342 'BEGIN:VEVENT',
2690 3343 'CREATED:'.$this->ics_date(strtotime($event->post_date)).'Z',
2691 3344 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
@@ -2691,19 +3344,20 @@
2691 3344 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
2692 3345 'SUMMARY:'.$event->post_title,
2693 3346 'UID:'.md5(site_url()."_eventpost_".$event->ID),
2694 3347 'LOCATION:'.str_replace(',','\,',$event->address),
3348 + 'DTSTAMP:'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2695 3349 'DTSTART'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2696 3350 'DTEND'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_end).(!empty($vtz)?'':'Z'),
2697 - 'DESCRIPTION:'.$event->guid,
3351 + 'DESCRIPTION:'.$description,
2698 3352 'END:VEVENT'
2699 3353 );
2700 3354 }
3355 + }
2701 3356
2702 - // End
2703 - $props[] = 'END:VCALENDAR';
3357 + // End
3358 + $props[] = 'END:VCALENDAR';
2704 3359
2705 - echo implode($separator, $props);
2706 - exit;
2707 - }
3360 + echo esc_html(implode($separator, $props));
3361 + exit;
2708 3362 }
2709 3363 }