PluginProbe
Event Post / 5.7
Event Post v5.7
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 5.6.1 All 46 releases
event-post / eventpost.php

eventpost.php in Event Post 5.7, at eventpost.php

2,662 lines 87.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Event Post
4 Plugin URI: https://event-post.com?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard
5 Description: Add calendar and/or geolocation metadata on any posts.
6 Version: 5.7
7 Author: N.O.U.S. Open Useful and Simple
8 Contributors: bastho, sabrinaleroy, unecologeek, agencenous
9 Author URI: https://apps.avecnous.eu/?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard
10 License: GPLv2
11 Text Domain: event-post
12 Domain Path: /languages/
13 Tags: Post,posts,event,date,geolocalization,gps,widget,map,openstreetmap,EELV,calendar,agenda,blocks
14 */
15
16 /**
17 *
18 * @package event-post
19 */
20 global $EventPost;
21 $EventPost = new EventPost();
22
23 $EventPost_cache=array();
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
39 /**
40 * The main class where everything begins.
41 *
42 * Add calendar and/or geolocation metadata on posts
43 */
44 class EventPost {
45 const META_START = 'event_begin';
46 const META_END = 'event_end';
47 const META_COLOR = 'event_color';
48 const META_ICON = 'event_icon';
49 // http://codex.wordpress.org/Geodata
50 const META_ADD = 'geo_address';
51 const META_LAT = 'geo_latitude';
52 const META_LONG = 'geo_longitude';
53 // https://schema.org/eventStatus
54 const META_STATUS = 'event_status';
55 // https://schema.org/location
56 const META_VIRTUAL_LOCATION = 'event_virtual_location';
57 // https://pending.schema.org/eventAttendanceMode
58 const META_ATTENDANCE_MODE = 'event_attendance_mode';
59
60 public $list_id;
61 public $NomDuMois;
62 public $Week;
63 public $settings;
64 public $dateformat;
65
66 private $pagination;
67 public $version = '5.7';
68 public $plugin_path ;
69 private $script_sufix;
70
71 public $map_interactions;
72 public $quick_edit_fields;
73
74 public $Shortcodes;
75
76 public $attendance_modes;
77 public $statuses;
78 private $is_schema_output=false;
79
80 public function __construct() {
81 add_action('init', array(&$this,'init'), 1);
82 add_action('widgets_init', array(&$this,'widgets_init'), 1);
83 add_action('save_post', array(&$this, 'save_postdata'));
84 add_filter('dashboard_glance_items', array(&$this, 'dashboard_right_now'));
85
86 // Scripts
87 add_action( 'admin_init', array(&$this, 'editor_styles'));
88 add_action('admin_enqueue_scripts', array(&$this, 'admin_head'));
89 add_action('admin_print_scripts', array(&$this, 'admin_scripts'));
90 add_action('wp_enqueue_scripts', array(&$this, 'load_styles'));
91
92 // Single
93 add_filter('the_content', array(&$this, 'display_single'), 9999);
94 add_filter('the_title', array(&$this, 'the_title'), 9999, 2);
95 add_action('the_event', array(&$this, 'print_single'));
96 add_action('wp_head', array(&$this, 'single_header'));
97 add_action('wpseo_schema_webpage', array(&$this, 'wpseo_schema_webpage'));
98
99 // Ajax
100 add_action('wp_ajax_EventPostGetLatLong', array(&$this, 'GetLatLong'));
101 add_action('wp_ajax_EventPostHumanDate', array(&$this, 'HumanDate'));
102 add_action('wp_ajax_EventPostList', array(&$this, 'ajaxlist'));
103 add_action('wp_ajax_EventPostTimeline', array(&$this, 'ajaxTimeline'));
104 add_action('wp_ajax_EventPostNextPage', array(&$this, 'ajaxGetNextPage'));
105 add_action('wp_ajax_nopriv_EventPostNextPage', array(&$this, 'ajaxGetNextPage'));
106 add_action('wp_ajax_EventPostMap', array(&$this, 'ajaxmap'));
107 add_action('wp_ajax_EventPostCalendar', array(&$this, 'ajaxcal'));
108 add_action('wp_ajax_nopriv_EventPostCalendar', array(&$this, 'ajaxcal'));
109 add_action('wp_ajax_EventPostCalendarDate', array(&$this, 'ajaxdate'));
110 add_action('wp_ajax_nopriv_EventPostCalendarDate', array(&$this, 'ajaxdate'));
111
112 // Calendar publishing
113 add_action('parse_request', array(&$this, 'parse_request'), 100);
114 add_action('wp_ajax_EventPostExport', array(&$this, 'export'));
115 add_action('wp_ajax_nopriv_EventPostExport', array(&$this, 'export'));
116 add_action('wp_ajax_EventPostFeed', array(&$this, 'feed'));
117 add_action('wp_ajax_nopriv_EventPostFeed', array(&$this, 'feed'));
118
119 //
120 add_filter('eventpost_list_shema',array(&$this, 'custom_shema'),10,1);
121
122
123 add_action('widgets_init', array(&$this, 'register_widgets'),1,1);
124
125 // Quick edit
126 add_action( 'bulk_edit_custom_box', array( &$this, 'bulk_edit' ), 10, 2 );
127 add_action( 'quick_edit_custom_box', array( &$this, 'quick_edit' ), 10, 2 );
128 add_action( 'admin_print_scripts-edit.php', array(&$this, 'scripts_edit') );
129 add_action( 'wp_ajax_inline-save', array(&$this, 'inline_save'), 1 );
130 add_action( 'wp_ajax_eventpost_save_bulk', array(&$this, 'save_bulkdatas') );
131 add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_color'), 10, 3);
132 add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_icon'), 10, 3);
133
134 $inc_path = plugin_dir_path(__FILE__).'inc/';
135 $this->plugin_path = plugin_dir_path(__FILE__);
136 include_once ($inc_path . 'settings.php');
137 include_once ($inc_path . 'wrappers.php');
138 include_once ($inc_path . 'widget.php');
139 include_once ($inc_path . 'widget.cal.php');
140 include_once ($inc_path . 'widget.map.php');
141 include_once ($inc_path . 'multisite.php');
142 include_once ($inc_path . 'shortcodes.php');
143 include_once ($inc_path . 'openweathermap.php');
144 include_once ($inc_path . 'children.php');
145 include_once ($inc_path . 'icons.php');
146 include_once ($inc_path . 'taxonomies.php');
147
148 $this->DashIcons = new EventPost\DashIcons();
149 $this->Settings = new EventPost\Settings($this->DashIcons);
150 $this->Categories = new EventPost\Categories($this->DashIcons);
151 }
152
153 /**
154 * PHP4 constructor
155 */
156 public function EventPost(){
157 $this->__construct();
158 }
159
160 public function init(){
161 add_rewrite_rule('event-feed/?', admin_url('admin-ajax.php?action=EventPostFeed'), 'top');
162 add_rewrite_rule('eventpost/([0-9]*)\.(ics|vcs)?', plugins_url('export/ics.php', __FILE__), 'top');
163 }
164
165 /**
166 * Init all variables when WP is ready
167 *
168 * @action evenpost_init
169 * @filter eventpost_default_list_shema
170 * @filter eventpost_list_shema
171 */
172 public function widgets_init(){
173 $this->META_START = 'event_begin';
174 $this->META_END = 'event_end';
175 $this->META_COLOR = 'event_color';
176 $this->META_ICON = 'event_icon';
177 // http://codex.wordpress.org/Geodata
178 $this->META_ADD = 'geo_address';
179 $this->META_LAT = 'geo_latitude';
180 $this->META_LONG = 'geo_longitude';
181 // https://schema.org/eventStatus
182 $this->META_STATUS = 'event_status';
183 // https://schema.org/location
184 $this->META_VIRTUAL_LOCATION = 'event_virtual_location';
185 // https://pending.schema.org/eventAttendanceMode
186 $this->META_ATTENDANCE_MODE = 'event_attendance_mode';
187 $this->list_id = 0;
188 $this->NomDuMois = array('', __('Jan', 'event-post'), __('Feb', 'event-post'), __('Mar', 'event-post'), __('Apr', 'event-post'), __('May', 'event-post'), __('Jun', 'event-post'), __('Jul', 'event-post'), __('Aug', 'event-post'), __('Sept', 'event-post'), __('Oct', 'event-post'), __('Nov', 'event-post'), __('Dec', 'event-post'));
189 $this->Week = array(__('Sunday', 'event-post'), __('Monday', 'event-post'), __('Tuesday', 'event-post'), __('Wednesday', 'event-post'), __('Thursday', 'event-post'), __('Friday', 'event-post'), __('Saturday', 'event-post'));
190 $this->attendance_modes = array(
191 'OfflineEventAttendanceMode' => _x('Physical', 'Attendance Mode', 'event-post'),
192 'MixedEventAttendanceMode' => _x('Mixed', 'Attendance Mode', 'event-post'),
193 'OnlineEventAttendanceMode' => _x('Online', 'Attendance Mode', 'event-post'),
194 );
195 $this->statuses = array(
196 'EventScheduled' =>_x('Scheduled', 'Event Status', 'event-post'),
197 'EventCancelled'=>_x('Cancelled', 'Event Status', 'event-post'),
198 'EventMovedOnline'=>_x('Moved Online', 'Event Status', 'event-post'),
199 'EventPostponed'=>_x('Postoned', 'Event Status', 'event-post'),
200 'EventRescheduled'=>_x('Rescheduled', 'Event Status', 'event-post'),
201 );
202
203 $this->maps = $this->get_maps();
204 $this->settings = $this->get_settings();
205
206 do_action('evenpost_init', $this);
207
208 $this->Shortcodes = new EventPost_Shortcodes();
209
210 if(function_exists('register_block_type')){
211 $block_path = plugin_dir_path(__FILE__).'inc/blocks/';
212 include_once ($block_path . 'eventslist.php');
213 include_once ($block_path . 'eventstimeline.php');
214 include_once ($block_path . 'eventsmap.php');
215 include_once ($block_path . 'eventscalendar.php');
216 include_once ($block_path . 'eventdetails.php');
217 }
218
219 // Edit
220 add_action('add_meta_boxes', array(&$this, 'add_custom_box'));
221 foreach($this->settings['posttypes'] as $posttype){
222 add_filter('manage_'.$posttype.'_posts_columns', array(&$this, 'columns_head'), 2);
223 add_action('manage_'.$posttype.'_posts_custom_column', array(&$this, 'columns_content'), 10, 2);
224 }
225 $this->Categories->add_fields_to_taxonomies($this->settings['posttypes']);
226
227 $this->markpath = '';
228 $this->markurl = '';
229 if (!empty($this->settings['markpath']) && !empty($this->settings['markurl'])) {
230 $this->markpath = ABSPATH.'/'.$this->settings['markpath'];
231 $this->markurl = $this->settings['markurl'];
232 } else {
233 // $this->markpath = plugin_dir_path(__FILE__) . 'markers/';
234 // $this->markurl = plugins_url('/markers/', __FILE__);
235 }
236
237 $this->dateformat = str_replace(array('yy', 'mm', 'dd'), array('Y', 'm', 'd'), __('yy-mm-dd', 'event-post'));
238
239 $this->default_list_shema = apply_filters('eventpost_default_list_shema', array(
240 'container' => '<%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>'.
241 '%list%'.
242 '%pagination%'.
243 '</%type%><!-- .event_loop -->',
244 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">'.
245 '<a href="%event_link%">'.
246 '%event_thumbnail%'.
247 '<h5>%event_title%</h5>'.
248 '</a>'.
249 '%event_date%'.
250 '%event_cat%'.
251 '%event_location%'.
252 '%event_excerpt%'.
253 '</%child%><!-- .event_item -->'
254 ));
255 $this->list_shema = apply_filters('eventpost_list_shema',$this->default_list_shema);
256
257 $this->default_timeline_shema = apply_filters('eventpost_default_timeline_shema', array(
258 'container' => '
259 <%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>
260 %prev_arrow%
261 <div class="track">
262 %list%
263 </div>
264 %next_arrow%
265 </%type%><!-- .event_loop -->',
266 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">
267 <div class="anchor" style="background-color:#%color%"></div>
268 %event_date%
269 %event_location%
270 %event_cat%
271 %event_excerpt%
272 <a href="%event_link%">
273 %event_thumbnail%
274 <h5>%event_title%</h5>
275 </a>
276 </%child%><!-- .event_item -->'
277 ));
278 $this->timeline_shema = apply_filters('eventpost_timeline_shema',$this->default_timeline_shema);
279
280 $this->map_interactions=array(
281 'DragRotate'=>__('Drag Rotate', 'event-post'),
282 'DoubleClickZoom'=>__('Double Click Zoom', 'event-post'),
283 'DragPan'=>__('Drag Pan', 'event-post'),
284 'PinchRotate'=>__('Pinch Rotate', 'event-post'),
285 'PinchZoom'=>__('Pinch Zoom', 'event-post'),
286 'KeyboardPan'=>__('Keyboard Pan', 'event-post'),
287 'KeyboardZoom'=>__('Keyboard Zoom', 'event-post'),
288 'MouseWheelZoom'=>__('Mouse Wheel Zoom', 'event-post'),
289 'DragZoom'=>__('Drag Zoom', 'event-post'),
290 );
291
292 $this->quick_edit_fields = apply_filters('eventpost_quick_edit_fields', array(
293 'event'=>array(
294 $this->META_START=>__('Begin:', 'event-post'),
295 $this->META_END=>__('End:', 'event-post'),
296 $this->META_COLOR=>__('Color:', 'event-post'),
297 $this->META_ICON=>__('Icon:', 'event-post'),
298 ),
299 'location'=>array(
300 $this->META_ADD=>__('Address:', 'event-post'),
301 $this->META_LAT=>__('Latitude:', 'event-post'),
302 $this->META_LONG=>__('Longitude:', 'event-post'),
303 ),
304 )
305 );
306 $this->bulk_edit_fields = apply_filters('eventpost_bulk_edit_fields', array(
307 'event'=>array(
308 $this->META_COLOR=>__('Color:', 'event-post'),
309 $this->META_ICON=>__('Icon:', 'event-post'),
310 ),
311 )
312 );
313
314 }
315
316 public function register_widgets(){
317 register_widget('EventPost_List');
318 register_widget('EventPost_Map');
319 register_widget('EventPost_Cal');
320 }
321
322 /**
323 * Usefull hexadecimal to decimal converter. Returns an array of RGB from a given hexadecimal color.
324 * @param string $color
325 * @return array $color($R, $G, $B)
326 */
327 public function hex2dec($color = '000000') {
328 $tbl_color = array();
329 if (!strstr('#', $color)){
330 $color = '#' . $color;
331 }
332 $tbl_color['R'] = hexdec(substr($color, 1, 2));
333 $tbl_color['G'] = hexdec(substr($color, 3, 2));
334 $tbl_color['B'] = hexdec(substr($color, 5, 2));
335 return $tbl_color;
336 }
337 /**
338 * Fetch all registered image sizes
339 * @global array $_wp_additional_image_sizes
340 * @return array
341 */
342 function get_thumbnail_sizes(){
343 global $_wp_additional_image_sizes;
344 $sizes = array('thumbnail', 'medium', 'large', 'full');
345 foreach(array_keys($_wp_additional_image_sizes) as $size){
346 $sizes[]=$size;
347 }
348 return $sizes;
349 }
350
351 /**
352 * Get blog settings, load and saves default settings if needed. Can be filterred using
353 *
354 * `<?php add_filter('eventpost_getsettings', 'some_function'); ?>`
355 *
356 * @action eventpost_getsettings_action
357 * @filter eventpost_getsettings
358 * @return array
359 */
360 public function get_settings() {
361 $ep_settings = $this->Settings->get_settings();
362 return apply_filters('eventpost_getsettings', $ep_settings);
363 }
364
365 /**
366 * Checks if HTML schemas are not empty
367 * @param array $shema
368 * @return array
369 */
370 public function custom_shema($shema){
371 if(!empty($this->settings['container_shema'])){
372 $shema['container']=$this->settings['container_shema'];
373 }
374 if(!empty($this->settings['item_shema'])){
375 $shema['item']=$this->settings['item_shema'];
376 }
377 return $shema;
378 }
379
380 /**
381 * Parse the maps.json file. Custom maps can be added by using the `eventpost_getsettings` filter like the following example:
382 *
383 * ```
384 * <?php
385 * add_filter('eventpost_getsettings', 'map_function');
386 * function map_function($maps){
387 * array_push($maps, array(
388 * 'name'=>'Myt custom map',
389 * 'id'=>'custom_map',
390 * 'urls'=>array(
391 * 'http://a.customurl.org/{z}/{x}/{y}.png',
392 * 'http://b.customurl.org/{z}/{x}/{y}.png',
393 * 'http://c.customurl.org/{z}/{x}/{y}.png',
394 * )
395 * ));
396 * return $maps;
397 * }
398 * ?>
399 * ```
400 *
401 * @filter eventpost_maps
402 * @return array of map arrays ['name', 'id', 'urls']
403 */
404 public function get_maps() {
405 $maps = array();
406 $filename = plugin_dir_path(__FILE__) . 'maps.json';
407 if (is_file($filename) && (false !== $json = json_decode(file_get_contents($filename)))) {
408 // Convert objects to array to ensure retrocompatibility
409 $arrays = array();
410 foreach($json as $map){
411 $arrays[$map->id] = (array) $map;
412 }
413 $maps = apply_filters('eventpost_maps', $arrays);
414 }
415 return $maps;
416 }
417
418 /**
419 *
420 * @return array
421 */
422 public function get_colors() {
423 $colors = array();
424 if (is_dir($this->markpath)) {
425 $files = scandir($this->markpath);
426 foreach ($files as $file) {
427 if (substr($file, -4) == '.png') {
428 $colors[substr($file, 0, -4)] = $this->markurl . $file;
429 }
430 }
431 }
432 return $colors;
433 }
434
435 /**
436 *
437 * @return color
438 */
439 public function get_post_color($post_id, $default = false, $check_taxo = false) {
440 $color = get_post_meta($post_id, $this->META_COLOR,true);
441 if($color && !empty($color)){
442 return event_post_format_color($color);
443 }else{
444 if($check_taxo){
445 foreach(event_post_get_all_terms($post_id) as $term){
446 $taxo_color = $this->Categories->get_taxonomy_color($term->term_id);
447 if($taxo_color){
448 return event_post_format_color($taxo_color);
449 }
450 }
451 }
452 }
453 return event_post_format_color($default);
454 }
455
456 /**
457 *
458 * @return class
459 */
460 public function get_post_icon($post_id, $default = false, $check_taxo = false) {
461 $icon = get_post_meta($post_id, $this->META_ICON,true);
462 if($icon && !empty($icon)){
463 return $icon;
464 }else{
465 if($check_taxo){
466 foreach(event_post_get_all_terms($post_id) as $term){
467 $taxo_icon = $this->Categories->get_taxonomy_icon($term->term_id);
468 if($taxo_icon){
469 return event_post_format_color($taxo_icon);
470 }
471 }
472 }
473 }
474 return $default;
475 }
476
477 /**
478 *
479 * @param string $color
480 * @return sring
481 */
482 public function get_marker($color) {
483 if (is_file($this->markpath . $color . '.png')) {
484 return $this->markurl . $color . '.png';
485 }
486 return "";
487 }
488
489 /**
490 * Enqueue CSS files
491 */
492 public function load_styles() {
493 //CSS
494 if(!empty($this->settings['customcss'])){
495 wp_enqueue_style('event-post-custom', $this->settings['customcss']);
496 }
497 elseif(is_file(get_stylesheet_directory().'/event-post.css') || is_file(get_template_directory().'/event-post.css')){
498 wp_enqueue_style('event-post-custom', get_theme_file_uri('event-post.css'));
499 }
500 else{
501 wp_register_style('event-post', plugins_url('/css/event-post.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/event-post.css" ));
502 wp_enqueue_style('event-post');
503 }
504
505 // Lib scripts
506 wp_enqueue_style('openlayers', plugins_url('/css/ol.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/ol.css" ));
507 wp_enqueue_style('dashicons', includes_url('/css/dashicons.min.css'));
508 }
509 /**
510 * Enqueue Editor style
511 */
512 public function editor_styles() {
513 add_editor_style( plugins_url('/css/event-post.css', __FILE__) );
514 }
515
516 /**
517 * Enqueue JS files
518 */
519 public function load_scripts($deps = array('jquery')) {
520 // JS
521 wp_enqueue_script('jquery', false, false, false, true);
522 wp_enqueue_script('event-post', plugins_url('/js/event-post.min.js', __FILE__), $deps, filemtime( "{$this->plugin_path}/js/event-post.min.js" ), true);
523 $maps = $this->maps;
524 foreach($maps as $m=>$map){
525 if(isset($map['api_param']) && $this->settings['tile_api_key']){
526 foreach($map['urls'] as $i=>$url){
527 $maps[$m]['urls'][$i] = add_query_arg($map['api_param'], $this->settings['tile_api_key'], $url);
528 }
529 }
530 }
531 wp_localize_script('event-post', 'eventpost_params', array(
532 'imgpath' => plugins_url('/img/', __FILE__),
533 'maptiles' => $maps,
534 'defaulttile' => $this->settings['tile'],
535 'zoom' => $this->settings['zoom'],
536 'ajaxurl' => admin_url() . 'admin-ajax.php',
537 'map_interactions'=>$this->map_interactions,
538 ));
539 }
540 /**
541 * Enqueue JS files for maps
542 */
543 public function load_map_scripts() {
544 // JS
545 wp_enqueue_script('openlayers', plugins_url('/js/ol.js', __FILE__), false, filemtime( "{$this->plugin_path}/js/ol.js" ), true);
546 $this->load_scripts(array('jquery', 'openlayers'));
547 if(is_admin()){
548 $this->admin_scripts(array('jquery', 'openlayers'));
549 }
550 }
551
552 /**
553 * Enqueue CSS files in admin
554 */
555 public function admin_head() {
556 $page = basename($_SERVER['SCRIPT_NAME']);
557 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') ){
558 return;
559 }
560 wp_enqueue_style('openlayers', plugins_url('/css/ol.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/ol.css" ));
561 wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/jquery-ui.css" ));
562 wp_enqueue_style('event-post-admin', plugins_url('/css/event-post-admin.css', __FILE__), false, filemtime( "{$this->plugin_path}/css/event-post-admin.css" ));
563 }
564
565 /**
566 * Enqueue JS files in admin
567 */
568 public function admin_scripts($deps = array('jquery'), $force=false) {
569 $page = basename($_SERVER['SCRIPT_NAME']);
570 if(!$force &&
571 $page!='post-new.php' &&
572 $page!='edit-tags.php' &&
573 $page!='term.php' &&
574 !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') &&
575 !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings')
576 ){
577 return;
578 }
579 wp_enqueue_script('jquery');
580 wp_enqueue_script('jquery-effects-core');
581 wp_enqueue_script('jquery-effects-shake');
582 wp_enqueue_style( 'wp-color-picker');
583 wp_enqueue_script( 'wp-color-picker');
584 if(!is_array($deps)){
585 $deps = array('jquery','wp-color-picker');
586 }
587 if($this->settings['datepicker']=='simple' || !is_admin() || (isset($_GET['page']) && $_GET['page']=='event-settings')){
588 wp_enqueue_script('jquery-ui-datepicker');
589 $deps[] = 'jquery-ui-datepicker';
590 }
591 wp_enqueue_script('event-post-admin', plugins_url('/js/event-post-admin.min.js', __FILE__), $deps, filemtime( "{$this->plugin_path}/js/event-post-admin.min.js" ), true);
592 $language = get_bloginfo('language');
593 if (strpos($language, '-') > -1) {
594 $language = strtolower(substr($language, 0, 2));
595 }
596 wp_localize_script('event-post-admin', 'eventpost', array(
597 'ajaxurl' => admin_url('admin-ajax.php'),
598 'imgpath' => plugins_url('/img/', __FILE__),
599 'date_choose' => __('Choose', 'event-post'),
600 'date_format' => __('yy-mm-dd', 'event-post'),
601 'more_icons' => __('More icons', 'event-post'),
602 'pick_a_date'=>__('Pick a date','event-post'),
603 'use_current_location'=>__('Use my current location','event-post'),
604 'start_drag'=>__('Click to<br>drag the map<br>and change location','event-post'),
605 'empty_address'=>__('Be kind to fill a non empty address:)', 'event-post'),
606 'search'=>__('Type an address', 'event-post'),
607 'stop_drag'=>_x('Done','Stop allowing to drag the map', 'event-post'),
608 'datepickeri18n'=>array(
609 'order'=>__( '%1$s %2$s, %3$s @ %4$s:%5$s', 'event-post'),
610 'day'=>__('Day', 'event-post'),
611 'month'=>__('Month', 'event-post'),
612 'year'=>__('Day', 'event-post'),
613 'hour'=>__('Hour', 'event-post'),
614 'minute'=>__('Minute', 'event-post'),
615 'ok'=>__('OK', 'event-post'),
616 'cancel'=>__('Cancel', 'event-post'),
617 'remove'=>__('Remove', 'event-post'),
618 'edit'=>__('Edit', 'event-post'),
619 'months'=>$this->NomDuMois,
620 ),
621 'META_START' => $this->META_START,
622 'META_END' => $this->META_END,
623 'META_ADD' => $this->META_ADD,
624 'META_LAT' => $this->META_LAT,
625 'META_LONG' => $this->META_LONG,
626 'META_STATUS' => $this->META_STATUS,
627 'META_ATTENDANCE_MODE' => $this->META_ATTENDANCE_MODE,
628 'lang'=>$language,
629 'maptiles' => $this->maps,
630 'defaulttile' => $this->settings['tile'],
631 'palette' => $this->get_theme_palette("hex"),
632 'available_images' => $this->get_colors(),
633 ));
634 }
635 function scripts_edit() {
636 // load only when editing a supported post type
637 $current_post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
638 if ( in_array( $current_post_type, $this->settings['posttypes'] ) ) {
639 wp_enqueue_script( 'eventpost-inline-edit', plugins_url( 'js/inline-edit.min.js', __FILE__ ), array( 'jquery', 'inline-edit-post' ), '', true );
640 wp_localize_script('eventpost-inline-edit', 'eventpost_inline_edit', array(
641 'quick'=>$this->quick_edit_fields,
642 'bulk'=>$this->bulk_edit_fields,
643 ));
644 }
645 }
646
647 function get_rich_result($event){
648 /**
649 * https://search.google.com/test/rich-results
650 {
651 "@context": "https://schema.org",
652 "@type": "Event",
653 "name": "The Adventures of Kira and Morrison",
654 "startDate": "2025-07-21T19:00",
655 "endDate": "2025-07-21T23:00",
656 "eventStatus": "https://schema.org/EventScheduled",
657 "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
658 "location": {
659 "@type": "VirtualLocation",
660 "url": "https://operaonline.stream5.com/"
661 },
662 "image": [
663 "https://example.com/photos/1x1/photo.jpg",
664 "https://example.com/photos/4x3/photo.jpg",
665 "https://example.com/photos/16x9/photo.jpg"
666 ],
667 "description": "The Adventures of Kira and Morrison is coming to Snickertown in a can’t miss performance.",
668 "offers": {
669 "@type": "Offer",
670 "url": "https://www.example.com/event_offer/12345_201803180430",
671 "price": "30",
672 "priceCurrency": "USD",
673 "availability": "https://schema.org/InStock",
674 "validFrom": "2024-05-21T12:00"
675 },
676 "performer": {
677 "@type": "PerformingGroup",
678 "name": "Kira and Morrison"
679 }
680 }
681 */
682 $location_virtual = array(
683 '@type'=>'VirtualLocation',
684 'url'=>$event->virtual_location,
685 );
686 $physical_location = array(
687 '@type'=>'place',
688 'name'=>$event->address,
689 'address'=>$event->address,
690 'geo'=>array(
691 '@type'=>'GeoCoordinates',
692 'latitude'=>$event->lat,
693 'longitude'=>$event->long,
694 ),
695 );
696 $min = 60 * get_option('gmt_offset');
697 $sign = $min < 0 ? "-" : "+";
698 $absmin = abs($min);
699 $gmt_offset = sprintf("%s%02d:%02d", $sign, $absmin/60, $absmin%60);
700 $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';
701
702 return apply_filters('event-post-rich-result', array(
703 '@context'=>'https://schema.org',
704 '@type'=>'event',
705 'name'=>$event->post_title,
706 'datePublished'=>str_replace(' ', 'T', $event->post_date_gmt).$gmt_offset,
707 'dateModified'=>str_replace(' ', 'T', $event->post_modified_gmt).$gmt_offset,
708 'startDate'=>$event->time_start ? date($time_format, $event->time_start) : null,
709 'endDate'=>$event->time_end ? date($time_format, $event->time_end) : null,
710 'eventStatus'=>$event->status,
711 'eventAttendanceMode'=>$event->attendance_mode,
712 'location'=> ($event->attendance_mode == 'MixedEventAttendanceMode') ? array($location_virtual,$physical_location) : ($event->attendance_mode == 'OnlineEventAttendanceMode' ? $location_virtual : $physical_location),
713 'image'=> has_post_thumbnail($event->ID) ? array(
714 get_the_post_thumbnail_url($event->ID, 'post-thumbnail'),
715 get_the_post_thumbnail_url($event->ID, 'medium'),
716 get_the_post_thumbnail_url($event->ID, 'large'),
717 get_the_post_thumbnail_url($event->ID, 'full'),
718 ) : null,
719 'description'=>$event->post_excerpt,
720 ), $event);
721 }
722
723 function wpseo_schema_webpage($rich_result){
724 $event = $this->retreive();
725 if ($event->time_start != '' && $event->time_end != '') {
726 $rich_result = array_merge($rich_result, $this->get_rich_result($event));
727 }
728 $this->is_schema_output = true;
729 return $rich_result;
730 }
731
732 function get_theme_palette($return = "hex"){
733 $theme_options = wp_get_global_settings();
734 $colors = [];
735 if(isset($theme_options['color']['palette']['theme'])){
736 $colors = $theme_options['color']['palette']['theme'];
737 }elseif(isset($theme_options['color']['palette']['default'])){
738 $colors = $theme_options['color']['palette']['default'];
739 }
740 if($return == "hex"){
741 $color_hexs = [];
742 foreach($colors as $color){
743 $color_hexs[] = $color["color"];
744 }
745 return $color_hexs;
746 }
747 return $colors;
748 }
749
750 /**
751 * Add custom header meta for single events
752 */
753 public function single_header() {
754 if (is_single()) {
755 $twitter_label_id=0;
756 $event = $this->retreive();
757 $has_location = $has_time = false;
758 if ($event->address != '' || ($event->lat != '' && $event->long != '')) {
759 $twitter_label_id++;
760 $has_location = true;
761 ?>
762 <meta name="geo.placename" content="<?php echo esc_attr($event->address) ?>" />
763 <meta name="geo.position" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
764 <meta name="ICBM" content="<?php echo $event->lat ?>;<?php echo esc_attr($event->long) ?>" />
765 <meta property="place:location:latitude" content="<?php echo esc_attr($event->lat) ?>" />
766 <meta property="place:location:longitude" content="<?php echo esc_attr($event->long) ?>" />
767 <meta name="twitter:label<?php echo $twitter_label_id; ?>" content="<?php _e('Location', 'event-post'); ?>"/>
768 <meta name="twitter:data<?php echo $twitter_label_id; ?>" content="<?php echo esc_attr($event->address) ?>"/>
769 <?php
770 }
771 if ($event->start != '' && $event->end != '') {
772 $has_time = true;
773 $twitter_label_id++;
774 ?>
775 <meta name="datetime-coverage-start" content="<?php echo date('c', $event->time_start) ?>" />
776 <meta name="datetime-coverage-end" content="<?php echo date('c', $event->time_end) ?>" />
777 <meta name="twitter:label<?php echo $twitter_label_id; ?>" content="<?php _e('Date', 'event-post'); ?>"/>
778 <meta name="twitter:data<?php echo $twitter_label_id; ?>" content="<?php echo esc_attr($this->human_date($event->time_start)) ?>"/>
779 <?php
780 }
781 if(($has_location || $has_time) && !$this->is_schema_output){
782 $rich_result = $this->get_rich_result($event);
783 $this->is_schema_output = true;
784 ?>
785 <script type="application/ld+json"><?php echo json_encode($rich_result); ?></script>
786 <?php
787 }
788
789 }
790 }
791
792 /**
793 *
794 * @param type $str
795 * @return string
796 * @since 5.0.1
797 */
798 public function date_cleanup($str){
799 return trim(str_replace(array('0', ' ', ':', '-'), '', $str));
800 }
801
802 /**
803 *
804 * @param string $str
805 * @return boolean
806 */
807 public function dateisvalid($str) {
808 return is_string($str) && $this->date_cleanup($str) != '';
809 }
810
811 /**
812 *
813 * @param string $date
814 * @param string $sep
815 * @return string
816 */
817 public function parsedate($date, $sep = '') {
818 if (!empty($date)) {
819 return substr($date, 0, 10) . $sep . substr($date, 11, 8);
820 } else {
821 return '';
822 }
823 }
824
825 /**
826 *
827 * @param mixed $date
828 * @param string $format
829 * @return type
830 */
831 public function human_date($date, $format = 'l j F Y') {
832 if($this->settings['dateforhumans']){
833 if (is_numeric($date) && date('d/m/Y', $date) == date('d/m/Y')) {
834 return __('today', 'event-post');
835 } elseif (is_numeric($date) && date('d/m/Y', $date) == date('d/m/Y', strtotime('+1 day'))) {
836 return __('tomorrow', 'event-post');
837 } elseif (is_numeric($date) && date('d/m/Y', $date) == date('d/m/Y', strtotime('-1 day'))) {
838 return __('yesterday', 'event-post');
839 }
840 }
841 return date_i18n($format, $date);
842 }
843
844 /**
845 *
846 * @param timestamp $time_start
847 * @param timestamp $time_end
848 * @return string
849 */
850 public function delta_date($time_start, $time_end){
851 if(!$time_start || !$time_end){
852 return;
853 }
854
855 $from_to_days = _x('%1$sfrom%2$s %3$s %4$sto%5$s %6$s', 'Days', 'event-post');
856 $single_day_at = _x('%1$s%2$s,%3$s %4$s', 'From/To single day at time', 'event-post');
857 $from_to_hours = _x('%1$sfrom%2$s %3$s %4$sto%5$s %6$s', 'Hours', 'event-post');
858 $at_time = _x('%1$sat%2$s %3$s', 'Time', 'event-post');
859
860 //Display dates
861 $dates="\t\t\t\t".'<div class="event_date" data-start="' . $this->human_date($time_start) . '" data-end="' . $this->human_date($time_end) . '">';
862 // Same day
863 if (date('Ymd', $time_start) == date('Ymd', $time_end)) {
864 $dates.= "\n\t\t\t\t\t\t\t".'<time itemprop="dtstart" datetime="' . date_i18n('c', $time_start) . '">'
865 . '<span class="date date-single">' . $this->human_date($time_end, $this->settings['dateformat']) . "</span>";
866 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') {
867 $dates.= ' '.sprintf(
868 $from_to_hours,
869 '<span class="linking_word linking_word-from">',
870 '</span>',
871 '<span class="time time-start">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>',
872 '<span class="linking_word linking_word-to">',
873 '</span>',
874 '<span class="time time-end">' . date_i18n($this->settings['timeformat'], $time_end) . '</span>'
875 );
876 }
877 elseif (date('H:i', $time_start) != '00:00') {
878 $dates.= ' '.sprintf(
879 $at_time,
880 '<span class="linking_word">',
881 '</span>',
882 '<span class="time time-single">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>'
883 );
884 }
885 $dates.="\n\t\t\t\t\t\t\t".'</time>';
886 }
887 // Not same day
888 else {
889 $dates.= ' '.sprintf(
890 $from_to_days,
891 '<span class="linking_word linking_word-from">',
892 '</span>',
893 '<time class="date date-start" itemprop="dtstart" datetime="' . date('c', $time_start) . '">'
894 . ((date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00')
895 ? 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>')
896 : $this->human_date($time_start, $this->settings['dateformat'])
897 )
898 . '</time>',
899 '<span class="linking_word linking_word-to">',
900 '</span>',
901 '<time class="date date-to" itemprop="dtend" datetime="' . date('c', $time_end) . '">'
902 . ((date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00')
903 ? 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>')
904 : $this->human_date($time_end, $this->settings['dateformat'])
905 )
906 . '</time>'
907 );
908 }
909 $dates.="\n\t\t\t\t\t\t".'</div><!-- .event_date -->';
910 return $dates;
911 }
912
913 /**
914 *
915 * @param WP_Post object $post
916 * @param mixed $links
917 * @return string
918 */
919 public function print_date($post = null, $links = 'deprecated', $context='') {
920 $dates = '';
921 $event = $this->retreive($post);
922 if ($event->start != '' && $event->end != '') {
923
924 $dates.=$this->delta_date($event->time_start, $event->time_end);
925 if( // Status setting
926 $this->settings['displaystatus'] == 'both' ||
927 ($this->settings['displaystatus'] == 'single' && is_single() ) ||
928 ($this->settings['displaystatus'] == 'list' && !is_single() )
929 ){
930 $dates.='<span class="eventpost-status">'.$this->statuses[$event->status].'</span>';
931 }
932 $timezone_string = get_option('timezone_string');
933 $gmt_offset = $gmt = $this->get_gmt_offset();
934
935 if (
936 !is_admin()
937 && ( // Export when setting
938 $this->settings['export_when'] == 'both' ||
939 ( $this->settings['export_when'] == 'future' && $this->is_future($event) ) ||
940 ( $this->settings['export_when'] == 'past' && $this->is_past($event) )
941 )
942 && ( // Export setting
943 $this->settings['export'] == 'both' ||
944 ($this->settings['export'] == 'single' && is_single() ) ||
945 ($this->settings['export'] == 'list' && !is_single() )
946 )
947 ) {
948 // Export event
949 $title = urlencode($post->post_title);
950 $address = urlencode($post->address);
951 $desc = urlencode($event->post_excerpt."\n\n".$post->permalink);
952 $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');
953 $d_s = date("Ymd", $event->time_start) . ($allday ? '' : 'T' . date("His", $event->time_start));
954 $d_e = date("Ymd", $event->time_end) . ($allday ? '' : 'T' . date("His", $event->time_end));
955 $uid = $post->ID . '-' . $post->blog_id;
956 $url = $event->permalink;
957
958 // format de date ICS
959 $permalink_structure = get_option( 'permalink_structure' );
960 if($permalink_structure != ""){
961 $ics_url = site_url('eventpost/'.$event->ID.'.ics');
962 $vcs_url = site_url('eventpost/'.$event->ID.'.vcs');
963 }
964 else{
965 $ics_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'ics'), admin_url('admin-ajax.php'));
966 $vcs_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'vcs'), admin_url('admin-ajax.php'));
967
968 }
969
970 // format de date Google cal
971 //$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';
972 $google_url = add_query_arg(array(
973 'action'=>'TEMPLATE',
974 'trp'=>'false',
975 'sprop'=>'name',
976 'text'=>$title,
977 'dates'=>$d_s.'/'.$d_e.'', // Removed Z to fix TZ issue
978 'location'=>$address,
979 'details'=>$desc,
980 'gmt'=> urlencode($gmt_offset)
981 ), 'https://www.google.com/calendar/event');
982 if(!empty($timezone_string)){
983 $google_url = add_query_arg(array(
984 'ctz'=>$timezone_string,
985 ), $google_url);
986 }
987
988 $dates.='
989 <span class="eventpost-date-export">
990 <a href="' . $ics_url . '" class="event_link event-export ics" target="_blank" title="' . __('Download ICS file', 'event-post') . '">ical</a>
991 <a href="' . $google_url . '" class="event_link event-export gcal" target="_blank" title="' . __('Add to Google calendar', 'event-post') . '">Google</a>
992 <a href="' . $vcs_url . '" class="event_link event-export vcs" target="_blank" title="' . __('Add to Outlook', 'event-post') . '">outlook</a>
993 <i class="dashicons-before dashicons-calendar"></i>
994 </span>';
995 }
996 }
997 return apply_filters('eventpost_printdate', $dates);
998 }
999
1000 /**
1001 *
1002 * @param WP_Post object $post
1003 * @return string
1004 */
1005 public function print_location($post=null, $context='') {
1006 $location = '';
1007 if ($post == null)
1008 $post = get_post();
1009 elseif (is_numeric($post)) {
1010 $post = get_post($post);
1011 }
1012 if (!isset($post->start)) {
1013 $post = $this->retreive($post);
1014 }
1015 $address = $post->address;
1016 $lat = $post->lat;
1017 $long = $post->long;
1018 $color = $this->get_post_color($post->ID, $this->settings['default_color'], true);
1019 $icon = $this->DashIcons->icons[$this->get_post_icon($post->ID, $this->settings['default_icon'], true)];
1020 $virtual_location = $post->virtual_location;
1021 $attendance_mode = $post->attendance_mode;
1022
1023 if ($this->is_online($post) && $virtual_location) {
1024 $location.="\t\t\t\t".'<div><a href="'.esc_url($virtual_location).'" class="eventpost-virtual-location-link" target="_blank" rel="noopener">'
1025 .__('Join link', 'event-post')
1026 .'</a></div>'
1027 ."\n";
1028 }
1029 if ($this->is_offline($post) && ($address != '' || ($lat != '' && $long != ''))) {
1030 $location.="\t\t\t\t".'<address';
1031 if ($lat != '' && $long != '') {
1032 $location.=' data-id="' . $post->ID . '"
1033 data-latitude="' . $lat . '"
1034 data-longitude="' . $long . '"
1035 data-marker="' . $this->get_marker($color) . '"
1036 data-iconcode="' .$icon. '"
1037 data-icon="' . mb_convert_encoding('&#x'.$icon.';', 'UTF-8', 'HTML-ENTITIES'). '"
1038 data-color="#' . $color. '"';
1039 }
1040 $location.=' itemprop="adr" class="eventpost-address">'
1041 . "\n\t\t\t\t\t\t\t".'<span>'
1042 . "\n".$address
1043 . "\n\t\t\t\t\t\t\t". '</span>';
1044 if ($context=='single' && $lat != '' && $long != '') {
1045 $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>';
1046 }
1047 $location.="\n\t\t\t\t\t\t".'</address>';
1048 if (wp_is_mobile() && $lat != '' && $long != '') {
1049 $location.="\n\t\t\t\t\t\t".'<a class="event_link gps-geo-link" href="geo:' . $lat . ',' . $long . '" target="_blank" itemprop="geo"><i class="dashicons-before dashicons-location"></i> ' . __('Open in app', 'event-post') . '</a>';
1050 }
1051 }
1052
1053 return apply_filters('eventpost_printlocation', $location);
1054 }
1055
1056 /**
1057 *
1058 * @param WP_Post object $post
1059 * @return string
1060 */
1061 public function print_categories($post=null, $context='') {
1062 if ($post == null)
1063 $post = get_post();
1064 elseif (is_numeric($post)) {
1065 $post = get_post($post);
1066 }
1067 if (!isset($post->start)) {
1068 $post = $this->retreive($post);
1069 }
1070 $cats = '';
1071 $categories = $post->categories;
1072 if ($categories) {
1073 $cats.="\t\t\t\t".'<span class="event_categories">';
1074
1075 foreach ($categories as $category) {
1076 $cats.="\t\t\t\t\t".'<span class="event_category"';
1077 $color = $this->Categories->get_taxonomy_color($category->term_id);
1078 if ($color != '' && $color) {
1079 $cats.=' style="color:#' . $color . '"';
1080 }
1081 $cats.='>';
1082 $cats .= $category->name . ' ';
1083 $cats.='</span>';
1084 }
1085 $cats.='</span>';
1086 }
1087 return $cats;
1088 }
1089
1090 /**
1091 * Generate, return or output date event datas
1092 * @param WP_Post object $post
1093 * @param string $class
1094 * @filter eventpost_get_single
1095 * @return string
1096 */
1097 public function get_single($post = null, $class = '', $context='') {
1098 if ($post == null) {
1099 $post = $this->retreive();
1100 }
1101 $datas_date = $this->print_date($post, null, $context);
1102 $datas_cat = $this->print_categories($post, $context);
1103 $datas_loc = $this->print_location($post, $context);
1104 $classes = array(
1105 'event_data',
1106 'status-'.$post->status,
1107 'location-type-'.$post->attendance_mode,
1108 $class
1109 );
1110 if ($datas_date != '' || $datas_loc != '') {
1111 $rgb = $this->hex2dec($post->color);
1112 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">'
1113 . apply_filters('eventpost_get_single', $datas_date . $datas_cat . $datas_loc, $post)
1114 . '</div>';
1115 }
1116 return '';
1117 }
1118
1119 /**
1120 * Displays dates of a gieven post
1121 * @param WP_Post object $post
1122 * @param string $class
1123 * @return string
1124 */
1125 public function get_singledate($post = null, $class = '', $context='') {
1126 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 -->';
1127 }
1128
1129 /**
1130 * Displays coloured terms of a given post
1131 * @param WP_Post object $post
1132 * @param string $class
1133 * @return string
1134 */
1135 public function get_singlecat($post = null, $class = '', $context='') {
1136 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 -->';
1137 }
1138
1139 /**
1140 * Displays location of a given post
1141 * @param WP_Post object $post
1142 * @param string $class
1143 * @return string
1144 */
1145 public function get_singleloc($post = null, $class = '', $context='') {
1146 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 -->';
1147 }
1148
1149 /**
1150 * Uses `the_content` filter to add event details before or after the content of the current post
1151 * @param string $content
1152 * @return string
1153 */
1154 public function display_single($content) {
1155 if (is_page() || !is_single() || is_home() || !in_the_loop() || !is_main_query()){
1156 return $content;
1157 }
1158
1159 $post = $this->retreive();
1160 $eventbar = apply_filters('eventpost_contentbar', $this->get_single($post, 'event_single', 'single'), $post);
1161 if($this->settings['singlepos']=='before'){
1162 $content=$eventbar.$content;
1163 }
1164 elseif($this->settings['singlepos']=='after'){
1165 $content.=$eventbar;
1166 }
1167 $this->load_map_scripts();
1168 return $content;
1169 }
1170
1171 /**
1172 * Outputs events details (dates, geoloc, terms) of given post
1173 * @param WP_Post object $post
1174 * @echoes string
1175 * @return void
1176 */
1177 public function print_single($post = null) {
1178 echo $this->get_single($post);
1179 }
1180
1181 /**
1182 * Alter the post title in order to add icons if needed
1183 * @param string $title
1184 * @return string
1185 */
1186 public function the_title($title, $post_id = null){
1187 if(!$post_id || !in_the_loop() || !$this->settings['loopicons']){
1188 return $title;
1189 }
1190 $icons_ = array(
1191 // Emojis
1192 1=>array('🗓', '🗺'),
1193 // Dashicons
1194 2=>array('<span class="dashicons dashicons-calendar"></span>', '<span class="dashicons dashicons-location"></span>'),
1195 );
1196
1197 $event = $this->retreive($post_id);
1198 if(!empty($event->start)){
1199 $title .= ' '.$icons_[$this->settings['loopicons']][0];
1200 }
1201 if(!empty($event->lat) && !empty($event->long)){
1202 $title .= ' '.$icons_[$this->settings['loopicons']][1];
1203 }
1204 return $title;
1205 }
1206
1207
1208 /**
1209 * Return an HTML list of events
1210 *
1211 * @filter eventpost_params($defaults, 'list_events')
1212 * @filter eventpost_listevents
1213 * @filter eventpost_item_scheme_entities
1214 * @filter eventpost_item_scheme_values
1215 *
1216 * @param array $atts
1217 * @param string $id
1218 * @param string $context
1219 * @return string
1220 */
1221 public function list_events($atts, $id = 'event_list', $context='') {
1222 $ep_settings = $this->settings;
1223 $defaults = array(
1224 'nb' => 0,
1225 'type' => 'div',
1226 'future' => true,
1227 'past' => false,
1228 'geo' => 0,
1229 'width' => '',
1230 'height' => '',
1231 'list' => 0,
1232 'zoom' => '',
1233 'map_position' => 'false',
1234 'latitude' => '',
1235 'longitude' => '',
1236 'tile' => $ep_settings['tile'],
1237 'pop_element_schema' => 'false',
1238 'htmlPop_element_schema' => '',
1239 'title' => '',
1240 'before_title' => '<h3>',
1241 'after_title' => '</h3>',
1242 'cat' => '',
1243 'tag' => '',
1244 'tax_name' => '',
1245 'tax_term' => '',
1246 'events' => '',
1247 'style' => '',
1248 'thumbnail' => '',
1249 'thumbnail_size' => '',
1250 'excerpt' => '',
1251 'orderby' => 'meta_value',
1252 'order' => 'ASC',
1253 'class' => '',
1254 'className' => '',
1255 'container_schema' => $this->list_shema['container'],
1256 'item_schema' => $this->list_shema['item'],
1257 'pages' => false,
1258 'paged' => '',
1259 );
1260 // Map UI options
1261 foreach($this->map_interactions as $int_key=>$int_name){
1262 $defaults[$int_key]=true;
1263 }
1264 $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events'), $atts);
1265
1266 extract($atts);
1267 if (!is_array($events)) {
1268 $events = $this->get_events($atts);
1269 }
1270
1271 $ret = '';
1272 $this->list_id++;
1273 if (sizeof($events) > 0) {
1274 if (!empty($title)) {
1275 $ret.= html_entity_decode($before_title) . $title . html_entity_decode($after_title);
1276 }
1277
1278 $child = ($type == 'ol' || $type == 'ul') ? 'li' : 'div';
1279
1280 $html = '';
1281
1282 if($id=='event_geolist'){
1283 $this->load_map_scripts();
1284 $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);
1285 }
1286 $attributes = '';
1287 $prev_arrow = "";
1288 $next_arrow = "";
1289 $item_child_style = "";
1290 if($id == "event_timeline"){
1291 $prev_arrow = '<div class="previous">'.__('« Previous Events', 'event-post')."</div>";
1292 $next_arrow = '<div class="next">'.__('Next Events »', 'event-post')."</div>";
1293 if($nb != 0){
1294 $item_child_style = 'width : '.((100/$nb) - 2).'%;';
1295 }
1296 $attributes .= ' data-nb="'.$nb.'" data-filter="'.http_build_query($atts).'" ';
1297 }
1298
1299 foreach ($events as $event) {
1300
1301 $class_item = array(
1302 $this->is_future($event) ? 'event_future' : 'event_past',
1303 'status-'.$event->status,
1304 'location-type-'.$event->attendance_mode,
1305 );
1306 $taxonomies= get_taxonomies('','names');
1307 $post_terms = [];
1308 $terms = wp_get_post_terms($event->ID, $taxonomies);
1309 foreach($terms as $term){
1310 $class_item[] = $term->taxonomy.'-'.$term->name;
1311 }
1312 if ($ep_settings['emptylink'] == 0 && empty($event->post_content)) {
1313 $event->permalink = '#' . $id . $this->list_id;
1314 }
1315 elseif(empty($event->permalink)){
1316 $event->permalink=$event->guid;
1317 }
1318 $html.=str_replace(
1319 apply_filters('eventpost_item_scheme_entities', array(
1320 '%child%',
1321 '%class%',
1322 '%color%',
1323 '%event_link%',
1324 '%event_thumbnail%',
1325 '%event_title%',
1326 '%event_date%',
1327 '%event_cat%',
1328 '%event_location%',
1329 '%event_excerpt%',
1330 '%style%',
1331 )), apply_filters('eventpost_item_scheme_values', array(
1332 $child,
1333 implode(' ', $class_item),
1334 $this->get_post_color($event->ID, $this->settings['default_color'],true),
1335 $event->permalink,
1336 $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>' : '',
1337 $event->post_title,
1338 $this->get_singledate($event, '', $context),
1339 $this->get_singlecat($event, '', $context),
1340 $this->get_singleloc($event, '', $context),
1341 $excerpt == true && $event->post_excerpt!='' ? '<span class="event_exerpt">'.$event->post_excerpt.'</span>' : '',
1342 $item_child_style,
1343 ), $event), $item_schema
1344 );
1345
1346 }
1347 if($id == 'event_geolist'){
1348 if($height==''){
1349 $height = '300px';
1350 }
1351 if($width==''){
1352 $width = '100%';
1353 }
1354 $attributes .= ' data-tile="'.$tile.'"
1355 data-width="'.$width.'"
1356 data-height="'.$height.'"
1357 data-zoom="'.$zoom.'"
1358 data-map_position="'.$map_position.'"
1359 data-latitude="'.$latitude.'"
1360 data-longitude="'.$longitude.'"
1361 data-pop_element_schema="'.$pop_element_schema.'"
1362 data-htmlPop_element_schema="'.esc_attr($htmlPop_element_schema).'"
1363 data-list="'.$list.'"
1364 data-disabled-interactions="';
1365 // add data-position avec ma variables
1366 foreach($this->map_interactions as $int_key=>$int_name){
1367 $attributes.=$atts[$int_key]==false ? $int_key.', ' : '';
1368 }
1369 $attributes.='" ';
1370 }
1371 $pagination = '';
1372 if($pages && $this->pagination){
1373 global $wp_rewrite;
1374 $paged = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1375 $pagination = paginate_links( array(
1376 'prev_text' => __('« Previous Events', 'event-post'),
1377 'next_text' => __('Next Events »', 'event-post'),
1378 'current' => $paged,
1379 'total' => $this->pagination['max_num_pages'],
1380 )
1381 );
1382 }
1383
1384 if($context == 'events_only'){
1385 $ret = $html;
1386 }else{
1387 $ret.=str_replace(
1388 array(
1389 '%type%',
1390 '%id%',
1391 '%class%',
1392 '%listid%',
1393 '%style%',
1394 '%attributes%',
1395 '%list%',
1396 '%pagination%',
1397 '%prev_arrow%',
1398 '%next_arrow%',
1399 '%number%'
1400 ), array(
1401 $type,
1402 $id,
1403 $class.($className ? ' '.$className : '').($id == 'event_geolist' && $list ? ' has-list list-'.$list : ' no-list'),
1404 $id . $this->list_id,
1405 (!empty($width) ? 'width:' . $width . ';' : '') . (!empty($height) ? 'height:' . $height . ';' : '') . $style,
1406 $attributes,
1407 $html,
1408 $pagination,
1409 $prev_arrow,
1410 $next_arrow
1411 ), $container_schema
1412 );
1413 }
1414
1415 }
1416 elseif(filter_input(INPUT_POST, 'action')=='bulk_do_shortcode'){
1417 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>';
1418 }
1419 return apply_filters('eventpost_listevents', $ret, $id.$this->list_id, $atts, $events, $context);
1420 }
1421
1422
1423 /**
1424 * get_events
1425 * @param array $atts
1426 * @filter eventpost_params
1427 * @filter eventpost_get_items
1428 * @return array of post_ids which are events
1429 */
1430 public function get_events($atts) {
1431 if(isset($atts['future'])){
1432 $atts['future'] = filter_var( $atts['future'], FILTER_VALIDATE_BOOLEAN);
1433 }
1434 if(isset($atts['past'])){
1435 $atts['past'] = filter_var( $atts['past'], FILTER_VALIDATE_BOOLEAN);
1436 }
1437 if(isset($atts['geo'])){
1438 $atts['geo'] = filter_var( $atts['geo'], FILTER_VALIDATE_BOOLEAN);
1439 }
1440 if(isset($atts['pages'])){
1441 $atts['pages'] = filter_var( $atts['pages'], FILTER_VALIDATE_BOOLEAN);
1442 }
1443
1444
1445
1446 $requete = (shortcode_atts(apply_filters('eventpost_params', array(
1447 'nb' => 5,
1448 'future' => true,
1449 'past' => false,
1450 'geo' => 0,
1451 'cat' => '',
1452 'tag' => '',
1453 'date' => '',
1454 'orderby' => 'meta_value',
1455 'orderbykey' => $this->META_START,
1456 'order' => 'ASC',
1457 'tax_name' => '',
1458 'tax_term' => '',
1459 'paged' => 1,
1460 'post_type'=> $this->settings['posttypes']
1461 ), 'get_events'), $atts));
1462 if(!isset($requete['paged']) || $requete['paged'] == ""){
1463 $requete['paged'] = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1464 }
1465 extract($requete);
1466 wp_reset_query();
1467
1468
1469 $arg = array(
1470 'post_status' => 'publish',
1471 'post_type' => $post_type,
1472 'posts_per_page' => $nb,
1473 'paged' => $paged,
1474 'meta_key' => $orderbykey,
1475 'orderby' => $orderby,
1476 'order' => $order
1477 );
1478
1479 if($tax_name=='category'){
1480 $tax_name='';
1481 $cat=$tax_term;
1482 }
1483 elseif($tax_name=='post-tag'){
1484 $tax_name='';
1485 $tag=$tax_term;
1486 }
1487
1488 // CUSTOM TAXONOMY
1489 if ($tax_name != '' && $tax_term != '') {
1490 $arg['tax_query'] = array(
1491 array(
1492 'taxonomy' => $tax_name,
1493 'field' => 'slug',
1494 'terms' => $tax_term,
1495 ),
1496 );
1497 }
1498 // CAT
1499 if ($cat != '') {
1500 if (preg_match('/[a-zA-Z]/i', $cat)) {
1501 $arg['category_name'] = $cat;
1502 } else {
1503 $arg['cat'] = $cat;
1504 }
1505 }
1506 // TAG
1507 if ($tag != '') {
1508 $arg['tag'] = $tag;
1509 }
1510 // DATES
1511 $meta_query = array(
1512 array(
1513 'key' => $this->META_END,
1514 'value' => '',
1515 'compare' => '!='
1516 ),
1517 array(
1518 'key' => $this->META_END,
1519 'value' => '0:0:00 0:',
1520 'compare' => '!='
1521 ),
1522 array(
1523 'key' => $this->META_END,
1524 'value' => ':00',
1525 'compare' => '!='
1526 ),
1527 array(
1528 'key' => $this->META_START,
1529 'value' => '',
1530 'compare' => '!='
1531 ),
1532 array(
1533 'key' => $this->META_START,
1534 'value' => '0:0:00 0:',
1535 'compare' => '!='
1536 )
1537 );
1538 if ($future == 0 && $past == 0) {
1539 $meta_query = array();
1540 $arg['meta_key'] = null;
1541 $arg['orderby'] = null;
1542 $arg['order'] = null;
1543 }
1544 elseif ($future == 1 && $past == 0) {
1545 $meta_query[] = array(
1546 'key' => $this->META_END,
1547 'value' => current_time('mysql'),
1548 'compare' => '>=',
1549 //'type'=>'DATETIME'
1550 );
1551 }
1552 elseif ($future == 0 && $past == 1) {
1553 $meta_query[] = array(
1554 'key' => $this->META_END,
1555 'value' => current_time('mysql'),
1556 'compare' => '<=',
1557 //'type'=>'DATETIME'
1558 );
1559 }
1560 if ($date != '') {
1561 $date = date('Y-m-d', $date);
1562
1563 $meta_query = array(
1564 array(
1565 'key' => $this->META_END,
1566 'value' => $date . ' 00:00:00',
1567 'compare' => '>=',
1568 'type' => 'DATETIME'
1569 ),
1570 array(
1571 'key' => $this->META_START,
1572 'value' => $date . ' 23:59:59',
1573 'compare' => '<=',
1574 'type' => 'DATETIME'
1575 )
1576 );
1577 }
1578 // GEO
1579 if ($geo == 1) {
1580 $meta_query[] = array(
1581 'key' => $this->META_LAT,
1582 'value' => '',
1583 'compare' => '!='
1584 );
1585 $meta_query[] = array(
1586 'key' => $this->META_LONG,
1587 'value' => '',
1588 'compare' => '!='
1589 );
1590 $arg['meta_key'] = $this->META_LAT;
1591 $arg['orderby'] = 'meta_value';
1592 $arg['order'] = 'DESC';
1593 }
1594
1595 $arg['meta_query'] = $meta_query;
1596
1597 $query_md5 = 'eventpost_' . md5(var_export($requete, true));
1598 // Check if cache is activated
1599 if ($this->settings['cache'] == 1 && false !== ( $cached_events = get_transient($query_md5) )) {
1600 return apply_filters('eventpost_get_items', is_array($cached_events) ? $cached_events : array(), $requete, $arg);
1601 }
1602
1603 $events = apply_filters('eventpost_get', '', $requete, $arg);
1604 if ('' === $events) {
1605 global $wpdb;
1606 $query = new WP_Query($arg);
1607 $events = $wpdb->get_col($query->request);
1608 $this->pagination = array(
1609 'found_posts' => $query->found_posts,
1610 'max_num_pages' => $query->max_num_pages,
1611 );
1612 foreach ($events as $k => $post) {
1613 $event = $this->retreive($post);
1614 $events[$k] = $event;
1615 }
1616 }
1617 if ($this->settings['cache'] == 1){
1618 set_transient($query_md5, $events, 5 * MINUTE_IN_SECONDS);
1619 }
1620 return apply_filters('eventpost_get_items', $events, $requete, $arg);
1621 }
1622
1623 /**
1624 * Checks if the given event is in the future or not
1625 *
1626 * @param object $event
1627 * @param boolean $exact Future status has to be calculated against time or entire day
1628 * @return boolean
1629 */
1630 function is_future($event, $exact=false){
1631 $match = current_time('timestamp');
1632 // if EXACT is false, end date is set to begining of the current day
1633 if(!$exact){
1634 $match = mktime(0, 0, 0, date('m', $match), date('d', $match), date('Y', $match));
1635 }
1636 return ($event->time_end >= $match);
1637 }
1638
1639 /**
1640 * Checks if the given event is completed or not
1641 *
1642 * @param object $event
1643 * @param boolean $exact Past status has to be calculated against time or entire day
1644 * @return boolean
1645 */
1646 function is_past($event, $exact=false){
1647 $match = current_time('timestamp');
1648 // if EXACT is false or full day event, end date is set to end of the current day
1649 if(!$exact || ( date('H:i:s', $event->time_start) == '00:00:00' && date('H:i:s', $event->time_end) == '00:00:00' )){
1650 $match = mktime(23, 59, 59, date('m', $match), date('d', $match), date('Y', $match));
1651 }
1652 return ($event->time_end < $match);
1653 }
1654
1655 /**
1656 * Checks if an event is online
1657 * @param $event
1658 * @return boolean
1659 */
1660 function is_online($event){
1661 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OnlineEventAttendanceMode')));
1662 }
1663
1664 /**
1665 * Checks if an event is offline
1666 * @param $event
1667 * @return boolean
1668 */
1669 function is_offline($event){
1670 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OfflineEventAttendanceMode')));
1671 }
1672
1673
1674 /**
1675 *
1676 * @param object $event
1677 * @return object
1678 */
1679 public function retreive($event = null) {
1680 global $EventPost_cache;
1681 $ob = get_post($event);
1682 if(is_object($ob) && $ob->start){
1683 return $ob;
1684 }
1685 if(is_object($ob) && isset($EventPost_cache[$ob->ID])){
1686 return $EventPost_cache[$ob->ID];
1687 }
1688 $ob->start = get_post_meta($ob->ID, $this->META_START, true);
1689 $ob->end = get_post_meta($ob->ID, $this->META_END, true);
1690 if (!$this->dateisvalid($ob->start)){
1691 $ob->start = '';
1692 }
1693 if (!$this->dateisvalid($ob->end)){
1694 $ob->end = '';
1695 }
1696 $ob->root_ID = $ob->ID;
1697 $ob->time_start = !empty($ob->start) ? strtotime($ob->start) : '';
1698 $ob->time_end = !empty($ob->end) ? strtotime($ob->end) : '';
1699 $ob->virtual_location = get_post_meta($ob->ID, $this->META_VIRTUAL_LOCATION, true);
1700 $ob->address = get_post_meta($ob->ID, $this->META_ADD, true);
1701 $ob->lat = get_post_meta($ob->ID, $this->META_LAT, true);
1702 $ob->long = get_post_meta($ob->ID, $this->META_LONG, true);
1703 $ob->attendance_mode = (null != $att_mod = get_post_meta($ob->ID, $this->META_ATTENDANCE_MODE, true)) ? $att_mod : array_keys($this->attendance_modes)[0];
1704 $ob->status = (null != $status = get_post_meta($ob->ID, $this->META_STATUS, true)) ? $status : array_keys($this->statuses)[0];
1705 $ob->color = $this->get_post_color($ob->ID);
1706 $ob->icon = $this->get_post_icon($ob->ID);
1707 $ob->categories = get_the_category($ob->ID);
1708 $ob->permalink = get_permalink($ob->ID);
1709 $ob->blog_id = get_current_blog_id();
1710
1711 $EventPost_cache[$ob->ID] = apply_filters('eventpost_retreive', $ob);
1712 return $EventPost_cache[$ob->ID];
1713 }
1714
1715 /**
1716 *
1717 * @param mixte $_term
1718 * @param string $taxonomy
1719 * @param string $post_type
1720 */
1721 public function retreive_term($_term=null, $taxonomy='category', $post_type='post') {
1722 $term = get_term($_term, $taxonomy);
1723
1724 if(!$term){
1725 return $term;
1726 }
1727
1728 $term->start = $term->end = $term->time_start = $term->time_end = Null;
1729
1730 $request = array(
1731 'post_type'=>$post_type,
1732 'tax_name'=>$term->taxonomy,
1733 'tax_term'=>$term->slug,
1734 'future'=>true,
1735 'past'=>true,
1736 'nb'=>-1,
1737 'order'=>'ASC'
1738 );
1739
1740 $events = $this->get_events($request);
1741
1742 $term->events_count = count($events);
1743 if($term->events_count){
1744 $term->start = $events[0]->start;
1745 $term->time_start = $events[0]->time_start;
1746 $term->end = $events[$term->events_count-1]->end;
1747 $term->time_end = $events[$term->events_count-1]->time_end;
1748 }
1749
1750 $request['order']='DESC';
1751 $request['nb']=1;
1752 $request['orderbykey']=$this->META_END;
1753 $events = $this->get_events($request);
1754 if(count($events)){
1755 $term->end = $events[0]->end;
1756 $term->time_end = $events[0]->time_end;
1757 }
1758
1759 return $term;
1760
1761 }
1762
1763 /** ADMIN ISSUES * */
1764
1765 /**
1766 * add custom boxes in posts edit page
1767 */
1768 public function add_custom_box() {
1769 foreach($this->settings['posttypes'] as $posttype){
1770 add_meta_box(
1771 'event_post_date',
1772 __('Event date', 'event-post'),
1773 array(&$this, 'inner_custom_box_date'),
1774 $posttype,
1775 apply_filters('eventpost_add_custom_box_position', $this->settings['adminpos'], $posttype),
1776 'core',
1777 array(
1778 '__block_editor_compatible_meta_box' => true,
1779 )
1780 );
1781 add_meta_box(
1782 'event_post_loc',
1783 __('Location', 'event-post'),
1784 array(&$this, 'inner_custom_box_loc'),
1785 $posttype,
1786 apply_filters('eventpost_add_custom_box_position', $this->settings['adminpos'], $posttype),
1787 'core',
1788 array(
1789 '__block_editor_compatible_meta_box' => true,
1790 )
1791 );
1792 do_action('eventpost_add_custom_box', $posttype);
1793 }
1794 }
1795 /**
1796 * display the date custom box
1797 */
1798 public function inner_custom_box_date() {
1799
1800
1801
1802 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1803 $post_id = get_the_ID();
1804 $event = $this->retreive($post_id);
1805 $start_date = $event->start;
1806 $end_date = $event->end;
1807 $eventcolor = $event->color;
1808 $eventicon = $event->icon;
1809
1810 $language = get_bloginfo('language');
1811 if (strpos($language, '-') > -1) {
1812 $language = strtolower(substr($language, 0, 2));
1813 }
1814 $colors = $this->get_colors();
1815 include (plugin_dir_path(__FILE__) . 'views/admin/custombox-date.php');
1816 do_action ('eventpost_custom_box_date', $event);
1817 }
1818 /**
1819 * displays the location custom box
1820 */
1821 public function inner_custom_box_loc($post) {
1822 $event = $this->retreive($post);
1823 include (plugin_dir_path(__FILE__) . 'views/admin/custombox-location.php');
1824 do_action ('eventpost_custom_box_loc', $event);
1825 $this->load_map_scripts();
1826 }
1827
1828 public function icon_color_fields($item_id, $meta_color,$value_color,$meta_icon,$value_icon ){
1829 ?>
1830 <div class="eventpost-misc-pub-section event-color-section">
1831 <span class="screen-reader-text"><?php _e('Color:', 'event-post'); ?></span>
1832
1833 <input class="color-field-post eventpost-colorpicker"
1834 type="text"
1835 name="<?php echo $meta_color; ?>"
1836 value="<?php echo $value_color; ?>"
1837 id="color-field<?php echo $item_id; ?>"/>
1838
1839 <select style="font-family : dashicons;" class="eventpost-iconpicker" name="<?php echo $meta_icon; ?>">
1840 <option value=""><?php echo __('None','event-post') ?></option>
1841 <?php
1842 foreach($this->DashIcons->icons as $class => $unicode){
1843 ?>
1844 <option value="<?php echo $class ?>" <?php selected($value_icon, $class, true); ?>>&#x<?php echo $unicode ?>; <?php echo $class ?></option>
1845 <?php
1846 }
1847 ?>
1848 </select>
1849 <div class="custom-marker-container">
1850 <p><?php echo __('An image was found in your custom folder for this color', 'event-post')?> <span class="color-hex"></span> </p>
1851 <img src="" class="image-marker">
1852 </div>
1853 </div>
1854
1855
1856 <?php
1857 }
1858
1859 /**
1860 *
1861 * @param string $column_name
1862 * @param boolean $bulk
1863 */
1864 function quick_edit( $column_name, $post_type, $bulk=false) {
1865
1866 if ($bulk) {
1867 static $eventpostprintNonceBulk = TRUE;
1868 if ($eventpostprintNonceBulk) {
1869 $eventpostprintNonceBulk = FALSE;
1870 }
1871 $fields = $this->bulk_edit_fields;
1872 echo '<input type="hidden" name="eventpost-bulk-editor" id="eventpost-bulk-editor" value="eventpost-bulk-editor">';
1873 }
1874 else {
1875 static $eventpostprintNonce = TRUE;
1876 if ($eventpostprintNonce) {
1877 $eventpostprintNonce = FALSE;
1878 }
1879 $fields = $this->quick_edit_fields;
1880 }
1881 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1882 if(isset($fields[$column_name])): ?>
1883 <fieldset class="inline-edit-col-left inline-edit-<?php echo $column_name; ?>">
1884 <div class="inline-edit-group">
1885 <?php foreach ($fields[$column_name] as $fieldname=>$fieldlabel): ?>
1886 <fieldset class="inline-edit-col inline-edit-<?php echo $fieldname; ?>">
1887 <div class="inline-edit-col column-<?php echo $fieldname; ?>">
1888 <label class="inline-edit-group">
1889 <span class="title"><?php echo $fieldlabel; ?></span>
1890 <span class="input-text-wrap">
1891 <?php echo $this->inline_field($fieldname, $bulk); ?>
1892 </span>
1893 </label>
1894 </div>
1895 </fieldset>
1896 <?php endforeach; ?>
1897 </div>
1898 </fieldset>
1899 <?php endif;
1900 }
1901
1902 /**
1903 *
1904 * @param type $fieldname
1905 * @return type
1906 */
1907 function inline_field($fieldname, $bulk){
1908 return apply_filters('eventpost_inline_field', '<input name="'.$fieldname.'" class="eventpost-inline-'.$fieldname.'" value="" type="text">', $fieldname, $bulk);
1909 }
1910
1911 function inline_field_color($html, $fieldname, $bulk){
1912 if($fieldname==$this->META_COLOR){
1913 $html='';
1914 if($bulk){
1915 $html.= '<span class="eventpost-bulk-colorpicker-button link">'.__('No Change', 'event-post').'</span>';
1916 }
1917 $html .= '
1918
1919 <input class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'" type="text" name="'.$fieldname.'" >';
1920 }
1921 return $html;
1922 }
1923 function inline_field_icon($html, $fieldname, $bulk){
1924 if($fieldname==$this->META_ICON){
1925 if($bulk){
1926 $html.= '<span class="eventpost-bulk-icon-button link">'.__('No Change', 'event-post').'</span>';
1927 }
1928 $html = '<select class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'"
1929 type="text"
1930 name="'.$fieldname.'"
1931 style="font-family : dashicons">
1932 <option value="">'.__("None", 'event-post').'</option>';
1933 foreach($this->DashIcons->icons as $class => $unicode){
1934 $html .= '<option value="'.$class.'">&#x'.$unicode.'; '.$class.'</option>';
1935
1936 }
1937 $html .= '</select>';
1938
1939 }
1940 return $html;
1941 }
1942
1943
1944 /**
1945 *
1946 * @param type $column_name
1947 * @param type $post_type
1948 */
1949 function bulk_edit($column_name, $post_type){
1950 $this->quick_edit($column_name, $post_type, true);
1951 }
1952
1953 /**
1954 * Saves data from quick-edit via `wp_ajax_inline-save` action
1955 * @return void
1956 */
1957 function inline_save(){
1958 $post_id = filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT);
1959 $this->save_postdata($post_id);
1960 }
1961 /**
1962 * When the post is saved, saves our custom data
1963 * @param int $post_id
1964 * @return void
1965 */
1966 public function save_postdata($post_id) {
1967 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
1968 return;
1969 }
1970
1971 if (!wp_verify_nonce(filter_input(INPUT_POST, 'eventpost_nonce', FILTER_SANITIZE_STRING), plugin_basename(__FILE__))){
1972 return;
1973 }
1974
1975 // Clean color or no color
1976 if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR, FILTER_SANITIZE_STRING)) {
1977 update_post_meta($post_id, $this->META_COLOR, $color);
1978 }
1979 // Clean color or no color
1980 if (false !== $icon = filter_input(INPUT_POST, $this->META_ICON, FILTER_SANITIZE_STRING)) {
1981 update_post_meta($post_id, $this->META_ICON, $icon);
1982 }
1983 if (false !== $attendance_mode = filter_input(INPUT_POST, $this->META_ATTENDANCE_MODE, FILTER_SANITIZE_STRING)) {
1984 update_post_meta($post_id, $this->META_ATTENDANCE_MODE, $attendance_mode);
1985 }
1986 if (false !== $status = filter_input(INPUT_POST, $this->META_STATUS, FILTER_SANITIZE_STRING)) {
1987 update_post_meta($post_id, $this->META_STATUS, $status);
1988 }
1989 if (false !== $virtual_location = filter_input(INPUT_POST, $this->META_VIRTUAL_LOCATION, FILTER_SANITIZE_URL)) {
1990 update_post_meta($post_id, $this->META_VIRTUAL_LOCATION, $virtual_location);
1991 }
1992 // Clean date or no date
1993 if ((false !== $start = filter_input(INPUT_POST, $this->META_START, FILTER_SANITIZE_STRING)) &&
1994 (false !== $end = filter_input(INPUT_POST, $this->META_END, FILTER_SANITIZE_STRING)) &&
1995 '' != $start &&
1996 '' != $end) {
1997 update_post_meta($post_id, $this->META_START, substr($start,0,16).':00');
1998 update_post_meta($post_id, $this->META_END, substr($end,0,16).':00');
1999 }
2000 else {
2001 delete_post_meta($post_id, $this->META_START);
2002 delete_post_meta($post_id, $this->META_END);
2003 }
2004
2005 // Clean location or no location
2006 if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT, FILTER_SANITIZE_STRING)) &&
2007 (false !== $long = filter_input(INPUT_POST, $this->META_LONG, FILTER_SANITIZE_STRING)) &&
2008 '' != $lat &&
2009 '' != $long) {
2010 update_post_meta($post_id, $this->META_ADD, filter_input(INPUT_POST, $this->META_ADD, FILTER_SANITIZE_STRING));
2011 update_post_meta($post_id, $this->META_LAT, $lat);
2012 update_post_meta($post_id, $this->META_LONG, $long);
2013 }
2014 else {
2015 delete_post_meta($post_id, $this->META_ADD);
2016 delete_post_meta($post_id, $this->META_LAT);
2017 delete_post_meta($post_id, $this->META_LONG);
2018 }
2019
2020 $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
2021 }
2022
2023 /**
2024 * Saves data from bulk-edit
2025 * Should be used via AJAX
2026 *
2027 * outputs JSON
2028 * @return void
2029 */
2030 function save_bulkdatas() {
2031 $current_post_type = isset($_POST['post_type']) ? $_POST['post_type'] : 'post';
2032 if (in_array($current_post_type, $this->settings['posttypes'])) {
2033 $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
2034 if (!empty($post_ids) && is_array($post_ids)) {
2035 foreach ($this->bulk_edit_fields as $sets) {
2036 foreach ($sets as $fieldname => $fieldlabel) {
2037 if ((false != $value = filter_input(INPUT_POST, $fieldname))) {
2038 foreach ($post_ids as $post_id) {
2039 update_post_meta($post_id, $fieldname, $value);
2040 }
2041 }
2042 }
2043 }
2044 }
2045 wp_send_json(true);
2046 exit;
2047 }
2048 wp_send_json(false);
2049 }
2050
2051 /**
2052 *
2053 * @param string $date
2054 * @param string $cat
2055 * @param boolean $display
2056 * @return boolean
2057 */
2058 public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='',$tax_name='' ,$tax_term='') {
2059 $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true,'tax_name' => $tax_name ,'tax_term' => $tax_term));
2060 $nb = count($events);
2061 $ret = "";
2062 if(!$display && !$nb){
2063 $ret = date('j', $date);
2064 }
2065 if($nb){
2066 if ($display || $title) {
2067 $ret='<ul>';
2068 foreach ($events as $event) {
2069 if ($this->settings['emptylink'] == 0 && empty($event->post_content)) {
2070 $event->guid = '#';
2071 }
2072 $ret.='<li>'
2073 . '<a href="' . $event->permalink . '" title="'.esc_attr(sprintf(__('View event: %s', 'event-post'), $event->post_title)).'">'
2074 . '<h4>' . $event->post_title . '</h4>'
2075 .$this->get_single($event)
2076 . (!empty($thumbnail) ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->ID, $thumbnail) . '</span>' : '')
2077 .'</a>'
2078 . '</li>';
2079 }
2080 $ret.='</ul>';
2081 }
2082 if ($display) {
2083 // return $ret;
2084 }
2085 elseif($title) {
2086 $ret = '<span '.($colored?' style="color:#'.$events[0]->color.'"':'').'>'.date('j', $date).'</span>'.$ret;
2087 }
2088 else {
2089 $ret = '<button data-event="'. $tax_term .'" data-date="' . date('Y-m-d', $date).'"'
2090 .' class="'.apply_filters( 'event_post_class_calendar_link', 'eventpost_cal_link' ).'"'.($colored?' style="background-color:#'.$events[0]->color.'"':'')
2091 .' 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']))).'"'
2092 .'>'
2093 . date('j', $date)
2094 . '</button>';
2095 }
2096 }
2097
2098 return apply_filters('eventpost_display_caldate', $ret, $events, $date, $cat ,$display ,$colored ,$thumbnail ,$title ,$tax_name ,$tax_term );
2099 }
2100
2101
2102 /**
2103 * @param array $atts
2104 * @filter eventpost_params
2105 * @return string
2106 */
2107 public function calendar($atts) {
2108 extract(shortcode_atts(apply_filters('eventpost_params', array(
2109 'date' => date('Y-n'),
2110 'cat' => '',
2111 'mondayfirst' => 0, //1 : weeks starts on monday
2112 'datepicker' => 1,
2113 'colored' => 1,
2114 'display_title'=>0,
2115 'tax_name' => '',
2116 'tax_term' => '',
2117 'thumbnail'=>'',
2118 ), 'calendar'), $atts));
2119
2120 if($date && !preg_match('#[0-9][0-9][0-9][0-9]-[0-9][0-9]?#i', $date)){
2121 $date = date('Y-n', strtotime($date));
2122 }
2123 if(!$date){
2124 $date = date('Y-n');
2125 }
2126
2127 $annee = substr($date, 0, 4);
2128 $mois = substr($date, 5);
2129
2130 $time = mktime(0, 0, 0, $mois, 1, $annee);
2131
2132 $prev_year = strtotime('-1 Year', $time);
2133 $next_year = strtotime('+1 Year', $time);
2134 $prev_month = strtotime('-1 Month', $time);
2135 $next_month = strtotime('+1 Month', $time);
2136
2137 $JourMax = date("t", $time);
2138 $NoJour = -date("w", $time);
2139 if ($mondayfirst == 0) {
2140 $NoJour +=1;
2141 } else {
2142 $NoJour +=2;
2143 $this->Week[] = array_shift($this->Week);
2144 }
2145 if ($NoJour > 0 && $mondayfirst == 1) {
2146 $NoJour -=7;
2147 }
2148 $ret = '<table class="event-post-calendar-table">'
2149 . '<caption class="screen-reader-text">'
2150 . __('A calendar of events', 'event-post')
2151 . '</caption>';
2152 $ret.='<thead><tr><th colspan="7">';
2153 if ($datepicker == 1) {
2154 $ret.='<div class="eventpost-calendar-header">';
2155 $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">';
2156 $ret.=$annee;
2157 $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>';
2158 $ret.='<span class="eventpost-cal-month"><button data-date="' . date('Y-n', $prev_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $prev_month)).'" class="eventpost_cal_bt eventpost-cal-bt-prev">&laquo;</button><span class="eventpost-cal-header-text">';
2159 $ret.=$this->NomDuMois[abs($mois)];
2160 $ret.='</span><button data-date="' . date('Y-n', $next_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $next_month)).'" class="eventpost_cal_bt eventpost-cal-bt-next">&raquo;</button> </span>';
2161 $ret.='<span class="eventpost-cal-today"><button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button></span>';
2162 $ret.='</div>';
2163 }
2164 $ret.='</th></tr><tr class="event_post_cal_days">';
2165 for ($w = 0; $w < 7; $w++) {
2166 $ret.='<th scope="col">' . strtoupper(substr($this->Week[$w], 0, 1)) . '</th>';
2167 }
2168 $ret.='</tr>';
2169 $ret.='</thead>';
2170
2171 $ret.='<tbody>';
2172 $sqldate = date('Y-m', $time);
2173 $cejour = date('Y-m-d');
2174 for ($semaine = 0; $semaine <= 5; $semaine++) { // 6 semaines par mois
2175 $tr_row_content ='';
2176 for ($journee = 0; $journee <= 6; $journee++) { // 7 jours par semaine
2177 if ($NoJour > 0 && $NoJour <= $JourMax) { // si le jour est valide a afficher
2178 $td = '<td class="event_post_day">';
2179 if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour == $cejour) {
2180 $td = '<td class="event_post_day_now">';
2181 }
2182 if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour < $cejour){
2183 $td = '<td class="event_post_day_over">'; // Patch ahf
2184 }
2185 $tr_row_content.=$td;
2186 $tr_row_content.= $this->display_caldate(mktime(0, 0, 0, $mois, $NoJour, $annee), $cat, false, $colored, $thumbnail, $display_title ,$tax_name ,$tax_term);
2187 $tr_row_content.='</td>';
2188 } else {
2189 $tr_row_content.='<td></td>';
2190 }
2191 $NoJour ++;
2192 }
2193 if($tr_row_content){
2194 $ret.='<tr>'.$tr_row_content.'</tr>';
2195 }
2196
2197 }
2198 $ret.='</tbody></table>';
2199 return $ret;
2200 }
2201
2202 /**
2203 * echoes a list of event, should be called via AJAX
2204 *
2205 * @return void
2206 */
2207 public function ajaxlist(){
2208 echo $this->list_events(array(
2209 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2210 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2211 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2212 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2213 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2214 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2215 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2216 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2217 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2218 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2219 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2220 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2221 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2222 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2223 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2224 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2225 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2226 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2227 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2228 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2229 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2230 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2231 ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2232 exit;
2233 }
2234
2235 /**
2236 * echoes a list of event, should be called via AJAX
2237 *
2238 * @return void
2239 */
2240 public function ajaxTimeline(){
2241 echo $this->list_events(array(
2242 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2243 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2244 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2245 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2246 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2247 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2248 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2249 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2250 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2251 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2252 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2253 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2254 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2255 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2256 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2257 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2258 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2259 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2260 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2261 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2262 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2263 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2264 ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2265 exit;
2266 }
2267 /**
2268 * echoes next page of events, should be called via AJAX
2269 *
2270 * @return void
2271 */
2272 public function ajaxGetNextPage(){
2273 $response = [
2274 "success" => false,
2275 "next_query" => false,
2276 ];
2277 if(isset($_POST['query'])){
2278 parse_str($_POST['query'],$query);
2279 foreach($query as $key => $value){
2280 $query[$key] = esc_attr($value);
2281 }
2282 if(isset($_POST['paged'])){
2283 $query["paged"] = esc_attr($_POST['paged']);
2284 }else{
2285 $response['message'] = __('Page number missing');
2286 }
2287 $query['container_schema'] = $this->timeline_shema['container'];
2288 $query['item_schema'] = $this->timeline_shema['item'];
2289 $html = $this->list_events($query,'event_timeline','events_only');
2290 if($html == ""){
2291 $response['message'] = __('No more to load');
2292 }else{
2293 $query["paged"] = $query["paged"] + 1;
2294 $next_html = $this->list_events($query,'event_timeline','events_only');
2295 $response = [
2296 "success" => true,
2297 "html" => $html,
2298 "next_query" => $next_html == "" ? false : true,
2299 ];
2300 }
2301 }else{
2302 $response['message'] = __('Query missing');
2303 }
2304 wp_send_json($response);
2305 exit;
2306 }
2307
2308 /**
2309 * echoes the content of the calendar in ajax context
2310 * @return void
2311 */
2312 public function ajaxcal() {
2313 $method = isset($_GET['action']) ? INPUT_GET : INPUT_POST;
2314 echo $this->calendar(array(
2315 'date' => esc_attr(FILTER_INPUT($method, 'date')),
2316 'cat' => esc_attr(FILTER_INPUT($method, 'cat')),
2317 'mondayfirst' => esc_attr(FILTER_INPUT($method, 'mf')),
2318 'datepicker' => esc_attr(FILTER_INPUT($method, 'dp')),
2319 'colored' => esc_attr(FILTER_INPUT($method, 'color')),
2320 'display_title' => esc_attr(FILTER_INPUT($method, 'display_title')),
2321 'thumbnail' => esc_attr(FILTER_INPUT($method, 'thumbnail')),
2322 'tax_name' => esc_attr(FILTER_INPUT($method, 'tax_name')),
2323 'tax_term' => esc_attr(FILTER_INPUT($method, 'tax_term')),
2324 ));
2325 exit();
2326 }
2327
2328 /**
2329 * echoes the date of the calendar in ajax context
2330 */
2331 public function ajaxdate() {
2332 echo $this->display_caldate(
2333 strtotime(esc_attr(FILTER_INPUT(INPUT_GET, 'date'))),
2334 esc_attr(FILTER_INPUT(INPUT_GET, 'cat')),
2335 true,
2336 esc_attr(FILTER_INPUT(INPUT_GET, 'color')),
2337 esc_attr(FILTER_INPUT(INPUT_GET, 'thumbnail')),
2338 esc_attr(FILTER_INPUT(INPUT_GET, 'display_title')),
2339 esc_attr(FILTER_INPUT(INPUT_GET, 'tax_name')),
2340 esc_attr(FILTER_INPUT(INPUT_GET, 'tax_term'))
2341 );
2342 exit();
2343 }
2344
2345 /**
2346 * echoes a date in ajax context
2347 */
2348 public function HumanDate() {
2349 if (isset($_REQUEST['date']) && !empty($_REQUEST['date'])) {
2350 $date = strtotime($_REQUEST['date']);
2351 echo $this->human_date($date, $this->settings['dateformat']).(date('H:i', $date)=='00:00' ? '' : ' '. date($this->settings['timeformat'], $date));
2352 exit();
2353 }
2354 }
2355
2356 /**
2357 * Displays a search form
2358 *
2359 * @param type $atts
2360 * @return type
2361 */
2362 public function search($atts) {
2363 $params = shortcode_atts(apply_filters('eventpost_params', array(
2364 'dates' => true,
2365 'q' => true,
2366 'tax' => false,
2367 ), 'search'), $atts);
2368 $this->list_id++;
2369
2370 $list_id = $this->list_id;
2371 $q = (false !== $q = filter_input(INPUT_GET, 'q')) ? $q : '';
2372 $from = (false !== $from = filter_input(INPUT_GET, 'from')) ? $from : '';
2373 $to = (false !== $to = filter_input(INPUT_GET, 'to')) ? $to : '';
2374 $tax = (false !== $tax = filter_input(INPUT_GET, 'tax')) ? $tax : '';
2375
2376 $cleaned_from = $this->date_cleanup($from);
2377 $cleaned_to = $this->date_cleanup($to);
2378 if(empty($cleaned_from)){
2379 $from=false;
2380 }
2381 if(empty($cleaned_to)){
2382 $to=false;
2383 }
2384
2385 // Search form
2386 $this->admin_scripts(null, true);
2387 wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, filemtime( "/$block_js" ));
2388 include (plugin_dir_path(__FILE__) . 'views/search-form.php');
2389
2390 // Results
2391 if ($list_id == filter_input(INPUT_GET, 'evenpost_search')) {
2392 $arg = array(
2393 'post_type' => $this->settings['posttypes'],
2394 'meta_key' => $this->META_START,
2395 'orderby' => 'meta_value',
2396 'order' => 'ASC',
2397 's' => $q
2398 );
2399 if ($tax) {
2400 $arg['cat'] = $tax;
2401 }
2402
2403 if ($from || $to) {
2404
2405 $arg['meta_query'] = array();
2406 if ($from) {
2407 $arg['meta_query'][] = array(
2408 'key' => $this->META_START,
2409 'value' => $from,
2410 'compare' => '>=',
2411 'type' => 'DATETIME'
2412 );
2413 }
2414 if ($to) {
2415 $arg['meta_query'][] = $meta_query = array(
2416 array(
2417 'key' => $this->META_END,
2418 'value' => $to,
2419 'compare' => '<=',
2420 'type' => 'DATETIME'
2421 ),
2422 );
2423 }
2424 }
2425 $events = new WP_Query($arg);
2426 include (plugin_dir_path(__FILE__) . 'views/search-results.php');
2427 wp_reset_query();
2428 }
2429 }
2430
2431 /**
2432 * AJAX Get lat long from address
2433 */
2434 public function GetLatLong() {
2435 if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
2436 // verifier le cache
2437 $q = $_REQUEST['q'];
2438 header('Content-Type: application/json');
2439 $transient_name = 'eventpost_osquery_' . $q;
2440 $val = get_transient($transient_name);
2441 if (false === $val || empty($val) || !is_string($val)) {
2442 $language = get_bloginfo('language');
2443 if (strpos($language, '-') > -1) {
2444 $language = strtolower(substr($language, 0, 2));
2445 }
2446 $remote_val = wp_safe_remote_request('http://nominatim.openstreetmap.org/search?q=' . urlencode($q) . '&format=json&accept-language=' . $language);
2447 if(json_decode($remote_val['body'])){
2448 $val = $remote_val['body'];
2449 }
2450 set_transient($transient_name, $val, 30 * DAY_IN_SECONDS);
2451 }
2452 echo $val;
2453 exit();
2454 }
2455 }
2456
2457 /**
2458 * alters columns
2459 * @param array $defaults
2460 * @return array
2461 * @filter eventpost_columns_head
2462 */
2463 public function columns_head($defaults) {
2464 $defaults['event'] = __('Event', 'event-post');
2465 $defaults['location'] = __('Location', 'event-post');
2466 return apply_filters('eventpost_columns_head', $defaults);
2467 }
2468
2469 /**
2470 * echoes content of a row in a given column
2471 * @param string $column_name
2472 * @param int $post_id
2473 * @action eventpost_columns_content
2474 */
2475 public function columns_content($column_name, $post_id) {
2476 if ($column_name == 'location') {
2477 $lat = get_post_meta($post_id, $this->META_LAT, true);
2478 $lon = get_post_meta($post_id, $this->META_LONG, true);
2479
2480 if (!empty($lat) && !empty($lon)) {
2481 add_thickbox();
2482 $color = $this->get_post_color($post_id, $this->settings['default_color'], true);
2483 $icon = $this->get_post_icon($post_id, $this->settings['default_icon'], true);
2484 if ($color == ''){
2485 $color = '777777';
2486 }
2487 if ($icon == ''){
2488 $icon = 'location';
2489 }
2490 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">'
2491 . '<i class="dashicons dashicons-'.$icon.'" style="color:#'.$color.';"></i>'
2492 . '<span class="screen-reader-text">'.__('View on a map', 'event-post').'</span>'
2493 . get_post_meta($post_id, $this->META_ADD, true)
2494 . '</a> ';
2495 }
2496 $this->column_edit_hidden_fields($post_id, 'location');
2497 }
2498 if ($column_name == 'event') {
2499 echo $this->print_date($post_id, false);
2500 $this->column_edit_hidden_fields($post_id, 'event');
2501 }
2502 do_action('eventpost_columns_content', $column_name, $post_id);
2503 }
2504
2505 function column_edit_hidden_fields($post_id, $set){
2506 $event = $this->retreive($post_id);
2507 echo '<div class="hidden">';
2508 foreach($this->quick_edit_fields[$set] as $fieldname=>$fieldlabel){
2509 echo'<span class="inline-edit-value '.$fieldname.'">'.esc_attr($event->$fieldname).'</span>';
2510 }
2511 echo '</div>';
2512 }
2513
2514 /** ADMIN PAGES **/
2515
2516 /**
2517 * adds items to the native "right now" dashboard widget
2518 * @param array $elements
2519 * @return array
2520 */
2521 public function dashboard_right_now($elements){
2522 $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
2523 $nb_geo = count($this->get_events(array('future'=>1, 'past'=>1, 'geo'=>1, 'nb'=>-1)));
2524 if($nb_date){
2525 array_push($elements, '<i class="dashicons dashicons-calendar"></i> <i href="edit.php?post_type=post">'.sprintf(__('%d Events','event-post'), $nb_date)."</i>");
2526 }
2527 if($nb_geo){
2528 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>");
2529 }
2530 return $elements;
2531 }
2532
2533 /*
2534 * feed
2535 * generate ICS or VCS files from a category
2536 */
2537
2538 /**
2539 *
2540 * @param timestamp $timestamp
2541 * @return string
2542 */
2543 public function ics_date($timestamp){
2544 return date("Ymd",$timestamp).'T'.date("His",$timestamp);
2545 }
2546
2547 public function get_gmt_offset(){
2548 $gmt_offset = get_option('gmt_offset ');
2549 $codegmt = 0;
2550 if ($gmt_offset != 0 && substr($gmt_offset, 0, 1) != '-' && substr($gmt_offset, 0, 1) != '+') {
2551 $codegmt = $gmt_offset * -1;
2552 $gmt_offset = '+' . $gmt_offset;
2553 }
2554 if(abs($gmt_offset < 10)){
2555 $gmt_offset = substr($gmt_offset, 0, 1).'0'.substr($gmt_offset, 1);
2556 }
2557 return $gmt_offset;
2558 }
2559
2560 private function generate_ics($event_id, $format){
2561 $export_file = plugin_dir_path(__FILE__).'inc/export/'.$format.'.php';
2562 if(is_numeric($event_id) && file_exists($export_file)){
2563 $event = $this->retreive($event_id);
2564 include $export_file;
2565 exit;
2566 }
2567 }
2568
2569 public function parse_request(){
2570 global $wp;
2571 if (preg_match('#^event-feed#i', $wp->request, $match)) {
2572 $this->feed();
2573 exit;
2574 }
2575 if (preg_match('#^eventpost/([0-9]*)\.(ics|vcs)#i', $wp->request, $match)) {
2576 $this->generate_ics($match[1], $match[2]);
2577 }
2578 }
2579
2580 public function export(){
2581 if(false !== $event_id=\filter_input(INPUT_GET, 'event_id',FILTER_SANITIZE_NUMBER_INT)){
2582 $format = \filter_input(INPUT_GET, 'format',FILTER_SANITIZE_STRING);
2583 $this->generate_ics($event_id, $format);
2584 }
2585 }
2586
2587
2588 /**
2589 * outputs an ICS document
2590 */
2591 public function feed(){
2592 if(false !== $cat=\filter_input(INPUT_GET, 'cat',FILTER_SANITIZE_STRING)){
2593 $vtz = get_option('timezone_string');
2594 $gmt = $this->get_gmt_offset();
2595 date_default_timezone_set($vtz);
2596 $separator = "\n";
2597
2598 header("content-type:text/calendar");
2599 header("Pragma: public");
2600 header("Expires: 0");
2601 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
2602 header("Cache-Control: public");
2603 header("Content-Disposition: attachment; filename=". str_replace('+','-',urlencode(get_option('blogname').'-'.$cat)).".ics;" );
2604
2605 $props = array();
2606
2607 // General
2608 $props[] = 'BEGIN:VCALENDAR';
2609 $props[] = 'PRODID://WordPress//Event-Post-V'. file_get_contents(('VERSION')).'//EN';
2610 $props[] = 'VERSION:2.0';
2611
2612 // Timezone
2613 if(!empty($vtz)){
2614 array_push($props,
2615 'BEGIN:VTIMEZONE',
2616 'TZID:'.$vtz,
2617 'BEGIN:DAYLIGHT',
2618 'TZOFFSETFROM:+0100',
2619 'TZOFFSETTO:'.($gmt).'00',
2620 'DTSTART:19700329T020000',
2621 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3',
2622 'END:DAYLIGHT',
2623 'BEGIN:STANDARD',
2624 'TZOFFSETFROM:'.($gmt).'00',
2625 'TZOFFSETTO:+0100',
2626 'TZNAME:CET',
2627 'DTSTART:19701025T030000',
2628 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
2629 'END:STANDARD',
2630 'END:VTIMEZONE'
2631 );
2632 }
2633
2634 // Events
2635 $events=$this->get_events(array('cat'=>$cat,'nb'=>-1));
2636 foreach ($events as $event) {
2637 if($event->time_start && $event->time_end){
2638 array_push($props,
2639 'BEGIN:VEVENT',
2640 'CREATED:'.$this->ics_date(strtotime($event->post_date)).'Z',
2641 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
2642 'SUMMARY:'.$event->post_title,
2643 'UID:'.md5(site_url()."_eventpost_".$event->ID),
2644 'LOCATION:'.str_replace(',','\,',$event->address),
2645 'DTSTAMP:'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2646 'DTSTART'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2647 'DTEND'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_end).(!empty($vtz)?'':'Z'),
2648 'DESCRIPTION:'.trim(chunk_split($event->post_excerpt."\\n\\n".$event->permalink, 60, "\n")),
2649 'END:VEVENT'
2650 );
2651 }
2652 }
2653
2654 // End
2655 $props[] = 'END:VCALENDAR';
2656
2657 echo implode($separator, $props);
2658 exit;
2659 }
2660 }
2661 }
2662