PluginProbe
Essential Widgets / 3.2
Essential Widgets v3.2
3.2.1 3.3 3.2 trunk 1.0.0 1.0.1 1.1 1.2 1.2.1 1.2.2 1.3 1.4 1.4.1 1.5 1.6 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.8 1.9 2.0 2.1 2.2 All 31 releases
essential-widgets / includes / widgets / class-ew-pages.php

class-ew-pages.php in Essential Widgets 3.2, at includes/widgets/class-ew-pages.php

464 lines 17.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly.
5 }
6
7 /**
8 * Pages Widget
9 *
10 * @package Essential_Widgets
11 */
12
13
14 /**
15 * Makes a custom Widget for Displaying About
16 *
17 * Learn more: http://codex.wordpress.org/Widgets_API#Developing_Widgets
18 *
19 * @package Essential_Widgets
20 */
21 if ( ! function_exists( 'get_meta_keys' ) ) :
22 /**
23 * Returns a list of distinct, non-private post meta keys for use in the
24 * widget's "Order by meta key" dropdown.
25 *
26 * @since 3.2
27 * @return array
28 */
29 function get_meta_keys() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- guarded with function_exists(); shared helper used by both the free and pro Pages widgets.
30 global $wpdb;
31
32 $cached_keys = get_transient( 'ew_meta_keys' );
33 if ( false !== $cached_keys ) {
34 return $cached_keys;
35 }
36
37 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- distinct meta key lookup has no WP_Query equivalent; result is cached via transient below.
38 $keys = $wpdb->get_col( "SELECT DISTINCT meta_key FROM {$wpdb->postmeta} WHERE meta_key NOT LIKE '\_%' ORDER BY meta_key ASC" );
39 $keys = is_array( $keys ) ? $keys : array();
40
41 set_transient( 'ew_meta_keys', $keys, HOUR_IN_SECONDS );
42
43 return $keys;
44 }
45 endif;
46
47 if ( ! class_exists( 'EW_Pages' ) ) :
48 class EW_Pages extends WP_Widget // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- EW_ is this plugin's abbreviated prefix; wrapped in class_exists() guard.
49 {
50
51
52 /**
53 * Holds widget settings defaults, populated in constructor.
54 *
55 * @var array
56 */
57 protected $defaults;
58
59 public function __construct() {
60
61 // Set up the defaults.
62 $this->defaults = array(
63 'title' => esc_attr__( 'Pages', 'essential-widgets' ),
64 'post_type' => 'page',
65 'depth' => 0,
66 'number' => '',
67 'offset' => '',
68 'child_of' => '',
69 'include' => '',
70 'exclude' => '', // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Required wp_list_pages() parameter, not a WP_Query post__not_in clause.
71 'exclude_tree' => '',
72 'meta_key' => '', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Required wp_list_pages() parameter.
73 'meta_value' => '', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Required wp_list_pages() parameter.
74 'authors' => '',
75 'link_before' => '',
76 'link_after' => '',
77 'show_date' => '',
78 'hierarchical' => true,
79 'sort_column' => 'post_title',
80 'sort_order' => 'ASC',
81 'date_format' => get_option( 'date_format' ),
82 );
83
84 $widget_ops = array(
85 'classname' => 'essential-widgets ew-pages ewpages',
86 'description' => esc_html__( 'Displays a list of pages.', 'essential-widgets' ),
87 );
88
89 $control_ops = array(
90 'id_base' => 'ew-pages',
91 );
92
93 parent::__construct(
94 'ew-pages', // Base ID
95 esc_html__( 'EW: Pages', 'essential-widgets' ), // Name
96 $widget_ops,
97 $control_ops
98 );
99 }
100
101 /**
102 * Displays the widget control options in the Widgets admin screen.
103 *
104 * @since 1.0.0
105 * @access public
106 * @param array $instance
107 * @param void
108 */
109 public function form( $instance ) {
110 // Merge the user-selected arguments with the defaults.
111 $instance = wp_parse_args( (array) $instance, $this->defaults );
112
113 $post_types = get_post_types(
114 array(
115 'public' => true,
116 'hierarchical' => true,
117 ),
118 'objects'
119 );
120
121 $sort_order = array(
122 'ASC' => esc_attr__( 'Ascending', 'essential-widgets' ),
123 'DESC' => esc_attr__( 'Descending', 'essential-widgets' ),
124 );
125
126 $sort_column = array(
127 'post_author' => esc_attr__( 'Author', 'essential-widgets' ),
128 'post_date' => esc_attr__( 'Date', 'essential-widgets' ),
129 'ID' => esc_attr__( 'ID', 'essential-widgets' ),
130 'menu_order' => esc_attr__( 'Menu Order', 'essential-widgets' ),
131 'post_modified' => esc_attr__( 'Modified', 'essential-widgets' ),
132 'post_name' => esc_attr__( 'Slug', 'essential-widgets' ),
133 'post_title' => esc_attr__( 'Title', 'essential-widgets' ),
134 );
135
136 $show_date = array(
137 '' => esc_attr__( 'Select', 'essential-widgets' ),
138 'created' => esc_attr__( 'Created', 'essential-widgets' ),
139 'modified' => esc_attr__( 'Modified', 'essential-widgets' ),
140 );
141
142 $meta_key = array_merge( array( '' ), (array) get_meta_keys() ); ?>
143
144 <p>
145 <label>
146 <?php esc_html_e( 'Title:', 'essential-widgets' ); ?>
147 <input type="text" class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" value="<?php echo esc_attr( $instance['title'] ); ?>" placeholder="<?php echo esc_attr( $this->defaults['title'] ); ?>" />
148 </label>
149 </p>
150
151 <p>
152 <label>
153 <?php esc_html_e( 'Post Type:', 'essential-widgets' ); ?>
154
155 <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'post_type' ) ); ?>">
156
157 <?php foreach ( $post_types as $post_type ) : ?>
158
159 <option value="<?php echo esc_attr( $post_type->name ); ?>" <?php selected( $instance['post_type'], $post_type->name ); ?>><?php echo esc_html( $post_type->labels->singular_name ); ?></option>
160
161 <?php endforeach; ?>
162
163 </select>
164 </label>
165 </p>
166
167 <p>
168 <label>
169 <?php esc_html_e( 'Order:', 'essential-widgets' ); ?>
170
171 <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'sort_order' ) ); ?>">
172
173 <?php foreach ( $sort_order as $option_value => $option_label ) : ?>
174
175 <option value="<?php echo esc_attr( $option_value ); ?>" <?php selected( $instance['sort_order'], $option_value ); ?>><?php echo esc_html( $option_label ); ?></option>
176
177 <?php endforeach; ?>
178
179 </select>
180 </label>
181 </p>
182
183 <p>
184 <label>
185 <?php esc_html_e( 'Order By:', 'essential-widgets' ); ?>
186
187 <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'sort_column' ) ); ?>">
188
189 <?php foreach ( $sort_column as $option_value => $option_label ) : ?>
190
191 <option value="<?php echo esc_attr( $option_value ); ?>" <?php selected( $instance['sort_column'], $option_value ); ?>><?php echo esc_html( $option_label ); ?></option>
192
193 <?php endforeach; ?>
194
195 </select>
196 </label>
197 </p>
198
199 <p>
200 <label>
201 <?php esc_html_e( 'Depth:', 'essential-widgets' ); ?>
202 <input type="number" class="widefat" size="5" min="0" name="<?php echo esc_attr( $this->get_field_name( 'depth' ) ); ?>" value="<?php echo esc_attr( $instance['depth'] ); ?>" placeholder="0" />
203 </label>
204 </p>
205
206 <p>
207 <label>
208 <?php esc_html_e( 'Number:', 'essential-widgets' ); ?>
209 <input type="number" class="widefat" size="5" min="0" name="<?php echo esc_attr( $this->get_field_name( 'number' ) ); ?>" value="<?php echo esc_attr( $instance['number'] ); ?>" placeholder="0" />
210 </label>
211 </p>
212
213 <p>
214 <label>
215 <?php esc_html_e( 'Offset:', 'essential-widgets' ); ?>
216 <input type="number" class="widefat" size="5" min="0" name="<?php echo esc_attr( $this->get_field_name( 'offset' ) ); ?>" value="<?php echo esc_attr( $instance['offset'] ); ?>" placeholder="0" />
217 </label>
218 </p>
219
220 <p>
221 <label>
222 <?php esc_html_e( 'Child Of:', 'essential-widgets' ); ?>
223 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'child_of' ) ); ?>" value="<?php echo esc_attr( $instance['child_of'] ); ?>" placeholder="0" />
224 </label>
225 </p>
226
227 <p>
228 <label>
229 <?php esc_html_e( 'Include:', 'essential-widgets' ); ?>
230 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'include' ) ); ?>" value="<?php echo esc_attr( $instance['include'] ); ?>" placeholder="1,2,3&hellip;" />
231 </label>
232 </p>
233
234 <p>
235 <label>
236 <?php esc_html_e( 'Exclude:', 'essential-widgets' ); ?>
237 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'exclude' ) ); ?>" value="<?php echo esc_attr( $instance['exclude'] ); ?>" placeholder="1,2,3&hellip;" />
238 </label>
239 </p>
240
241 <p class="button-primary ect-toggle-btn more">
242 <span class="ect-more-text"><?php esc_html_e( 'More Options', 'essential-widgets' ); ?><i class="dashicons dashicons-arrow-down"></i></span>
243 <span class="ect-hide-text"><?php esc_html_e( 'Hide Options', 'essential-widgets' ); ?><i class="dashicons dashicons-arrow-up"></i></span>
244
245 <div class="advanced-section">
246
247 <p>
248 <label>
249 <?php esc_html_e( 'Exclude Tree:', 'essential-widgets' ); ?>
250 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'exclude_tree' ) ); ?>" value="<?php echo esc_attr( $instance['exclude_tree'] ); ?>" placeholder="1,2,3&hellip;" />
251 </label>
252 </p>
253
254 <p>
255 <label>
256 <?php esc_html_e( 'Meta Key:', 'essential-widgets' ); ?>
257
258 <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'meta_key' ) ); ?>">
259
260 <?php foreach ( $meta_key as $meta ) : ?>
261
262 <option value="<?php echo esc_attr( $meta ); ?>" <?php selected( $instance['meta_key'], $meta ); ?>><?php echo esc_html( $meta ); ?></option>
263
264 <?php endforeach; ?>
265
266 </select>
267 </label>
268 </p>
269
270 <p>
271 <label>
272 <?php esc_html_e( 'Meta Value:', 'essential-widgets' ); ?>
273 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'meta_value' ) ); ?>" value="<?php echo esc_attr( $instance['meta_value'] ); ?>" />
274 </label>
275 </p>
276
277 <p>
278 <label>
279 <?php esc_html_e( 'Authors:', 'essential-widgets' ); ?>
280 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'authors' ) ); ?>" value="<?php echo esc_attr( $instance['authors'] ); ?>" placeholder="1,2,3&hellip;" />
281 </label>
282 </p>
283
284 <p>
285 <label>
286 <?php esc_html_e( 'Link Before:', 'essential-widgets' ); ?>
287 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'link_before' ) ); ?>" value="<?php echo esc_attr( $instance['link_before'] ); ?>" />
288 </label>
289 </p>
290
291 <p>
292 <label>
293 <?php esc_html_e( 'Link After:', 'essential-widgets' ); ?>
294 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'link_after' ) ); ?>" value="<?php echo esc_attr( $instance['link_after'] ); ?>" />
295 </label>
296 </p>
297
298 <p>
299 <label>
300 <?php esc_html_e( 'Show Date:', 'essential-widgets' ); ?>
301
302 <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'show_date' ) ); ?>">
303
304 <?php foreach ( $show_date as $option_value => $option_label ) : ?>
305
306 <option value="<?php echo esc_attr( $option_value ); ?>" <?php selected( $instance['show_date'], $option_value ); ?>><?php echo esc_html( $option_label ); ?></option>
307
308 <?php endforeach; ?>
309
310 </select>
311 </label>
312 </p>
313
314 <p>
315 <label>
316 <?php esc_html_e( 'Date Format:', 'essential-widgets' ); ?>
317 <input type="text" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'date_format' ) ); ?>" value="<?php echo esc_attr( $instance['date_format'] ); ?>" placeholder="<?php echo esc_attr( get_option( 'date_format' ) ); ?>" />
318 </label>
319 </p>
320
321 <p>
322 <label>
323 <input type="checkbox" <?php checked( $instance['hierarchical'], true ); ?> name="<?php echo esc_attr( $this->get_field_name( 'hierarchical' ) ); ?>" />
324 <?php esc_html_e( 'Hierarchical?', 'essential-widgets' ); ?>
325 </label>
326 </p>
327
328 </div><!-- .advanced-section -->
329
330 <div style="clear:both;">&nbsp;</div>
331 <?php
332 }
333
334 /**
335 * update the particular instant
336 *
337 * This function should check that $new_instance is set correctly.
338 * The newly calculated value of $instance should be returned.
339 * If "false" is returned, the instance won't be saved/updated.
340 *
341 * $new_instance New settings for this instance as input by the user via form()
342 * $old_instance Old settings for this instance
343 * Settings to save or bool false to cancel saving
344 */
345 public function update( $new_instance, $old_instance ) {
346 $instance = $old_instance;
347
348 // Sanitize title.
349 $instance['title'] = sanitize_text_field( $new_instance['title'] );
350
351 // Strip tags.
352 $instance['meta_key'] = wp_strip_all_tags( $new_instance['meta_key'] ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Required wp_list_pages() parameter.
353 $instance['meta_value'] = wp_strip_all_tags( $new_instance['meta_value'] ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Required wp_list_pages() parameter.
354 $instance['date_format'] = wp_strip_all_tags( $new_instance['date_format'] );
355
356 // Sanitize key.
357 $instance['post_type'] = sanitize_key( $new_instance['post_type'] );
358
359 // Whitelist options.
360 $sort_order = array( 'ASC', 'DESC' );
361 $sort_column = array( 'post_author', 'post_date', 'ID', 'menu_order', 'post_modified', 'post_name', 'post_title' );
362 $show_date = array( '', 'created', 'modified' );
363
364 $instance['sort_column'] = in_array( $new_instance['sort_column'], $sort_column, true ) ? $new_instance['sort_column'] : 'post_title';
365 $instance['sort_order'] = in_array( $new_instance['sort_order'], $sort_order, true ) ? $new_instance['sort_order'] : 'ASC';
366 $instance['show_date'] = in_array( $new_instance['show_date'], $show_date, true ) ? $new_instance['show_date'] : '';
367
368 // Text boxes. Make sure user can use 'unfiltered_html'.
369 $instance['link_before'] = current_user_can( 'unfiltered_html' ) ? $new_instance['link_before'] : wp_kses_post( $new_instance['link_before'] );
370 $instance['link_after'] = current_user_can( 'unfiltered_html' ) ? $new_instance['link_after'] : wp_kses_post( $new_instance['link_after'] );
371
372 // Integers.
373 $instance['number'] = absint( $new_instance['number'] );
374 $instance['depth'] = absint( $new_instance['depth'] );
375 $instance['child_of'] = absint( $new_instance['child_of'] );
376 $instance['offset'] = absint( $new_instance['offset'] );
377
378 // Sanitize text field
379 $instance['include'] = sanitize_text_field( $new_instance['include'] );
380 $instance['exclude'] = sanitize_text_field( $new_instance['exclude'] ); // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Required wp_list_pages() parameter.
381 $instance['exclude_tree'] = sanitize_text_field( $new_instance['exclude_tree'] );
382 $instance['authors'] = sanitize_text_field( $new_instance['authors'] );
383
384 // Then restrict to numbers & commas
385 $instance['include'] = preg_replace( '/[^0-9,]/', '', $new_instance['include'] );
386 $instance['exclude'] = preg_replace( '/[^0-9,]/', '', $new_instance['exclude'] ); // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Required wp_list_pages() parameter.
387 $instance['exclude_tree'] = preg_replace( '/[^0-9,]/', '', $new_instance['exclude_tree'] );
388 $instance['authors'] = preg_replace( '/[^0-9,]/', '', $new_instance['authors'] );
389
390 // Checkboxes.
391 $instance['hierarchical'] = isset( $new_instance['hierarchical'] ) ? 1 : 0;
392
393 // Return sanitized options.
394 return $instance;
395 }
396
397 /**
398 * Displays the Widget in the front-end.
399 *
400 * $args Display arguments including before_title, after_title, before_widget, and after_widget.
401 * $instance The settings for the particular instance of the widget
402 */
403 public function widget( $args, $instance ) {
404 // Merge instance with defaults.
405 $instance = wp_parse_args( $instance, $this->defaults );
406
407 // Escape widget wrapper attributes.
408 echo wp_kses_post( $args['before_widget'] );
409
410 // If a title was input by the user, display it safely.
411 if ( ! empty( $instance['title'] ) ) {
412 echo wp_kses_post( $args['before_title'] );
413
414 // Apply filters to title, then escape it for output
415 $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
416 echo esc_html( $title );
417
418 echo wp_kses_post( $args['after_title'] );
419 }
420
421 // Output the main content of the widget (shortcode output)
422 echo wp_kses_post( $this->shortcode( $instance ) );
423
424 // Close the widget wrapper safely.
425 echo wp_kses_post( $args['after_widget'] );
426 }
427
428 public function shortcode( $atts ) {
429 // Set the $title_li and $echo to false.
430 $atts['title_li'] = false;
431 $atts['echo'] = false;
432
433 $ew_pages = '';
434
435 // Only show this title in block element and not on widget.
436 if ( isset( $atts['is_block'] ) && true === $atts['is_block'] && !empty( $atts['title'] ) ) {
437 $ew_pages .= '<h2 class="ew-page-block-title">' . esc_html( $atts['title'] ) . '</h2>';
438 }
439
440 // Output the page list.
441 $ew_pages .= '<ul class="pages">' . str_replace(
442 array( "\r", "\n", "\t" ),
443 '',
444 wp_list_pages( $atts )
445 ) . '</ul>';
446
447 return wp_kses_post( $ew_pages );
448 }
449 }
450 endif;
451
452
453 if ( ! function_exists( 'ew_pages_register' ) ) :
454 /**
455 * Intiate About_Widget Class.
456 *
457 * @since 1.0.0
458 */
459 function ew_pages_register() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- ew_ is this plugin's abbreviated prefix.
460 register_widget( 'EW_Pages' );
461 }
462 add_action( 'widgets_init', 'ew_pages_register' );
463 endif;
464