PluginProbe
Event Post / 5.6.1
Event Post v5.6.1
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.6.1, at eventpost.php

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