PluginProbe
Event Post / 5.2
Event Post v5.2
6.1.1 6.1.0 6.0.1 6.0.0 5.12.0 trunk 3.9 4.0 4.2 4.3 4.4 4.5 5.0 5.1 5.10.0 5.10.1 5.10.2 5.10.3 5.10.4 5.11.0 5.11.1 5.2 5.5 5.6 5.6.1 All 46 releases
event-post / eventpost.php

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

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