PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.7.3
Jetpack – WP Security, Backup, Speed, & Growth v12.7.3
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 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 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 2 years ago _inc 2 years ago css 2 years ago extensions 2 years ago images 3 years ago jetpack_vendor 23 hours ago json-endpoints 2 years ago modules 1 year ago sal 2 years ago src 3 years ago vendor 2 years ago views 3 years ago CHANGELOG.md 2 years ago LICENSE.txt 5 years ago SECURITY.md 2 years ago class-jetpack-connection-status.php 2 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 2 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 2 years ago class.jetpack-affiliate.php 2 years ago class.jetpack-autoupdate.php 2 years ago class.jetpack-bbpress-json-api.compat.php 2 years ago class.jetpack-boost-modules.php 3 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 2 years ago class.jetpack-gutenberg.php 2 years ago class.jetpack-heartbeat.php 2 years ago class.jetpack-idc.php 5 years ago class.jetpack-modules-list-table.php 2 years ago class.jetpack-network-sites-list-table.php 3 years ago class.jetpack-network.php 3 years ago class.jetpack-plan.php 3 years ago class.jetpack-post-images.php 2 years ago class.jetpack-twitter-cards.php 3 years ago class.jetpack-user-agent.php 2 years ago class.jetpack.php 2 years ago class.json-api-endpoints.php 2 years ago class.json-api.php 3 years ago class.photon.php 3 years ago composer.json 2 years ago enhanced-open-graph.php 3 years ago functions.compat.php 2 years ago functions.cookies.php 2 years ago functions.global.php 2 years ago functions.is-mobile.php 2 years ago functions.opengraph.php 2 years ago functions.photon.php 2 years ago jetpack.php 23 hours ago json-api-config.php 3 years ago json-endpoints.php 2 years ago load-jetpack.php 3 years ago locales.php 4 years ago readme.txt 23 hours ago uninstall.php 5 years ago wpml-config.xml 4 years ago
class.jetpack-modules-list-table.php
477 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 if ( 'lazy-images' == item.module && ! item.activated ) return; #>
121 <tr class="jetpack-module <# if ( ++i % 2 ) { #> alternate<# } #><# if ( item.activated ) { #> active<# } #><# if ( ! item.available ) { #> unavailable<# } #>" id="{{{ item.module }}}">
122 <th scope="row" class="check-column">
123 <input type="checkbox" name="modules[]" value="{{{ item.module }}}" {{{ item.disabled }}} />
124 </th>
125 <td class='name column-name'>
126 <p class='info'><a href="{{{item.learn_more_button}}}" target="blank" style="text-decoration: none;">{{{ item.name }}}</a></p>
127 <div class="row-actions">
128 <# if ( item.configurable ) { #>
129 <span class='configure'>{{{ item.configurable }}}</span>
130 <# } #>
131 <# if ( item.activated && 'vaultpress' !== item.module && item.available ) { #>
132 <span class='delete'><a class="dops-button is-compact" 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>
133 <# } else if ( item.available ) { #>
134 <span class='activate'><a class="dops-button is-compact" 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>
135 <# } #>
136 <# if ( ! item.available ) { #>
137 <p class='unavailable_reason'>{{{ item.unavailable_reason }}}</p>
138 <# } #>
139 </div>
140 </td>
141 </tr>
142 <#
143 });
144 } else {
145 #>
146 <tr class="no-modules-found">
147 <td colspan="2"><?php esc_html_e( 'No Modules Found', 'jetpack' ); ?></td>
148 </tr>
149 <#
150 }
151 #>
152 </script>
153 <?php
154 }
155
156 /**
157 * Get views data.
158 *
159 * @return array Maps identifier to display HTML.
160 */
161 public function get_views() {
162 /** This filter is already documented in class.jetpack-modules-list-table.php */
163 $modules = apply_filters( 'jetpack_modules_list_table_items', Jetpack_Admin::init()->get_modules() );
164 $array_of_module_tags = wp_list_pluck( $modules, 'module_tags' );
165 $module_tags = array_merge( ...array_values( $array_of_module_tags ) );
166 $module_tags = array_map( 'jetpack_get_module_i18n_tag', $module_tags );
167 $module_tags_unique = array_count_values( $module_tags );
168 ksort( $module_tags_unique );
169
170 $format = '<a href="%3$s" %4$s data-title="%1$s">%1$s</a> <span class="count">(%2$s)</span>';
171 $title = __( 'All', 'jetpack' );
172 $count = is_countable( $modules ) ? count( $modules ) : 0;
173 $url = esc_url( remove_query_arg( 'module_tag' ) );
174 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
175 $views = array(
176 'all' => sprintf( $format, $title, $count, $url, 'class="all"' ),
177 );
178 foreach ( $module_tags_unique as $title => $count ) {
179 $key = sanitize_title( $title );
180 $display_title = esc_html( wptexturize( $title ) );
181 $url = esc_url( add_query_arg( 'module_tag', rawurlencode( $title ) ) );
182 $views[ $key ] = sprintf( $format, $display_title, $count, $url, '' );
183 }
184 return $views;
185 }
186
187 /**
188 * Output views HTML.
189 */
190 public function views() {
191 $views = $this->get_views();
192
193 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
194 $module_tag = empty( $_GET['module_tag'] ) ? 'all' : sanitize_title( wp_unslash( $_GET['module_tag'] ) );
195
196 echo "<ul class='subsubsub'>\n";
197 foreach ( $views as $class => $view ) {
198 $class_name = $class;
199 if ( $class === $module_tag ) {
200 $class_name .= ' current';
201 }
202
203 $views[ $class ] = "\t<li class='$class_name'>$view</li>";
204 }
205 echo implode( "\n", $views ) . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Is HTML. Escaping happens in get_views().
206 echo '</ul>';
207 }
208
209 /**
210 * Filter a modules array for displayed items.
211 *
212 * @param array $modules Modules.
213 * @return array Displayed modules.
214 */
215 public function filter_displayed_table_items( $modules ) {
216 return array_filter( $modules, array( $this, 'is_module_displayed' ) );
217 }
218
219 /**
220 * Determine if a module is displayed.
221 *
222 * @param array $module Module data.
223 * @return bool
224 */
225 public static function is_module_displayed( $module ) {
226 // Handle module tag based filtering.
227 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
228 if ( ! empty( $_REQUEST['module_tag'] ) ) {
229 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is a view, not a model or controller.
230 $module_tag = sanitize_text_field( wp_unslash( $_REQUEST['module_tag'] ) );
231 if ( ! in_array( $module_tag, array_map( 'jetpack_get_module_i18n_tag', $module['module_tags'] ), true ) ) {
232 return false;
233 }
234 }
235
236 // If nothing rejected it, include it!
237 return true;
238 }
239
240 /**
241 * Sort callback to put modules with `requires_connection` last.
242 *
243 * @param array $module1 Module data.
244 * @param array $module2 Module data.
245 * @return int Indicating the relative ordering of module1 and module2.
246 */
247 public static function sort_requires_connection_last( $module1, $module2 ) {
248 if ( (bool) $module1['requires_connection'] === (bool) $module2['requires_connection'] ) {
249 return 0;
250 }
251 if ( $module1['requires_connection'] ) {
252 return 1;
253 }
254 if ( $module2['requires_connection'] ) {
255 return -1;
256 }
257
258 return 0;
259 }
260
261 /**
262 * Get table columns.
263 *
264 * @return string[] Column name to header HTML.
265 */
266 public function get_columns() {
267 $columns = array(
268 'cb' => '<input type="checkbox" />',
269 'name' => __( 'Name', 'jetpack' ),
270 );
271 return $columns;
272 }
273
274 /**
275 * Get bulk actions for the table.
276 *
277 * @return string[] Actions, code => text.
278 */
279 public function get_bulk_actions() {
280 $actions = array(
281 'bulk-activate' => __( 'Activate', 'jetpack' ),
282 'bulk-deactivate' => __( 'Deactivate', 'jetpack' ),
283 );
284 return $actions;
285 }
286
287 /**
288 * Print a single row of the table.
289 *
290 * @param object|array $item Item.
291 */
292 public function single_row( $item ) {
293 static $i = 0;
294 $row_class = ( ( ++$i ) % 2 ) ? ' alternate' : '';
295
296 if ( ! empty( $item['activated'] ) ) {
297 $row_class .= ' active';
298 }
299
300 if ( ! Jetpack_Admin::is_module_available( $item ) ) {
301 $row_class .= ' unavailable';
302 }
303
304 echo '<tr class="jetpack-module' . esc_attr( $row_class ) . '" id="' . esc_attr( $item['module'] ) . '">';
305 $this->single_row_columns( $item );
306 echo '</tr>';
307 }
308
309 /**
310 * Table classes.
311 *
312 * @return string[] HTML.
313 */
314 public function get_table_classes() {
315 return array( 'table', 'table-bordered', 'wp-list-table', 'widefat', 'fixed' );
316 }
317
318 /**
319 * Column checkbox.
320 *
321 * @param object|array $item Item.
322 * @return string HTML.
323 */
324 public function column_cb( $item ) {
325 if ( ! Jetpack_Admin::is_module_available( $item ) ) {
326 return '';
327 }
328
329 return sprintf( '<input type="checkbox" name="modules[]" value="%s" />', $item['module'] );
330 }
331
332 /**
333 * Column icon.
334 *
335 * @return string HTML.
336 */
337 public function column_icon() {
338 $badge_text = '';
339 $free_text = '';
340 ob_start();
341 ?>
342 <a href="#TB_inline?width=600&height=550&inlineId=more-info-module-settings-modal" class="thickbox">
343 <div class="module-image">
344 <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>
345 </div>
346 </a>
347 <?php
348 return ob_get_clean();
349 }
350
351 /**
352 * Column name.
353 *
354 * @param object|array $item Item.
355 * @return string HTML.
356 */
357 public function column_name( $item ) {
358 $actions = array(
359 'info' => sprintf( '<a href="%s" target="blank">%s</a>', esc_url( $item['learn_more_button'] ), esc_html__( 'Feature Info', 'jetpack' ) ),
360 );
361
362 if ( ! empty( $item['configurable'] ) ) {
363 $actions['configure'] = $item['configurable'];
364 }
365
366 if ( empty( $item['activated'] ) && Jetpack_Admin::is_module_available( $item ) ) {
367 $url = wp_nonce_url(
368 Jetpack::admin_url(
369 array(
370 'page' => 'jetpack',
371 'action' => 'activate',
372 'module' => $item['module'],
373 )
374 ),
375 'jetpack_activate-' . $item['module']
376 );
377 $actions['activate'] = sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Activate', 'jetpack' ) );
378 } elseif ( ! empty( $item['activated'] ) ) {
379 $url = wp_nonce_url(
380 Jetpack::admin_url(
381 array(
382 'page' => 'jetpack',
383 'action' => 'deactivate',
384 'module' => $item['module'],
385 )
386 ),
387 'jetpack_deactivate-' . $item['module']
388 );
389 $actions['delete'] = sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Deactivate', 'jetpack' ) );
390 }
391
392 return $this->row_actions( $actions ) . wptexturize( $item['name'] );
393 }
394
395 /**
396 * Column description.
397 *
398 * @param object|array $item Item.
399 * @return string HTML.
400 */
401 public function column_description( $item ) {
402 ob_start();
403 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
404 /** This action is documented in class.jetpack-admin.php */
405 echo apply_filters( 'jetpack_short_module_description', $item['description'], $item['module'] );
406 /** This action is documented in class.jetpack-admin.php */
407 do_action( 'jetpack_learn_more_button_' . $item['module'] );
408 echo '<div id="more-info-' . $item['module'] . '" class="more-info">';
409 /** This action is documented in class.jetpack-admin.php */
410 do_action( 'jetpack_module_more_info_' . $item['module'] );
411 echo '</div>';
412 // phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
413 return ob_get_clean();
414 }
415
416 /**
417 * Return module tags HTML.
418 *
419 * @param object|array $item Item.
420 * @return string HTML.
421 */
422 public function column_module_tags( $item ) {
423 $module_tags = array();
424 foreach ( array_map( 'jetpack_get_module_i18n_tag', $item['module_tags'] ) as $module_tag ) {
425 $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 ) ) ) );
426 }
427 return implode( ', ', $module_tags );
428 }
429
430 /**
431 * Column default value.
432 *
433 * @param object|array $item Item.
434 * @param string $column_name Column name.
435 * @return string
436 */
437 public function column_default( $item, $column_name ) {
438 switch ( $column_name ) {
439 case 'icon':
440 case 'name':
441 case 'description':
442 return '';
443 default:
444 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
445 return print_r( $item, true );
446 }
447 }
448
449 /**
450 * Check if the info parameter provided in the URL corresponds to an actual module.
451 *
452 * @param string|false $info Info parameter.
453 * @param array $modules Modules array.
454 * @return string|false
455 */
456 public function module_info_check( $info, $modules ) {
457 if ( ! $info ) {
458 return false;
459 } elseif ( array_key_exists( $info, $modules ) ) {
460 return $info;
461 }
462 }
463
464 /**
465 * Core switched their `display_tablenav()` method to protected, so we can't access it directly.
466 * Instead, let's include an access function to make it doable without errors!
467 *
468 * @see https://github.com/WordPress/WordPress/commit/d28f6344de97616de8ece543ed290c4ba2383622
469 *
470 * @param string $which Which nav table to display.
471 * @return mixed
472 */
473 public function unprotected_display_tablenav( $which = 'top' ) {
474 return $this->display_tablenav( $which );
475 }
476 }
477