PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | modules/widgets/upcoming-events.php +200 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,200 @@
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 +/**
3 + * Upcoming Events widget
4 + *
5 + * It relies on the icalendar-reader library.
6 + *
7 + * @package automattic/jetpack
8 + */
9 +
10 +if ( ! defined( 'ABSPATH' ) ) {
11 + exit( 0 );
12 +}
13 +
14 +// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
15 +
16 +/**
17 + * Register the widget.
18 + */
19 +function upcoming_events_register_widgets() {
20 + register_widget( Jetpack_Upcoming_Events_Widget::class );
21 +}
22 +add_action( 'widgets_init', 'upcoming_events_register_widgets' );
23 +
24 +/**
25 + * Widget class.
26 + */
27 +class Jetpack_Upcoming_Events_Widget extends WP_Widget {
28 + /**
29 + * Constructor
30 + */
31 + public function __construct() {
32 + parent::__construct(
33 + 'upcoming_events_widget',
34 + /** This filter is documented in modules/widgets/facebook-likebox.php */
35 + apply_filters( 'jetpack_widget_name', __( 'Upcoming Events', 'jetpack' ) ),
36 + array(
37 + 'description' => __( 'Display upcoming events from an iCalendar feed.', 'jetpack' ),
38 + 'customize_selective_refresh' => true,
39 + )
40 + );
41 + if ( is_active_widget( false, false, $this->id_base ) ) {
42 + add_action( 'wp_head', array( $this, 'css' ) );
43 + }
44 + }
45 +
46 + /**
47 + * Output CSS in the header everywhere where the widget is active.
48 + */
49 + public function css() {
50 + ?>
51 +<style type="text/css">
52 +.upcoming-events li {
53 + margin-bottom: 10px;
54 +}
55 +.upcoming-events li span {
56 + display: block;
57 +}
58 +</style>
59 + <?php
60 + }
61 +
62 + /**
63 + * Displays the form for this widget on the Widgets page of the WP Admin area.
64 + *
65 + * @param array $instance Instance configuration.
66 + *
67 + * @return string|void
68 + */
69 + public function form( $instance ) {
70 + $defaults = array(
71 + 'title' => __( 'Upcoming Events', 'jetpack' ),
72 + 'feed-url' => '',
73 + 'count' => 3,
74 + );
75 + $instance = array_merge( $defaults, (array) $instance );
76 + ?>
77 +
78 + <p>
79 + <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
80 + <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>" />
81 + </p>
82 +
83 + <p>
84 + <label for="<?php echo esc_attr( $this->get_field_id( 'feed-url' ) ); ?>"><?php esc_html_e( 'iCalendar Feed URL:', 'jetpack' ); ?></label>
85 + <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'feed-url' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'feed-url' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['feed-url'] ); ?>" />
86 + </p>
87 +
88 + <p>
89 + <label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_html_e( 'Items to show:', 'jetpack' ); ?></label>
90 + <select id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'count' ) ); ?>">
91 + <?php for ( $i = 1; $i <= 10; $i++ ) { ?>
92 + <option <?php selected( $instance['count'], $i ); ?>><?php echo esc_html( (string) $i ); ?></option>
93 + <?php } ?>
94 + <option value="0" <?php selected( $instance['count'], 0 ); ?>><?php esc_html_e( 'All', 'jetpack' ); ?></option>
95 + </select>
96 + </p>
97 + <?php
98 + }
99 +
100 + /**
101 + * Deals with the settings when they are saved by the admin.
102 + *
103 + * @param array $new_instance New configuration values.
104 + * @param array $old_instance Old configuration values.
105 + *
106 + * @return array
107 + */
108 + public function update( $new_instance, $old_instance ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
109 + $instance = array();
110 + $instance['title'] = wp_strip_all_tags( $new_instance['title'] );
111 + $instance['feed-url'] = wp_strip_all_tags( $new_instance['feed-url'] );
112 + $instance['count'] = min( absint( $new_instance['count'] ), 10 ); // 10 or less
113 + return $instance;
114 + }
115 +
116 + /**
117 + * Outputs the HTML for this widget.
118 + *
119 + * @param array $args An array of standard parameters for widgets in this theme.
120 + * @param array $instance An array of settings for this widget instance.
121 + *
122 + * @return void Echoes it's output
123 + */
124 + public function widget( $args, $instance ) {
125 + require_once JETPACK__PLUGIN_DIR . '/_inc/lib/icalendar-reader.php';
126 +
127 + $ical = new iCalendarReader();
128 + $events = array();
129 + if ( ! empty( $instance['feed-url'] ) ) {
130 + $events = $ical->get_events( $instance['feed-url'], $instance['count'] );
131 + $events = $this->apply_timezone_offset( $events );
132 + }
133 + $ical->timezone = null;
134 +
135 + echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
136 + if ( ! empty( $instance['title'] ) ) {
137 + echo $args['before_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
138 + echo esc_html( $instance['title'] );
139 + echo $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
140 + }
141 +
142 + if ( empty( $instance['feed-url'] ) ) {
143 + if ( current_user_can( 'manage_options' ) ) {
144 + echo '<div class="error-message">';
145 + esc_html_e( 'The events feed URL is not properly set up in this widget.', 'jetpack' );
146 + echo '</div>';
147 + }
148 + } elseif ( ! $events ) {
149 + echo '<p>';
150 + esc_html_e( 'No upcoming events', 'jetpack' );
151 + echo '</p>';
152 + } else {
153 + ?>
154 + <ul class="upcoming-events">
155 + <?php foreach ( $events as $event ) : ?>
156 + <li>
157 + <strong class="event-summary">
158 + <?php
159 + echo $ical->escape( stripslashes( $event['SUMMARY'] ?? '' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- this method is built to escape.
160 + ?>
161 + </strong>
162 + <span class="event-when"><?php echo esc_html( $ical->formatted_date( $event ) ); ?></span>
163 + <?php if ( ! empty( $event['LOCATION'] ) ) : ?>
164 + <span class="event-location">
165 + <?php
166 + echo $ical->escape( stripslashes( $event['LOCATION'] ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- this method is built to escape.
167 + ?>
168 + </span>
169 + <?php endif; ?>
170 + <?php if ( ! empty( $event['DESCRIPTION'] ) ) : ?>
171 + <span class="event-description">
172 + <?php
173 + echo wp_trim_words( $ical->escape( stripcslashes( $event['DESCRIPTION'] ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- this method is built to escape.
174 + ?>
175 + </span>
176 + <?php endif; ?>
177 + </li>
178 + <?php endforeach; ?>
179 + </ul>
180 + <?php
181 + }
182 +
183 + echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
184 +
185 + /** This action is documented in modules/widgets/gravatar-profile.php */
186 + do_action( 'jetpack_stats_extra', 'widget_view', 'upcoming_events' );
187 + }
188 +
189 + /**
190 + * Left this function here for backward compatibility
191 + * just incase a site using jetpack is also using this function
192 + *
193 + * @param array|false $events Array of events, false on failure.
194 + */
195 + private function apply_timezone_offset( $events ) {
196 + require_once JETPACK__PLUGIN_DIR . '/_inc/lib/icalendar-reader.php';
197 +
198 + return ( new iCalendarReader() )->apply_timezone_offset( $events );
199 + }
200 +}