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

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

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