PluginProbe
Event Post / 4.5
Event Post v4.5
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 4.5, at eventpost.php

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