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

2,657 lines 87.8 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
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 $item_child_style = 'width : '.((100/$nb) - 2).'%;';
1291 $attributes .= ' data-nb="'.$nb.'" data-filter="'.http_build_query($atts).'" ';
1292 }
1293
1294 foreach ($events as $event) {
1295
1296 $class_item = array(
1297 $this->is_future($event) ? 'event_future' : 'event_past',
1298 'status-'.$event->status,
1299 'location-type-'.$event->attendance_mode,
1300 );
1301 $taxonomies= get_taxonomies('','names');
1302 $post_terms = [];
1303 $terms = wp_get_post_terms($event->ID, $taxonomies);
1304 foreach($terms as $term){
1305 $class_item[] = $term->taxonomy.'-'.$term->name;
1306 }
1307 if ($ep_settings['emptylink'] == 0 && empty($event->post_content)) {
1308 $event->permalink = '#' . $id . $this->list_id;
1309 }
1310 elseif(empty($event->permalink)){
1311 $event->permalink=$event->guid;
1312 }
1313 $html.=str_replace(
1314 apply_filters('eventpost_item_scheme_entities', array(
1315 '%child%',
1316 '%class%',
1317 '%color%',
1318 '%event_link%',
1319 '%event_thumbnail%',
1320 '%event_title%',
1321 '%event_date%',
1322 '%event_cat%',
1323 '%event_location%',
1324 '%event_excerpt%',
1325 '%style%',
1326 )), apply_filters('eventpost_item_scheme_values', array(
1327 $child,
1328 implode(' ', $class_item),
1329 $this->get_post_color($event->ID, $this->settings['default_color'],true),
1330 $event->permalink,
1331 $thumbnail == true ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->root_ID, !empty($thumbnail_size) ? $thumbnail_size : 'thumbnail', array('class' => 'attachment-thumbnail wp-post-image event_thumbnail')) . '</span>' : '',
1332 $event->post_title,
1333 $this->get_singledate($event, '', $context),
1334 $this->get_singlecat($event, '', $context),
1335 $this->get_singleloc($event, '', $context),
1336 $excerpt == true && $event->post_excerpt!='' ? '<span class="event_exerpt">'.$event->post_excerpt.'</span>' : '',
1337 $item_child_style,
1338 ), $event), $item_schema
1339 );
1340
1341 }
1342 if($id == 'event_geolist'){
1343 if($height==''){
1344 $height = '300px';
1345 }
1346 if($width==''){
1347 $width = '100%';
1348 }
1349 $attributes .= ' data-tile="'.$tile.'"
1350 data-width="'.$width.'"
1351 data-height="'.$height.'"
1352 data-zoom="'.$zoom.'"
1353 data-map_position="'.$map_position.'"
1354 data-latitude="'.$latitude.'"
1355 data-longitude="'.$longitude.'"
1356 data-pop_element_schema="'.$pop_element_schema.'"
1357 data-htmlPop_element_schema="'.esc_attr($htmlPop_element_schema).'"
1358 data-list="'.$list.'"
1359 data-disabled-interactions="';
1360 // add data-position avec ma variables
1361 foreach($this->map_interactions as $int_key=>$int_name){
1362 $attributes.=$atts[$int_key]==false ? $int_key.', ' : '';
1363 }
1364 $attributes.='" ';
1365 }
1366 $pagination = '';
1367 if($pages && $this->pagination){
1368 global $wp_rewrite;
1369 $paged = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1370 $pagination = paginate_links( array(
1371 'prev_text' => __('« Previous Events', 'event-post'),
1372 'next_text' => __('Next Events »', 'event-post'),
1373 'current' => $paged,
1374 'total' => $this->pagination['max_num_pages'],
1375 )
1376 );
1377 }
1378
1379 if($context == 'events_only'){
1380 $ret = $html;
1381 }else{
1382 $ret.=str_replace(
1383 array(
1384 '%type%',
1385 '%id%',
1386 '%class%',
1387 '%listid%',
1388 '%style%',
1389 '%attributes%',
1390 '%list%',
1391 '%pagination%',
1392 '%prev_arrow%',
1393 '%next_arrow%',
1394 '%number%'
1395 ), array(
1396 $type,
1397 $id,
1398 $class.($className ? ' '.$className : '').($id == 'event_geolist' && $list ? ' has-list list-'.$list : ' no-list'),
1399 $id . $this->list_id,
1400 (!empty($width) ? 'width:' . $width . ';' : '') . (!empty($height) ? 'height:' . $height . ';' : '') . $style,
1401 $attributes,
1402 $html,
1403 $pagination,
1404 $prev_arrow,
1405 $next_arrow
1406 ), $container_schema
1407 );
1408 }
1409
1410 }
1411 elseif(filter_input(INPUT_POST, 'action')=='bulk_do_shortcode'){
1412 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>';
1413 }
1414 return apply_filters('eventpost_listevents', $ret, $id.$this->list_id, $atts, $events, $context);
1415 }
1416
1417
1418 /**
1419 * get_events
1420 * @param array $atts
1421 * @filter eventpost_params
1422 * @filter eventpost_get_items
1423 * @return array of post_ids which are events
1424 */
1425 public function get_events($atts) {
1426 if(isset($atts['future'])){
1427 $atts['future'] = filter_var( $atts['future'], FILTER_VALIDATE_BOOLEAN);
1428 }
1429 if(isset($atts['past'])){
1430 $atts['past'] = filter_var( $atts['past'], FILTER_VALIDATE_BOOLEAN);
1431 }
1432 if(isset($atts['geo'])){
1433 $atts['geo'] = filter_var( $atts['geo'], FILTER_VALIDATE_BOOLEAN);
1434 }
1435 if(isset($atts['pages'])){
1436 $atts['pages'] = filter_var( $atts['pages'], FILTER_VALIDATE_BOOLEAN);
1437 }
1438
1439
1440
1441 $requete = (shortcode_atts(apply_filters('eventpost_params', array(
1442 'nb' => 5,
1443 'future' => true,
1444 'past' => false,
1445 'geo' => 0,
1446 'cat' => '',
1447 'tag' => '',
1448 'date' => '',
1449 'orderby' => 'meta_value',
1450 'orderbykey' => $this->META_START,
1451 'order' => 'ASC',
1452 'tax_name' => '',
1453 'tax_term' => '',
1454 'paged' => 1,
1455 'post_type'=> $this->settings['posttypes']
1456 ), 'get_events'), $atts));
1457 if(!isset($requete['paged']) || $requete['paged'] == ""){
1458 $requete['paged'] = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1459 }
1460 extract($requete);
1461 wp_reset_query();
1462
1463
1464 $arg = array(
1465 'post_status' => 'publish',
1466 'post_type' => $post_type,
1467 'posts_per_page' => $nb,
1468 'paged' => $paged,
1469 'meta_key' => $orderbykey,
1470 'orderby' => $orderby,
1471 'order' => $order
1472 );
1473
1474 if($tax_name=='category'){
1475 $tax_name='';
1476 $cat=$tax_term;
1477 }
1478 elseif($tax_name=='post-tag'){
1479 $tax_name='';
1480 $tag=$tax_term;
1481 }
1482
1483 // CUSTOM TAXONOMY
1484 if ($tax_name != '' && $tax_term != '') {
1485 $arg['tax_query'] = array(
1486 array(
1487 'taxonomy' => $tax_name,
1488 'field' => 'slug',
1489 'terms' => $tax_term,
1490 ),
1491 );
1492 }
1493 // CAT
1494 if ($cat != '') {
1495 if (preg_match('/[a-zA-Z]/i', $cat)) {
1496 $arg['category_name'] = $cat;
1497 } else {
1498 $arg['cat'] = $cat;
1499 }
1500 }
1501 // TAG
1502 if ($tag != '') {
1503 $arg['tag'] = $tag;
1504 }
1505 // DATES
1506 $meta_query = array(
1507 array(
1508 'key' => $this->META_END,
1509 'value' => '',
1510 'compare' => '!='
1511 ),
1512 array(
1513 'key' => $this->META_END,
1514 'value' => '0:0:00 0:',
1515 'compare' => '!='
1516 ),
1517 array(
1518 'key' => $this->META_END,
1519 'value' => ':00',
1520 'compare' => '!='
1521 ),
1522 array(
1523 'key' => $this->META_START,
1524 'value' => '',
1525 'compare' => '!='
1526 ),
1527 array(
1528 'key' => $this->META_START,
1529 'value' => '0:0:00 0:',
1530 'compare' => '!='
1531 )
1532 );
1533 if ($future == 0 && $past == 0) {
1534 $meta_query = array();
1535 $arg['meta_key'] = null;
1536 $arg['orderby'] = null;
1537 $arg['order'] = null;
1538 }
1539 elseif ($future == 1 && $past == 0) {
1540 $meta_query[] = array(
1541 'key' => $this->META_END,
1542 'value' => current_time('mysql'),
1543 'compare' => '>=',
1544 //'type'=>'DATETIME'
1545 );
1546 }
1547 elseif ($future == 0 && $past == 1) {
1548 $meta_query[] = array(
1549 'key' => $this->META_END,
1550 'value' => current_time('mysql'),
1551 'compare' => '<=',
1552 //'type'=>'DATETIME'
1553 );
1554 }
1555 if ($date != '') {
1556 $date = date('Y-m-d', $date);
1557
1558 $meta_query = array(
1559 array(
1560 'key' => $this->META_END,
1561 'value' => $date . ' 00:00:00',
1562 'compare' => '>=',
1563 'type' => 'DATETIME'
1564 ),
1565 array(
1566 'key' => $this->META_START,
1567 'value' => $date . ' 23:59:59',
1568 'compare' => '<=',
1569 'type' => 'DATETIME'
1570 )
1571 );
1572 }
1573 // GEO
1574 if ($geo == 1) {
1575 $meta_query[] = array(
1576 'key' => $this->META_LAT,
1577 'value' => '',
1578 'compare' => '!='
1579 );
1580 $meta_query[] = array(
1581 'key' => $this->META_LONG,
1582 'value' => '',
1583 'compare' => '!='
1584 );
1585 $arg['meta_key'] = $this->META_LAT;
1586 $arg['orderby'] = 'meta_value';
1587 $arg['order'] = 'DESC';
1588 }
1589
1590 $arg['meta_query'] = $meta_query;
1591
1592 $query_md5 = 'eventpost_' . md5(var_export($requete, true));
1593 // Check if cache is activated
1594 if ($this->settings['cache'] == 1 && false !== ( $cached_events = get_transient($query_md5) )) {
1595 return apply_filters('eventpost_get_items', is_array($cached_events) ? $cached_events : array(), $requete, $arg);
1596 }
1597
1598 $events = apply_filters('eventpost_get', '', $requete, $arg);
1599 if ('' === $events) {
1600 global $wpdb;
1601 $query = new WP_Query($arg);
1602 $events = $wpdb->get_col($query->request);
1603 $this->pagination = array(
1604 'found_posts' => $query->found_posts,
1605 'max_num_pages' => $query->max_num_pages,
1606 );
1607 foreach ($events as $k => $post) {
1608 $event = $this->retreive($post);
1609 $events[$k] = $event;
1610 }
1611 }
1612 if ($this->settings['cache'] == 1){
1613 set_transient($query_md5, $events, 5 * MINUTE_IN_SECONDS);
1614 }
1615 return apply_filters('eventpost_get_items', $events, $requete, $arg);
1616 }
1617
1618 /**
1619 * Checks if the given event is in the future or not
1620 *
1621 * @param object $event
1622 * @param boolean $exact Future status has to be calculated against time or entire day
1623 * @return boolean
1624 */
1625 function is_future($event, $exact=false){
1626 $match = current_time('timestamp');
1627 // if EXACT is false, end date is set to begining of the current day
1628 if(!$exact){
1629 $match = mktime(0, 0, 0, date('m', $match), date('d', $match), date('Y', $match));
1630 }
1631 return ($event->time_end >= $match);
1632 }
1633
1634 /**
1635 * Checks if the given event is completed or not
1636 *
1637 * @param object $event
1638 * @param boolean $exact Past status has to be calculated against time or entire day
1639 * @return boolean
1640 */
1641 function is_past($event, $exact=false){
1642 $match = current_time('timestamp');
1643 // if EXACT is false or full day event, end date is set to end of the current day
1644 if(!$exact || ( date('H:i:s', $event->time_start) == '00:00:00' && date('H:i:s', $event->time_end) == '00:00:00' )){
1645 $match = mktime(23, 59, 59, date('m', $match), date('d', $match), date('Y', $match));
1646 }
1647 return ($event->time_end < $match);
1648 }
1649
1650 /**
1651 * Checks if an event is online
1652 * @param $event
1653 * @return boolean
1654 */
1655 function is_online($event){
1656 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OnlineEventAttendanceMode')));
1657 }
1658
1659 /**
1660 * Checks if an event is offline
1661 * @param $event
1662 * @return boolean
1663 */
1664 function is_offline($event){
1665 return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OfflineEventAttendanceMode')));
1666 }
1667
1668
1669 /**
1670 *
1671 * @param object $event
1672 * @return object
1673 */
1674 public function retreive($event = null) {
1675 global $EventPost_cache;
1676 $ob = get_post($event);
1677 if(is_object($ob) && $ob->start){
1678 return $ob;
1679 }
1680 if(is_object($ob) && isset($EventPost_cache[$ob->ID])){
1681 return $EventPost_cache[$ob->ID];
1682 }
1683 $ob->start = get_post_meta($ob->ID, $this->META_START, true);
1684 $ob->end = get_post_meta($ob->ID, $this->META_END, true);
1685 if (!$this->dateisvalid($ob->start)){
1686 $ob->start = '';
1687 }
1688 if (!$this->dateisvalid($ob->end)){
1689 $ob->end = '';
1690 }
1691 $ob->root_ID = $ob->ID;
1692 $ob->time_start = !empty($ob->start) ? strtotime($ob->start) : '';
1693 $ob->time_end = !empty($ob->end) ? strtotime($ob->end) : '';
1694 $ob->virtual_location = get_post_meta($ob->ID, $this->META_VIRTUAL_LOCATION, true);
1695 $ob->address = get_post_meta($ob->ID, $this->META_ADD, true);
1696 $ob->lat = get_post_meta($ob->ID, $this->META_LAT, true);
1697 $ob->long = get_post_meta($ob->ID, $this->META_LONG, true);
1698 $ob->attendance_mode = (null != $att_mod = get_post_meta($ob->ID, $this->META_ATTENDANCE_MODE, true)) ? $att_mod : array_keys($this->attendance_modes)[0];
1699 $ob->status = (null != $status = get_post_meta($ob->ID, $this->META_STATUS, true)) ? $status : array_keys($this->statuses)[0];
1700 $ob->color = $this->get_post_color($ob->ID);
1701 $ob->icon = $this->get_post_icon($ob->ID);
1702 $ob->categories = get_the_category($ob->ID);
1703 $ob->permalink = get_permalink($ob->ID);
1704 $ob->blog_id = get_current_blog_id();
1705
1706 $EventPost_cache[$ob->ID] = apply_filters('eventpost_retreive', $ob);
1707 return $EventPost_cache[$ob->ID];
1708 }
1709
1710 /**
1711 *
1712 * @param mixte $_term
1713 * @param string $taxonomy
1714 * @param string $post_type
1715 */
1716 public function retreive_term($_term=null, $taxonomy='category', $post_type='post') {
1717 $term = get_term($_term, $taxonomy);
1718
1719 if(!$term){
1720 return $term;
1721 }
1722
1723 $term->start = $term->end = $term->time_start = $term->time_end = Null;
1724
1725 $request = array(
1726 'post_type'=>$post_type,
1727 'tax_name'=>$term->taxonomy,
1728 'tax_term'=>$term->slug,
1729 'future'=>true,
1730 'past'=>true,
1731 'nb'=>-1,
1732 'order'=>'ASC'
1733 );
1734
1735 $events = $this->get_events($request);
1736
1737 $term->events_count = count($events);
1738 if($term->events_count){
1739 $term->start = $events[0]->start;
1740 $term->time_start = $events[0]->time_start;
1741 $term->end = $events[$term->events_count-1]->end;
1742 $term->time_end = $events[$term->events_count-1]->time_end;
1743 }
1744
1745 $request['order']='DESC';
1746 $request['nb']=1;
1747 $request['orderbykey']=$this->META_END;
1748 $events = $this->get_events($request);
1749 if(count($events)){
1750 $term->end = $events[0]->end;
1751 $term->time_end = $events[0]->time_end;
1752 }
1753
1754 return $term;
1755
1756 }
1757
1758 /** ADMIN ISSUES * */
1759
1760 /**
1761 * add custom boxes in posts edit page
1762 */
1763 public function add_custom_box() {
1764 foreach($this->settings['posttypes'] as $posttype){
1765 add_meta_box(
1766 'event_post_date',
1767 __('Event date', 'event-post'),
1768 array(&$this, 'inner_custom_box_date'),
1769 $posttype,
1770 apply_filters('eventpost_add_custom_box_position', $this->settings['adminpos'], $posttype),
1771 'core',
1772 array(
1773 '__block_editor_compatible_meta_box' => true,
1774 )
1775 );
1776 add_meta_box(
1777 'event_post_loc',
1778 __('Location', 'event-post'),
1779 array(&$this, 'inner_custom_box_loc'),
1780 $posttype,
1781 apply_filters('eventpost_add_custom_box_position', $this->settings['adminpos'], $posttype),
1782 'core',
1783 array(
1784 '__block_editor_compatible_meta_box' => true,
1785 )
1786 );
1787 do_action('eventpost_add_custom_box', $posttype);
1788 }
1789 }
1790 /**
1791 * display the date custom box
1792 */
1793 public function inner_custom_box_date() {
1794
1795
1796
1797 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1798 $post_id = get_the_ID();
1799 $event = $this->retreive($post_id);
1800 $start_date = $event->start;
1801 $end_date = $event->end;
1802 $eventcolor = $event->color;
1803 $eventicon = $event->icon;
1804
1805 $language = get_bloginfo('language');
1806 if (strpos($language, '-') > -1) {
1807 $language = strtolower(substr($language, 0, 2));
1808 }
1809 $colors = $this->get_colors();
1810 include (plugin_dir_path(__FILE__) . 'views/admin/custombox-date.php');
1811 do_action ('eventpost_custom_box_date', $event);
1812 }
1813 /**
1814 * displays the location custom box
1815 */
1816 public function inner_custom_box_loc($post) {
1817 $event = $this->retreive($post);
1818 include (plugin_dir_path(__FILE__) . 'views/admin/custombox-location.php');
1819 do_action ('eventpost_custom_box_loc', $event);
1820 $this->load_map_scripts();
1821 }
1822
1823 public function icon_color_fields($item_id, $meta_color,$value_color,$meta_icon,$value_icon ){
1824 ?>
1825 <div class="eventpost-misc-pub-section event-color-section">
1826 <span class="screen-reader-text"><?php _e('Color:', 'event-post'); ?></span>
1827
1828 <input class="color-field-post eventpost-colorpicker"
1829 type="text"
1830 name="<?php echo $meta_color; ?>"
1831 value="<?php echo $value_color; ?>"
1832 id="color-field<?php echo $item_id; ?>"/>
1833
1834 <select style="font-family : dashicons;" class="eventpost-iconpicker" name="<?php echo $meta_icon; ?>">
1835 <option value=""><?php echo __('None','event-post') ?></option>
1836 <?php
1837 foreach($this->DashIcons->icons as $class => $unicode){
1838 ?>
1839 <option value="<?php echo $class ?>" <?php selected($value_icon, $class, true); ?>>&#x<?php echo $unicode ?>; <?php echo $class ?></option>
1840 <?php
1841 }
1842 ?>
1843 </select>
1844 <div class="custom-marker-container">
1845 <p><?php echo __('An image was found in your custom folder for this color', 'event-post')?> <span class="color-hex"></span> </p>
1846 <img src="" class="image-marker">
1847 </div>
1848 </div>
1849
1850
1851 <?php
1852 }
1853
1854 /**
1855 *
1856 * @param string $column_name
1857 * @param boolean $bulk
1858 */
1859 function quick_edit( $column_name, $post_type, $bulk=false) {
1860
1861 if ($bulk) {
1862 static $eventpostprintNonceBulk = TRUE;
1863 if ($eventpostprintNonceBulk) {
1864 $eventpostprintNonceBulk = FALSE;
1865 }
1866 $fields = $this->bulk_edit_fields;
1867 echo '<input type="hidden" name="eventpost-bulk-editor" id="eventpost-bulk-editor" value="eventpost-bulk-editor">';
1868 }
1869 else {
1870 static $eventpostprintNonce = TRUE;
1871 if ($eventpostprintNonce) {
1872 $eventpostprintNonce = FALSE;
1873 }
1874 $fields = $this->quick_edit_fields;
1875 }
1876 wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
1877 if(isset($fields[$column_name])): ?>
1878 <fieldset class="inline-edit-col-left inline-edit-<?php echo $column_name; ?>">
1879 <div class="inline-edit-group">
1880 <?php foreach ($fields[$column_name] as $fieldname=>$fieldlabel): ?>
1881 <fieldset class="inline-edit-col inline-edit-<?php echo $fieldname; ?>">
1882 <div class="inline-edit-col column-<?php echo $fieldname; ?>">
1883 <label class="inline-edit-group">
1884 <span class="title"><?php echo $fieldlabel; ?></span>
1885 <span class="input-text-wrap">
1886 <?php echo $this->inline_field($fieldname, $bulk); ?>
1887 </span>
1888 </label>
1889 </div>
1890 </fieldset>
1891 <?php endforeach; ?>
1892 </div>
1893 </fieldset>
1894 <?php endif;
1895 }
1896
1897 /**
1898 *
1899 * @param type $fieldname
1900 * @return type
1901 */
1902 function inline_field($fieldname, $bulk){
1903 return apply_filters('eventpost_inline_field', '<input name="'.$fieldname.'" class="eventpost-inline-'.$fieldname.'" value="" type="text">', $fieldname, $bulk);
1904 }
1905
1906 function inline_field_color($html, $fieldname, $bulk){
1907 if($fieldname==$this->META_COLOR){
1908 $html='';
1909 if($bulk){
1910 $html.= '<span class="eventpost-bulk-colorpicker-button link">'.__('No Change', 'event-post').'</span>';
1911 }
1912 $html .= '
1913
1914 <input class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'" type="text" name="'.$fieldname.'" >';
1915 }
1916 return $html;
1917 }
1918 function inline_field_icon($html, $fieldname, $bulk){
1919 if($fieldname==$this->META_ICON){
1920 if($bulk){
1921 $html.= '<span class="eventpost-bulk-icon-button link">'.__('No Change', 'event-post').'</span>';
1922 }
1923 $html = '<select class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'"
1924 type="text"
1925 name="'.$fieldname.'"
1926 style="font-family : dashicons">
1927 <option value="">'.__("None", 'event-post').'</option>';
1928 foreach($this->DashIcons->icons as $class => $unicode){
1929 $html .= '<option value="'.$class.'">&#x'.$unicode.'; '.$class.'</option>';
1930
1931 }
1932 $html .= '</select>';
1933
1934 }
1935 return $html;
1936 }
1937
1938
1939 /**
1940 *
1941 * @param type $column_name
1942 * @param type $post_type
1943 */
1944 function bulk_edit($column_name, $post_type){
1945 $this->quick_edit($column_name, $post_type, true);
1946 }
1947
1948 /**
1949 * Saves data from quick-edit via `wp_ajax_inline-save` action
1950 * @return void
1951 */
1952 function inline_save(){
1953 $post_id = filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT);
1954 $this->save_postdata($post_id);
1955 }
1956 /**
1957 * When the post is saved, saves our custom data
1958 * @param int $post_id
1959 * @return void
1960 */
1961 public function save_postdata($post_id) {
1962 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
1963 return;
1964 }
1965
1966 if (!wp_verify_nonce(filter_input(INPUT_POST, 'eventpost_nonce', FILTER_SANITIZE_STRING), plugin_basename(__FILE__))){
1967 return;
1968 }
1969
1970 // Clean color or no color
1971 if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR, FILTER_SANITIZE_STRING)) {
1972 update_post_meta($post_id, $this->META_COLOR, $color);
1973 }
1974 // Clean color or no color
1975 if (false !== $icon = filter_input(INPUT_POST, $this->META_ICON, FILTER_SANITIZE_STRING)) {
1976 update_post_meta($post_id, $this->META_ICON, $icon);
1977 }
1978 if (false !== $attendance_mode = filter_input(INPUT_POST, $this->META_ATTENDANCE_MODE, FILTER_SANITIZE_STRING)) {
1979 update_post_meta($post_id, $this->META_ATTENDANCE_MODE, $attendance_mode);
1980 }
1981 if (false !== $status = filter_input(INPUT_POST, $this->META_STATUS, FILTER_SANITIZE_STRING)) {
1982 update_post_meta($post_id, $this->META_STATUS, $status);
1983 }
1984 if (false !== $virtual_location = filter_input(INPUT_POST, $this->META_VIRTUAL_LOCATION, FILTER_SANITIZE_URL)) {
1985 update_post_meta($post_id, $this->META_VIRTUAL_LOCATION, $virtual_location);
1986 }
1987 // Clean date or no date
1988 if ((false !== $start = filter_input(INPUT_POST, $this->META_START, FILTER_SANITIZE_STRING)) &&
1989 (false !== $end = filter_input(INPUT_POST, $this->META_END, FILTER_SANITIZE_STRING)) &&
1990 '' != $start &&
1991 '' != $end) {
1992 update_post_meta($post_id, $this->META_START, substr($start,0,16).':00');
1993 update_post_meta($post_id, $this->META_END, substr($end,0,16).':00');
1994 }
1995 else {
1996 delete_post_meta($post_id, $this->META_START);
1997 delete_post_meta($post_id, $this->META_END);
1998 }
1999
2000 // Clean location or no location
2001 if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT, FILTER_SANITIZE_STRING)) &&
2002 (false !== $long = filter_input(INPUT_POST, $this->META_LONG, FILTER_SANITIZE_STRING)) &&
2003 '' != $lat &&
2004 '' != $long) {
2005 update_post_meta($post_id, $this->META_ADD, filter_input(INPUT_POST, $this->META_ADD, FILTER_SANITIZE_STRING));
2006 update_post_meta($post_id, $this->META_LAT, $lat);
2007 update_post_meta($post_id, $this->META_LONG, $long);
2008 }
2009 else {
2010 delete_post_meta($post_id, $this->META_ADD);
2011 delete_post_meta($post_id, $this->META_LAT);
2012 delete_post_meta($post_id, $this->META_LONG);
2013 }
2014
2015 $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
2016 }
2017
2018 /**
2019 * Saves data from bulk-edit
2020 * Should be used via AJAX
2021 *
2022 * outputs JSON
2023 * @return void
2024 */
2025 function save_bulkdatas() {
2026 $current_post_type = isset($_POST['post_type']) ? $_POST['post_type'] : 'post';
2027 if (in_array($current_post_type, $this->settings['posttypes'])) {
2028 $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
2029 if (!empty($post_ids) && is_array($post_ids)) {
2030 foreach ($this->bulk_edit_fields as $sets) {
2031 foreach ($sets as $fieldname => $fieldlabel) {
2032 if ((false != $value = filter_input(INPUT_POST, $fieldname))) {
2033 foreach ($post_ids as $post_id) {
2034 update_post_meta($post_id, $fieldname, $value);
2035 }
2036 }
2037 }
2038 }
2039 }
2040 wp_send_json(true);
2041 exit;
2042 }
2043 wp_send_json(false);
2044 }
2045
2046 /**
2047 *
2048 * @param string $date
2049 * @param string $cat
2050 * @param boolean $display
2051 * @return boolean
2052 */
2053 public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='',$tax_name='' ,$tax_term='') {
2054 $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true,'tax_name' => $tax_name ,'tax_term' => $tax_term));
2055 $nb = count($events);
2056 $ret = "";
2057 if(!$display && !$nb){
2058 $ret = date('j', $date);
2059 }
2060 if($nb){
2061 if ($display || $title) {
2062 $ret='<ul>';
2063 foreach ($events as $event) {
2064 if ($this->settings['emptylink'] == 0 && empty($event->post_content)) {
2065 $event->guid = '#';
2066 }
2067 $ret.='<li>'
2068 . '<a href="' . $event->permalink . '" title="'.esc_attr(sprintf(__('View event: %s', 'event-post'), $event->post_title)).'">'
2069 . '<h4>' . $event->post_title . '</h4>'
2070 .$this->get_single($event)
2071 . (!empty($thumbnail) ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->ID, $thumbnail) . '</span>' : '')
2072 .'</a>'
2073 . '</li>';
2074 }
2075 $ret.='</ul>';
2076 }
2077 if ($display) {
2078 // return $ret;
2079 }
2080 elseif($title) {
2081 $ret = '<span '.($colored?' style="color:#'.$events[0]->color.'"':'').'>'.date('j', $date).'</span>'.$ret;
2082 }
2083 else {
2084 $ret = '<button data-event="'. $tax_term .'" data-date="' . date('Y-m-d', $date).'"'
2085 .' class="'.apply_filters( 'event_post_class_calendar_link', 'eventpost_cal_link' ).'"'.($colored?' style="background-color:#'.$events[0]->color.'"':'')
2086 .' title="'.esc_attr(sprintf(_n('View %1$d event at date %2$s', 'View %1$d events at date %2$s', $nb, 'event-post'), $nb, $this->human_date($date, $this->settings['dateformat']))).'"'
2087 .'>'
2088 . date('j', $date)
2089 . '</button>';
2090 }
2091 }
2092
2093 return apply_filters('eventpost_display_caldate', $ret, $events, $date, $cat ,$display ,$colored ,$thumbnail ,$title ,$tax_name ,$tax_term );
2094 }
2095
2096
2097 /**
2098 * @param array $atts
2099 * @filter eventpost_params
2100 * @return string
2101 */
2102 public function calendar($atts) {
2103 extract(shortcode_atts(apply_filters('eventpost_params', array(
2104 'date' => date('Y-n'),
2105 'cat' => '',
2106 'mondayfirst' => 0, //1 : weeks starts on monday
2107 'datepicker' => 1,
2108 'colored' => 1,
2109 'display_title'=>0,
2110 'tax_name' => '',
2111 'tax_term' => '',
2112 'thumbnail'=>'',
2113 ), 'calendar'), $atts));
2114
2115 if($date && !preg_match('#[0-9][0-9][0-9][0-9]-[0-9][0-9]?#i', $date)){
2116 $date = date('Y-n', strtotime($date));
2117 }
2118 if(!$date){
2119 $date = date('Y-n');
2120 }
2121
2122 $annee = substr($date, 0, 4);
2123 $mois = substr($date, 5);
2124
2125 $time = mktime(0, 0, 0, $mois, 1, $annee);
2126
2127 $prev_year = strtotime('-1 Year', $time);
2128 $next_year = strtotime('+1 Year', $time);
2129 $prev_month = strtotime('-1 Month', $time);
2130 $next_month = strtotime('+1 Month', $time);
2131
2132 $JourMax = date("t", $time);
2133 $NoJour = -date("w", $time);
2134 if ($mondayfirst == 0) {
2135 $NoJour +=1;
2136 } else {
2137 $NoJour +=2;
2138 $this->Week[] = array_shift($this->Week);
2139 }
2140 if ($NoJour > 0 && $mondayfirst == 1) {
2141 $NoJour -=7;
2142 }
2143 $ret = '<table class="event-post-calendar-table">'
2144 . '<caption class="screen-reader-text">'
2145 . __('A calendar of events', 'event-post')
2146 . '</caption>';
2147 $ret.='<thead><tr><th colspan="7">';
2148 if ($datepicker == 1) {
2149 $ret.='<div class="eventpost-calendar-header">';
2150 $ret.='<span class="eventpost-cal-year"><button data-date="' . date('Y-n', $prev_year) . '" tabindex="0" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $prev_year)).'" class="eventpost_cal_bt eventpost-cal-bt-prev">&laquo;</button><span class="eventpost-cal-header-text">';
2151 $ret.=$annee;
2152 $ret.='</span><button data-date="' . date('Y-n', $next_year) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $next_year)).'" class="eventpost_cal_bt eventpost-cal-bt-next">&raquo;</button></span>';
2153 $ret.='<span class="eventpost-cal-month"><button data-date="' . date('Y-n', $prev_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $prev_month)).'" class="eventpost_cal_bt eventpost-cal-bt-prev">&laquo;</button><span class="eventpost-cal-header-text">';
2154 $ret.=$this->NomDuMois[abs($mois)];
2155 $ret.='</span><button data-date="' . date('Y-n', $next_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $next_month)).'" class="eventpost_cal_bt eventpost-cal-bt-next">&raquo;</button> </span>';
2156 $ret.='<span class="eventpost-cal-today"><button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button></span>';
2157 $ret.='</div>';
2158 }
2159 $ret.='</th></tr><tr class="event_post_cal_days">';
2160 for ($w = 0; $w < 7; $w++) {
2161 $ret.='<th scope="col">' . strtoupper(substr($this->Week[$w], 0, 1)) . '</th>';
2162 }
2163 $ret.='</tr>';
2164 $ret.='</thead>';
2165
2166 $ret.='<tbody>';
2167 $sqldate = date('Y-m', $time);
2168 $cejour = date('Y-m-d');
2169 for ($semaine = 0; $semaine <= 5; $semaine++) { // 6 semaines par mois
2170 $tr_row_content ='';
2171 for ($journee = 0; $journee <= 6; $journee++) { // 7 jours par semaine
2172 if ($NoJour > 0 && $NoJour <= $JourMax) { // si le jour est valide a afficher
2173 $td = '<td class="event_post_day">';
2174 if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour == $cejour) {
2175 $td = '<td class="event_post_day_now">';
2176 }
2177 if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour < $cejour){
2178 $td = '<td class="event_post_day_over">'; // Patch ahf
2179 }
2180 $tr_row_content.=$td;
2181 $tr_row_content.= $this->display_caldate(mktime(0, 0, 0, $mois, $NoJour, $annee), $cat, false, $colored, $thumbnail, $display_title ,$tax_name ,$tax_term);
2182 $tr_row_content.='</td>';
2183 } else {
2184 $tr_row_content.='<td></td>';
2185 }
2186 $NoJour ++;
2187 }
2188 if($tr_row_content){
2189 $ret.='<tr>'.$tr_row_content.'</tr>';
2190 }
2191
2192 }
2193 $ret.='</tbody></table>';
2194 return $ret;
2195 }
2196
2197 /**
2198 * echoes a list of event, should be called via AJAX
2199 *
2200 * @return void
2201 */
2202 public function ajaxlist(){
2203 echo $this->list_events(array(
2204 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2205 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2206 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2207 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2208 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2209 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2210 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2211 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2212 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2213 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2214 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2215 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2216 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2217 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2218 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2219 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2220 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2221 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2222 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2223 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2224 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2225 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2226 ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2227 exit;
2228 }
2229
2230 /**
2231 * echoes a list of event, should be called via AJAX
2232 *
2233 * @return void
2234 */
2235 public function ajaxTimeline(){
2236 echo $this->list_events(array(
2237 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2238 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2239 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2240 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2241 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2242 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2243 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2244 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2245 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2246 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2247 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2248 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2249 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2250 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2251 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2252 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2253 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2254 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2255 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2256 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2257 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2258 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2259 ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type')));
2260 exit;
2261 }
2262 /**
2263 * echoes next page of events, should be called via AJAX
2264 *
2265 * @return void
2266 */
2267 public function ajaxGetNextPage(){
2268 $response = [
2269 "success" => false,
2270 "next_query" => false,
2271 ];
2272 if(isset($_POST['query'])){
2273 parse_str($_POST['query'],$query);
2274 foreach($query as $key => $value){
2275 $query[$key] = esc_attr($value);
2276 }
2277 if(isset($_POST['paged'])){
2278 $query["paged"] = esc_attr($_POST['paged']);
2279 }else{
2280 $response['message'] = __('Page number missing');
2281 }
2282 $query['container_schema'] = $this->timeline_shema['container'];
2283 $query['item_schema'] = $this->timeline_shema['item'];
2284 $html = $this->list_events($query,'event_timeline','events_only');
2285 if($html == ""){
2286 $response['message'] = __('No more to load');
2287 }else{
2288 $query["paged"] = $query["paged"] + 1;
2289 $next_html = $this->list_events($query,'event_timeline','events_only');
2290 $response = [
2291 "success" => true,
2292 "html" => $html,
2293 "next_query" => $next_html == "" ? false : true,
2294 ];
2295 }
2296 }else{
2297 $response['message'] = __('Query missing');
2298 }
2299 wp_send_json($response);
2300 exit;
2301 }
2302
2303 /**
2304 * echoes the content of the calendar in ajax context
2305 * @return void
2306 */
2307 public function ajaxcal() {
2308 $method = isset($_GET['action']) ? INPUT_GET : INPUT_POST;
2309 echo $this->calendar(array(
2310 'date' => esc_attr(FILTER_INPUT($method, 'date')),
2311 'cat' => esc_attr(FILTER_INPUT($method, 'cat')),
2312 'mondayfirst' => esc_attr(FILTER_INPUT($method, 'mf')),
2313 'datepicker' => esc_attr(FILTER_INPUT($method, 'dp')),
2314 'colored' => esc_attr(FILTER_INPUT($method, 'color')),
2315 'display_title' => esc_attr(FILTER_INPUT($method, 'display_title')),
2316 'thumbnail' => esc_attr(FILTER_INPUT($method, 'thumbnail')),
2317 'tax_name' => esc_attr(FILTER_INPUT($method, 'tax_name')),
2318 'tax_term' => esc_attr(FILTER_INPUT($method, 'tax_term')),
2319 ));
2320 exit();
2321 }
2322
2323 /**
2324 * echoes the date of the calendar in ajax context
2325 */
2326 public function ajaxdate() {
2327 echo $this->display_caldate(
2328 strtotime(esc_attr(FILTER_INPUT(INPUT_GET, 'date'))),
2329 esc_attr(FILTER_INPUT(INPUT_GET, 'cat')),
2330 true,
2331 esc_attr(FILTER_INPUT(INPUT_GET, 'color')),
2332 esc_attr(FILTER_INPUT(INPUT_GET, 'thumbnail')),
2333 esc_attr(FILTER_INPUT(INPUT_GET, 'display_title')),
2334 esc_attr(FILTER_INPUT(INPUT_GET, 'tax_name')),
2335 esc_attr(FILTER_INPUT(INPUT_GET, 'tax_term'))
2336 );
2337 exit();
2338 }
2339
2340 /**
2341 * echoes a date in ajax context
2342 */
2343 public function HumanDate() {
2344 if (isset($_REQUEST['date']) && !empty($_REQUEST['date'])) {
2345 $date = strtotime($_REQUEST['date']);
2346 echo $this->human_date($date, $this->settings['dateformat']).(date('H:i', $date)=='00:00' ? '' : ' '. date($this->settings['timeformat'], $date));
2347 exit();
2348 }
2349 }
2350
2351 /**
2352 * Displays a search form
2353 *
2354 * @param type $atts
2355 * @return type
2356 */
2357 public function search($atts) {
2358 $params = shortcode_atts(apply_filters('eventpost_params', array(
2359 'dates' => true,
2360 'q' => true,
2361 'tax' => false,
2362 ), 'search'), $atts);
2363 $this->list_id++;
2364
2365 $list_id = $this->list_id;
2366 $q = (false !== $q = filter_input(INPUT_GET, 'q')) ? $q : '';
2367 $from = (false !== $from = filter_input(INPUT_GET, 'from')) ? $from : '';
2368 $to = (false !== $to = filter_input(INPUT_GET, 'to')) ? $to : '';
2369 $tax = (false !== $tax = filter_input(INPUT_GET, 'tax')) ? $tax : '';
2370
2371 $cleaned_from = $this->date_cleanup($from);
2372 $cleaned_to = $this->date_cleanup($to);
2373 if(empty($cleaned_from)){
2374 $from=false;
2375 }
2376 if(empty($cleaned_to)){
2377 $to=false;
2378 }
2379
2380 // Search form
2381 $this->admin_scripts(null, true);
2382 wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, filemtime( "/$block_js" ));
2383 include (plugin_dir_path(__FILE__) . 'views/search-form.php');
2384
2385 // Results
2386 if ($list_id == filter_input(INPUT_GET, 'evenpost_search')) {
2387 $arg = array(
2388 'post_type' => $this->settings['posttypes'],
2389 'meta_key' => $this->META_START,
2390 'orderby' => 'meta_value',
2391 'order' => 'ASC',
2392 's' => $q
2393 );
2394 if ($tax) {
2395 $arg['cat'] = $tax;
2396 }
2397
2398 if ($from || $to) {
2399
2400 $arg['meta_query'] = array();
2401 if ($from) {
2402 $arg['meta_query'][] = array(
2403 'key' => $this->META_START,
2404 'value' => $from,
2405 'compare' => '>=',
2406 'type' => 'DATETIME'
2407 );
2408 }
2409 if ($to) {
2410 $arg['meta_query'][] = $meta_query = array(
2411 array(
2412 'key' => $this->META_END,
2413 'value' => $to,
2414 'compare' => '<=',
2415 'type' => 'DATETIME'
2416 ),
2417 );
2418 }
2419 }
2420 $events = new WP_Query($arg);
2421 include (plugin_dir_path(__FILE__) . 'views/search-results.php');
2422 wp_reset_query();
2423 }
2424 }
2425
2426 /**
2427 * AJAX Get lat long from address
2428 */
2429 public function GetLatLong() {
2430 if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
2431 // verifier le cache
2432 $q = $_REQUEST['q'];
2433 header('Content-Type: application/json');
2434 $transient_name = 'eventpost_osquery_' . $q;
2435 $val = get_transient($transient_name);
2436 if (false === $val || empty($val) || !is_string($val)) {
2437 $language = get_bloginfo('language');
2438 if (strpos($language, '-') > -1) {
2439 $language = strtolower(substr($language, 0, 2));
2440 }
2441 $remote_val = wp_safe_remote_request('http://nominatim.openstreetmap.org/search?q=' . urlencode($q) . '&format=json&accept-language=' . $language);
2442 if(json_decode($remote_val['body'])){
2443 $val = $remote_val['body'];
2444 }
2445 set_transient($transient_name, $val, 30 * DAY_IN_SECONDS);
2446 }
2447 echo $val;
2448 exit();
2449 }
2450 }
2451
2452 /**
2453 * alters columns
2454 * @param array $defaults
2455 * @return array
2456 * @filter eventpost_columns_head
2457 */
2458 public function columns_head($defaults) {
2459 $defaults['event'] = __('Event', 'event-post');
2460 $defaults['location'] = __('Location', 'event-post');
2461 return apply_filters('eventpost_columns_head', $defaults);
2462 }
2463
2464 /**
2465 * echoes content of a row in a given column
2466 * @param string $column_name
2467 * @param int $post_id
2468 * @action eventpost_columns_content
2469 */
2470 public function columns_content($column_name, $post_id) {
2471 if ($column_name == 'location') {
2472 $lat = get_post_meta($post_id, $this->META_LAT, true);
2473 $lon = get_post_meta($post_id, $this->META_LONG, true);
2474
2475 if (!empty($lat) && !empty($lon)) {
2476 add_thickbox();
2477 $color = $this->get_post_color($post_id, $this->settings['default_color'], true);
2478 $icon = $this->get_post_icon($post_id, $this->settings['default_icon'], true);
2479 if ($color == ''){
2480 $color = '777777';
2481 }
2482 if ($icon == ''){
2483 $icon = 'location';
2484 }
2485 echo '<a href="https://www.openstreetmap.org/export/embed.html?bbox='.($lon-0.005).'%2C'.($lat-0.005).'%2C'.($lon+0.005).'%2C'.($lat+0.005).'&TB_iframe=true&width=600&height=550" class="thickbox" target="_blank">'
2486 . '<i class="dashicons dashicons-'.$icon.'" style="color:#'.$color.';"></i>'
2487 . '<span class="screen-reader-text">'.__('View on a map', 'event-post').'</span>'
2488 . get_post_meta($post_id, $this->META_ADD, true)
2489 . '</a> ';
2490 }
2491 $this->column_edit_hidden_fields($post_id, 'location');
2492 }
2493 if ($column_name == 'event') {
2494 echo $this->print_date($post_id, false);
2495 $this->column_edit_hidden_fields($post_id, 'event');
2496 }
2497 do_action('eventpost_columns_content', $column_name, $post_id);
2498 }
2499
2500 function column_edit_hidden_fields($post_id, $set){
2501 $event = $this->retreive($post_id);
2502 echo '<div class="hidden">';
2503 foreach($this->quick_edit_fields[$set] as $fieldname=>$fieldlabel){
2504 echo'<span class="inline-edit-value '.$fieldname.'">'.esc_attr($event->$fieldname).'</span>';
2505 }
2506 echo '</div>';
2507 }
2508
2509 /** ADMIN PAGES **/
2510
2511 /**
2512 * adds items to the native "right now" dashboard widget
2513 * @param array $elements
2514 * @return array
2515 */
2516 public function dashboard_right_now($elements){
2517 $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
2518 $nb_geo = count($this->get_events(array('future'=>1, 'past'=>1, 'geo'=>1, 'nb'=>-1)));
2519 if($nb_date){
2520 array_push($elements, '<i class="dashicons dashicons-calendar"></i> <i href="edit.php?post_type=post">'.sprintf(__('%d Events','event-post'), $nb_date)."</i>");
2521 }
2522 if($nb_geo){
2523 array_push($elements, '<i class="dashicons dashicons-location"></i> <i href="edit.php?post_type=post">'.sprintf(__('%d Geolocalized events','event-post'), $nb_geo)."</i>");
2524 }
2525 return $elements;
2526 }
2527
2528 /*
2529 * feed
2530 * generate ICS or VCS files from a category
2531 */
2532
2533 /**
2534 *
2535 * @param timestamp $timestamp
2536 * @return string
2537 */
2538 public function ics_date($timestamp){
2539 return date("Ymd",$timestamp).'T'.date("His",$timestamp);
2540 }
2541
2542 public function get_gmt_offset(){
2543 $gmt_offset = get_option('gmt_offset ');
2544 $codegmt = 0;
2545 if ($gmt_offset != 0 && substr($gmt_offset, 0, 1) != '-' && substr($gmt_offset, 0, 1) != '+') {
2546 $codegmt = $gmt_offset * -1;
2547 $gmt_offset = '+' . $gmt_offset;
2548 }
2549 if(abs($gmt_offset < 10)){
2550 $gmt_offset = substr($gmt_offset, 0, 1).'0'.substr($gmt_offset, 1);
2551 }
2552 return $gmt_offset;
2553 }
2554
2555 private function generate_ics($event_id, $format){
2556 $export_file = plugin_dir_path(__FILE__).'inc/export/'.$format.'.php';
2557 if(is_numeric($event_id) && file_exists($export_file)){
2558 $event = $this->retreive($event_id);
2559 include $export_file;
2560 exit;
2561 }
2562 }
2563
2564 public function parse_request(){
2565 global $wp;
2566 if (preg_match('#^event-feed#i', $wp->request, $match)) {
2567 $this->feed();
2568 exit;
2569 }
2570 if (preg_match('#^eventpost/([0-9]*)\.(ics|vcs)#i', $wp->request, $match)) {
2571 $this->generate_ics($match[1], $match[2]);
2572 }
2573 }
2574
2575 public function export(){
2576 if(false !== $event_id=\filter_input(INPUT_GET, 'event_id',FILTER_SANITIZE_NUMBER_INT)){
2577 $format = \filter_input(INPUT_GET, 'format',FILTER_SANITIZE_STRING);
2578 $this->generate_ics($event_id, $format);
2579 }
2580 }
2581
2582
2583 /**
2584 * outputs an ICS document
2585 */
2586 public function feed(){
2587 if(false !== $cat=\filter_input(INPUT_GET, 'cat',FILTER_SANITIZE_STRING)){
2588 $vtz = get_option('timezone_string');
2589 $gmt = $this->get_gmt_offset();
2590 date_default_timezone_set($vtz);
2591 $separator = "\n";
2592
2593 header("content-type:text/calendar");
2594 header("Pragma: public");
2595 header("Expires: 0");
2596 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
2597 header("Cache-Control: public");
2598 header("Content-Disposition: attachment; filename=". str_replace('+','-',urlencode(get_option('blogname').'-'.$cat)).".ics;" );
2599
2600 $props = array();
2601
2602 // General
2603 $props[] = 'BEGIN:VCALENDAR';
2604 $props[] = 'PRODID://WordPress//Event-Post-V'. file_get_contents(('VERSION')).'//EN';
2605 $props[] = 'VERSION:2.0';
2606
2607 // Timezone
2608 if(!empty($vtz)){
2609 array_push($props,
2610 'BEGIN:VTIMEZONE',
2611 'TZID:'.$vtz,
2612 'BEGIN:DAYLIGHT',
2613 'TZOFFSETFROM:+0100',
2614 'TZOFFSETTO:'.($gmt).'00',
2615 'DTSTART:19700329T020000',
2616 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3',
2617 'END:DAYLIGHT',
2618 'BEGIN:STANDARD',
2619 'TZOFFSETFROM:'.($gmt).'00',
2620 'TZOFFSETTO:+0100',
2621 'TZNAME:CET',
2622 'DTSTART:19701025T030000',
2623 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
2624 'END:STANDARD',
2625 'END:VTIMEZONE'
2626 );
2627 }
2628
2629 // Events
2630 $events=$this->get_events(array('cat'=>$cat,'nb'=>-1));
2631 foreach ($events as $event) {
2632 if($event->time_start && $event->time_end){
2633 array_push($props,
2634 'BEGIN:VEVENT',
2635 'CREATED:'.$this->ics_date(strtotime($event->post_date)).'Z',
2636 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
2637 'SUMMARY:'.$event->post_title,
2638 'UID:'.md5(site_url()."_eventpost_".$event->ID),
2639 'LOCATION:'.str_replace(',','\,',$event->address),
2640 'DTSTAMP:'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2641 'DTSTART'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
2642 'DTEND'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_end).(!empty($vtz)?'':'Z'),
2643 'DESCRIPTION:'.trim(chunk_split($event->post_excerpt."\\n\\n".$event->permalink, 60, "\n")),
2644 'END:VEVENT'
2645 );
2646 }
2647 }
2648
2649 // End
2650 $props[] = 'END:VCALENDAR';
2651
2652 echo implode($separator, $props);
2653 exit;
2654 }
2655 }
2656 }
2657