| @@ -2,9 +2,9 @@ | ||
| 2 | 2 | /** |
| 3 | 3 | * Plugin Name: Event Post |
| 4 | 4 | * Plugin URI: https://event-post.com?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard&mtm_source=plugin-uri |
| 5 | 5 | * Description: Add calendar and/or geolocation metadata on any posts. |
| 6 | - * Version: 5.12.0 | |
| 6 | + * Version: 6.1.2 | |
| 7 | 7 | * Author: N.O.U.S. Open Useful and Simple |
| 8 | 8 | * Contributors: bastho, sabrinaleroy, unecologeek, agencenous |
| 9 | 9 | * Author URI: https://apps.avecnous.eu/?mtm_campaign=wp-plugin&mtm_kwd=event-post&mtm_medium=dashboard&mtm_source=author |
| 10 | 10 | * License: GPLv2 |
| @@ -13,8 +13,11 @@ | ||
| 13 | 13 | * Tags: Post,posts,event,date,geolocalization,gps,widget,map,openstreetmap,EELV,calendar,agenda,blocks |
| 14 | 14 | * |
| 15 | 15 | * @package event-post |
| 16 | 16 | */ |
| 17 | + | |
| 18 | +if ( ! defined( 'ABSPATH' ) ) exit; | |
| 19 | + | |
| 17 | 20 | global $EventPost; |
| 18 | 21 | $EventPost = new EventPost(); |
| 19 | 22 | |
| 20 | 23 | $EventPost_cache=array(); |
| @@ -40,12 +43,15 @@ | ||
| 40 | 43 | */ |
| 41 | 44 | class EventPost { |
| 42 | 45 | /** |
| 43 | 46 | * The current version |
| 44 | - * | |
| 45 | - * @var array | |
| 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 | |
| 46 | 52 | */ |
| 47 | - public $version = '5.9.2'; | |
| 53 | + public $version = '6.1.2'; | |
| 48 | 54 | |
| 49 | 55 | // -------------------------------------------------------------------------------- |
| 50 | 56 | // Post metas |
| 51 | 57 | |
| @@ -1518,10 +1524,10 @@ | ||
| 1518 | 1524 | $datas_cat = $this->print_categories($post, $context); |
| 1519 | 1525 | $datas_loc = $this->print_location($post, $context); |
| 1520 | 1526 | $classes = array( |
| 1521 | 1527 | 'event_data', |
| 1522 | - 'status-'.$post->status, | |
| 1523 | - 'location-type-'.$post->attendance_mode, | |
| 1528 | + 'status-'.strtolower(str_replace('Event', '', $post->status)), | |
| 1529 | + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $post->attendance_mode)), | |
| 1524 | 1530 | $class |
| 1525 | 1531 | ); |
| 1526 | 1532 | if ($datas_date != '' || $datas_loc != '') { |
| 1527 | 1533 | $rgb = $this->hex2dec($post->color); |
| @@ -1681,8 +1687,11 @@ | ||
| 1681 | 1687 | public function list_events($atts, $id = 'event_list', $context='') { |
| 1682 | 1688 | $ep_settings = $this->settings; |
| 1683 | 1689 | $defaults = array( |
| 1684 | 1690 | 'nb' => 0, |
| 1691 | + 'nb_desktop' => 0, | |
| 1692 | + 'nb_tablet' => 0, | |
| 1693 | + 'nb_mobile' => 0, | |
| 1685 | 1694 | 'type' => 'div', |
| 1686 | 1695 | 'future' => true, |
| 1687 | 1696 | 'past' => false, |
| 1688 | 1697 | 'geo' => 0, |
| @@ -1710,13 +1719,16 @@ | ||
| 1710 | 1719 | 'excerpt' => '', |
| 1711 | 1720 | 'orderby' => 'meta_value', |
| 1712 | 1721 | 'order' => 'ASC', |
| 1713 | 1722 | 'class' => '', |
| 1723 | + 'align' => '', | |
| 1714 | 1724 | 'className' => '', |
| 1715 | 1725 | 'container_schema' => $this->list_shema['container'], |
| 1716 | 1726 | 'item_schema' => $this->list_shema['item'], |
| 1717 | 1727 | 'pages' => false, |
| 1718 | 1728 | 'paged' => '', |
| 1729 | + 'separate_years' => false, | |
| 1730 | + 'separate_months' => false, | |
| 1719 | 1731 | ); |
| 1720 | 1732 | // Map UI options |
| 1721 | 1733 | foreach($this->map_interactions as $int_key=>$int_name){ |
| 1722 | 1734 | $defaults[$int_key]=true; |
| @@ -1722,13 +1734,13 @@ | ||
| 1722 | 1734 | $defaults[$int_key]=true; |
| 1723 | 1735 | } |
| 1724 | 1736 | $atts_old_nb = $defaults['nb']; |
| 1725 | 1737 | if($id == "event_timeline"){ |
| 1726 | - $atts_old_nb = $atts['nb']; | |
| 1727 | - $atts['nb'] = 0; | |
| 1738 | + $atts_old_nb = intval($atts['nb']); | |
| 1739 | + $atts['nb'] = -1; | |
| 1728 | 1740 | } |
| 1729 | 1741 | |
| 1730 | - $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events'), $atts); | |
| 1742 | + $atts = shortcode_atts(apply_filters('eventpost_params', $defaults, 'list_events', $context), $atts); | |
| 1731 | 1743 | |
| 1732 | 1744 | extract($atts); |
| 1733 | 1745 | if (!is_array($events)) { |
| 1734 | 1746 | $events = $this->get_events($atts); |
| @@ -1737,9 +1749,9 @@ | ||
| 1737 | 1749 | $ret = ''; |
| 1738 | 1750 | $this->list_id++; |
| 1739 | 1751 | if (sizeof($events) > 0) { |
| 1740 | 1752 | if (!empty($title)) { |
| 1741 | - $ret .= esc_html($before_title) . esc_html($title) . esc_html($after_title); | |
| 1753 | + $ret .= wp_kses_post($before_title . esc_html($title) . $after_title); | |
| 1742 | 1754 | } |
| 1743 | 1755 | |
| 1744 | 1756 | $type = in_array($type, ['div', 'ul', 'ol']) ? $type : 'div'; |
| 1745 | 1757 | $child = in_array($type, ['ul', 'ol']) ? 'li' : 'div'; |
| @@ -1759,23 +1771,42 @@ | ||
| 1759 | 1771 | $next_arrow = '<div class="next"><span class="screen-reader-text">'.__('Next Events »', 'event-post')."</span></div>"; |
| 1760 | 1772 | if($atts_old_nb != 0){ |
| 1761 | 1773 | $item_child_style = 'width : '.((100/$atts_old_nb) - 2).'%;'; |
| 1762 | 1774 | } |
| 1763 | - $attributes .= ' data-nb="'.$atts_old_nb.'" data-filter="'.http_build_query($atts).'" '; | |
| 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).'" '; | |
| 1764 | 1780 | } |
| 1765 | 1781 | |
| 1782 | + if($id === 'event_timeline'){ | |
| 1783 | + $previous_year = $atts['separate_years'] ? true : false; | |
| 1784 | + $previous_month = $atts['separate_months'] ? true : false; | |
| 1785 | + } | |
| 1786 | + | |
| 1766 | 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 | + } | |
| 1767 | 1798 | $text_price = $this->get_price($event,true); |
| 1768 | 1799 | $class_item = array( |
| 1769 | 1800 | $this->is_future($event) ? 'event_future' : 'event_past', |
| 1770 | - 'status-'.$event->status, | |
| 1771 | - 'location-type-'.$event->attendance_mode, | |
| 1801 | + 'status-'.strtolower(str_replace('Event', '', $event->status)), | |
| 1802 | + 'location-type-'.strtolower(str_replace('EventAttendanceMode', '', $event->attendance_mode)), | |
| 1772 | 1803 | ); |
| 1773 | 1804 | $taxonomies= get_taxonomies('','names'); |
| 1774 | 1805 | $post_terms = []; |
| 1775 | 1806 | $terms = wp_get_post_terms($event->ID, $taxonomies); |
| 1776 | 1807 | foreach($terms as $term){ |
| 1777 | - $class_item[] = $term->taxonomy.'-'.$term->name; | |
| 1808 | + $class_item[] = $term->taxonomy.'-'.$term->slug; | |
| 1778 | 1809 | } |
| 1779 | 1810 | if ($ep_settings['emptylink'] == 0 && empty($event->post_content)) { |
| 1780 | 1811 | $event->permalink = '#' . $id . $this->list_id; |
| 1781 | 1812 | } |
| @@ -1852,8 +1883,20 @@ | ||
| 1852 | 1883 | |
| 1853 | 1884 | if($context == 'events_only'){ |
| 1854 | 1885 | $ret = $html; |
| 1855 | 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 | + } | |
| 1856 | 1899 | $ret.=str_replace( |
| 1857 | 1900 | array( |
| 1858 | 1901 | '%type%', |
| 1859 | 1902 | '%id%', |
| @@ -1868,9 +1911,9 @@ | ||
| 1868 | 1911 | '%number%' |
| 1869 | 1912 | ), array( |
| 1870 | 1913 | $type, |
| 1871 | 1914 | $id, |
| 1872 | - $class.($className ? ' '.esc_attr($className) : '').($id == 'event_geolist' && $list ? ' has-list list-'.esc_attr($list) : ' no-list'), | |
| 1915 | + esc_attr(implode(' ', $classes)), | |
| 1873 | 1916 | $id . $this->list_id, |
| 1874 | 1917 | (!empty($width) ? 'width:' . esc_attr($width) . ';' : '') . (!empty($height) ? 'height:' . esc_attr($height) . ';' : '') . esc_attr($style), |
| 1875 | 1918 | $attributes, |
| 1876 | 1919 | $html, |
| @@ -2341,9 +2384,9 @@ | ||
| 2341 | 2384 | <option value=""><?php esc_attr_e('None','event-post') ?></option> |
| 2342 | 2385 | <?php |
| 2343 | 2386 | foreach($this->DashIcons->icons as $class => $unicode){ |
| 2344 | 2387 | ?> |
| 2345 | - <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> | |
| 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 ?> | |
| 2346 | 2389 | <?php |
| 2347 | 2390 | } |
| 2348 | 2391 | ?> |
| 2349 | 2392 | </select> |
| @@ -2459,9 +2502,9 @@ | ||
| 2459 | 2502 | * |
| 2460 | 2503 | * @return void |
| 2461 | 2504 | */ |
| 2462 | 2505 | function inline_save(){ |
| 2463 | - $post_id = filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT); | |
| 2506 | + $post_id = absint(filter_input(INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT)); | |
| 2464 | 2507 | $this->save_postdata($post_id); |
| 2465 | 2508 | } |
| 2466 | 2509 | /** |
| 2467 | 2510 | * When the post is saved, saves our custom data |
| @@ -2474,12 +2517,17 @@ | ||
| 2474 | 2517 | if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){ |
| 2475 | 2518 | return; |
| 2476 | 2519 | } |
| 2477 | 2520 | |
| 2478 | - if (!wp_verify_nonce(filter_input(INPUT_POST, 'eventpost_nonce'), plugin_basename(__FILE__))){ | |
| 2521 | + if (!wp_verify_nonce((string) filter_input(INPUT_POST, 'eventpost_nonce'), plugin_basename(__FILE__))){ | |
| 2479 | 2522 | return; |
| 2480 | 2523 | } |
| 2481 | 2524 | |
| 2525 | + $post_id = absint($post_id); | |
| 2526 | + if (!$post_id || !current_user_can('edit_post', $post_id)) { | |
| 2527 | + return; | |
| 2528 | + } | |
| 2529 | + | |
| 2482 | 2530 | // Clean color or no color |
| 2483 | 2531 | if (false !== $color = filter_input(INPUT_POST, $this->META_COLOR)) { |
| 2484 | 2532 | update_post_meta($post_id, $this->META_COLOR, sanitize_text_field($color)); |
| 2485 | 2533 | } |
| @@ -2697,12 +2745,12 @@ | ||
| 2697 | 2745 | $ret.=$annee; |
| 2698 | 2746 | // Translators: %s is the year |
| 2699 | 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">»</button></span>'; |
| 2700 | 2748 | // Translators: %s is the month name |
| 2701 | - $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">«</button><span class="eventpost-cal-header-text">'; | |
| 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">«</button><span class="eventpost-cal-header-text">'; | |
| 2702 | 2750 | $ret.=$this->NomDuMois[abs($mois)]; |
| 2703 | 2751 | // Translators: %s is the month name |
| 2704 | - $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">»</button> </span>'; | |
| 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">»</button> </span>'; | |
| 2705 | 2753 | $ret.='<span class="eventpost-cal-today"><button data-date="' . date('Y-n') . '" class="eventpost_cal_bt">' . __('Today', 'event-post') . '</button></span>'; |
| 2706 | 2754 | $ret.='</div>'; |
| 2707 | 2755 | } |
| 2708 | 2756 | $ret.='</th></tr><tr class="event_post_cal_days">'; |
| @@ -3166,13 +3214,16 @@ | ||
| 3166 | 3214 | if (in_array($format, $allowed_formats)) { |
| 3167 | 3215 | $export_file = plugin_dir_path(__FILE__) . 'inc/export/' . $format . '.php'; |
| 3168 | 3216 | if (is_numeric($event_id) && file_exists($export_file)) { |
| 3169 | 3217 | $event = $this->retreive($event_id); |
| 3218 | + if($event->post_status != 'publish'){ | |
| 3219 | + wp_die(esc_html__('Event not found.', 'event-post'), 404); | |
| 3220 | + } | |
| 3170 | 3221 | include $export_file; |
| 3171 | 3222 | exit; |
| 3172 | 3223 | } |
| 3173 | 3224 | } |
| 3174 | - wp_die(esc_html__('Invalid request.', 'event-post')); | |
| 3225 | + wp_die(esc_html__('Invalid request.', 'event-post'), 400); | |
| 3175 | 3226 | } |
| 3176 | 3227 | |
| 3177 | 3228 | |
| 3178 | 3229 | public function parse_request(){ |