PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.0.2
Jetpack – WP Security, Backup, Speed, & Growth v12.0.2
15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / class.jetpack-modules-list-table.php
jetpack Last commit date
3rd-party 3 years ago _inc 3 years ago css 3 years ago extensions 3 years ago images 3 years ago jetpack_vendor 1 year ago json-endpoints 3 years ago modules 1 year ago sal 3 years ago src 3 years ago vendor 3 years ago views 3 years ago CHANGELOG.md 3 years ago LICENSE.txt 5 years ago SECURITY.md 5 years ago class-jetpack-connection-status.php 5 years ago class-jetpack-connection-widget.php 3 years ago class-jetpack-gallery-settings.php 3 years ago class-jetpack-pre-connection-jitms.php 4 years ago class-jetpack-recommendations-banner.php 3 years ago class-jetpack-stats-dashboard-widget.php 3 years ago class-jetpack-wizard-banner.php 5 years ago class-jetpack-xmlrpc-methods.php 3 years ago class.frame-nonce-preview.php 4 years ago class.jetpack-admin.php 3 years ago class.jetpack-affiliate.php 4 years ago class.jetpack-autoupdate.php 3 years ago class.jetpack-bbpress-json-api.compat.php 5 years ago class.jetpack-cli.php 3 years ago class.jetpack-client-server.php 4 years ago class.jetpack-connection-banner.php 3 years ago class.jetpack-data.php 5 years ago class.jetpack-gutenberg.php 3 years ago class.jetpack-heartbeat.php 4 years ago class.jetpack-idc.php 4 years ago class.jetpack-modules-list-table.php 3 years ago class.jetpack-network-sites-list-table.php 4 years ago class.jetpack-network.php 3 years ago class.jetpack-plan.php 3 years ago class.jetpack-post-images.php 3 years ago class.jetpack-twitter-cards.php 3 years ago class.jetpack-user-agent.php 3 years ago class.jetpack.php 3 years ago class.json-api-endpoints.php 3 years ago class.json-api.php 3 years ago class.photon.php 3 years ago composer.json 3 years ago enhanced-open-graph.php 3 years ago functions.compat.php 3 years ago functions.cookies.php 5 years ago functions.global.php 3 years ago functions.is-mobile.php 3 years ago functions.opengraph.php 3 years ago functions.photon.php 3 years ago jetpack.php 1 year ago json-api-config.php 3 years ago json-endpoints.php 3 years ago load-jetpack.php 3 years ago locales.php 4 years ago readme.txt 1 year ago uninstall.php 5 years ago wpml-config.xml 3 years ago
class.jetpack-modules-list-table.php
474 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Jetpack modules list table.
4 *
5 * @package automattic/jetpack
6 */
7
8 use Automattic\Jetpack\Assets;
9
10 if ( ! class_exists( 'WP_List_Table' ) ) {
11 require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
12 }
13
14 /**
15 * Jetpack modules list table.
16 */
17 class Jetpack_Modules_List_Table extends WP_List_Table {
18
19 /** Constructor. */
20 public function __construct() {
21 parent::__construct();
22
23 Jetpack::init();
24
25 if ( $this->compat_fields && is_array( $this->compat_fields ) ) {
26 array_push( $this->compat_fields, 'all_items' );
27 }
28
29 /**
30 * Filters the list of modules available to be displayed in the Jetpack Settings screen.
31 *
32 * @since 3.0.0
33 *
34 * @param array $modules Array of Jetpack modules.
35 */
36 $this->all_items = apply_filters( 'jetpack_modules_list_table_items', Jetpack_Admin::init()->get_modules() );
37 $this->items = $this->all_items;
38 $this->items = $this->filter_displayed_table_items( $this->items );
39 $this->_column_headers = array( $this->get_columns(), array(), array(), 'name' );
40 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce: This is a view, not a model or controller. InputNotSanitized: Sanitized below via `$this->module_info_check()`.
41 $modal_info = isset( $_GET['info'] ) ? wp_unslash( $_GET['info'] ) : false;
42
43 // Adding in a hidden h1 heading for screen-readers.
44 ?>
45 <h1 class="screen-reader-text"><?php esc_html_e( 'Jetpack Modules List', 'jetpack' ); ?></h1>
46 <?php
47
48 wp_register_script(
49 'models.jetpack-modules',
50 Assets::get_file_url_for_environment(
51 '_inc/build/jetpack-modules.models.min.js',
52 '_inc/jetpack-modules.models.js'
53 ),
54 array( 'jquery', 'backbone', 'underscore' ),
55 JETPACK__VERSION,
56 false // @todo Can this be put in the footer?
57 );
58 wp_register_script(
59 'views.jetpack-modules',
60 Assets::get_file_url_for_environment(
61 '_inc/build/jetpack-modules.views.min.js',
62 '_inc/jetpack-modules.views.js'
63 ),
64 array( 'jquery', 'backbone', 'underscore', 'wp-util' ),
65 JETPACK__VERSION,
66 false // @todo Can this be put in the footer?
67 );
68 wp_register_script(
69 'jetpack-modules-list-table',
70 Assets::get_file_url_for_environment(
71 '_inc/build/jetpack-modules.min.js',
72 '_inc/jetpack-modules.js'
73 ),
74 array(
75 'views.jetpack-modules',
76 'models.jetpack-modules',
77 'jquery',
78 ),
79 JETPACK__VERSION,
80 true
81 );
82
83 wp_localize_script(
84 'jetpack-modules-list-table',
85 'jetpackModulesData',
86 array(
87 'modules' => Jetpack::get_translated_modules( $this->all_items ),
88 'i18n' => array(
89 'search_placeholder' => __( 'Search Modules…', 'jetpack' ),
90 ),
91 'modalinfo' => $this->module_info_check( $modal_info, $this->all_items ),
92 'nonces' => array(
93 'bulk' => wp_create_nonce( 'bulk-jetpack_page_jetpack_modules' ),
94 ),
95 )
96 );
97
98 wp_enqueue_script( 'jetpack-modules-list-table' );
99
100 /**
101 * Filters the js_templates callback value.
102 *
103 * @since 3.6.0
104 *
105 * @param array array( $this, 'js_templates' ) js_templates callback.
106 */
107 add_action( 'admin_footer', apply_filters( 'jetpack_modules_list_table_js_template_callback', array( $this, 'js_templates' ) ), 9 );
108 }
109
110 /**
111 * Output row template.
112 */
113 public function js_templates() {
114 ?>
115 <script type="text/html" id="tmpl-Jetpack_Modules_List_Table_Template">
116 <# var i = 0;
117 if ( data.items.length ) {
118 _.each( data.items, function( item, key, list ) {
119 if ( item === undefined ) return; #>
120 <tr class="jetpack-module <# if ( ++i % 2 ) { #> alternate<# } #><# if ( item.activated ) { #> active<# } #><# if ( ! item.available ) { #> unavailable<# } #>" id="{{{ item.module }}}">
121 <th scope="row" class="check-column">
122 <input type="checkbox" name="modules[]" value="{{{ item.module }}}" />
123 </th>
124 <td class='name column-name'>
125 <span class='info'><a href="{{{item.learn_more_button}}}" target="blank">{{{ item.name }}}</a></span>
126 <div class="row-actions">
127 <# if ( item.configurable ) { #>
128 <span class='configure'>{{{ item.configurable }}}</span>
129 <# } #>
130 <# if ( item.activated && 'vaultpress' !== item.module && item.available ) { #>
131 <span class='delete'><a href="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>?page=jetpack&#038;action=deactivate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.deactivate_nonce }}}"><?php esc_html_e( 'Deactivate', 'jetpack' ); ?></a></span>
132 <# } else if ( item.available ) { #>
133 <span class='activate'><a href="<?php echo esc_url( admin_url( 'admin.php' ) ); ?>?page=jetpack&#038;action=activate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.activate_nonce }}}"><?php esc_html_e( 'Activate', 'jetpack' ); ?></a></span>
134 <# } #>
135 <# if ( ! item.available ) { #>
136 <span class='unavailable_reason'>{{{ item.unavailable_reason }}}</span>
137 <# } #>
138 </div>
139 </td>
140 </tr>
141 <#
142 });
143 } else {
144 #>
145 <tr class="no-modules-found">
146 <td colspan="2"><?php esc_html_e( 'No Modules Found', 'jetpack' ); ?></td>
147 </tr>
148 <#
149 }
150 #>
151 </script>
152 <?php
153 }
154
155 /**
156 * Get views data.
157 *
158 * @return array Maps identifier to display HTML.
159 */
160 public function get_views() {
161 /** This filter is already documented in class.jetpack-modules-list-table.php */
162 $modules = apply_filters( 'jetpack_modules_list_table_items', Jetpack_Admin::init()->get_modules() );
163 $array_of_module_tags = wp_list_pluck( $modules, 'module_tags' );
164 $module_tags = array_merge( ...array_values( $array_of_module_tags ) );
165 $module_tags_unique = array_count_values( $module_tags );
166 ksort( $module_tags_unique );
167
168 $format = '<a href="%3$s"%4$s data-title="%1$s">%1$s <span class="count">(%2$s)</span></a>';
169 $title = __( 'All', 'jetpack' );
170 $count = count( $modules );
171 $url = esc_url( remove_query_arg( 'module_tag' ) );
172 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
173 $current = empty( $_GET['module_tag'] ) ? ' class="current all"' : ' class="all"';
174 $views = array(
175 'all' => sprintf( $format, $title, $count, $url, $current ),
176 );
177 foreach ( $module_tags_unique as $title => $count ) {
178 $key = sanitize_title( $title );
179 $display_title = esc_html( wptexturize( $title ) );
180 $url = esc_url( add_query_arg( 'module_tag', rawurlencode( $title ) ) );
181 $current = '';
182 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
183 if ( ! empty( $_GET['module_tag'] ) && $title === $_GET['module_tag'] ) {
184 $current = ' class="current"';
185 }
186 $views[ $key ] = sprintf( $format, $display_title, $count, $url, $current );
187 }
188 return $views;
189 }
190
191 /**
192 * Output views HTML.
193 */
194 public function views() {
195 $views = $this->get_views();
196
197 echo "<ul class='subsubsub'>\n";
198 foreach ( $views as $class => $view ) {
199 $views[ $class ] = "\t<li class='$class'>$view</li>";
200 }
201 echo implode( "\n", $views ) . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Is HTML. Escaping happens in get_views().
202 echo '</ul>';
203 }
204
205 /**
206 * Filter a modules array for displayed items.
207 *
208 * @param array $modules Modules.
209 * @return array Displayed modules.
210 */
211 public function filter_displayed_table_items( $modules ) {
212 return array_filter( $modules, array( $this, 'is_module_displayed' ) );
213 }
214
215 /**
216 * Determine if a module is displayed.
217 *
218 * @param array $module Module data.
219 * @return bool
220 */
221 public static function is_module_displayed( $module ) {
222 // Handle module tag based filtering.
223 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
224 if ( ! empty( $_REQUEST['module_tag'] ) ) {
225 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
226 $module_tag = sanitize_text_field( wp_unslash( $_REQUEST['module_tag'] ) );
227 if ( ! in_array( $module_tag, $module['module_tags'], true ) ) {
228 return false;
229 }
230 }
231
232 // If nothing rejected it, include it!
233 return true;
234 }
235
236 /**
237 * Sort callback to put modules with `requires_connection` last.
238 *
239 * @param array $module1 Module data.
240 * @param array $module2 Module data.
241 * @return int Indicating the relative ordering of module1 and module2.
242 */
243 public static function sort_requires_connection_last( $module1, $module2 ) {
244 if ( (bool) $module1['requires_connection'] === (bool) $module2['requires_connection'] ) {
245 return 0;
246 }
247 if ( $module1['requires_connection'] ) {
248 return 1;
249 }
250 if ( $module2['requires_connection'] ) {
251 return -1;
252 }
253
254 return 0;
255 }
256
257 /**
258 * Get table columns.
259 *
260 * @return string[] Column name to header HTML.
261 */
262 public function get_columns() {
263 $columns = array(
264 'cb' => '<input type="checkbox" />',
265 'name' => __( 'Name', 'jetpack' ),
266 );
267 return $columns;
268 }
269
270 /**
271 * Get bulk actions for the table.
272 *
273 * @return string[] Actions, code => text.
274 */
275 public function get_bulk_actions() {
276 $actions = array(
277 'bulk-activate' => __( 'Activate', 'jetpack' ),
278 'bulk-deactivate' => __( 'Deactivate', 'jetpack' ),
279 );
280 return $actions;
281 }
282
283 /**
284 * Print a single row of the table.
285 *
286 * @param object|array $item Item.
287 */
288 public function single_row( $item ) {
289 static $i = 0;
290 $row_class = ( ( ++$i ) % 2 ) ? ' alternate' : '';
291
292 if ( ! empty( $item['activated'] ) ) {
293 $row_class .= ' active';
294 }
295
296 if ( ! Jetpack_Admin::is_module_available( $item ) ) {
297 $row_class .= ' unavailable';
298 }
299
300 echo '<tr class="jetpack-module' . esc_attr( $row_class ) . '" id="' . esc_attr( $item['module'] ) . '">';
301 $this->single_row_columns( $item );
302 echo '</tr>';
303 }
304
305 /**
306 * Table classes.
307 *
308 * @return string[] HTML.
309 */
310 public function get_table_classes() {
311 return array( 'table', 'table-bordered', 'wp-list-table', 'widefat', 'fixed', 'jetpack-modules' );
312 }
313
314 /**
315 * Column checkbox.
316 *
317 * @param object|array $item Item.
318 * @return string HTML.
319 */
320 public function column_cb( $item ) {
321 if ( ! Jetpack_Admin::is_module_available( $item ) ) {
322 return '';
323 }
324
325 return sprintf( '<input type="checkbox" name="modules[]" value="%s" />', $item['module'] );
326 }
327
328 /**
329 * Column icon.
330 *
331 * @return string HTML.
332 */
333 public function column_icon() {
334 $badge_text = '';
335 $free_text = '';
336 ob_start();
337 ?>
338 <a href="#TB_inline?width=600&height=550&inlineId=more-info-module-settings-modal" class="thickbox">
339 <div class="module-image">
340 <p><span class="module-image-badge"><?php echo esc_html( $badge_text ); ?></span><span class="module-image-free" style="display: none"><?php echo esc_html( $free_text ); ?></span></p>
341 </div>
342 </a>
343 <?php
344 return ob_get_clean();
345 }
346
347 /**
348 * Column name.
349 *
350 * @param object|array $item Item.
351 * @return string HTML.
352 */
353 public function column_name( $item ) {
354 $actions = array(
355 'info' => sprintf( '<a href="%s" target="blank">%s</a>', esc_url( $item['learn_more_button'] ), esc_html__( 'Feature Info', 'jetpack' ) ),
356 );
357
358 if ( ! empty( $item['configurable'] ) ) {
359 $actions['configure'] = $item['configurable'];
360 }
361
362 if ( empty( $item['activated'] ) && Jetpack_Admin::is_module_available( $item ) ) {
363 $url = wp_nonce_url(
364 Jetpack::admin_url(
365 array(
366 'page' => 'jetpack',
367 'action' => 'activate',
368 'module' => $item['module'],
369 )
370 ),
371 'jetpack_activate-' . $item['module']
372 );
373 $actions['activate'] = sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Activate', 'jetpack' ) );
374 } elseif ( ! empty( $item['activated'] ) ) {
375 $url = wp_nonce_url(
376 Jetpack::admin_url(
377 array(
378 'page' => 'jetpack',
379 'action' => 'deactivate',
380 'module' => $item['module'],
381 )
382 ),
383 'jetpack_deactivate-' . $item['module']
384 );
385 $actions['delete'] = sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Deactivate', 'jetpack' ) );
386 }
387
388 return $this->row_actions( $actions ) . wptexturize( $item['name'] );
389 }
390
391 /**
392 * Column description.
393 *
394 * @param object|array $item Item.
395 * @return string HTML.
396 */
397 public function column_description( $item ) {
398 ob_start();
399 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
400 /** This action is documented in class.jetpack-admin.php */
401 echo apply_filters( 'jetpack_short_module_description', $item['description'], $item['module'] );
402 /** This action is documented in class.jetpack-admin.php */
403 do_action( 'jetpack_learn_more_button_' . $item['module'] );
404 echo '<div id="more-info-' . $item['module'] . '" class="more-info">';
405 /** This action is documented in class.jetpack-admin.php */
406 do_action( 'jetpack_module_more_info_' . $item['module'] );
407 echo '</div>';
408 // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
409 return ob_get_clean();
410 }
411
412 /**
413 * Return module tags HTML.
414 *
415 * @param object|array $item Item.
416 * @return string HTML.
417 */
418 public function column_module_tags( $item ) {
419 $module_tags = array();
420 foreach ( $item['module_tags'] as $module_tag ) {
421 $module_tags[] = sprintf( '<a href="%3$s" data-title="%2$s">%1$s</a>', esc_html( $module_tag ), esc_attr( $module_tag ), esc_url( add_query_arg( 'module_tag', rawurlencode( $module_tag ) ) ) );
422 }
423 return implode( ', ', $module_tags );
424 }
425
426 /**
427 * Column default value.
428 *
429 * @param object|array $item Item.
430 * @param string $column_name Column name.
431 * @return string
432 */
433 public function column_default( $item, $column_name ) {
434 switch ( $column_name ) {
435 case 'icon':
436 case 'name':
437 case 'description':
438 return '';
439 default:
440 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
441 return print_r( $item, true );
442 }
443 }
444
445 /**
446 * Check if the info parameter provided in the URL corresponds to an actual module.
447 *
448 * @param string|false $info Info parameter.
449 * @param array $modules Modules array.
450 * @return string|false
451 */
452 public function module_info_check( $info, $modules ) {
453 if ( ! $info ) {
454 return false;
455 } elseif ( array_key_exists( $info, $modules ) ) {
456 return $info;
457 }
458 }
459
460 /**
461 * Core switched their `display_tablenav()` method to protected, so we can't access it directly.
462 * Instead, let's include an access function to make it doable without errors!
463 *
464 * @see https://github.com/WordPress/WordPress/commit/d28f6344de97616de8ece543ed290c4ba2383622
465 *
466 * @param string $which Which nav table to display.
467 * @return mixed
468 */
469 public function unprotected_display_tablenav( $which = 'top' ) {
470 return $this->display_tablenav( $which );
471 }
472
473 }
474