PluginProbe
Event Post / 6.1.2
Event Post v6.1.2
6.1.2 6.1.1 6.1.0 6.0.1 6.0.0 5.12.0 trunk 3.9 4.0 4.2 4.3 4.4 4.5 5.0 5.1 5.10.0 5.10.1 5.10.2 5.10.3 5.10.4 5.11.0 5.11.1 5.2 5.5 5.6 All 47 releases
← All changes | eventpost.php +3146 -2475 5.1 → 6.1.2 View file →
@@ -1,24 +1,42 @@
1 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
2 +/**
3 + * Plugin Name: Event Post
4 + * Plugin URI: https://event-post.com?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard&mtm_source=plugin-uri
5 + * Description: Add calendar and/or geolocation metadata on any posts.
6 + * Version: 6.1.2
7 + * Author: N.O.U.S. Open Useful and Simple
8 + * Contributors: bastho, sabrinaleroy, unecologeek, agencenous
9 + * Author URI: https://apps.avecnous.eu/?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard&mtm_source=author
10 + * License: GPLv2
11 + * Text Domain: event-post
12 + * Domain Path: /languages/
13 + * Tags: Post,posts,event,date,geolocalization,gps,widget,map,openstreetmap,EELV,calendar,agenda,blocks
14 + *
15 + * @package event-post
14 16 */
15 17
18 +if ( ! defined( 'ABSPATH' ) ) exit;
19 +
16 20 global $EventPost;
17 21 $EventPost = new EventPost();
18 22
19 23 $EventPost_cache=array();
20 24
25 +function EventPost(){
26 + global $EventPost;
27 + return $EventPost;
28 +}
29 +function event_post_format_color($color){
30 + return str_replace('#', '', $color);
31 +}
32 +function event_post_get_all_terms($post_id){
33 + $taxonomies= get_taxonomies('','names');
34 +
35 + return wp_get_post_terms($post_id, $taxonomies);
36 +}
37 +
38 +
21 39 /**
22 40 * The main class where everything begins.
23 41 *
24 42 * Add calendar and/or geolocation metadata on posts
@@ -23,2670 +41,3323 @@
23 41 *
24 42 * Add calendar and/or geolocation metadata on posts
25 43 */
26 44 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';
45 + /**
46 + * The current version
47 + *
48 + * Must be kept in sync with the `Version:` plugin header above: `bin/bump`
49 + * only rewrites header-style declarations, not this literal.
50 + *
51 + * @var string
52 + */
53 + public $version = '6.1.2';
34 54
35 - public $list_id;
36 - public $NomDuMois;
37 - public $Week;
38 - public $settings;
39 - public $dateformat;
55 + // --------------------------------------------------------------------------------
56 + // Post metas
40 57
41 - public $version = '4.5';
42 - private $script_sufix;
58 + /**
59 + * The meta name for event start date
60 + *
61 + * @var string
62 + */
63 + public $META_START = 'event_begin';
43 64
44 - public $map_interactions;
45 - public $quick_edit_fields;
65 + /**
66 + * The meta name for event end date
67 + *
68 + * @var string
69 + */
70 + public $META_END = 'event_end';
46 71
47 - public $Shortcodes;
72 + /**
73 + * The meta name for event color
74 + *
75 + * @var string
76 + */
77 + public $META_COLOR = 'event_color';
48 78
49 - public function __construct() {
50 - load_plugin_textdomain('event-post', false, 'event-post/languages');
79 + /**
80 + * The meta name for event icon
81 + *
82 + * @var string
83 + */
84 + public $META_ICON = 'event_icon';
51 85
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'));
86 + // --------------------------------------------------------------------------------
87 + // Post metas related to location
88 +
89 + /**
90 + * The meta name for event address
91 + *
92 + * @var string
93 + */
94 + public $META_ADD = 'geo_address';
56 95
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'));
96 + /**
97 + * The meta name for event latitude
98 + *
99 + * @var string
100 + *
101 + * @see http://codex.wordpress.org/Geodata
102 + */
103 + public $META_LAT = 'geo_latitude';
63 104
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'));
105 + /**
106 + * The meta name for event longitude
107 + *
108 + * @var string
109 + *
110 + * @see http://codex.wordpress.org/Geodata
111 + */
112 + public $META_LONG = 'geo_longitude';
69 113
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'));
114 + /**
115 + * The meta name for event location
116 + *
117 + * @var string
118 + *
119 + * @see https://schema.org/location
120 + */
121 + public $META_VIRTUAL_LOCATION = 'event_virtual_location';
122 +
123 + // --------------------------------------------------------------------------------
124 + // Post metas related to status
125 +
126 + /**
127 + * The meta name for event status
128 + *
129 + * @var string
130 + *
131 + * @see https://schema.org/eventStatus
132 + */
133 + public $META_STATUS = 'event_status';
134 +
135 + /**
136 + * The meta name for event attendance mode
137 + *
138 + * @var string
139 + *
140 + * @see https://schema.org/eventAttendanceMode
141 + */
142 + public $META_ATTENDANCE_MODE = 'event_attendance_mode';
79 143
80 - // Calendar publishing
81 - add_action('wp_ajax_EventPostFeed', array(&$this, 'feed'));
82 - add_action('wp_ajax_nopriv_EventPostFeed', array(&$this, 'feed'));
144 + /**
145 + * The meta name for event organizer
146 + *
147 + * @var string
148 + *
149 + * @see https://schema.org/Organization
150 + */
151 + public $META_ORGANIZATION = 'event_organization';
83 152
84 - //
85 - add_filter('eventpost_list_shema',array(&$this, 'custom_shema'),10,1);
153 + /**
154 + * The meta name for event organizer
155 + *
156 + * @var string
157 + * @see https://schema.org/Offer
158 + */
159 + public $META_OFFER = 'event_offer';
160 +
161 + // --------------------------------------------------------------------------------
162 + // Usefull variables
86 163
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);
164 + /**
165 + * ID of the current list
166 + *
167 + * @var int
168 + */
169 + public $list_id;
90 170
91 - add_action('widgets_init', array(&$this, 'register_widgets'),1,1);
171 + /**
172 + * ID of the current map
173 + *
174 + * @var int
175 + */
176 + public $map_id=0;
92 177
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);
178 + /**
179 + * Schema as been outputed or not
180 + *
181 + * @var bool
182 + */
183 + private $is_schema_output=false;
100 184
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');
185 + /**
186 + * Month names
187 + *
188 + * @var array
189 + */
190 + public $NomDuMois;
110 191
111 - $this->script_sufix = (defined('WP_DEBUG') && WP_DEBUG) ? '' : '.min';
112 - }
192 + /**
193 + * Week days
194 + *
195 + * @var array
196 + */
197 + public $Week;
113 198
114 - /**
115 - * PHP4 constructor
116 - */
117 - public function EventPost(){
118 - $this->__construct();
119 - }
199 + /**
200 + * Currencies
201 + *
202 + * @var array
203 + */
204 + public $currencies = array();
120 205
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'));
206 + /**
207 + * Date format
208 + *
209 + * @var string
210 + */
211 + public $dateformat;
139 212
140 - $this->maps = $this->get_maps();
141 - $this->settings = $this->get_settings();
213 + /**
214 + * Pagination
215 + *
216 + * @var array
217 + */
218 + private $pagination;
142 219
143 - do_action('evenpost_init', $this);
220 + /**
221 + * Plugin path
222 + *
223 + * @var string
224 + */
225 + public $plugin_path;
144 226
145 - $this->Shortcodes = new EventPost_Shortcodes();
227 + /**
228 + * Script suffix
229 + *
230 + * @var string
231 + */
232 + private $script_sufix;
146 233
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 - }
234 + /**
235 + * Settings values
236 + *
237 + * @var array
238 + */
239 + public $settings;
153 240
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 - }
241 + // --------------------------------------------------------------------------------
242 + // Option values
160 243
244 + /**
245 + * Map interractions (from openlayers)
246 + *
247 + * @var array
248 + */
249 + public $map_interactions;
161 250
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 - }
251 + /**
252 + * Fields supported by quick-edit
253 + *
254 + * @var array
255 + */
256 + public $quick_edit_fields;
169 257
170 - $this->dateformat = str_replace(array('yy', 'mm', 'dd'), array('Y', 'm', 'd'), __('yy-mm-dd', 'event-post'));
258 + /**
259 + * Fields supported by bulk-edit
260 + *
261 + * @var array
262 + */
263 + public $bulk_edit_fields;
171 264
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);
265 + /**
266 + * Supported attendance modes
267 + *
268 + * @var array
269 + */
270 + public $attendance_modes;
189 271
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 - );
272 + /**
273 + * Supported statuses
274 + *
275 + * @var array
276 + */
277 + public $statuses;
201 278
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 - );
279 + /**
280 + * Default list schema (HTML template)
281 + *
282 + * @var string
283 + */
284 + public $default_list_shema;
221 285
222 - }
286 + /**
287 + * Default timeline schema (HTML template)
288 + *
289 + * @var string
290 + */
291 + public $default_timeline_shema;
223 292
224 - public function register_widgets(){
225 - register_widget('EventPost_List');
226 - register_widget('EventPost_Map');
227 - register_widget('EventPost_Cal');
228 - }
293 + /**
294 + * Current list schema (HTML template)
295 + *
296 + * @var string
297 + */
298 + public $list_shema;
229 299
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;
300 + /**
301 + * Current timeline schema (HTML template)
302 + *
303 + * @var string
304 + */
305 + public $timeline_shema;
306 +
307 + // Map variables
308 + /**
309 + * Map tiles
310 + *
311 + * @var array
312 + */
313 + public $maps;
314 +
315 + /**
316 + * Dirpath for map tiles
317 + *
318 + * @var string
319 + */
320 + public $markpath;
321 +
322 + /**
323 + * Base URL for map tiles
324 + *
325 + * @var string
326 + */
327 + public $markurl;
328 +
329 + // --------------------------------------------------------------------------------
330 + // Classes
331 +
332 + /**
333 + * Taxonomies object
334 + *
335 + * @var \EventPost\Taxonomies
336 + */
337 + public $Taxonomies;
338 +
339 + /**
340 + * Icons object
341 + *
342 + * @var \EventPost\Icons
343 + */
344 + public $DashIcons;
345 +
346 + /**
347 + * Settings object
348 + *
349 + * @var \EventPost\Settings
350 + */
351 + public $Settings;
352 +
353 + /**
354 + * Shortcodes object
355 + *
356 + * @var \EventPost\Shortcodes
357 + */
358 + public $Shortcodes;
359 +
360 + /**
361 + * Allowed tags in main outputs
362 + *
363 + * @var array
364 + */
365 + public $kses_tags;
366 +
367 +
368 + public function __construct() {
369 + add_action('init', array(&$this,'init'), 1);
370 + add_action('init', array(&$this,'widgets_init'), 10);
371 + add_action('init', array(&$this, 'register_widgets'), 30, 1);
372 +
373 + add_action('save_post', array(&$this, 'save_postdata'));
374 + add_filter('dashboard_glance_items', array(&$this, 'dashboard_right_now'));
375 +
376 + // Scripts
377 + add_action( 'admin_init', array(&$this, 'editor_styles'));
378 + add_action('admin_enqueue_scripts', array(&$this, 'admin_head'));
379 + add_action('admin_print_scripts', array(&$this, 'admin_scripts'));
380 + add_action('admin_print_scripts', array(&$this, 'load_scripts'), 1);
381 + add_action('wp_enqueue_scripts', array(&$this, 'load_scripts'), 1);
382 + add_action('wp_enqueue_scripts', array(&$this, 'load_styles'));
383 +
384 + // Single
385 + add_filter('the_content', array(&$this, 'display_single'), 9999);
386 + add_filter('the_title', array(&$this, 'the_title'), 9999, 2);
387 + add_action('the_event', array(&$this, 'print_single'));
388 + add_action('wp_head', array(&$this, 'single_header'));
389 + add_action('wpseo_schema_webpage', array(&$this, 'wpseo_schema_webpage'));
390 +
391 + // Ajax
392 + add_action('wp_ajax_EventPostGetLatLong', array(&$this, 'GetLatLong'));
393 + add_action('wp_ajax_EventPostHumanDate', array(&$this, 'HumanDate'));
394 + add_action('wp_ajax_EventPostList', array(&$this, 'ajaxlist'));
395 + add_action('wp_ajax_EventPostTimeline', array(&$this, 'ajaxTimeline'));
396 + add_action('wp_ajax_EventPostNextPage', array(&$this, 'ajaxGetNextPage'));
397 + add_action('wp_ajax_nopriv_EventPostNextPage', array(&$this, 'ajaxGetNextPage'));
398 + add_action('wp_ajax_EventPostMap', array(&$this, 'ajaxmap'));
399 + add_action('wp_ajax_EventPostCalendar', array(&$this, 'ajaxcal'));
400 + add_action('wp_ajax_nopriv_EventPostCalendar', array(&$this, 'ajaxcal'));
401 + add_action('wp_ajax_EventPostCalendarDate', array(&$this, 'ajaxdate'));
402 + add_action('wp_ajax_nopriv_EventPostCalendarDate', array(&$this, 'ajaxdate'));
403 +
404 + // Calendar publishing
405 + add_action('parse_request', array(&$this, 'parse_request'), 100);
406 + add_action('wp_ajax_EventPostExport', array(&$this, 'export'));
407 + add_action('wp_ajax_nopriv_EventPostExport', array(&$this, 'export'));
408 + add_action('wp_ajax_EventPostFeed', array(&$this, 'feed'));
409 + add_action('wp_ajax_nopriv_EventPostFeed', array(&$this, 'feed'));
410 +
411 + // Internal filters
412 + add_filter('eventpost_list_shema',array(&$this, 'custom_shema'),10,1);
413 +
414 + // Quick edit
415 + add_action( 'bulk_edit_custom_box', array( &$this, 'bulk_edit' ), 10, 2 );
416 + add_action( 'quick_edit_custom_box', array( &$this, 'quick_edit' ), 10, 2 );
417 + add_action( 'admin_print_scripts-edit.php', array(&$this, 'scripts_edit') );
418 + add_action( 'wp_ajax_inline-save', array(&$this, 'inline_save'), 1 );
419 + add_action( 'bulk_edit_posts', array(&$this, 'save_bulkdatas'), 10, 2 );
420 + add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_color'), 10, 3);
421 + add_filter( 'eventpost_inline_field', array(&$this, 'inline_field_icon'), 10, 3);
422 +
423 + $inc_path = plugin_dir_path(__FILE__).'inc/';
424 + $this->plugin_path = plugin_dir_path(__FILE__);
425 + include_once ($inc_path . 'class-settings.php');
426 + include_once ($inc_path . 'wrappers.php');
427 + include_once ($inc_path . 'deprecated/widget.php');
428 + include_once ($inc_path . 'deprecated/widget.cal.php');
429 + include_once ($inc_path . 'deprecated/widget.map.php');
430 + include_once ($inc_path . 'class-multisite.php');
431 + include_once ($inc_path . 'class-shortcodes.php');
432 + include_once ($inc_path . 'openweathermap.php');
433 + include_once ($inc_path . 'class-children.php');
434 + include_once ($inc_path . 'class-icons.php');
435 + include_once ($inc_path . 'class-taxonomies.php');
436 +
437 + $this->DashIcons = new EventPost\Icons();
438 + $this->Settings = new EventPost\Settings($this->DashIcons);
439 + $this->Taxonomies = new EventPost\Taxonomies($this->DashIcons);
239 440 }
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 441
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 - }
442 + /**
443 + * PHP4 constructor
444 + */
445 + public function EventPost(){
446 + $this->__construct();
447 + }
266 448
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();
449 + public function init(){
450 + $admin_url = admin_url('admin-ajax.php?action=EventPostFeed');
451 + $admin_url = str_replace(site_url(), '', $admin_url);
452 + $plugins_url = plugins_url('export/ics.php', __FILE__);
453 + $plugins_url = str_replace(site_url(), '', $plugins_url);
454 + add_rewrite_rule('event-feed/?', $admin_url , 'top');
455 + add_rewrite_rule('eventpost/([0-9]*)\.(ics|vcs)?',$plugins_url, 'top');
456 +
457 + $this->list_id = 0;
458 + $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'));
459 + $this->Week = array(__('Sunday', 'event-post'), __('Monday', 'event-post'), __('Tuesday', 'event-post'), __('Wednesday', 'event-post'), __('Thursday', 'event-post'), __('Friday', 'event-post'), __('Saturday', 'event-post'));
460 + $this->attendance_modes = array(
461 + 'OfflineEventAttendanceMode' => _x('Physical', 'Attendance Mode', 'event-post'),
462 + 'MixedEventAttendanceMode' => _x('Mixed', 'Attendance Mode', 'event-post'),
463 + 'OnlineEventAttendanceMode' => _x('Online', 'Attendance Mode', 'event-post'),
464 + );
465 + $this->statuses = array(
466 + 'EventScheduled' => _x('Scheduled', 'Event Status', 'event-post'),
467 + 'EventCancelled' => _x('Cancelled', 'Event Status', 'event-post'),
468 + 'EventMovedOnline' => _x('Moved Online', 'Event Status', 'event-post'),
469 + 'EventPostponed' => _x('Postoned', 'Event Status', 'event-post'),
470 + 'EventRescheduled' => _x('Rescheduled', 'Event Status', 'event-post'),
471 + 'EventCompleted' => _x('Completed', 'Event Status', 'event-post'),
472 + );
473 +
474 + $this->maps = $this->get_maps();
475 + $this->settings = $this->get_settings();
476 +
477 + do_action('evenpost_init', $this);
478 +
479 + // Edit
480 + add_action('add_meta_boxes', array(&$this, 'add_custom_box'));
481 + foreach($this->settings['posttypes'] as $posttype){
482 + add_filter('manage_'.$posttype.'_posts_columns', array(&$this, 'columns_head'), 2);
483 + add_action('manage_'.$posttype.'_posts_custom_column', array(&$this, 'columns_content'), 10, 2);
484 + }
485 + $this->Taxonomies->add_fields_to_taxonomies($this->settings['posttypes']);
486 +
487 + $this->markpath = '';
488 + $this->markurl = '';
489 + if (!empty($this->settings['markpath']) && !empty($this->settings['markurl'])) {
490 + $this->markpath = ABSPATH.'/'.$this->settings['markpath'];
491 + $this->markurl = $this->settings['markurl'];
492 + } else {
493 + // $this->markpath = plugin_dir_path(__FILE__) . 'markers/';
494 + // $this->markurl = plugins_url('/markers/', __FILE__);
495 + }
496 +
497 + $this->currencies = include (plugin_dir_path(__FILE__) . 'inc/data/currencies.php');
498 +
499 + $this->dateformat = str_replace(array('yy', 'mm', 'dd'), array('Y', 'm', 'd'), __('yy-mm-dd', 'event-post'));
500 +
501 + $this->default_list_shema = apply_filters('eventpost_default_list_shema', array(
502 + 'container' => '<%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>'.
503 + '%list%'.
504 + '%pagination%'.
505 + '</%type%><!-- .event_loop -->',
506 + 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">'.
507 + '<a href="%event_link%">'.
508 + '%event_thumbnail%'.
509 + '<h5>%event_title% </h5>'.
510 + '</a>'.
511 + '%event_price%'.
512 + '%event_date%'.
513 + '%event_cat%'.
514 + '%event_location%'.
515 + '%event_excerpt%'.
516 + '</%child%><!-- .event_item -->'
517 + ));
518 + $this->list_shema = apply_filters('eventpost_list_shema',$this->default_list_shema);
519 +
520 + $this->default_timeline_shema = apply_filters('eventpost_default_timeline_shema', array(
521 + 'container' => '
522 + <%type% class="event_loop %id% %class%" id="%listid%" style="%style%" %attributes%>
523 + %prev_arrow%
524 + <div class="track">
525 + %list%
526 + </div>
527 + %next_arrow%
528 + </%type%><!-- .event_loop -->',
529 + 'item' => '<%child% class="event_item %class%" data-color="%color%" style="%style%">
530 + <div class="anchor" style="background-color:#%color%"></div>
531 + %event_date%
532 + %event_location%
533 + %event_cat%
534 + %event_excerpt%
535 + <a href="%event_link%">
536 + %event_thumbnail%
537 + <h5>%event_title%</h5>
538 + </a>
539 + %event_price%
540 + </%child%><!-- .event_item -->'
541 + ));
542 + $this->timeline_shema = apply_filters('eventpost_timeline_shema',$this->default_timeline_shema);
543 +
544 + $this->map_interactions=array(
545 + 'DragRotate'=>__('Drag Rotate', 'event-post'),
546 + 'DoubleClickZoom'=>__('Double Click Zoom', 'event-post'),
547 + 'DragPan'=>__('Drag Pan', 'event-post'),
548 + 'PinchRotate'=>__('Pinch Rotate', 'event-post'),
549 + 'PinchZoom'=>__('Pinch Zoom', 'event-post'),
550 + 'KeyboardPan'=>__('Keyboard Pan', 'event-post'),
551 + 'KeyboardZoom'=>__('Keyboard Zoom', 'event-post'),
552 + 'MouseWheelZoom'=>__('Mouse Wheel Zoom', 'event-post'),
553 + 'DragZoom'=>__('Drag Zoom', 'event-post'),
554 + );
555 +
556 + $this->quick_edit_fields = apply_filters('eventpost_quick_edit_fields', array(
557 + 'event'=>array(
558 + $this->META_START=>__('Begin:', 'event-post'),
559 + $this->META_END=>__('End:', 'event-post'),
560 + $this->META_COLOR=>__('Color:', 'event-post'),
561 + $this->META_ICON=>__('Icon:', 'event-post'),
562 + ),
563 + 'location'=>array(
564 + $this->META_ADD=>__('Address:', 'event-post'),
565 + $this->META_LAT=>__('Latitude:', 'event-post'),
566 + $this->META_LONG=>__('Longitude:', 'event-post'),
567 + ),
568 + )
569 + );
570 + $this->bulk_edit_fields = apply_filters('eventpost_bulk_edit_fields', array(
571 + 'event'=>array(
572 + $this->META_COLOR=>__('Color:', 'event-post'),
573 + $this->META_ICON=>__('Icon:', 'event-post'),
574 + ),
575 + )
576 + );
577 +
578 + $this->kses_tags = apply_filters('eventpost_kses_tags', json_decode(
579 + file_get_contents(plugin_dir_path(__FILE__).'inc/data/kses-tags.json'),
580 + true
581 + ));
582 +
583 +
281 584 }
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 585
348 - if (!isset($ep_settings['item_shema']) ) {
349 - $ep_settings['item_shema'] = '';
350 - $reg_settings=true;
351 - }
586 + /**
587 + * Init all variables when WP is ready
588 + *
589 + * @action evenpost_init
590 + * @filter eventpost_default_list_shema
591 + * @filter eventpost_list_shema
592 + */
593 + public function widgets_init(){
594 + $this->Shortcodes = new EventPost\Shortcodes();
352 595
353 - if(!isset($ep_settings['datepicker']) || !in_array($ep_settings['datepicker'], array('simple', 'native'))){
354 - $ep_settings['datepicker']='simple';
355 - $reg_settings=true;
356 - }
596 + if(function_exists('register_block_type')){
597 + $block_path = plugin_dir_path(__FILE__).'inc/blocks/';
598 + include_once ($block_path . 'eventslist.php');
599 + include_once ($block_path . 'eventstimeline.php');
600 + include_once ($block_path . 'eventsmap.php');
601 + include_once ($block_path . 'eventscalendar.php');
602 + include_once ($block_path . 'eventdetails.php');
603 + }
357 604
358 - if(!isset($ep_settings['posttypes']) || !is_array($ep_settings['posttypes'])){
359 - $ep_settings['posttypes']=array('post');
360 - $reg_settings=true;
361 - }
362 605
363 - do_action_ref_array('eventpost_getsettings_action', array(&$ep_settings, &$reg_settings));
606 + // WooCommerce
607 + if (class_exists('WooCommerce') && in_array('product', $this->settings['posttypes'])) {
608 + include_once (plugin_dir_path(__FILE__).'inc/woocommerce.php');
609 + }
610 + }
364 611
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 - }
612 + public function register_widgets(){
613 + register_widget('EventPost_List');
614 + register_widget('EventPost_Map');
615 + register_widget('EventPost_Cal');
616 + }
371 617
372 - /**
373 - * Checks if HTML schemas are not empty
374 - * @param array $shema
375 - * @return array
376 - */
377 - public function custom_shema($shema){
618 + /**
619 + * Usefull hexadecimal to decimal converter. Returns an array of RGB from a given hexadecimal color.
620 + *
621 + * @param string $color
622 + *
623 + * @return array $color($R, $G, $B)
624 + */
625 + public function hex2dec($color = '000000') {
626 + $tbl_color = array();
627 + if(!is_string($color) || empty($color)){
628 + $color = '000000';
629 + }
630 + if (substr($color, 0, 1)!='#'){
631 + $color = '#' . $color;
632 + }
633 + $tbl_color['R'] = hexdec(substr($color, 1, 2));
634 + $tbl_color['G'] = hexdec(substr($color, 3, 2));
635 + $tbl_color['B'] = hexdec(substr($color, 5, 2));
636 + return $tbl_color;
637 + }
638 +
639 + /**
640 + * Fetch all registered image sizes
641 + *
642 + * @global array $_wp_additional_image_sizes
643 + *
644 + * @return array
645 + */
646 + function get_thumbnail_sizes(){
647 + global $_wp_additional_image_sizes;
648 + $sizes = array('thumbnail', 'medium', 'large', 'full');
649 + foreach(array_keys($_wp_additional_image_sizes) as $size){
650 + $sizes[]=$size;
651 + }
652 + return $sizes;
653 + }
654 +
655 + /**
656 + * Get blog settings, load and saves default settings if needed. Can be filterred using
657 + *
658 + * @example `<?php add_filter('eventpost_getsettings', 'some_function'); ?>`
659 + *
660 + * @action eventpost_getsettings_action
661 + * @filter eventpost_getsettings
662 + *
663 + * @return array
664 + */
665 + public function get_settings() {
666 + $ep_settings = $this->Settings->get_settings();
667 + return apply_filters('eventpost_getsettings', $ep_settings);
668 + }
669 +
670 + /**
671 + * Checks if HTML schemas are not empty
672 + *
673 + * @param array $shema
674 + *
675 + * @return array
676 + */
677 + public function custom_shema($shema){
378 678 if(!empty($this->settings['container_shema'])){
379 - $shema['container']=$this->settings['container_shema'];
679 + $shema['container']=$this->settings['container_shema'];
380 680 }
381 681 if(!empty($this->settings['item_shema'])){
382 - $shema['item']=$this->settings['item_shema'];
682 + $shema['item']=$this->settings['item_shema'];
383 683 }
384 684 return $shema;
385 - }
685 + }
386 686
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 - }
687 + /**
688 + * Parse the maps.json file. Custom maps can be added by using the `eventpost_getsettings` filter like the following example:
689 + *
690 + * ```
691 + * <?php
692 + * add_filter('eventpost_getsettings', 'map_function');
693 + * function map_function($maps){
694 + * array_push($maps, array(
695 + * 'name'=>'Myt custom map',
696 + * 'id'=>'custom_map',
697 + * 'urls'=>array(
698 + * 'http://a.customurl.org/{z}/{x}/{y}.png',
699 + * 'http://b.customurl.org/{z}/{x}/{y}.png',
700 + * 'http://c.customurl.org/{z}/{x}/{y}.png',
701 + * )
702 + * ));
703 + * return $maps;
704 + * }
705 + * ?>
706 + * ```
707 + *
708 + * @filter eventpost_maps
709 + *
710 + * @return array of map arrays ['name', 'id', 'urls']
711 + */
712 + public function get_maps() {
713 + $maps = array();
714 + $filename = plugin_dir_path(__FILE__) . 'maps.json';
715 + if (is_file($filename) && (false !== $json = json_decode(file_get_contents($filename)))) {
716 + // Convert objects to array to ensure retrocompatibility
717 + $arrays = array();
718 + foreach($json as $map){
719 + $arrays[$map->id] = (array) $map;
720 + }
721 + $maps = apply_filters('eventpost_maps', $arrays);
722 + }
723 + return $maps;
724 + }
424 725
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 - }
726 + /**
727 + * Get colors
728 + *
729 + * @return array
730 + */
731 + public function get_colors() {
732 + $colors = array();
733 + if (is_dir($this->markpath)) {
734 + $files = scandir($this->markpath);
735 + foreach ($files as $file) {
736 + if (substr($file, -4) == '.png') {
737 + $colors[substr($file, 0, -4)] = $this->markurl . $file;
738 + }
739 + }
740 + }
741 + return $colors;
742 + }
441 743
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 - }
744 + /**
745 + * Get color of a post
746 + *
747 + * @param int $post_id
748 + * @param bool $default
749 + * @param bool $check_taxo
750 + *
751 + * @return string color
752 + */
753 + public function get_post_color($post_id, $default = false, $check_taxo = false) {
754 + $color = get_post_meta($post_id, $this->META_COLOR,true);
755 + if($color && !empty($color)){
756 + return event_post_format_color($color);
757 + }else{
758 + if($check_taxo){
759 + foreach(event_post_get_all_terms($post_id) as $term){
760 + $taxo_color = $this->Taxonomies->get_taxonomy_color($term->term_id);
761 + if($taxo_color){
762 + return event_post_format_color($taxo_color);
763 + }
764 + }
765 + }
766 + }
767 + return event_post_format_color($default);
768 + }
453 769
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 - }
770 + /**
771 + * Get icon of a post
772 + *
773 + * @param int $post_id
774 + * @param bool $default
775 + * @param bool $check_taxo
776 + *
777 + * @return string|false icon
778 + */
779 + public function get_post_icon($post_id, $default = false, $check_taxo = false) {
780 + $icon = get_post_meta($post_id, $this->META_ICON,true);
781 + if($icon && !empty($icon)){
782 + return $icon;
783 + }else{
784 + if($check_taxo){
785 + foreach(event_post_get_all_terms($post_id) as $term){
786 + $taxo_icon = $this->Taxonomies->get_taxonomy_icon($term->term_id);
787 + if($taxo_icon){
788 + return event_post_format_color($taxo_icon);
789 + }
790 + }
791 + }
792 + }
793 + return $default;
794 + }
469 795
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 - }
796 + /**
797 + * Get the URL of a marker
798 + *
799 + * @param string $color
800 + *
801 + * @return sring
802 + */
803 + public function get_marker($color) {
804 + if (is_file($this->markpath . $color . '.png')) {
805 + return $this->markurl . $color . '.png';
806 + }
807 + return "";
808 + }
480 809
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 - }
810 + /**
811 + * Enqueue CSS files
812 + */
813 + public function load_styles($deps = null) {
814 + //CSS
815 + if(!empty($this->settings['customcss'])){
816 + wp_enqueue_style('event-post-custom', $this->settings['customcss']);
817 + }
818 + elseif(is_file(get_stylesheet_directory().'/event-post.css') || is_file(get_template_directory().'/event-post.css')){
819 + wp_enqueue_style('event-post-custom', get_theme_file_uri('event-post.css'));
820 + }
821 + else{
822 + wp_register_style('event-post', plugins_url('/build/front/front.css', __FILE__), $deps, filemtime( "{$this->plugin_path}/build/front/front.css" ));
823 + wp_enqueue_style('event-post');
824 + }
508 825
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 - }
826 + // Lib scripts
827 + wp_enqueue_style('dashicons', includes_url('/css/dashicons.min.css'));
828 + }
521 829
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 - }
830 + /**
831 + * Enqueue Editor style
832 + */
833 + public function editor_styles() {
834 + add_editor_style( plugins_url('/build/front/front.css', __FILE__) );
835 + }
590 836
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) ?>"/>
837 + /**
838 + * Enqueue JS files
839 + */
840 + public function load_scripts() {
841 + wp_enqueue_script('event-post', plugins_url('/build/front/front.js', __FILE__), array(), filemtime( "{$this->plugin_path}/build/front/front.js" ), true);
842 + $maps = $this->maps;
843 + foreach($maps as $m=>$map){
844 + if(isset($map['api_param']) && $this->settings['tile_api_key']){
845 + foreach($map['urls'] as $i=>$url){
846 + $maps[$m]['urls'][$i] = add_query_arg($map['api_param'], $this->settings['tile_api_key'], $url);
847 + }
848 + }
849 + }
850 + wp_add_inline_script('event-post', 'var EventPost = EventPost || {}; EventPost.front='.wp_json_encode(array(
851 + 'scripts' => array(
852 + 'map' => plugins_url('/build/map/event-map.js', __FILE__)
853 + ),
854 + 'imgpath' => plugins_url('/img/', __FILE__),
855 + 'maptiles' => $maps,
856 + 'defaulttile' => $this->settings['tile'],
857 + 'zoom' => $this->settings['zoom'],
858 + 'ajaxurl' => admin_url() . 'admin-ajax.php',
859 + 'map_interactions'=>$this->map_interactions,
860 + )), 'before');
861 + }
862 + /**
863 + * Enqueue JS files for maps
864 + */
865 + public function load_map_scripts() {
866 + $this->load_styles(array('event-post-map'));
867 + // JS
868 + if(is_admin()){
869 + $this->admin_scripts(array('jquery', 'event-post-map'));
870 + }
871 + }
872 +
873 + /**
874 + * Enqueue CSS files in admin
875 + */
876 + public function admin_head() {
877 + $page = basename($_SERVER['SCRIPT_NAME']);
878 + if( $page!='post-new.php' && $page!='edit-tags.php' && !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') && !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings') ){
879 + return;
880 + }
881 + wp_enqueue_style('event-post-admin', plugins_url('/build/admin/admin.css', __FILE__), false, filemtime( "{$this->plugin_path}/build/admin/admin.css" ));
882 + }
883 +
884 + /**
885 + * Enqueue JS files in admin
886 + */
887 + public function admin_scripts($deps = array('jquery'), $force=false) {
888 + $page = basename($_SERVER['SCRIPT_NAME']);
889 + if(!$force &&
890 + $page!='post-new.php' &&
891 + $page!='edit-tags.php' &&
892 + $page!='term.php' &&
893 + !($page=='post.php' && filter_input(INPUT_GET, 'action')=='edit') &&
894 + !($page=='options-general.php' && filter_input(INPUT_GET, 'page')=='event-settings')
895 + ){
896 + return;
897 + }
898 + wp_enqueue_script('jquery');
899 + wp_enqueue_script('jquery-effects-core');
900 + wp_enqueue_script('jquery-effects-shake');
901 + wp_enqueue_style( 'wp-color-picker');
902 + wp_enqueue_script( 'wp-color-picker');
903 + if(!is_array($deps)){
904 + $deps = array('jquery','wp-color-picker');
905 + }
906 + if($this->settings['datepicker']=='simple' || !is_admin() || (isset($_GET['page']) && $_GET['page']=='event-settings')){
907 + wp_enqueue_script('jquery-ui-datepicker');
908 + $deps[] = 'jquery-ui-datepicker';
909 + }
910 + wp_enqueue_script('event-post-admin', plugins_url('/build/admin/admin.js', __FILE__), $deps, filemtime( "{$this->plugin_path}/build/admin/admin.js" ), true);
911 + $language = get_bloginfo('language');
912 + if (strpos($language, '-') > -1) {
913 + $language = strtolower(substr($language, 0, 2));
914 + }
915 + wp_add_inline_script('event-post-admin', 'var EventPost = EventPost || {}; EventPost.admin='.wp_json_encode(array(
916 + 'ajaxurl' => admin_url('admin-ajax.php'),
917 + 'imgpath' => plugins_url('/img/', __FILE__),
918 + 'date_choose' => __('Choose', 'event-post'),
919 + 'date_format' => __('yy-mm-dd', 'event-post'),
920 + 'more_icons' => __('More icons', 'event-post'),
921 + 'pick_a_date'=>__('Pick a date','event-post'),
922 + 'use_current_location'=>__('Use my current location','event-post'),
923 + 'start_drag'=>__('Click to<br>drag the map<br>and change location','event-post'),
924 + 'empty_address'=>__('Be kind to fill a non empty address:)', 'event-post'),
925 + 'search'=>__('Type an address', 'event-post'),
926 + 'search_button'=>__('Search', 'event-post'),
927 + 'geocoding_attribution'=>__('Geocoding by <a href="https://nominatim.openstreetmap.org/" target="_blank">OpenStreetmap Nominatim</a>', 'event-post'),
928 + 'stop_drag'=>_x('Done','Stop allowing to drag the map', 'event-post'),
929 + 'datepickeri18n'=>array(
930 + // Translators: %1$s is the month name, %2$s is the day number, %3$s is the year, %4$s is the hour, %5$s is the minute
931 + 'order'=>__( '%1$s %2$s, %3$s @ %4$s:%5$s', 'event-post'),
932 + 'day'=>__('Day', 'event-post'),
933 + 'month'=>__('Month', 'event-post'),
934 + 'year'=>__('Day', 'event-post'),
935 + 'hour'=>__('Hour', 'event-post'),
936 + 'minute'=>__('Minute', 'event-post'),
937 + 'ok'=>__('OK', 'event-post'),
938 + 'cancel'=>__('Cancel', 'event-post'),
939 + 'remove'=>__('Remove', 'event-post'),
940 + 'edit'=>__('Edit', 'event-post'),
941 + 'months'=>$this->NomDuMois,
942 + ),
943 + 'META_START' => $this->META_START,
944 + 'META_END' => $this->META_END,
945 + 'META_ADD' => $this->META_ADD,
946 + 'META_LAT' => $this->META_LAT,
947 + 'META_LONG' => $this->META_LONG,
948 + 'META_STATUS' => $this->META_STATUS,
949 + 'META_ATTENDANCE_MODE' => $this->META_ATTENDANCE_MODE,
950 + 'lang'=>$language,
951 + 'maptiles' => $this->maps,
952 + 'defaulttile' => $this->settings['tile'],
953 + 'palette' => $this->get_theme_palette("hex"),
954 + 'available_images' => $this->get_colors(),
955 + )));
956 + }
957 + function scripts_edit() {
958 + // load only when editing a supported post type
959 + $current_post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
960 + if ( in_array( $current_post_type, $this->settings['posttypes'] ) ) {
961 + wp_enqueue_script( 'eventpost-inline-edit', plugins_url( 'build/admin/inline-edit.js', __FILE__ ), array( 'jquery', 'inline-edit-post' ), '', true );
962 + wp_add_inline_script('eventpost-inline-edit', 'var EventPost = EventPost || {}; EventPost.inlineEdit='.wp_json_encode(array(
963 + 'quick'=>$this->quick_edit_fields,
964 + 'bulk'=>$this->bulk_edit_fields,
965 + )));
966 + }
967 + }
968 +
969 + function get_rich_result($event){
970 + /*
971 + * https://search.google.com/test/rich-results
972 + {
973 + "@context": "https://schema.org",
974 + "@type": "Event",
975 + "name": "The Adventures of Kira and Morrison",
976 + "startDate": "2025-07-21T19:00",
977 + "endDate": "2025-07-21T23:00",
978 + "eventStatus": "https://schema.org/EventScheduled",
979 + "eventAttendanceMode": "https://schema.org/OnlineEventAttendanceMode",
980 + "location": {
981 + "@type": "VirtualLocation",
982 + "url": "https://operaonline.stream5.com/"
983 + },
984 + "image": [
985 + "https://example.com/photos/1x1/photo.jpg",
986 + "https://example.com/photos/4x3/photo.jpg",
987 + "https://example.com/photos/16x9/photo.jpg"
988 + ],
989 + "description": "The Adventures of Kira and Morrison is coming to Snickertown in a can’t miss performance.",
990 + "offers": {
991 + "@type": "Offer",
992 + "url": "https://www.example.com/event_offer/12345_201803180430",
993 + "price": "30",
994 + "priceCurrency": "USD",
995 + "availability": "https://schema.org/InStock",
996 + "validFrom": "2024-05-21T12:00"
997 + },
998 + "performer": {
999 + "@type": "PerformingGroup",
1000 + "name": "Kira and Morrison"
1001 + }
1002 + }
1003 + */
1004 + $location_virtual = array(
1005 + '@type'=>'VirtualLocation',
1006 + 'url'=>$event->virtual_location,
1007 + );
1008 + $physical_location = array(
1009 + '@type'=>'place',
1010 + 'name'=>$event->address,
1011 + 'address'=>$event->address,
1012 + 'geo'=>array(
1013 + '@type'=>'GeoCoordinates',
1014 + 'latitude'=>$event->lat,
1015 + 'longitude'=>$event->long,
1016 + ),
1017 + );
1018 + $min = 60 * get_option('gmt_offset');
1019 + $sign = $min < 0 ? "-" : "+";
1020 + $absmin = abs($min);
1021 + $gmt_offset = sprintf("%s%02d:%02d", $sign, $absmin/60, $absmin%60);
1022 + $time_format = (is_numeric($event->time_start) && is_numeric($event->time_end) && date('H:i', $event->time_start) != date('H:i', $event->time_end) && date('H:i', $event->time_start) != '00:00' && date('H:i', $event->time_end) != '00:00') ? 'Y-m-d\Th:i:00'.$gmt_offset : 'Y-m-d';
1023 +
1024 + $rich_data = array(
1025 + '@context'=>'https://schema.org',
1026 + '@type'=>'event',
1027 + 'name'=>$event->post_title,
1028 + 'datePublished'=>str_replace(' ', 'T', $event->post_date_gmt).$gmt_offset,
1029 + 'dateModified'=>str_replace(' ', 'T', $event->post_modified_gmt).$gmt_offset,
1030 + 'startDate'=>$event->time_start ? date($time_format, $event->time_start) : null,
1031 + 'endDate'=>$event->time_end ? date($time_format, $event->time_end) : null,
1032 + 'eventStatus'=>$event->status,
1033 + 'eventAttendanceMode'=>$event->attendance_mode,
1034 + 'location'=> ($event->attendance_mode == 'MixedEventAttendanceMode') ? array($location_virtual,$physical_location) : ($event->attendance_mode == 'OnlineEventAttendanceMode' ? $location_virtual : $physical_location),
1035 + 'image'=> has_post_thumbnail($event->ID) ? array(
1036 + get_the_post_thumbnail_url($event->ID, 'post-thumbnail'),
1037 + get_the_post_thumbnail_url($event->ID, 'medium'),
1038 + get_the_post_thumbnail_url($event->ID, 'large'),
1039 + get_the_post_thumbnail_url($event->ID, 'full'),
1040 + ) : null,
1041 + 'description'=>$event->description,
1042 + );
1043 + if(!empty($event->organization)){
1044 + $rich_data['organizer'] = array(
1045 + '@type'=>'Organization',
1046 + 'name'=>$event->organization,
1047 + );
1048 + }
1049 + if(!empty($event->offer)){
1050 + $rich_data['offers'] = array(
1051 + '@type'=>'Offer',
1052 + // 'availability'=>$event->availability,
1053 + // 'validFrom'=>date($time_format, $event->time_start),
1054 + );
1055 + if(!empty($event->offer['url'])){
1056 + $rich_data['offers']['url'] = $event->offer['url'];
1057 + }
1058 + if(!empty($event->offer['price'])){
1059 + $rich_data['offers']['price'] = $event->offer['price'];
1060 + }
1061 + if(!empty($event->offer['currency'])){
1062 + $rich_data['offers']['priceCurrency'] = $event->offer['currency'];
1063 + }
1064 + }
1065 +
1066 + return apply_filters('event-post-rich-result', $rich_data, $event);
1067 + }
1068 +
1069 + function wpseo_schema_webpage($rich_result){
1070 + $event = $this->retreive();
1071 + if ($event != false){
1072 + if ($event->time_start != '' && $event->time_end != '') {
1073 + $rich_result = array_merge($rich_result, $this->get_rich_result($event));
1074 + }
1075 + $this->is_schema_output = true;
1076 + }
1077 + return $rich_result;
1078 + }
1079 +
1080 + function get_theme_palette($return = "hex"){
1081 + $theme_options = wp_get_global_settings();
1082 + $colors = [];
1083 + if(isset($theme_options['color']['palette']['theme'])){
1084 + $colors = $theme_options['color']['palette']['theme'];
1085 + }elseif(isset($theme_options['color']['palette']['default'])){
1086 + $colors = $theme_options['color']['palette']['default'];
1087 + }
1088 + if($return == "hex"){
1089 + $color_hexs = [];
1090 + foreach($colors as $color){
1091 + $color_hexs[] = $color["color"];
1092 + }
1093 + return $color_hexs;
1094 + }
1095 + return $colors;
1096 + }
1097 +
1098 + /**
1099 + * Add custom header meta for single events
1100 + */
1101 + public function single_header() {
1102 + if (is_single()) {
1103 + $twitter_label_id=0;
1104 + $event = $this->retreive();
1105 + $has_location = $has_time = false;
1106 + if ($event != false) {
1107 + if ($event->address != '' || ($event->lat != '' && $event->long != '')) {
1108 + $twitter_label_id++;
1109 + $has_location = true;
1110 + ?>
1111 +<meta name="geo.placename" content="<?php echo esc_attr($event->address) ?>" />
1112 +<meta name="geo.position" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
1113 +<meta name="ICBM" content="<?php echo esc_attr($event->lat) ?>;<?php echo esc_attr($event->long) ?>" />
1114 +<meta property="place:location:latitude" content="<?php echo esc_attr($event->lat) ?>" />
1115 +<meta property="place:location:longitude" content="<?php echo esc_attr($event->long) ?>" />
1116 +<meta name="twitter:label<?php echo esc_attr($twitter_label_id); ?>" content="<?php esc_attr_e('Location', 'event-post'); ?>"/>
1117 +<meta name="twitter:data<?php echo esc_attr($twitter_label_id); ?>" content="<?php echo esc_attr($event->address) ?>"/>
608 1118 <?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)) ?>"/>
1119 + }
1120 + if ($event->start != '' && $event->end != '') {
1121 + $has_time = true;
1122 + $twitter_label_id++;
1123 + ?>
1124 +<meta name="datetime-coverage-start" content="<?php echo esc_attr(date('c', $event->time_start)) ?>" />
1125 +<meta name="datetime-coverage-end" content="<?php echo esc_attr(date('c', $event->time_end)) ?>" />
1126 +<meta name="twitter:label<?php echo esc_attr($twitter_label_id); ?>" content="<?php echo esc_attr('Date', 'event-post'); ?>"/>
1127 +<meta name="twitter:data<?php echo esc_attr($twitter_label_id); ?>" content="<?php echo esc_attr($this->human_date($event->time_start)) ?>"/>
617 1128 <?php
618 - }
619 - }
620 - }
1129 + }
1130 + if(($has_location || $has_time) && !$this->is_schema_output){
1131 + $rich_result = $this->get_rich_result($event);
1132 + $this->is_schema_output = true;
1133 + ?>
1134 + <script type="application/ld+json"><?php echo \wp_json_encode($rich_result); ?></script>
1135 + <?php
1136 + }
1137 + }
1138 + }
1139 + }
621 1140
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 - }
1141 + /**
1142 + * Cleanups a date
1143 + *
1144 + * @param type $str
1145 + *
1146 + * @since 5.0.1
1147 + *
1148 + * @return string
1149 + */
1150 + public function date_cleanup($str){
1151 + return trim(str_replace(array('0', ' ', ':', '-'), '', $str));
1152 + }
631 1153
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 - }
1154 + /**
1155 + * Checks if a date is valid or not
1156 + *
1157 + * @param string $str
1158 + *
1159 + * @return boolean
1160 + */
1161 + public function dateisvalid($str) {
1162 + return is_string($str) && $this->date_cleanup($str) != '';
1163 + }
640 1164
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 - }
1165 + /**
1166 + * Parse a date from a string
1167 + *
1168 + * @param string $date
1169 + * @param string $sep
1170 + *
1171 + * @return string
1172 + */
1173 + public function parsedate($date, $sep = '') {
1174 + if (!empty($date)) {
1175 + return substr($date, 0, 10) . $sep . substr($date, 11, 8);
1176 + } else {
1177 + return '';
1178 + }
1179 + }
654 1180
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 - }
1181 + /**
1182 + * Sanitize a coordinate string
1183 + * Only keeps, numbers, dots and commas
1184 + *
1185 + * @param string $str
1186 + *
1187 + * @since 5.9.9
1188 + *
1189 + * @return string
1190 + */
1191 + public function sanitize_coordinate($str){
1192 + return preg_replace('/[^0-9\.,-]/', '', $str);
1193 + }
673 1194
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 - }
1195 + /**
1196 + * Format a date for humans
1197 + *
1198 + * @param mixed $date
1199 + * @param string $format
1200 + *
1201 + * @return type
1202 + */
1203 + public function human_date($date, $format = 'l j F Y') {
1204 + if($this->settings['dateforhumans']){
1205 + if (is_numeric($date) && date('d/m/Y', $date) == date('d/m/Y')) {
1206 + return __('today', 'event-post');
1207 + } elseif (is_numeric($date) && date('d/m/Y', $date) == date('d/m/Y', strtotime('+1 day'))) {
1208 + return __('tomorrow', 'event-post');
1209 + } elseif (is_numeric($date) && date('d/m/Y', $date) == date('d/m/Y', strtotime('-1 day'))) {
1210 + return __('yesterday', 'event-post');
1211 + }
1212 + }
1213 + return date_i18n($format, $date);
1214 + }
684 1215
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 - }
1216 + /**
1217 + * Returns a range of dates
1218 + *
1219 + * @param timestamp $time_start
1220 + * @param timestamp $time_end
1221 + *
1222 + * @return string
1223 + */
1224 + public function delta_date($time_start, $time_end){
1225 + if(!$time_start || !$time_end){
1226 + return;
1227 + }
719 1228
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 != '') {
1229 + // Translators: %1$s, %4$s are opening tags, %2$s and %5$s are closing tag, %3$s is the first date, %6$s is the second date
1230 + $from_to_days = _x('%1$sfrom%2$s %3$s %4$sto%5$s %6$s', 'Days', 'event-post');
1231 + // Translators: %1$s is the first date, %4$s is the second date, %2$s is an opening tag, %3$s is a closing tag
1232 + $single_day_at = _x('%1$s%2$s,%3$s %4$s', 'From/To single day at time', 'event-post');
1233 + // Translators: %1$s, %4$s are opening tags, %2$s and %5$s are closing tag, %3$s is the first hour, %6$s is the second hour
1234 + $from_to_hours = _x('%1$sfrom%2$s %3$s %4$sto%5$s %6$s', 'Hours', 'event-post');
1235 + // Translators: %1$s is an opening tag, %2$s is a closing tag, %3$s is the time
1236 + $at_time = _x('%1$sat%2$s %3$s', 'Time', 'event-post');
730 1237
731 - $dates.=$this->delta_date($event->time_start, $event->time_end);
1238 + //Display dates
1239 + $dates="\t\t\t\t".'<div class="event_date" data-start="' . $this->human_date($time_start) . '" data-end="' . $this->human_date($time_end) . '">';
1240 + // Same day
1241 + if (date('Ymd', $time_start) == date('Ymd', $time_end)) {
1242 + $dates.= "\n\t\t\t\t\t\t\t".'<time itemprop="dtstart" datetime="' . date_i18n('c', $time_start) . '">'
1243 + . '<span class="date date-single">' . $this->human_date($time_end, $this->settings['dateformat']) . "</span>";
1244 + 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') {
1245 + $dates.= ' '.sprintf(
1246 + $from_to_hours,
1247 + '<span class="linking_word linking_word-from">',
1248 + '</span>',
1249 + '<span class="time time-start">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>',
1250 + '<span class="linking_word linking_word-to">',
1251 + '</span>',
1252 + '<span class="time time-end">' . date_i18n($this->settings['timeformat'], $time_end) . '</span>'
1253 + );
1254 + }
1255 + elseif (date('H:i', $time_start) != '00:00') {
1256 + $dates.= ' '.sprintf(
1257 + $at_time,
1258 + '<span class="linking_word">',
1259 + '</span>',
1260 + '<span class="time time-single">' . date_i18n($this->settings['timeformat'], $time_start) . '</span>'
1261 + );
1262 + }
1263 + $dates.="\n\t\t\t\t\t\t\t".'</time>';
1264 + }
1265 + // Not same day
1266 + else {
1267 + $dates.= ' '.sprintf(
1268 + $from_to_days,
1269 + '<span class="linking_word linking_word-from">',
1270 + '</span>',
1271 + '<time class="date date-start" itemprop="dtstart" datetime="' . date('c', $time_start) . '">'
1272 + . ((date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00')
1273 + ? sprintf($single_day_at, '<span class="date">'.$this->human_date($time_start, $this->settings['dateformat']).'</span>', '<span class="linking_word">', '</span>', '<span class="time">'.date_i18n($this->settings['timeformat'], $time_start).'</span>')
1274 + : $this->human_date($time_start, $this->settings['dateformat'])
1275 + )
1276 + . '</time>',
1277 + '<span class="linking_word linking_word-to">',
1278 + '</span>',
1279 + '<time class="date date-to" itemprop="dtend" datetime="' . date('c', $time_end) . '">'
1280 + . ((date('H:i:s', $time_start) != '00:00:00' || date('H:i:s', $time_end) != '00:00:00')
1281 + ? sprintf($single_day_at, '<span class="date">'.$this->human_date($time_end, $this->settings['dateformat']).'</span>', '<span class="linking_word">', '</span>', '<span class="time">'.date_i18n($this->settings['timeformat'], $time_end).'</span>')
1282 + : $this->human_date($time_end, $this->settings['dateformat'])
1283 + )
1284 + . '</time>'
1285 + );
1286 + }
1287 + $dates.="\n\t\t\t\t\t\t".'</div><!-- .event_date -->';
1288 + return $dates;
1289 + }
732 1290
733 - $timezone_string = get_option('timezone_string');
734 - $gmt_offset = $gmt = $this->get_gmt_offset();
1291 + /**
1292 + * Displays a date
1293 + *
1294 + * @param WP_Post object $post
1295 + * @param mixed $links
1296 + *
1297 + * @return string
1298 + */
1299 + public function print_date($post = null, $links = 'deprecated', $context='') {
1300 + $dates = '';
1301 + $event = $this->retreive($post);
1302 + if ($event != false){
1303 + if ($event->start != '' && $event->end != '') {
735 1304
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;
1305 + $dates.=$this->delta_date($event->time_start, $event->time_end);
1306 + if( // Status setting
1307 + $this->settings['displaystatus'] == 'both' ||
1308 + ($this->settings['displaystatus'] == 'single' && is_single() ) ||
1309 + ($this->settings['displaystatus'] == 'list' && !is_single() )
1310 + ){
1311 + $dates.='<span class="eventpost-status">'.$this->statuses[$event->status].'</span>';
1312 + }
1313 + $timezone_string = get_option('timezone_string');
1314 + $gmt_offset = $gmt = $this->get_gmt_offset();
757 1315
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__));
1316 + if (
1317 + !is_admin()
1318 + && ( // Export when setting
1319 + $this->settings['export_when'] == 'both' ||
1320 + ( $this->settings['export_when'] == 'future' && $this->is_future($event) ) ||
1321 + ( $this->settings['export_when'] == 'past' && $this->is_past($event) )
1322 + )
1323 + && ( // Export setting
1324 + $this->settings['export'] == 'both' ||
1325 + ($this->settings['export'] == 'single' && is_single() ) ||
1326 + ($this->settings['export'] == 'list' && !is_single() )
1327 + )
1328 + ) {
1329 + // Export event
1330 + $title = urlencode($post->post_title);
1331 + $address = urlencode($post->address);
1332 + $desc = urlencode($event->description."\n\n".$post->permalink);
1333 + $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');
1334 + $d_s = date("Ymd", $event->time_start) . ($allday ? '' : 'T' . date("His", $event->time_start));
1335 + $d_e = date("Ymd", $event->time_end) . ($allday ? '' : 'T' . date("His", $event->time_end));
1336 + $uid = $post->ID . '-' . $post->blog_id;
1337 + $url = $event->permalink;
769 1338
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 - }
1339 + // format de date ICS
1340 + $permalink_structure = get_option( 'permalink_structure' );
1341 + if($permalink_structure != ""){
1342 + $ics_url = site_url('eventpost/'.$event->ID.'.ics');
1343 + $vcs_url = site_url('eventpost/'.$event->ID.'.vcs');
1344 + }
1345 + else{
1346 + $ics_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'ics'), admin_url('admin-ajax.php'));
1347 + $vcs_url = add_query_arg(array('action'=>'EventPostExport', 'event_id'=>$event->ID, 'format'=>'vcs'), admin_url('admin-ajax.php'));
787 1348
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 - }
1349 + }
810 1350
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;
1351 + // format de date Google cal
1352 + //$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';
1353 + $google_url = add_query_arg(array(
1354 + 'action'=>'TEMPLATE',
1355 + 'trp'=>'false',
1356 + 'sprop'=>'name',
1357 + 'text'=>$title,
1358 + 'dates'=>$d_s.'/'.$d_e.'', // Removed Z to fix TZ issue
1359 + 'location'=>$address,
1360 + 'details'=>$desc,
1361 + 'gmt'=> urlencode($gmt_offset)
1362 + ), 'https://www.google.com/calendar/event');
1363 + if(!empty($timezone_string)){
1364 + $google_url = add_query_arg(array(
1365 + 'ctz'=>$timezone_string,
1366 + ), $google_url);
1367 + }
830 1368
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 - }
1369 + $dates.='
1370 + <span class="eventpost-date-export">
1371 + <a href="' . $ics_url . '" class="event_link event-export ics" target="_blank" title="' . __('Download ICS file', 'event-post') . '">ical</a>
1372 + <a href="' . $google_url . '" class="event_link event-export gcal" target="_blank" title="' . __('Add to Google calendar', 'event-post') . '">Google</a>
1373 + <a href="' . $vcs_url . '" class="event_link event-export vcs" target="_blank" title="' . __('Add to Outlook', 'event-post') . '">outlook</a>
1374 + <i class="dashicons-before dashicons-calendar"></i>
1375 + </span>';
1376 + }
1377 + }
1378 + }
1379 + return apply_filters('eventpost_printdate', $dates);
1380 + }
845 1381
846 - return apply_filters('eventpost_printlocation', $location);
847 - }
1382 + /**
1383 + * Outputs location of an event
1384 + *
1385 + * @param WP_Post object $post
1386 + *
1387 + * @return string
1388 + */
1389 + public function print_location($post=null, $context='') {
1390 + $location = '';
1391 + if ($post == null)
1392 + $post = get_post();
1393 + elseif (is_numeric($post)) {
1394 + $post = get_post($post);
1395 + }
1396 + if (!isset($post->start)) {
1397 + $post = $this->retreive($post);
1398 + }
1399 + if ($post != false){
1400 + $this->map_id++;
1401 + $address = $post->address;
1402 + $lat = $post->lat;
1403 + $long = $post->long;
1404 + $color = $this->get_post_color($post->ID, $this->settings['default_color'], true);
1405 + $icon = $this->DashIcons->icons[$this->get_post_icon($post->ID, $this->settings['default_icon'], true)];
1406 + $virtual_location = $post->virtual_location;
1407 + $attendance_mode = $post->attendance_mode;
848 1408
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 - }
1409 + if ($this->is_online($post) && $virtual_location) {
1410 + $location.="\t\t\t\t".'<div><a href="'.esc_url($virtual_location).'" class="eventpost-virtual-location-link" target="_blank" rel="noopener">'
1411 + .__('Join link', 'event-post')
1412 + .'</a></div>'
1413 + ."\n";
1414 + }
1415 + if ($this->is_offline($post) && ($address != '' || ($lat != '' && $long != ''))) {
1416 + $location.="\t\t\t\t".'<address';
1417 + if ($lat != '' && $long != '') {
1418 + $geo_attributes = ' data-latitude="' . esc_attr($lat) . '"
1419 + data-longitude="' . esc_attr($long) . '"
1420 + data-marker="' . esc_attr($this->get_marker($color)) . '"
1421 + data-iconcode="' .esc_attr($icon). '"
1422 + data-icon="' . esc_attr(mb_convert_encoding('&#x'.$icon.';', 'UTF-8', 'HTML-ENTITIES')). '"
1423 + data-color="#' . esc_attr($color). '"
1424 + data-id="' . $post->ID . '-'.$this->map_id.'"';
1425 + $location.=' '.$geo_attributes;
1426 + }
1427 + $location.=' itemprop="adr" class="eventpost-address">'
1428 + . "\n\t\t\t\t\t\t\t".'<span>'
1429 + . "\n".$address
1430 + . "\n\t\t\t\t\t\t\t". '</span>';
1431 + if ($context=='single' && $lat != '' && $long != '') {
1432 + $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=' . esc_attr($lat) .'&amp;lon=' . esc_attr($long) . '&amp;zoom=13" target="_blank" itemprop="geo" ' . $geo_attributes . '>' . __('Map', 'event-post') . '</a>';
1433 + }
1434 + $location.="\n\t\t\t\t\t\t".'</address>';
1435 + if (wp_is_mobile() && $lat != '' && $long != '') {
1436 + $location.="\n\t\t\t\t\t\t".'<a class="event_link gps-geo-link" href="geo:' . esc_attr($lat) . ',' . esc_attr($long) . '" target="_blank" itemprop="geo" ' . $geo_attributes . '><i class="dashicons-before dashicons-location"></i> ' . __('Open in app', 'event-post') . '</a>';
1437 + }
1438 + }
1439 + }
1440 + return apply_filters('eventpost_printlocation', $location);
1441 + }
879 1442
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 - }
1443 + /**
1444 + * Compute darkness of the color
1445 + *
1446 + * @param string $color
1447 + *
1448 + * @return float
1449 + */
1450 + public function color_darkness($color){
1451 + $color = str_replace('#', '', $color);
1452 + $rgb = array();
1453 + for ($x=0;$x<3;$x++) {
1454 + $rgb[$x] = hexdec(substr($color,(2*$x),2));
1455 + }
1456 + return (max($rgb) + min($rgb)) / 510;
1457 + }
902 1458
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 - }
1459 + /**
1460 + * Outputs categories of an event
1461 + *
1462 + * @param WP_Post object $post
1463 + *
1464 + * @return string
1465 + */
1466 + public function print_categories($post=null, $context='') {
1467 + if ($post == null)
1468 + $post = get_post();
1469 + elseif (is_numeric($post)) {
1470 + $post = get_post($post);
1471 + }
1472 + if (!isset($post->start)) {
1473 + $post = $this->retreive($post);
1474 + }
1475 + $cats = '';
1476 + if ($post != false){
1477 + $categories = $post->Taxonomies;
1478 + if ($categories) {
1479 + $cats.="\t\t\t\t".'<span class="event_categories">';
912 1480
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 - }
1481 + foreach ($categories as $category) {
1482 + $cats.="\t\t\t\t\t".'<span ';
1483 + $classes = array('event-term', 'event_term_category');
1484 + $darkness = 0;
1485 + $color = $this->Taxonomies->get_taxonomy_color($category->term_id);
1486 + if ($color != '' && $color) {
1487 + $cats.=' style="background-color:#' . $color . '"';
922 1488
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 - }
1489 + $darkness = $this->color_darkness($color);
1490 + if($darkness < 0.5){
1491 + array_push($classes, 'event-post-bg-dark');
1492 + }
1493 + else{
1494 + array_push($classes, 'event-post-bg-light');
1495 + }
932 1496
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 - }
1497 + }
1498 + $cats.=' class="'.implode(' ', $classes).'">';
1499 + $cats .= $category->name . ' ';
1500 + $cats.='</span>';
1501 + }
1502 + $cats.='</span>';
1503 + }
1504 + }
1505 + return $cats;
1506 + }
942 1507
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 - }
1508 + /**
1509 + * Generate, return or output date event datas
1510 + *
1511 + * @param WP_Post object $post
1512 + * @param string $class
1513 + *
1514 + * @filter eventpost_get_single
1515 + *
1516 + * @return string
1517 + */
1518 + public function get_single($post = null, $class = '', $context='') {
1519 + if ($post == null) {
1520 + $post = $this->retreive();
1521 + }
1522 + if ($post != null){
1523 + $datas_date = $this->print_date($post, null, $context);
1524 + $datas_cat = $this->print_categories($post, $context);
1525 + $datas_loc = $this->print_location($post, $context);
1526 + $classes = array(
1527 + 'event_data',
1528 + 'status-'.strtolower(str_replace('Event', '', $post->status)),
1529 + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $post->attendance_mode)),
1530 + $class
1531 + );
1532 + if ($datas_date != '' || $datas_loc != '') {
1533 + $rgb = $this->hex2dec($post->color);
1534 + return '<div class="' . implode(' ', $classes) . '" style="border-left-color:#' . $post->color . ';background:rgba(' . $rgb['R'] . ',' . $rgb['G'] . ',' . $rgb['B'] . ',0.1)" itemscope itemtype="http://microformats.org/profile/hcard">'
1535 + . apply_filters('eventpost_get_single', $datas_date . $datas_cat . $datas_loc, $post)
1536 + . '</div>';
1537 + }
1538 + }
1539 + return '';
1540 + }
954 1541
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 - }
1542 + /**
1543 + * Displays dates of a gieven post
1544 + *
1545 + * @param WP_Post object $post
1546 + * @param string $class
1547 + *
1548 + * @return string
1549 + */
1550 + public function get_singledate($post = null, $class = '', $context='') {
1551 + 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 -->';
1552 + }
964 1553
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){
1554 + /**
1555 + * Displays coloured terms of a given post
1556 + *
1557 + * @param WP_Post object $post
1558 + * @param string $class
1559 + *
1560 + * @return string
1561 + */
1562 + public function get_singlecat($post = null, $class = '', $context='') {
1563 + 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 -->';
1564 + }
1565 +
1566 + /**
1567 + * Displays location of a given post
1568 + *
1569 + * @param WP_Post object $post
1570 + * @param string $class
1571 + *
1572 + * @return string
1573 + */
1574 + public function get_singleloc($post = null, $class = '', $context='') {
1575 + 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 -->';
1576 + }
1577 +
1578 + /**
1579 + * Uses `the_content` filter to add event details before or after the content of the current post
1580 + *
1581 + * @param string $content
1582 + *
1583 + * @return string
1584 + */
1585 + public function display_single($content) {
1586 + if (is_page() || !is_single() || is_home() || !in_the_loop() || !is_main_query()){
1587 + return $content;
1588 + }
1589 +
1590 + $post = $this->retreive();
1591 + if($post != false){
1592 + // If the post is a product, don't display the event bar, use product tab instead
1593 + if($post->post_type=='product'){
1594 + return $content;
1595 + }
1596 +
1597 + $eventbar = apply_filters('eventpost_contentbar', $this->get_single($post, 'event_single', 'single'), $post);
1598 + if($this->settings['singlepos']=='before'){
1599 + $content=$eventbar.$content;
1600 + }
1601 + elseif($this->settings['singlepos']=='after'){
1602 + $content.=$eventbar;
1603 + }
1604 + $this->load_map_scripts();
1605 + }
1606 + return $content;
1607 + }
1608 +
1609 + /**
1610 + * Outputs events details (dates, geoloc, terms) of given post
1611 + *
1612 + * @param WP_Post object $post
1613 + *
1614 + * @return void
1615 + */
1616 + public function print_single($post = null) {
1617 + echo wp_kses_post($this->get_single($post));
1618 + }
1619 +
1620 + /**
1621 + * Alter the post title in order to add icons if needed
1622 + *
1623 + * @param string $title
1624 + *
1625 + * @return string
1626 + */
1627 + public function the_title($title, $post_id = null){
971 1628 if(!$post_id || !in_the_loop() || !$this->settings['loopicons']){
972 - return $title;
1629 + return $title;
973 1630 }
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 - );
1631 + $icons_ = array(
1632 + // Emojis
1633 + 1=>array('🗓', '🗺'),
1634 + // Dashicons
1635 + 2=>array('<span class="dashicons dashicons-calendar"></span>', '<span class="dashicons dashicons-location"></span>'),
1636 + );
980 1637
981 1638 $event = $this->retreive($post_id);
982 - if(!empty($event->start)){
983 - $title .= ' '.$icons_[$this->settings['loopicons']][0];
1639 + if ($event !== false){
1640 + if(!empty($event->start)){
1641 + $title .= ' '.$icons_[$this->settings['loopicons']][0];
1642 + }
1643 + if(!empty($event->lat) && !empty($event->long)){
1644 + $title .= ' '.$icons_[$this->settings['loopicons']][1];
1645 + }
984 1646 }
985 - if(!empty($event->lat) && !empty($event->long)){
986 - $title .= ' '.$icons_[$this->settings['loopicons']][1];
1647 + return $title;
987 1648 }
988 - return $title;
989 - }
990 1649
991 1650
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='') {
1651 + function get_price($event,$html=false){
1652 + $price = '';
1653 + $text_price = $price;
1654 + if($event->post_type == 'product'){
1655 + $product_id = $event->ID;
1656 + $product = wc_get_product($product_id);
1657 + $price = $product->get_price();
1658 + $currency = get_woocommerce_currency_symbol();
1659 + if($product->get_sale_price() != ""){
1660 + $old_price = $product->get_regular_price();
1661 + $text_price = '<span class="event_price"><del>'.$old_price . $currency . '</del> '.$price. $currency. '</span>';
1662 + } else {
1663 + $text_price = '<span class="event_price"> '.$price . $currency.'</span>';
1664 + }
1665 + }
1666 + if ($html == true) {
1667 + return $text_price;
1668 + } else {
1669 + return $price;
1670 + }
1671 + }
1672 +
1673 + /**
1674 + * Return an HTML list of events
1675 + *
1676 + * @param array $atts
1677 + * @param string $id
1678 + * @param string $context
1679 + *
1680 + * @filter eventpost_params($defaults, 'list_events')
1681 + * @filter eventpost_listevents
1682 + * @filter eventpost_item_scheme_entities
1683 + * @filter eventpost_item_scheme_values
1684 + *
1685 + * @return string
1686 + */
1687 + public function list_events($atts, $id = 'event_list', $context='') {
1006 1688 $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);
1689 + $defaults = array(
1690 + 'nb' => 0,
1691 + 'nb_desktop' => 0,
1692 + 'nb_tablet' => 0,
1693 + 'nb_mobile' => 0,
1694 + 'type' => 'div',
1695 + 'future' => true,
1696 + 'past' => false,
1697 + 'geo' => 0,
1698 + 'width' => '',
1699 + 'height' => '',
1700 + 'list' => 0,
1701 + 'zoom' => '',
1702 + 'map_position' => 'false',
1703 + 'latitude' => '',
1704 + 'longitude' => '',
1705 + 'tile' => $ep_settings['tile'],
1706 + 'pop_element_schema' => 'false',
1707 + 'htmlPop_element_schema' => '',
1708 + 'title' => '',
1709 + 'before_title' => '<h3>',
1710 + 'after_title' => '</h3>',
1711 + 'cat' => '',
1712 + 'tag' => '',
1713 + 'tax_name' => '',
1714 + 'tax_term' => '',
1715 + 'events' => '',
1716 + 'style' => '',
1717 + 'thumbnail' => '',
1718 + 'thumbnail_size' => '',
1719 + 'excerpt' => '',
1720 + 'orderby' => 'meta_value',
1721 + 'order' => 'ASC',
1722 + 'class' => '',
1723 + 'align' => '',
1724 + 'className' => '',
1725 + 'container_schema' => $this->list_shema['container'],
1726 + 'item_schema' => $this->list_shema['item'],
1727 + 'pages' => false,
1728 + 'paged' => '',
1729 + 'separate_years' => false,
1730 + 'separate_months' => false,
1731 + );
1732 + // Map UI options
1733 + foreach($this->map_interactions as $int_key=>$int_name){
1734 + $defaults[$int_key]=true;
1735 + }
1736 + $atts_old_nb = $defaults['nb'];
1737 + if($id == "event_timeline"){
1738 + $atts_old_nb = intval($atts['nb']);
1739 + $atts['nb'] = -1;
1740 + }
1038 1741
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 - }
1742 + $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events', $context), $atts);
1049 1743
1050 - $child = ($type == 'ol' || $type == 'ul') ? 'li' : 'div';
1744 + extract($atts);
1745 + if (!is_array($events)) {
1746 + $events = $this->get_events($atts);
1747 + }
1051 1748
1052 - $list = '';
1749 + $ret = '';
1750 + $this->list_id++;
1751 + if (sizeof($events) > 0) {
1752 + if (!empty($title)) {
1753 + $ret .= wp_kses_post($before_title . esc_html($title) . $after_title);
1754 + }
1053 1755
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 - }
1756 + $type = in_array($type, ['div', 'ul', 'ol']) ? $type : 'div';
1757 + $child = in_array($type, ['ul', 'ol']) ? 'li' : 'div';
1058 1758
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 - }
1759 + $html = '';
1126 1760
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();
1761 + if($id=='event_geolist'){
1762 + $this->load_map_scripts();
1763 + $html.=sprintf('<%1$s class="event_geolist_icon_loader"><p><span class="dashicons dashicons-location-alt"></span></p><p class="screen-reader-text">'.__('An events map', 'event-post').'</p></%1$s>', $type);
1764 + }
1765 + $attributes = '';
1766 + $prev_arrow = "";
1767 + $next_arrow = "";
1768 + $item_child_style = "";
1769 + if($id == "event_timeline"){
1770 + $prev_arrow = '<div class="previous"><span class="screen-reader-text">'.__('« Previous Events', 'event-post')."</span></div>";
1771 + $next_arrow = '<div class="next"><span class="screen-reader-text">'.__('Next Events »', 'event-post')."</span></div>";
1772 + if($atts_old_nb != 0){
1773 + $item_child_style = 'width : '.((100/$atts_old_nb) - 2).'%;';
1774 + }
1775 + $attributes .= ' data-nb="'.$atts_old_nb.'"';
1776 + $attributes .= ' data-nb-desktop="'.intval($atts['nb_desktop'] ?? 0).'"';
1777 + $attributes .= ' data-nb-tablet="'.intval($atts['nb_tablet'] ?? 0).'"';
1778 + $attributes .= ' data-nb-mobile="'.intval($atts['nb_mobile'] ?? 0).'"';
1779 + $attributes .= ' data-filter="'.http_build_query($atts).'" ';
1780 + }
1152 1781
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 - );
1782 + if($id === 'event_timeline'){
1783 + $previous_year = $atts['separate_years'] ? true : false;
1784 + $previous_month = $atts['separate_months'] ? true : false;
1785 + }
1161 1786
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 - }
1787 + foreach ($events as $event) {
1788 + if($id === 'event_timeline'){
1789 + if($previous_year && $previous_year !== date('Y', $event->time_start)){
1790 + $html.= '<div class="event-timeline-separator event-timeline-year"><span class="event-timeline-year-text">'.date_i18n('Y', $event->time_start).'</span></div>';
1791 + $previous_year = date('Y', $event->time_start);
1792 + }
1793 + if($previous_month && $previous_month !== date('Ym', $event->time_start)){
1794 + $html.= '<div class="event-timeline-separator event-timeline-month"><span class="event-timeline-month-text">'.date_i18n('F', $event->time_start).'</span>'.($previous_year ? '' : ' <span class="event-timeline-year-text">'.date_i18n('Y', $event->time_start).'</span>').'</div>';
1795 + $previous_month = date('Ym', $event->time_start);
1796 + }
1797 + }
1798 + $text_price = $this->get_price($event,true);
1799 + $class_item = array(
1800 + $this->is_future($event) ? 'event_future' : 'event_past',
1801 + 'status-'.strtolower(str_replace('Event', '', $event->status)),
1802 + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $event->attendance_mode)),
1803 + );
1804 + $taxonomies= get_taxonomies('','names');
1805 + $post_terms = [];
1806 + $terms = wp_get_post_terms($event->ID, $taxonomies);
1807 + foreach($terms as $term){
1808 + $class_item[] = $term->taxonomy.'-'.$term->slug;
1809 + }
1810 + if ($ep_settings['emptylink'] == 0 && empty($event->post_content)) {
1811 + $event->permalink = '#' . $id . $this->list_id;
1812 + }
1813 + elseif(empty($event->permalink)){
1814 + $event->permalink=$event->guid;
1815 + }
1816 + $html.=str_replace(
1817 + apply_filters('eventpost_item_scheme_entities', array(
1818 + '%child%',
1819 + '%class%',
1820 + '%color%',
1821 + '%event_link%',
1822 + '%event_thumbnail%',
1823 + '%event_title%',
1824 + '%event_price%',
1825 + '%event_date%',
1826 + '%event_cat%',
1827 + '%event_location%',
1828 + '%event_excerpt%',
1829 + '%style%',
1830 + )), apply_filters('eventpost_item_scheme_values', array(
1831 + $child,
1832 + implode(' ', $class_item),
1833 + $this->get_post_color($event->ID, $this->settings['default_color'],true),
1834 + $event->permalink,
1835 + $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>' : '',
1836 + $event->post_title,
1837 + $event->post_type == 'product' ? $text_price : '',
1838 + $this->get_singledate($event, '', $context),
1839 + $this->get_singlecat($event, '', $context),
1840 + $this->get_singleloc($event, '', $context),
1841 + $excerpt == true && $event->description!='' ? '<span class="event_exerpt">'.$event->description.'</span>' : '',
1842 + $item_child_style,
1843 + ), $event), $item_schema
1844 + );
1170 1845
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);
1846 + }
1847 + if($id == 'event_geolist'){
1848 + if($height==''){
1849 + $height = '300px';
1850 + }
1851 + if($width==''){
1852 + $width = '100%';
1853 + }
1854 + $attributes .= ' data-tile="'.esc_attr($tile).'"
1855 + data-width="'.esc_attr($width).'"
1856 + data-height="'.esc_attr($height).'"
1857 + data-zoom="'.esc_attr($zoom).'"
1858 + data-map_position="'.esc_attr($map_position).'"
1859 + data-latitude="'.esc_attr($latitude).'"
1860 + data-longitude="'.esc_attr($longitude).'"
1861 + data-pop_element_schema="'.esc_attr($pop_element_schema).'"
1862 + data-htmlPop_element_schema="'.esc_attr($htmlPop_element_schema).'"
1863 + data-list="'.esc_attr($list).'"
1864 + data-disabled-interactions="';
1865 + // add data-position avec ma variables
1866 + foreach($this->map_interactions as $int_key=>$int_name){
1867 + $attributes.=$atts[$int_key]==false ? esc_attr($int_key).', ' : '';
1868 + }
1869 + $attributes.='" ';
1870 + }
1871 + $pagination = '';
1872 + if($pages && $this->pagination){
1873 + global $wp_rewrite;
1874 + $paged = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1875 + $pagination = paginate_links( array(
1876 + 'prev_text' => __('« Previous Events', 'event-post'),
1877 + 'next_text' => __('Next Events »', 'event-post'),
1878 + 'current' => $paged,
1879 + 'total' => $this->pagination['max_num_pages'],
1880 + )
1881 + );
1882 + }
1237 1883
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 - }
1884 + if($context == 'events_only'){
1885 + $ret = $html;
1886 + }else{
1887 + $classes = [
1888 + $class,
1889 + $className,
1890 + 'className',
1891 + $id == 'event_geolist' && $list ? ' has-list list-'.esc_attr($list) : ' no-list',
1892 + ];
1893 + if(!empty($align)){
1894 + $classes[] = 'align'.esc_attr($align);
1895 + }
1896 + if($id === 'event_timeline' && ($previous_year || $previous_month)){
1897 + $classes[] = 'has-time-separators';
1898 + }
1899 + $ret.=str_replace(
1900 + array(
1901 + '%type%',
1902 + '%id%',
1903 + '%class%',
1904 + '%listid%',
1905 + '%style%',
1906 + '%attributes%',
1907 + '%list%',
1908 + '%pagination%',
1909 + '%prev_arrow%',
1910 + '%next_arrow%',
1911 + '%number%'
1912 + ), array(
1913 + $type,
1914 + $id,
1915 + esc_attr(implode(' ', $classes)),
1916 + $id . $this->list_id,
1917 + (!empty($width) ? 'width:' . esc_attr($width) . ';' : '') . (!empty($height) ? 'height:' . esc_attr($height) . ';' : '') . esc_attr($style),
1918 + $attributes,
1919 + $html,
1920 + $pagination,
1921 + $prev_arrow,
1922 + $next_arrow
1923 + ), $container_schema
1924 + );
1925 + }
1269 1926
1270 - $arg['meta_query'] = $meta_query;
1927 + }
1928 + elseif(filter_input(INPUT_POST, 'action')=='bulk_do_shortcode'){
1929 + 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>';
1930 + }
1931 + return apply_filters('eventpost_listevents', $ret, $id.$this->list_id, $atts, $events, $context);
1932 + }
1271 1933
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 1934
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 - }
1935 + /**
1936 + * Get events
1937 + *
1938 + * @param array $atts
1939 + *
1940 + * @filter eventpost_params
1941 + * @filter eventpost_get_items
1942 + *
1943 + * @return array of post_ids which are events
1944 + */
1945 + public function get_events($atts) {
1946 + if(isset($atts['future'])){
1947 + $atts['future'] = filter_var( $atts['future'], FILTER_VALIDATE_BOOLEAN);
1948 + }
1949 + if(isset($atts['past'])){
1950 + $atts['past'] = filter_var( $atts['past'], FILTER_VALIDATE_BOOLEAN);
1951 + }
1952 + if(isset($atts['geo'])){
1953 + $atts['geo'] = filter_var( $atts['geo'], FILTER_VALIDATE_BOOLEAN);
1954 + }
1955 + if(isset($atts['pages'])){
1956 + $atts['pages'] = filter_var( $atts['pages'], FILTER_VALIDATE_BOOLEAN);
1957 + }
1293 1958
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 1959
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 1960
1961 + $requete = (shortcode_atts(apply_filters('eventpost_params', array(
1962 + 'nb' => 5,
1963 + 'future' => true,
1964 + 'past' => false,
1965 + 'geo' => 0,
1966 + 'cat' => '',
1967 + 'tag' => '',
1968 + 'date' => '',
1969 + 'orderby' => 'meta_value',
1970 + 'orderbykey' => $this->META_START,
1971 + 'order' => 'ASC',
1972 + 'tax_name' => '',
1973 + 'tax_term' => '',
1974 + 'paged' => 1,
1975 + 'post_type'=> $this->settings['posttypes']
1976 + ), 'get_events'), $atts));
1977 + if(!isset($requete['paged']) || $requete['paged'] == ""){
1978 + $requete['paged'] = ( get_query_var( 'page' ) ) ? absint( get_query_var( 'page' ) ) : 1;
1979 + }
1980 + extract($requete);
1981 + wp_reset_query();
1326 1982
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 = '';
1983 +
1984 + $arg = array(
1985 + 'post_status' => 'publish',
1986 + 'post_type' => $post_type,
1987 + 'posts_per_page' => $nb,
1988 + 'paged' => $paged,
1989 + 'meta_key' => $orderbykey,
1990 + 'orderby' => $orderby,
1991 + 'order' => $order
1992 + );
1993 +
1994 + if($tax_name=='category'){
1995 + $tax_name='';
1996 + $cat=$tax_term;
1997 + }
1998 + elseif($tax_name=='post-tag'){
1999 + $tax_name='';
2000 + $tag=$tax_term;
2001 + }
2002 +
2003 + // CUSTOM TAXONOMY
2004 + if ($tax_name != '' && $tax_term != '') {
2005 + $arg['tax_query'] = array(
2006 + array(
2007 + 'taxonomy' => $tax_name,
2008 + 'field' => 'slug',
2009 + 'terms' => $tax_term,
2010 + ),
2011 + );
2012 + }
2013 + // CAT
2014 + if ($cat != '') {
2015 + if (preg_match('/[a-zA-Z]/i', $cat)) {
2016 + $arg['category_name'] = $cat;
2017 + } else {
2018 + $arg['cat'] = $cat;
2019 + }
2020 + }
2021 + // TAG
2022 + if ($tag != '') {
2023 + $arg['tag'] = $tag;
2024 + }
2025 + // DATES
2026 + $meta_query = array(
2027 + array(
2028 + 'key' => $this->META_END,
2029 + 'value' => '',
2030 + 'compare' => '!='
2031 + ),
2032 + array(
2033 + 'key' => $this->META_END,
2034 + 'value' => '0:0:00 0:',
2035 + 'compare' => '!='
2036 + ),
2037 + array(
2038 + 'key' => $this->META_END,
2039 + 'value' => ':00',
2040 + 'compare' => '!='
2041 + ),
2042 + array(
2043 + 'key' => $this->META_START,
2044 + 'value' => '',
2045 + 'compare' => '!='
2046 + ),
2047 + array(
2048 + 'key' => $this->META_START,
2049 + 'value' => '0:0:00 0:',
2050 + 'compare' => '!='
2051 + )
2052 + );
2053 + if ($future == 0 && $past == 0) {
2054 + $meta_query = array();
2055 + $arg['meta_key'] = null;
2056 + $arg['orderby'] = null;
2057 + $arg['order'] = null;
2058 + }
2059 + elseif ($future == 1 && $past == 0) {
2060 + $meta_query[] = array(
2061 + 'key' => $this->META_END,
2062 + 'value' => current_time('mysql'),
2063 + 'compare' => '>=',
2064 + //'type'=>'DATETIME'
2065 + );
2066 + }
2067 + elseif ($future == 0 && $past == 1) {
2068 + $meta_query[] = array(
2069 + 'key' => $this->META_END,
2070 + 'value' => current_time('mysql'),
2071 + 'compare' => '<=',
2072 + //'type'=>'DATETIME'
2073 + );
2074 + }
2075 + if ($date != '') {
2076 + $date = date('Y-m-d', $date);
2077 +
2078 + $meta_query = array(
2079 + array(
2080 + 'key' => $this->META_END,
2081 + 'value' => $date . ' 00:00:00',
2082 + 'compare' => '>=',
2083 + 'type' => 'DATETIME'
2084 + ),
2085 + array(
2086 + 'key' => $this->META_START,
2087 + 'value' => $date . ' 23:59:59',
2088 + 'compare' => '<=',
2089 + 'type' => 'DATETIME'
2090 + )
2091 + );
2092 + }
2093 + // GEO
2094 + if ($geo == 1) {
2095 + $meta_query[] = array(
2096 + 'key' => $this->META_LAT,
2097 + 'value' => '',
2098 + 'compare' => '!='
2099 + );
2100 + $meta_query[] = array(
2101 + 'key' => $this->META_LONG,
2102 + 'value' => '',
2103 + 'compare' => '!='
2104 + );
2105 + $arg['meta_key'] = $this->META_LAT;
2106 + $arg['orderby'] = 'meta_value';
2107 + $arg['order'] = 'DESC';
2108 + }
2109 +
2110 + $arg['meta_query'] = $meta_query;
2111 +
2112 + $query_md5 = 'eventpost_' . md5(wp_json_encode($requete, true));
2113 + // Check if cache is activated
2114 + if ($this->settings['cache'] == 1 && false !== ( $cached_events = get_transient($query_md5) )) {
2115 + return apply_filters('eventpost_get_items', is_array($cached_events) ? $cached_events : array(), $requete, $arg);
2116 + }
2117 +
2118 + $events = apply_filters('eventpost_get', '', $requete, $arg);
2119 + if ('' === $events) {
2120 + global $wpdb;
2121 + $query = new WP_Query($arg);
2122 + $events = $wpdb->get_col($query->request);
2123 + $this->pagination = array(
2124 + 'found_posts' => $query->found_posts,
2125 + 'max_num_pages' => $query->max_num_pages,
2126 + );
2127 + foreach ($events as $k => $post) {
2128 + $event = $this->retreive($post);
2129 + if ($event != false){
2130 + $events[$k] = $event;
2131 + }
2132 + }
2133 + }
2134 + if ($this->settings['cache'] == 1){
2135 + set_transient($query_md5, $events, 5 * MINUTE_IN_SECONDS);
2136 + }
2137 + return apply_filters('eventpost_get_items', $events, $requete, $arg);
1345 2138 }
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';
2139 +
2140 + /**
2141 + * Checks if the given event is in the future or not
2142 + *
2143 + * @param object $event
2144 + * @param boolean $exact Future status has to be calculated against time or entire day
2145 + *
2146 + * @return boolean
2147 + */
2148 + function is_future($event, $exact=false){
2149 + $match = current_time('timestamp');
2150 + // if EXACT is false, end date is set to begining of the current day
2151 + if(!$exact){
2152 + $match = mktime(0, 0, 0, date('m', $match), date('d', $match), date('Y', $match));
2153 + }
2154 + return ($event->time_end >= $match);
1361 2155 }
1362 2156
1363 - $EventPost_cache[$ob->ID] = apply_filters('eventpost_retreive', $ob);
1364 - return $EventPost_cache[$ob->ID];
1365 - }
2157 + /**
2158 + * Checks if the given event is completed or not
2159 + *
2160 + * @param object $event
2161 + * @param boolean $exact Past status has to be calculated against time or entire day
2162 + *
2163 + * @return boolean
2164 + */
2165 + function is_past($event, $exact=false){
2166 + $match = current_time('timestamp');
2167 + // if EXACT is false or full day event, end date is set to end of the current day
2168 + if(!$exact || ( date('H:i:s', $event->time_start) == '00:00:00' && date('H:i:s', $event->time_end) == '00:00:00' )){
2169 + $match = mktime(23, 59, 59, date('m', $match), date('d', $match), date('Y', $match));
2170 + }
2171 + return ($event->time_end < $match);
2172 + }
1366 2173
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);
2174 + /**
2175 + * Checks if an event is online
2176 + *
2177 + * @param $event
2178 + *
2179 + * @return boolean
2180 + */
2181 + function is_online($event){
2182 + return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OnlineEventAttendanceMode')));
2183 + }
1375 2184
1376 - if(!$term){
1377 - return $term;
1378 - }
2185 + /**
2186 + * Checks if an event is offline
2187 + *
2188 + * @param $event
2189 + *
2190 + * @return boolean
2191 + */
2192 + function is_offline($event){
2193 + return (in_array($event->attendance_mode, array('MixedEventAttendanceMode', 'OfflineEventAttendanceMode')));
2194 + }
1379 2195
1380 - $term->start = $term->end = $term->time_start = $term->time_end = Null;
2196 + /**
2197 + * Populates a WP_Post object with event datas
2198 + *
2199 + * @param object $event
2200 + *
2201 + * @return object
2202 + */
2203 + public function retreive($event = null) {
2204 + global $EventPost_cache;
2205 + $ob = get_post($event);
2206 + if(!$ob){
2207 + return false;
2208 + }
2209 + if(is_object($ob) && $ob->start){
2210 + return $ob;
2211 + }
2212 + if(is_object($ob) && isset($EventPost_cache[$ob->ID])){
2213 + return $EventPost_cache[$ob->ID];
2214 + }
2215 + $ob->start = get_post_meta($ob->ID, $this->META_START, true);
2216 + $ob->end = get_post_meta($ob->ID, $this->META_END, true);
2217 + if (!$this->dateisvalid($ob->start)){
2218 + $ob->start = '';
2219 + }
2220 + if (!$this->dateisvalid($ob->end)){
2221 + $ob->end = '';
2222 + }
2223 + $ob->root_ID = $ob->ID;
2224 + $ob->time_start = !empty($ob->start) ? strtotime($ob->start) : '';
2225 + $ob->time_end = !empty($ob->end) ? strtotime($ob->end) : '';
2226 + $ob->virtual_location = get_post_meta($ob->ID, $this->META_VIRTUAL_LOCATION, true);
2227 + $ob->virtual_location = esc_url($ob->virtual_location);
2228 + $ob->organization = get_post_meta($ob->ID, $this->META_ORGANIZATION, true);
2229 + $ob->offer = get_post_meta($ob->ID, $this->META_OFFER, true);
2230 + if(empty($ob->offer)){
2231 + $ob->offer = array(
2232 + 'url' => null,
2233 + 'price' => null,
2234 + 'currency' => null,
2235 + );
2236 + }
2237 + $ob->address = get_post_meta($ob->ID, $this->META_ADD, true);
2238 + $ob->lat = $this->sanitize_coordinate(get_post_meta($ob->ID, $this->META_LAT, true));
2239 + $ob->long = $this->sanitize_coordinate(get_post_meta($ob->ID, $this->META_LONG, true));
2240 + $ob->attendance_mode = (null != $att_mod = get_post_meta($ob->ID, $this->META_ATTENDANCE_MODE, true)) ? $att_mod : array_keys($this->attendance_modes)[0];
2241 + $ob->status = (null != $status = get_post_meta($ob->ID, $this->META_STATUS, true)) ? $status : array_keys($this->statuses)[0];
2242 + $ob->color = $this->get_post_color($ob->ID);
2243 + $ob->icon = $this->get_post_icon($ob->ID);
2244 + $ob->Taxonomies = get_the_category($ob->ID);
2245 + $ob->permalink = get_permalink($ob->ID);
2246 + $ob->blog_id = get_current_blog_id();
2247 + $ob->description = $ob->post_excerpt ? $ob->post_excerpt : str_replace('&nbsp;', ' ', preg_replace("/\n+/", "\n", trim(wp_strip_all_tags(excerpt_remove_blocks($ob->post_content)))));
2248 + $EventPost_cache[$ob->ID] = apply_filters('eventpost_retreive', $ob);
2249 + return $EventPost_cache[$ob->ID];
2250 + }
1381 2251
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 - );
2252 + /**
2253 + * Fetch terms of a post
2254 + *
2255 + * @param mixed $_term
2256 + * @param string $taxonomy
2257 + * @param string $post_type
2258 + */
2259 + public function retreive_term($_term=null, $taxonomy='category', $post_type='post') {
2260 + $term = get_term($_term, $taxonomy);
1391 2261
1392 - $events = $this->get_events($request);
2262 + if(!$term){
2263 + return $term;
2264 + }
1393 2265
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 - }
2266 + $term->start = $term->end = $term->time_start = $term->time_end = Null;
1401 2267
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 - }
2268 + $request = array(
2269 + 'post_type'=>$post_type,
2270 + 'tax_name'=>$term->taxonomy,
2271 + 'tax_term'=>$term->slug,
2272 + 'future'=>true,
2273 + 'past'=>true,
2274 + 'nb'=>-1,
2275 + 'order'=>'ASC'
2276 + );
1410 2277
1411 - return $term;
2278 + $events = $this->get_events($request);
1412 2279
1413 - }
2280 + $term->events_count = count($events);
2281 + if($term->events_count){
2282 + $term->start = $events[0]->start;
2283 + $term->time_start = $events[0]->time_start;
2284 + $term->end = $events[$term->events_count-1]->end;
2285 + $term->time_end = $events[$term->events_count-1]->time_end;
2286 + }
1414 2287
1415 - /** ADMIN ISSUES * */
2288 + $request['order']='DESC';
2289 + $request['nb']=1;
2290 + $request['orderbykey']=$this->META_END;
2291 + $events = $this->get_events($request);
2292 + if(count($events)){
2293 + $term->end = $events[0]->end;
2294 + $term->time_end = $events[0]->time_end;
2295 + }
1416 2296
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');
2297 + return $term;
2298 +
1428 2299 }
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 2300
1441 - $language = get_bloginfo('language');
1442 - if (strpos($language, '-') > -1) {
1443 - $language = strtolower(substr($language, 0, 2));
1444 - }
1445 - $colors = $this->get_colors();
1446 - ?>
2301 + // ADMIN ISSUES
1447 2302
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 - ?>
2303 + /**
2304 + * Add custom boxes in posts edit page
2305 + */
2306 + public function add_custom_box() {
2307 + foreach($this->settings['posttypes'] as $posttype){
2308 + add_meta_box(
2309 + 'event_post_date',
2310 + __('Event date', 'event-post'),
2311 + array(&$this, 'inner_custom_box_date'),
2312 + $posttype,
2313 + apply_filters('eventpost_add_custom_box_position', $this->settings['adminpos'], $posttype),
2314 + 'core',
2315 + array(
2316 + '__block_editor_compatible_meta_box' => true,
2317 + )
2318 + );
2319 + add_meta_box(
2320 + 'event_post_loc',
2321 + __('Location', 'event-post'),
2322 + array(&$this, 'inner_custom_box_loc'),
2323 + $posttype,
2324 + apply_filters('eventpost_add_custom_box_position', $this->settings['adminpos'], $posttype),
2325 + 'core',
2326 + array(
2327 + '__block_editor_compatible_meta_box' => true,
2328 + )
2329 + );
2330 + do_action('eventpost_add_custom_box', $posttype);
2331 + }
2332 + }
1515 2333
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>
2334 + /**
2335 + * Displays the date custom box
2336 + */
2337 + public function inner_custom_box_date() {
1522 2338
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 2339
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 2340
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>
2341 + wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
2342 + $post_id = get_the_ID();
2343 + $event = $this->retreive($post_id);
2344 + if ($event != false){
2345 + $start_date = $event->start;
2346 + $end_date = $event->end;
2347 + $eventcolor = $event->color;
2348 + $eventicon = $event->icon;
1551 2349
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 - }
2350 + $language = get_bloginfo('language');
2351 + if (strpos($language, '-') > -1) {
2352 + $language = strtolower(substr($language, 0, 2));
2353 + }
2354 + $colors = $this->get_colors();
2355 + include (plugin_dir_path(__FILE__) . 'views/admin/custombox-date.php');
2356 + do_action ('eventpost_custom_box_date', $event);
2357 + }
2358 + }
1559 2359
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>
2360 + /**
2361 + * Displays the location custom box
2362 + */
2363 + public function inner_custom_box_loc($post) {
2364 + $event = $this->retreive($post);
2365 + if ($event != false){
2366 + include (plugin_dir_path(__FILE__) . 'views/admin/custombox-location.php');
2367 + do_action ('eventpost_custom_box_loc', $event);
2368 + $this->load_map_scripts();
2369 + }
2370 + }
1576 2371
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>
2372 + public function icon_color_fields($item_id, $meta_color,$value_color,$meta_icon,$value_icon ){
2373 + ?>
2374 + <div class="eventpost-misc-pub-section event-color-section">
2375 + <span class="screen-reader-text"><?php esc_html_e('Color:', 'event-post'); ?></span>
1583 2376
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>
2377 + <input class="color-field-post eventpost-colorpicker"
2378 + type="text"
2379 + name="<?php echo esc_attr($meta_color); ?>"
2380 + value="<?php echo esc_attr($value_color); ?>"
2381 + id="color-field<?php echo esc_attr($item_id); ?>"/>
1601 2382
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>
2383 + <select style="font-family : dashicons;" class="eventpost-iconpicker" name="<?php echo esc_attr($meta_icon); ?>">
2384 + <option value=""><?php esc_attr_e('None','event-post') ?></option>
2385 + <?php
2386 + foreach($this->DashIcons->icons as $class => $unicode){
2387 + ?>
2388 + <option value="<?php echo esc_attr($class) ?>" <?php selected($value_icon, $class, true); ?>>&#x<?php esc_attr_e($unicode) ?>; <?php echo esc_html($class) ?></option><?php // phpcs:ignore WordPress.WP.I18n ?>
2389 + <?php
2390 + }
2391 + ?>
2392 + </select>
2393 + <div class="custom-marker-container">
2394 + <p><?php esc_html_e('An image was found in your custom folder for this color', 'event-post')?> <span class="color-hex"></span> </p>
2395 + <img src="" class="image-marker">
2396 + </div>
2397 + </div>
1616 2398
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 2399
1671 - /**
1672 - *
1673 - * @param string $column_name
1674 - * @param boolean $bulk
1675 - */
2400 + <?php
2401 + }
2402 +
2403 + /**
2404 + * Quick edit
2405 + *
2406 + * @param string $column_name
2407 + * @param boolean $bulk
2408 + */
1676 2409 function quick_edit( $column_name, $post_type, $bulk=false) {
1677 2410
1678 2411 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 - }
2412 + static $eventpostprintNonceBulk = TRUE;
2413 + if ($eventpostprintNonceBulk) {
2414 + $eventpostprintNonceBulk = FALSE;
2415 + }
2416 + $fields = $this->bulk_edit_fields;
2417 + echo '<input type="hidden" name="eventpost-bulk-editor" id="eventpost-bulk-editor" value="eventpost-bulk-editor">';
2418 + }
2419 + else {
2420 + static $eventpostprintNonce = TRUE;
2421 + if ($eventpostprintNonce) {
2422 + $eventpostprintNonce = FALSE;
2423 + }
2424 + $fields = $this->quick_edit_fields;
2425 + }
2426 + wp_nonce_field(plugin_basename(__FILE__), 'eventpost_nonce');
2427 + if(isset($fields[$column_name])): ?>
2428 + <fieldset class="inline-edit-col-left inline-edit-<?php echo esc_attr($column_name); ?>">
2429 + <div class="inline-edit-group">
2430 + <?php foreach ($fields[$column_name] as $fieldname=>$fieldlabel): ?>
2431 + <fieldset class="inline-edit-col inline-edit-<?php echo esc_attr($fieldname); ?>">
2432 + <div class="inline-edit-col column-<?php echo esc_attr($fieldname); ?>">
2433 + <label class="inline-edit-group">
2434 + <span class="title"><?php echo esc_html($fieldlabel); ?></span>
2435 + <span class="input-text-wrap">
2436 + <?php echo wp_kses($this->inline_field($fieldname, $bulk), $this->kses_tags); ?>
2437 + </span>
2438 + </label>
2439 + </div>
2440 + </fieldset>
2441 + <?php endforeach; ?>
2442 + </div>
2443 + </fieldset>
2444 + <?php endif;
2445 + }
1713 2446
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 - }
2447 + /**
2448 + * Inline field in bulk edit
2449 + *
2450 + * @param type $fieldname
2451 + *
2452 + * @return string
2453 + */
2454 + function inline_field($fieldname, $bulk){
2455 + return apply_filters('eventpost_inline_field', '<input name="'.esc_attr($fieldname).'" class="eventpost-inline-'.esc_attr($fieldname).'" value="" type="text">', $fieldname, $bulk);
2456 + }
1722 2457
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 - }
2458 + function inline_field_color($html, $fieldname, $bulk){
2459 + if($fieldname==$this->META_COLOR){
2460 + $html='';
2461 + if($bulk){
2462 + $html.= '<span class="eventpost-bulk-colorpicker-button link">'.esc_html(__('No Change', 'event-post')).'</span>';
2463 + }
2464 + $html .= '
1741 2465
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 - }
2466 + <input class="eventpost-inline-colorpicker eventpost-inline-'.esc_attr($fieldname).' '.($bulk?'is-bulk':'no-bulk').'" type="color" name="'.esc_attr($fieldname).'" >';
2467 + }
2468 + return $html;
2469 + }
2470 + function inline_field_icon($html, $fieldname, $bulk){
2471 + if($fieldname==$this->META_ICON){
2472 + if($bulk){
2473 + $html.= '<span class="eventpost-bulk-icon-button link">'.__('No Change', 'event-post').'</span>';
2474 + }
2475 + $html = '<select class="eventpost-inline-colorpicker eventpost-inline-'.$fieldname.' '.($bulk?'is-bulk':'no-bulk').'"
2476 + type="text"
2477 + name="'.$fieldname.'"
2478 + style="font-family : dashicons">
2479 + <option value="">'.__("None", 'event-post').'</option>';
2480 + foreach($this->DashIcons->icons as $class => $unicode){
2481 + $html .= '<option value="'.$class.'">&#x'.$unicode.'; '.$class.'</option>';
2482 + }
2483 + $html .= '</select>';
1750 2484
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;
2485 + }
2486 + return $html;
1766 2487 }
1767 2488
1768 - if (!wp_verify_nonce(filter_input(INPUT_POST, 'eventpost_nonce', FILTER_SANITIZE_STRING), plugin_basename(__FILE__))){
1769 - return;
1770 - }
1771 2489
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);
2490 + /**
2491 + * Bulk edit
2492 + *
2493 + * @param type $column_name
2494 + * @param type $post_type
2495 + */
2496 + function bulk_edit($column_name, $post_type){
2497 + $this->quick_edit($column_name, $post_type, true);
1787 2498 }
1788 2499
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);
2500 + /**
2501 + * Saves data from quick-edit via `wp_ajax_inline-save` action
2502 + *
2503 + * @return void
2504 + */
2505 + function inline_save(){
2506 + $post_id = absint(filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT));
2507 + $this->save_postdata($post_id);
1797 2508 }
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 - }
2509 + /**
2510 + * When the post is saved, saves our custom data
2511 + *
2512 + * @param int $post_id
2513 + *
2514 + * @return void
2515 + */
2516 + public function save_postdata($post_id) {
2517 + if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
2518 + return;
2519 + }
1803 2520
1804 - $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
1805 - }
2521 + if (!wp_verify_nonce((string) filter_input(INPUT_POST, 'eventpost_nonce'), plugin_basename(__FILE__))){
2522 + return;
2523 + }
1806 2524
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 - }
2525 + $post_id = absint($post_id);
2526 + if (!$post_id || !current_user_can('edit_post', $post_id)) {
2527 + return;
2528 + }
1827 2529
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 - }
2530 + // Clean color or no color
2531 + if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR)) {
2532 + update_post_meta($post_id, $this->META_COLOR, sanitize_text_field($color));
2533 + }
2534 + // Clean color or no color
2535 + if (false !== $icon = filter_input(INPUT_POST, $this->META_ICON)) {
2536 + update_post_meta($post_id, $this->META_ICON, sanitize_text_field($icon));
2537 + }
2538 + if (false !== $attendance_mode = filter_input(INPUT_POST, $this->META_ATTENDANCE_MODE)) {
2539 + update_post_meta($post_id, $this->META_ATTENDANCE_MODE, sanitize_text_field($attendance_mode));
2540 + }
2541 + if (false !== $status = filter_input(INPUT_POST, $this->META_STATUS)) {
2542 + update_post_meta($post_id, $this->META_STATUS, sanitize_text_field($status));
2543 + }
2544 + $virtual_location = filter_input(INPUT_POST, $this->META_VIRTUAL_LOCATION, FILTER_SANITIZE_URL);
2545 + if ($virtual_location !== null && $virtual_location !== false) {
2546 + update_post_meta($post_id, $this->META_VIRTUAL_LOCATION, sanitize_url($virtual_location));
2547 + }
2548 + if (false !== $organization = filter_input(INPUT_POST, $this->META_ORGANIZATION)) {
2549 + update_post_meta($post_id, $this->META_ORGANIZATION, sanitize_text_field($organization));
2550 + }
2551 + $offer_url = filter_input(INPUT_POST, "{$this->META_OFFER}_url", FILTER_SANITIZE_URL);
2552 + $offer_price = filter_input(INPUT_POST, "{$this->META_OFFER}_price");
2553 + $offer_currency = filter_input(INPUT_POST, "{$this->META_OFFER}_currency");
2554 + if ($offer_url || ($offer_price && $offer_currency) ) {
2555 + // Format floating
2556 + $offer_price = $offer_price ? str_replace(',', '.', $offer_price) : null;
2557 + update_post_meta($post_id, $this->META_OFFER, array(
2558 + 'url' => $offer_url ? sanitize_text_field($offer_url) : null,
2559 + 'price' => $offer_price ? (float) $offer_price : null,
2560 + 'currency' => $offer_currency ? sanitize_text_field($offer_currency) : null,
2561 + ));
2562 + }
2563 + else{
2564 + delete_post_meta($post_id, $this->META_OFFER);
2565 + }
2566 + // Clean date or no date
2567 + if ((false !== $start = filter_input(INPUT_POST, $this->META_START)) &&
2568 + (false !== $end = filter_input(INPUT_POST, $this->META_END)) &&
2569 + '' != $start &&
2570 + '' != $end) {
2571 + update_post_meta($post_id, $this->META_START, sanitize_text_field(substr($start,0,16).':00'));
2572 + update_post_meta($post_id, $this->META_END, sanitize_text_field(substr($end,0,16).':00'));
2573 + }
2574 + else {
2575 + delete_post_meta($post_id, $this->META_START);
2576 + delete_post_meta($post_id, $this->META_END);
2577 + }
1844 2578
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 - }
2579 + // Clean location or no location
2580 + if ((false !== $lat = filter_input(INPUT_POST, $this->META_LAT)) &&
2581 + (false !== $long = filter_input(INPUT_POST, $this->META_LONG)) &&
2582 + '' != $lat &&
2583 + '' != $long) {
2584 + update_post_meta($post_id, $this->META_ADD, sanitize_text_field(filter_input(INPUT_POST, $this->META_ADD)));
2585 + update_post_meta($post_id, $this->META_LAT, $this->sanitize_coordinate(sanitize_text_field($lat)));
2586 + update_post_meta($post_id, $this->META_LONG, $this->sanitize_coordinate(sanitize_text_field($long)));
2587 + }
2588 + else {
2589 + delete_post_meta($post_id, $this->META_ADD);
2590 + delete_post_meta($post_id, $this->META_LAT);
2591 + delete_post_meta($post_id, $this->META_LONG);
2592 + }
1875 2593
1876 - }
2594 + $post_ids = (!empty($_POST['post_ids']) ) ? $_POST['post_ids'] : array();
2595 + }
1877 2596
2597 + /**
2598 + * Saves data from bulk-edit
2599 + * Uses bulk_edit_posts hook
2600 + *
2601 + * @see https://developer.wordpress.org/reference/hooks/bulk_edit_posts/
2602 + *
2603 + * @return void
2604 + */
2605 + function save_bulkdatas(array $post_ids, array $shared_post_data) {
2606 + if (!wp_verify_nonce(filter_input(INPUT_GET, 'eventpost_nonce'), plugin_basename(__FILE__))){
2607 + return;
2608 + }
2609 + $current_post_type = isset($shared_post_data['post_type']) ? $shared_post_data['post_type'] : 'post';
2610 + if (in_array($current_post_type, $this->settings['posttypes'])) {
2611 + if (!empty($post_ids) && is_array($post_ids)) {
2612 + foreach ($post_ids as $post_id) {
2613 + if(! current_user_can( 'edit_post', $post_id )){
2614 + continue;
2615 + }
2616 + foreach ($this->bulk_edit_fields as $sets) {
2617 + foreach ($sets as $fieldname => $fieldlabel) {
2618 + if (isset($shared_post_data[$fieldname])) {
2619 + update_post_meta($post_id, $fieldname, $shared_post_data[$fieldname]);
2620 + }
2621 + }
2622 + }
2623 + }
2624 + }
2625 + }
2626 + }
1878 2627
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));
2628 + /**
2629 + * Displays a date for calendar cell
2630 + *
2631 + * @param string $date
2632 + * @param string $cat
2633 + * @param boolean $display
2634 + *
2635 + * @return boolean
2636 + */
2637 + public function display_caldate($date, $cat = '', $display = false, $colored=true, $thumbnail='', $title='',$tax_name='' ,$tax_term='') {
2638 + $events = $this->get_events(array('nb' => -1, 'date' => $date, 'cat' => $cat, 'retreive' => true,'tax_name' => $tax_name ,'tax_term' => $tax_term));
2639 + $nb = count($events);
2640 + $ret = "";
2641 + $price = "";
2642 + if(!$display && !$nb){
2643 + $ret = date('j', $date);
2644 + }
2645 + $price = '';
2646 + if($nb){
2647 + if ($display || $title) {
2648 + $ret='<ul>';
2649 + foreach ($events as $event) {
2650 + $price = $this->get_price($event, true);
2651 + if ($this->settings['emptylink'] == 0 && empty($event->post_content)) {
2652 + $event->guid = '#';
2653 + }
2654 + $ret.='<li>'
2655 + // Translators: %s is the event title
2656 + . '<a href="' . $event->permalink . '" title="'.esc_attr(sprintf(__('View event: %s', 'event-post'), $event->post_title)).'">'
2657 + . '<h4>' . $event->post_title . '</h4>'
2658 + . '<span class="event_price">' . $price . '</span>'
2659 + .$this->get_single($event)
2660 + . (!empty($thumbnail) ? '<span class="event_thumbnail_wrap">' . get_the_post_thumbnail($event->ID, $thumbnail) . '</span>' : '')
2661 + .'</a>'
2662 + . '</li>';
2663 + }
2664 + $ret.='</ul>';
2665 + }
2666 + if ($display) {
2667 + // return $ret;
2668 + }
2669 + elseif($title) {
2670 + $ret = '<span '.($colored?' style="color:#'.$events[0]->color.'"':'').'>'.date('j', $date).'</span>'.$ret;
2671 + }
2672 + else {
2673 + $ret = '<button data-event="'. $tax_term .'" data-date="' . date('Y-m-d', $date).'"'
2674 + .' class="'.apply_filters( 'event_post_class_calendar_link', 'eventpost_cal_link' ).'"'.($colored?' style="background-color:#'.$events[0]->color.'"':'')
2675 + // Translators: %1$d is the number of events, %2$s is the date
2676 + .' 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']))).'"'
2677 + .'>'
2678 + . date('j', $date)
2679 + . '</button>';
2680 + }
2681 + }
2682 + return apply_filters('eventpost_display_caldate', $ret, $events, $date, $cat ,$price, $display ,$colored ,$thumbnail ,$title ,$tax_name ,$tax_term );
2683 + }
1894 2684
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 2685
1902 - $annee = substr($date, 0, 4);
1903 - $mois = substr($date, 5);
2686 + /**
2687 + * Returns a calendar HTML
2688 + *
2689 + * @param array $atts
2690 + *
2691 + * @filter eventpost_params
2692 + *
2693 + * @return string
2694 + */
2695 + public function calendar($atts) {
2696 + extract(shortcode_atts(apply_filters('eventpost_params', array(
2697 + 'date' => date('Y-n'),
2698 + 'cat' => '',
2699 + 'mondayfirst' => 0, //1 : weeks starts on monday
2700 + 'datepicker' => 1,
2701 + 'colored' => 1,
2702 + 'display_title'=>0,
2703 + 'tax_name' => '',
2704 + 'tax_term' => '',
2705 + 'thumbnail'=>'',
2706 + ), 'calendar'), $atts));
1904 2707
1905 - $time = mktime(0, 0, 0, $mois, 1, $annee);
2708 + if($date && !preg_match('#[0-9][0-9][0-9][0-9]-[0-9][0-9]?#i', $date)){
2709 + $date = date('Y-n', strtotime($date));
2710 + }
2711 + if(!$date){
2712 + $date = date('Y-n');
2713 + }
1906 2714
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);
2715 + $annee = substr($date, 0, 4);
2716 + $mois = substr($date, 5);
1911 2717
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>';
2718 + $time = mktime(0, 0, 0, $mois, 1, $annee);
1945 2719
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 - }
2720 + $prev_year = strtotime('-1 Year', $time);
2721 + $next_year = strtotime('+1 Year', $time);
2722 + $prev_month = strtotime('-1 Month', $time);
2723 + $next_month = strtotime('+1 Month', $time);
1971 2724
1972 - }
1973 - $ret.='</tbody></table>';
1974 - return $ret;
1975 - }
2725 + $JourMax = date("t", $time);
2726 + $NoJour = -date("w", $time);
2727 + if ($mondayfirst == 0) {
2728 + $NoJour +=1;
2729 + } else {
2730 + $NoJour +=2;
2731 + $this->Week[] = array_shift($this->Week);
2732 + }
2733 + if ($NoJour > 0 && $mondayfirst == 1) {
2734 + $NoJour -=7;
2735 + }
2736 + $ret = '<table class="event-post-calendar-table">'
2737 + . '<caption class="screen-reader-text">'
2738 + . __('A calendar of events', 'event-post')
2739 + . '</caption>';
2740 + $ret.='<thead><tr><th colspan="7">';
2741 + if ($datepicker == 1) {
2742 + $ret.='<div class="eventpost-calendar-header">';
2743 + // Translators: %s is the year
2744 + $ret.='<span class="eventpost-cal-year"><button data-date="' . date('Y-n', $prev_year) . '" tabindex="0" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $prev_year)).'" class="eventpost_cal_bt eventpost-cal-bt-prev">&laquo;</button><span class="eventpost-cal-header-text">';
2745 + $ret.=$annee;
2746 + // Translators: %s is the year
2747 + $ret.='</span><button data-date="' . date('Y-n', $next_year) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date('Y', $next_year)).'" class="eventpost_cal_bt eventpost-cal-bt-next">&raquo;</button></span>';
2748 + // Translators: %s is the month name
2749 + $ret.='<span class="eventpost-cal-month"><button data-date="' . date('Y-n', $prev_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $prev_month)).'" class="eventpost_cal_bt eventpost-cal-bt-prev eventpost-cal-bt-prev-month">&laquo;</button><span class="eventpost-cal-header-text">';
2750 + $ret.=$this->NomDuMois[abs($mois)];
2751 + // Translators: %s is the month name
2752 + $ret.='</span><button data-date="' . date('Y-n', $next_month) . '" title="'.sprintf(__('Switch to %s', 'event-post'), date_i18n('F Y', $next_month)).'" class="eventpost_cal_bt eventpost-cal-bt-next eventpost-cal-bt-next-month">&raquo;</button> </span>';
2753 + $ret.='<span class="eventpost-cal-today"><button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button></span>';
2754 + $ret.='</div>';
2755 + }
2756 + $ret.='</th></tr><tr class="event_post_cal_days">';
2757 + for ($w = 0; $w < 7; $w++) {
2758 + $ret.='<th scope="col">' . strtoupper(substr($this->Week[$w], 0, 1)) . '</th>';
2759 + }
2760 + $ret.='</tr>';
2761 + $ret.='</thead>';
1976 2762
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 - }
2763 + $ret.='<tbody>';
2764 + $sqldate = date('Y-m', $time);
2765 + $cejour = date('Y-m-d');
2766 + for ($semaine = 0; $semaine <= 5; $semaine++) { // 6 semaines par mois
2767 + $tr_row_content ='';
2768 + for ($journee = 0; $journee <= 6; $journee++) { // 7 jours par semaine
2769 + if ($NoJour > 0 && $NoJour <= $JourMax) { // si le jour est valide a afficher
2770 + $td = '<td class="event_post_day">';
2771 + if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour == $cejour) {
2772 + $td = '<td class="event_post_day_now">';
2773 + }
2774 + if ($sqldate . '-' . ($NoJour<10?'0':'').$NoJour < $cejour){
2775 + $td = '<td class="event_post_day_over">'; // Patch ahf
2776 + }
2777 + $tr_row_content.=$td;
2778 + $tr_row_content.= $this->display_caldate(mktime(0, 0, 0, $mois, $NoJour, $annee), $cat, false, $colored, $thumbnail, $display_title ,$tax_name ,$tax_term);
2779 + $tr_row_content.='</td>';
2780 + } else {
2781 + $tr_row_content.='<td></td>';
2782 + }
2783 + $NoJour ++;
2784 + }
2785 + if($tr_row_content){
2786 + $ret.='<tr>'.$tr_row_content.'</tr>';
2787 + }
2003 2788
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 - }
2789 + }
2790 + $ret.='</tbody></table>';
2791 + return $ret;
2792 + }
2020 2793
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 - }
2794 + /**
2795 + * Echoes a list of event, should be called via AJAX
2796 + *
2797 + * @return void
2798 + */
2799 + public function ajaxlist(){
2800 + echo wp_kses($this->list_events(array(
2801 + 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2802 + 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2803 + 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2804 + 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2805 + 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2806 + 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2807 + 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2808 + 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2809 + 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2810 + 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2811 + 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2812 + 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2813 + 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2814 + 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2815 + 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2816 + 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2817 + 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2818 + 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2819 + 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2820 + 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2821 + 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2822 + 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2823 + ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type'))), $this->kses_tags);
2824 + exit;
2825 + }
2035 2826
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 - }
2827 + /**
2828 + * Echoes a list of event, should be called via AJAX
2829 + *
2830 + * @return void
2831 + */
2832 + public function ajaxTimeline(){
2833 + echo wp_kses($this->list_events(array(
2834 + 'nb' => esc_attr(FILTER_INPUT(INPUT_POST, 'nb')),
2835 + 'future' => esc_attr(FILTER_INPUT(INPUT_POST, 'future')),
2836 + 'past' => esc_attr(FILTER_INPUT(INPUT_POST, 'past')),
2837 + 'geo' => esc_attr(FILTER_INPUT(INPUT_POST, 'geo')),
2838 + 'width' => esc_attr(FILTER_INPUT(INPUT_POST, 'width')),
2839 + 'height' => esc_attr(FILTER_INPUT(INPUT_POST, 'height')),
2840 + 'zoom' => esc_attr(FILTER_INPUT(INPUT_POST, 'zoom')),
2841 + 'tile' => esc_attr(FILTER_INPUT(INPUT_POST, 'tile')),
2842 + 'title' => esc_attr(FILTER_INPUT(INPUT_POST, 'title')),
2843 + 'before_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'before_title')),
2844 + 'after_title' => esc_attr(FILTER_INPUT(INPUT_POST, 'after_title')),
2845 + 'cat' => esc_attr(FILTER_INPUT(INPUT_POST, 'cat')),
2846 + 'tag' => esc_attr(FILTER_INPUT(INPUT_POST, 'tag')),
2847 + 'events' => esc_attr(FILTER_INPUT(INPUT_POST, 'events')),
2848 + 'style' => esc_attr(FILTER_INPUT(INPUT_POST, 'style')),
2849 + 'thumbnail' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail')),
2850 + 'thumbnail_size' => esc_attr(FILTER_INPUT(INPUT_POST, 'thumbnail_size')),
2851 + 'excerpt' => esc_attr(FILTER_INPUT(INPUT_POST, 'excerpt')),
2852 + 'orderby' => esc_attr(FILTER_INPUT(INPUT_POST, 'orderby')),
2853 + 'order' => esc_attr(FILTER_INPUT(INPUT_POST, 'order')),
2854 + 'class' => esc_attr(FILTER_INPUT(INPUT_POST, 'class')),
2855 + 'pages' => esc_attr(FILTER_INPUT(INPUT_POST, 'pages')),
2856 + ), esc_attr(FILTER_INPUT(INPUT_POST, 'list_type'))), $this->kses_tags);
2857 + exit;
2858 + }
2859 + /**
2860 + * Echoes next page of events, should be called via AJAX
2861 + *
2862 + * @return void
2863 + */
2864 + public function ajaxGetNextPage(){
2865 + $response = [
2866 + "success" => false,
2867 + "next_query" => false,
2868 + ];
2869 + if(isset($_POST['query'])){
2870 + parse_str($_POST['query'],$query);
2871 + foreach($query as $key => $value){
2872 + $query[$key] = esc_attr($value);
2873 + }
2874 + if(isset($_POST['paged'])){
2875 + $query["paged"] = esc_attr($_POST['paged']);
2876 + }else{
2877 + $response['message'] = __('Page number missing', 'event-post');
2878 + }
2879 + $query['container_schema'] = $this->timeline_shema['container'];
2880 + $query['item_schema'] = $this->timeline_shema['item'];
2881 + $html = $this->list_events($query,'event_timeline','events_only');
2882 + if($html == ""){
2883 + $response['message'] = __('No more to load', 'event-post');
2884 + }else{
2885 + $query["paged"] = $query["paged"] + 1;
2886 + $next_html = $this->list_events($query,'event_timeline','events_only');
2887 + $response = [
2888 + "success" => true,
2889 + "html" => $html,
2890 + "next_query" => $next_html == "" ? false : true,
2891 + ];
2892 + }
2893 + }else{
2894 + $response['message'] = __('Query missing', 'event-post');
2895 + }
2896 + wp_send_json($response);
2897 + exit;
2898 + }
2046 2899
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++;
2900 + /**
2901 + * Echoes the content of the calendar in ajax context
2902 + *
2903 + * @return void
2904 + */
2905 + public function ajaxcal() {
2906 + $method = isset($_GET['action']) ? INPUT_GET : INPUT_POST;
2907 + echo wp_kses($this->calendar(array(
2908 + 'date' => esc_attr(FILTER_INPUT($method, 'date')),
2909 + 'cat' => esc_attr(FILTER_INPUT($method, 'cat')),
2910 + 'mondayfirst' => esc_attr(FILTER_INPUT($method, 'mf')),
2911 + 'datepicker' => esc_attr(FILTER_INPUT($method, 'dp')),
2912 + 'colored' => esc_attr(FILTER_INPUT($method, 'color')),
2913 + 'display_title' => esc_attr(FILTER_INPUT($method, 'display_title')),
2914 + 'thumbnail' => esc_attr(FILTER_INPUT($method, 'thumbnail')),
2915 + 'tax_name' => esc_attr(FILTER_INPUT($method, 'tax_name')),
2916 + 'tax_term' => esc_attr(FILTER_INPUT($method, 'tax_term')),
2917 + )), $this->kses_tags);
2918 + exit();
2919 + }
2060 2920
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 : '';
2921 + /**
2922 + * Echoes the date of the calendar in ajax context
2923 + */
2924 + public function ajaxdate() {
2925 + echo wp_kses($this->display_caldate(
2926 + strtotime(esc_attr(FILTER_INPUT(INPUT_GET, 'date'))),
2927 + esc_attr(FILTER_INPUT(INPUT_GET, 'cat')),
2928 + true,
2929 + esc_attr(FILTER_INPUT(INPUT_GET, 'color')),
2930 + esc_attr(FILTER_INPUT(INPUT_GET, 'thumbnail')),
2931 + esc_attr(FILTER_INPUT(INPUT_GET, 'display_title')),
2932 + esc_attr(FILTER_INPUT(INPUT_GET, 'tax_name')),
2933 + esc_attr(FILTER_INPUT(INPUT_GET, 'tax_term'))
2934 + ), $this->kses_tags);
2935 + exit();
2936 + }
2066 2937
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 - }
2938 + /**
2939 + * Echoes a date in ajax context
2940 + */
2941 + public function HumanDate() {
2942 + if (isset($_REQUEST['date']) && !empty($_REQUEST['date'])) {
2943 + $date = strtotime($_REQUEST['date']);
2944 + echo esc_html($this->human_date($date, $this->settings['dateformat']).(date('H:i', $date)=='00:00' ? '' : ' '. date($this->settings['timeformat'], $date)));
2945 + exit();
2946 + }
2947 + }
2075 2948
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');
2949 + /**
2950 + * Displays a search form
2951 + *
2952 + * @param type $atts
2953 + *
2954 + * @return type
2955 + */
2956 + public function search($atts) {
2957 + $params = shortcode_atts(apply_filters('eventpost_params', array(
2958 + 'dates' => true,
2959 + 'q' => true,
2960 + 'tax' => false,
2961 + ), 'search'), $atts);
2962 + $this->list_id++;
2080 2963
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 - }
2964 + $list_id = $this->list_id;
2965 + $q = (false !== $q = filter_input(INPUT_GET, 'q')) ? $q : '';
2966 + $from = (false !== $from = filter_input(INPUT_GET, 'from')) ? $from : '';
2967 + $to = (false !== $to = filter_input(INPUT_GET, 'to')) ? $to : '';
2968 + $tax = (false !== $tax = filter_input(INPUT_GET, 'tax')) ? $tax : '';
2093 2969
2094 - if ($from || $to) {
2970 + $cleaned_from = $this->date_cleanup($from);
2971 + $cleaned_to = $this->date_cleanup($to);
2972 + if(empty($cleaned_from)){
2973 + $from=false;
2974 + }
2975 + if(empty($cleaned_to)){
2976 + $to=false;
2977 + }
2095 2978
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 - }
2979 + // Search form
2980 + $this->admin_scripts(null, true);
2981 + wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__), false, filemtime( "/$block_js" ));
2982 + include (plugin_dir_path(__FILE__) . 'views/search-form.php');
2121 2983
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 - }
2984 + // Results
2985 + if ($list_id == filter_input(INPUT_GET, 'evenpost_search')) {
2986 + $arg = array(
2987 + 'post_type' => $this->settings['posttypes'],
2988 + 'meta_key' => $this->META_START,
2989 + 'orderby' => 'meta_value',
2990 + 'order' => 'ASC',
2991 + 's' => $q
2992 + );
2993 + if ($tax) {
2994 + $arg['cat'] = $tax;
2995 + }
2147 2996
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 - }
2997 + if ($from || $to) {
2159 2998
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);
2999 + $arg['meta_query'] = array();
3000 + if ($from) {
3001 + $arg['meta_query'][] = array(
3002 + 'key' => $this->META_START,
3003 + 'value' => $from,
3004 + 'compare' => '>=',
3005 + 'type' => 'DATETIME'
3006 + );
3007 + }
3008 + if ($to) {
3009 + $arg['meta_query'][] = $meta_query = array(
3010 + array(
3011 + 'key' => $this->META_END,
3012 + 'value' => $to,
3013 + 'compare' => '<=',
3014 + 'type' => 'DATETIME'
3015 + ),
3016 + );
3017 + }
3018 + }
3019 + $events = new WP_Query($arg);
3020 + include (plugin_dir_path(__FILE__) . 'views/search-results.php');
3021 + wp_reset_query();
3022 + }
3023 + }
2170 3024
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';
3025 + /**
3026 + * Geocodes an address using OpenStreetMap Nominatim API and cache the result in a transient for 30 days
3027 + *
3028 + * @param string $address
3029 + * @param boolean $single_result Whether to return only the first result or all results
3030 + *
3031 + * @return array|false|string The geocoding result(s) or false on failure
3032 + */
3033 + public function geocode(string $address, bool $single_result = false){
3034 + $transient_name = 'eventpost_osquery_' . $address;
3035 + $val = get_transient($transient_name);
3036 + if (false === $val || empty($val) || !is_string($val)) {
3037 + $language = get_bloginfo('language');
3038 + if (strpos($language, '-') > -1) {
3039 + $language = strtolower(substr($language, 0, 2));
3040 + }
3041 + $remote_val = wp_safe_remote_request('https://nominatim.openstreetmap.org/search?q=' . rawurlencode($address) . '&format=json&accept-language=' . $language, [
3042 + 'user-agent' => getenv('HTTP_USER_AGENT') ?? 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url'),
3043 + 'headers' => [
3044 + 'Referer' => get_bloginfo('url'),
3045 + ],
3046 + 'timeout' => 5,
3047 + ]);
3048 + $remote_body = wp_remote_retrieve_body($remote_val);
3049 + if(strstr($remote_body, '<html>')){
3050 + $val = [
3051 + [
3052 + 'lat' => '',
3053 + 'lon' => '',
3054 + 'display_name' => strip_tags($remote_body),
3055 + ]
3056 + ];
3057 + }
3058 + else{
3059 + $val = json_decode($remote_body);
3060 + if($val){
3061 + set_transient($transient_name, $val, 30 * DAY_IN_SECONDS);
3062 + }
3063 + }
2176 3064 }
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 - }
3065 + if($single_result && is_array($val) && count($val) > 0){
3066 + $val = $val[0];
3067 + }
3068 + return $val;
3069 + }
2191 3070
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 - }
3071 + /**
3072 + * AJAX Get lat long from address
3073 + */
3074 + public function GetLatLong() {
3075 + if (isset($_REQUEST['q']) && !empty($_REQUEST['q'])) {
3076 + // verifier le cache
3077 + $q = $_REQUEST['q'];
3078 + header('Content-Type: application/json');
3079 + $val = $this->geocode($q);
3080 + wp_send_json( $val );
3081 + exit();
3082 + }
3083 + }
2200 3084
2201 - /** ADMIN PAGES **/
3085 + /**
3086 + * Alters columns
3087 + *
3088 + * @param array $defaults
3089 + *
3090 + * @filter eventpost_columns_head
3091 + *
3092 + * @return array
3093 + */
3094 + public function columns_head($defaults) {
3095 + $defaults['event'] = __('Event', 'event-post');
3096 + $defaults['location'] = __('Location', 'event-post');
3097 + return apply_filters('eventpost_columns_head', $defaults);
3098 + }
2202 3099
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 - }
3100 + /**
3101 + * Echoes content of a row in a given column
3102 + *
3103 + * @param string $column_name
3104 + * @param int $post_id
3105 + *
3106 + * @action eventpost_columns_content
3107 + */
3108 + public function columns_content($column_name, $post_id) {
3109 + if ($column_name == 'location') {
3110 + $lat = $this->sanitize_coordinate(get_post_meta($post_id, $this->META_LAT, true));
3111 + $lon = $this->sanitize_coordinate(get_post_meta($post_id, $this->META_LONG, true));
2228 3112
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 - }
3113 + if (!empty($lat) && !empty($lon)) {
3114 + add_thickbox();
3115 + $color = $this->get_post_color($post_id, $this->settings['default_color'], true);
3116 + $icon = $this->get_post_icon($post_id, $this->settings['default_icon'], true);
3117 + if ($color == ''){
3118 + $color = '777777';
3119 + }
3120 + if ($icon == ''){
3121 + $icon = 'location';
3122 + }
3123 + echo wp_kses( '<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">'
3124 + . '<i class="dashicons dashicons-'.$icon.'" style="color:#'.$color.';"></i>'
3125 + . '<span class="screen-reader-text">'.__('View on a map', 'event-post').'</span>'
3126 + . get_post_meta($post_id, $this->META_ADD, true)
3127 + . '</a> ', $this->kses_tags);
3128 + }
3129 + $this->column_edit_hidden_fields($post_id, 'location');
3130 + }
3131 + if ($column_name == 'event') {
3132 + echo wp_kses($this->print_date($post_id, false), $this->kses_tags);
3133 + $this->column_edit_hidden_fields($post_id, 'event');
3134 + }
3135 + do_action('eventpost_columns_content', $column_name, $post_id);
3136 + }
2251 3137
2252 - /**
2253 - * @action eventpost_register_settings
2254 - */
2255 - public function register_settings(){
2256 - register_setting( 'eventpost-settings', 'ep_settings' );
3138 + function column_edit_hidden_fields($post_id, $set){
3139 + $event = $this->retreive($post_id);
3140 + $html = '<div class="hidden">';
3141 + if ($event != false){
3142 + foreach($this->quick_edit_fields[$set] as $fieldname=>$fieldlabel){
3143 + $html .= '<span class="inline-edit-value '.$fieldname.'">'.esc_attr($event->$fieldname).'</span>';
3144 + }
3145 + }
3146 + $html .= '</div>';
3147 + echo wp_kses($html, $this->kses_tags);
3148 + }
2257 3149
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 - );
3150 + // ADMIN PAGES
2313 3151
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 - );
3152 + /**
3153 + * Adds items to the native "right now" dashboard widget
3154 + *
3155 + * @param array $elements
3156 + *
3157 + * @return array
3158 + */
3159 + public function dashboard_right_now($elements){
3160 + $nb_date = count($this->get_events(array('future'=>1, 'past'=>1, 'nb'=>-1)));
3161 + $nb_geo = count($this->get_events(array('future'=>1, 'past'=>1, 'geo'=>1, 'nb'=>-1)));
3162 + if($nb_date){
3163 + // Translators: %d is the number of events
3164 + array_push($elements, '<i class="dashicons dashicons-calendar"></i> <i href="edit.php?post_type=post">'.sprintf(__('%d Events','event-post'), $nb_date)."</i>");
3165 + }
3166 + if($nb_geo){
3167 + // Translators: %d is the number of geolocalized events
3168 + 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>");
3169 + }
3170 + return $elements;
3171 + }
2377 3172
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 - );
3173 + /*
3174 + * Feed
3175 + * generate ICS or VCS files from a category
3176 + */
2402 3177
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 - );
3178 + /**
3179 + * Get a date formatted for ICS
3180 + *
3181 + * @param timestamp $timestamp
3182 + *
3183 + * @return string
3184 + */
3185 + public function ics_date($timestamp){
3186 + return date("Ymd",$timestamp).'T'.date("His",$timestamp);
3187 + }
2447 3188
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 - );
3189 + public function get_gmt_offset(){
3190 + $gmt_offset = get_option('gmt_offset ');
3191 + $codegmt = 0;
3192 + if ($gmt_offset != 0 && substr($gmt_offset, 0, 1) != '-' && substr($gmt_offset, 0, 1) != '+') {
3193 + $codegmt = $gmt_offset * -1;
3194 + $gmt_offset = '+' . $gmt_offset;
3195 + }
3196 + if(abs($gmt_offset < 10)){
3197 + $gmt_offset = substr($gmt_offset, 0, 1).'0'.substr($gmt_offset, 1);
3198 + }
3199 + return $gmt_offset;
3200 + }
2496 3201
2497 - do_action('eventpost_register_settings');
2498 - }
2499 - function settings_section_callback( $arg ) {
2500 - echo '<hr>';
2501 - }
3202 + /**
3203 + * Outputs an ICS or VCS file for a given event
3204 + *
3205 + * @param int $event_id
3206 + * @param string $format
3207 + *
3208 + * @return void
3209 + */
3210 + private function generate_ics($event_id, $format){
3211 + $allowed_formats = array('ics', 'vcs');
3212 + $event_id = intval($event_id);
3213 + $format = sanitize_text_field($format);
3214 + if (in_array($format, $allowed_formats)) {
3215 + $export_file = plugin_dir_path(__FILE__) . 'inc/export/' . $format . '.php';
3216 + if (is_numeric($event_id) && file_exists($export_file)) {
3217 + $event = $this->retreive($event_id);
3218 + if($event->post_status != 'publish'){
3219 + wp_die(esc_html__('Event not found.', 'event-post'), 404);
3220 + }
3221 + include $export_file;
3222 + exit;
3223 + }
3224 + }
3225 + wp_die(esc_html__('Invalid request.', 'event-post'), 400);
3226 + }
3227 +
2502 3228
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 - }
3229 + public function parse_request(){
3230 + global $wp;
3231 + if (preg_match('#^event-feed#i', $wp->request, $match)) {
3232 + $this->feed();
3233 + exit;
3234 + }
3235 + if (preg_match('#^eventpost/([0-9]*)\.(ics|vcs)#i', $wp->request, $match)) {
3236 + $this->generate_ics($match[1], $match[2]);
3237 + }
3238 + }
2594 3239
2595 - /*
2596 - * feed
2597 - * generate ICS or VCS files from a category
2598 - */
3240 + public function export(){
3241 + if(false !== $event_id=\filter_input(INPUT_GET, 'event_id',FILTER_SANITIZE_NUMBER_INT)){
3242 + $format = \filter_input(INPUT_GET, 'format');
3243 + $this->generate_ics($event_id, $format);
3244 + }
3245 + }
2599 3246
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 3247
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 - }
3248 + /**
3249 + * Outputs an ICS document
3250 + *
3251 + * Filters can be applied to the criteria used to retrieve events in GET parameters:
3252 + * - cat : category slug
3253 + * - tag : tag slug
3254 + * - tax_name : custom taxonomy name
3255 + * - tax_term : custom taxonomy term slug
3256 + * - nb : number of events to retrieve (default 10)
3257 + * - future : retreive future events
3258 + * - past : retreive past events
3259 + *
3260 + * @return void
3261 + */
3262 + public function feed(){
3263 + $criteria = array(
3264 + 'nb'=>10,
3265 + );
3266 + if(false !== $cat=\filter_input(INPUT_GET, 'cat')){
3267 + $criteria['cat'] = sanitize_text_field($cat);
3268 + }
3269 + if(false !== $tag=\filter_input(INPUT_GET, 'tag')){
3270 + $criteria['tag'] = sanitize_text_field($tag);
3271 + }
3272 + if(false !== $tax_name=\filter_input(INPUT_GET, 'tax_name')){
3273 + $criteria['tax_name'] = sanitize_text_field($tax_name);
3274 + }
3275 + if(false !== $tax_term=\filter_input(INPUT_GET, 'tax_term')){
3276 + $criteria['tax_term'] = sanitize_text_field($tax_term);
3277 + }
3278 + if(false !== $nb=\filter_input(INPUT_GET, 'nb', FILTER_SANITIZE_NUMBER_INT)){
3279 + $criteria['nb'] = sanitize_text_field($nb);
3280 + }
3281 + if(false !== $future=\filter_input(INPUT_GET, 'future', FILTER_SANITIZE_NUMBER_INT)){
3282 + $criteria['future'] = sanitize_text_field($future);
3283 + }
3284 + if(false !== $past=\filter_input(INPUT_GET, 'past', FILTER_SANITIZE_NUMBER_INT)){
3285 + $criteria['past'] = sanitize_text_field($past);
3286 + }
3287 + $vtz = get_option('timezone_string');
3288 + $gmt = $this->get_gmt_offset();
3289 + date_default_timezone_set($vtz);
3290 + $separator = "\n";
2621 3291
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";
3292 + header("content-type:text/calendar");
3293 + header("Pragma: public");
3294 + header("Expires: 0");
3295 + header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
3296 + header("Cache-Control: public");
3297 + header("Content-Disposition: attachment; filename=". str_replace('+','-',rawurlencode(get_option('blogname').'-'.$cat)).".ics;" );
2631 3298
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;" );
3299 + $props = array();
2638 3300
2639 - $props = array();
3301 + // General
3302 + $props[] = 'BEGIN:VCALENDAR';
3303 + $props[] = 'PRODID://WordPress//Event-Post-V'.$this->version.'//EN';
3304 + $props[] = 'VERSION:2.0';
3305 + // Timezone
3306 + if(!empty($vtz)){
3307 + array_push($props,
3308 + 'BEGIN:VTIMEZONE',
3309 + 'TZID:'.$vtz,
3310 + 'BEGIN:DAYLIGHT',
3311 + 'TZOFFSETFROM:+0100',
3312 + 'TZOFFSETTO:'.($gmt).'00',
3313 + 'DTSTART:19700329T020000',
3314 + 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3',
3315 + 'END:DAYLIGHT',
3316 + 'BEGIN:STANDARD',
3317 + 'TZOFFSETFROM:'.($gmt).'00',
3318 + 'TZOFFSETTO:+0100',
3319 + 'TZNAME:CET',
3320 + 'DTSTART:19701025T030000',
3321 + 'RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10',
3322 + 'END:STANDARD',
3323 + 'END:VTIMEZONE'
3324 + );
3325 + }
2640 3326
2641 - // General
2642 - $props[] = 'BEGIN:VCALENDAR';
2643 - $props[] = 'PRODID://WordPress//Event-Post V'. file_get_contents(('VERSION')).'//EN';
2644 - $props[] = 'VERSION:2.0';
3327 + // Events
3328 + $events=$this->get_events($criteria);
3329 + foreach ($events as $event) {
3330 + if($event->time_start && $event->time_end){
3331 + $description = wordwrap(
3332 + str_replace(
3333 + ['\\', ';', ',', "\r", "\n"],
3334 + ['\\\\', '\;', '\,', '', '\n'],
3335 + wp_strip_all_tags($event->description . "\n\n" . $event->permalink)
3336 + ),
3337 + 70,
3338 + "\n ",
3339 + true
3340 + );
3341 + array_push($props,
3342 + 'BEGIN:VEVENT',
3343 + 'CREATED:'.$this->ics_date(strtotime($event->post_date)).'Z',
3344 + 'LAST-MODIFIED:'.$this->ics_date(strtotime($event->post_modified)).'Z',
3345 + 'SUMMARY:'.$event->post_title,
3346 + 'UID:'.md5(site_url()."_eventpost_".$event->ID),
3347 + 'LOCATION:'.str_replace(',','\,',$event->address),
3348 + 'DTSTAMP:'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
3349 + 'DTSTART'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_start).(!empty($vtz)?'':'Z'),
3350 + 'DTEND'.(!empty($vtz)?';TZID='.$vtz:'').':'.$this->ics_date($event->time_end).(!empty($vtz)?'':'Z'),
3351 + 'DESCRIPTION:'.$description,
3352 + 'END:VEVENT'
3353 + );
3354 + }
3355 + }
2645 3356
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 - }
3357 + // End
3358 + $props[] = 'END:VCALENDAR';
2667 3359
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;
3360 + echo esc_html(implode($separator, $props));
3361 + exit;
2690 3362 }
2691 - }
2692 3363 }