PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 3.6.4
Jetpack – WP Security, Backup, Speed, & Growth v3.6.4
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 All 500 releases
jetpack / class.jetpack-modules-list-table.php
class.jetpack-modules-list-table.php
352 lines 11.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! class_exists( 'WP_List_Table' ) )
4 require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
5
6 class Jetpack_Modules_List_Table extends WP_List_Table {
7
8 function __construct() {
9 parent::__construct();
10
11 Jetpack::init();
12
13 // In WP 4.2 WP_List_Table will be sanitizing which values are __set()
14 global $wp_version;
15 if ( version_compare( $wp_version, '4.2-z', '>=' ) && $this->compat_fields && is_array( $this->compat_fields ) ) {
16 array_push( $this->compat_fields, 'all_items' );
17 }
18
19 $this->items = $this->all_items = Jetpack_Admin::init()->get_modules();
20 $this->items = $this->filter_displayed_table_items( $this->items );
21 $this->items = apply_filters( 'jetpack_modules_list_table_items', $this->items );
22 $this->_column_headers = array( $this->get_columns(), array(), array(), 'name' );
23 $modal_info = isset( $_GET['info'] ) ? $_GET['info'] : false;
24
25 wp_register_script(
26 'models.jetpack-modules',
27 plugins_url( '_inc/jetpack-modules.models.js', JETPACK__PLUGIN_FILE ),
28 array( 'backbone', 'underscore' ),
29 JETPACK__VERSION
30 );
31 wp_register_script(
32 'views.jetpack-modules',
33 plugins_url( '_inc/jetpack-modules.views.js', JETPACK__PLUGIN_FILE ),
34 array( 'backbone', 'underscore', 'wp-util' ),
35 JETPACK__VERSION
36 );
37 wp_register_script(
38 'jetpack-modules-list-table',
39 plugins_url( '_inc/jetpack-modules.js', JETPACK__PLUGIN_FILE ),
40 array(
41 'views.jetpack-modules',
42 'models.jetpack-modules',
43 'jquery',
44 ),
45 JETPACK__VERSION,
46 true
47 );
48
49 wp_localize_script( 'jetpack-modules-list-table', 'jetpackModulesData', array(
50 'modules' => $this->all_items,
51 'i18n' => array(
52 'search_placeholder' => __( 'Search Modules…', 'jetpack' ),
53 ),
54 'modalinfo' => $this->module_info_check( $modal_info, $this->all_items ),
55 'nonces' => array(
56 'bulk' => wp_create_nonce( 'bulk-jetpack_page_jetpack_modules' ),
57 ),
58 'coreIconAvailable' => Jetpack::jetpack_site_icon_available_in_core(),
59 ) );
60
61 wp_enqueue_script( 'jetpack-modules-list-table' );
62
63 /**
64 * Filters the js_templates callback value
65 *
66 * @since 3.6.0
67 *
68 * @param array array( $this, 'js_templates' ) js_templates callback.
69 */
70 add_action( 'admin_footer', apply_filters( 'jetpack_modules_list_table_js_template_callback', array( $this, 'js_templates' ) ), 9 );
71 }
72
73 function js_templates() {
74 ?>
75 <script type="text/html" id="tmpl-Jetpack_Modules_List_Table_Template">
76 <# var i = 0;
77 if ( data.items.length ) {
78 _.each( data.items, function( item, key, list ) {
79 if ( item === undefined ) return;
80 if ( jetpackModulesData.coreIconAvailable && 'site-icon' == item.module ) { #>
81 <tr class="jetpack-module deprecated <# if ( ++i % 2 ) { #> alternate<# } #>" id="site-icon-deprecated">
82 <th scope="row" class="check-column">
83 <input type="checkbox" name="modules[]" value="{{{ item.module }}}" disabled />
84 </th>
85 <td class='name column-name'>
86 <span class='info'>{{{ item.name }}}</span>
87 <div class="row-actions">
88 <span class="dep-msg"><?php _ex( 'WordPress now has Site Icon built in!', '"Site Icon" is the feature name.', 'jetpack' ); ?></span>
89 <span class='configure'><a href="<?php esc_html_e( admin_url( 'options-general.php' ), 'jetpack' ); ?>"><?php _e( 'configure' , 'jetpack' ); ?></a></span>
90 </div>
91 </td>
92 </tr>
93 <# return; } #>
94 <tr class="jetpack-module <# if ( ++i % 2 ) { #> alternate<# } #><# if ( item.activated ) { #> active<# } #><# if ( ! item.available ) { #> unavailable<# } #>" id="{{{ item.module }}}">
95 <th scope="row" class="check-column">
96 <input type="checkbox" name="modules[]" value="{{{ item.module }}}" />
97 </th>
98 <td class='name column-name'>
99 <span class='info'><a href="#">{{{ item.name }}}</a></span>
100 <div class="row-actions">
101 <# if ( item.configurable ) { #>
102 <span class='configure'>{{{ item.configurable }}}</span>
103 <# } #>
104 <# if ( item.activated && 'vaultpress' !== item.module && item.available ) { #>
105 <span class='delete'><a href="<?php echo admin_url( 'admin.php' ); ?>?page=jetpack&#038;action=deactivate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.deactivate_nonce }}}"><?php _e( 'Deactivate', 'jetpack' ); ?></a></span>
106 <# } else if ( item.available ) { #>
107 <span class='activate'><a href="<?php echo admin_url( 'admin.php' ); ?>?page=jetpack&#038;action=activate&#038;module={{{ item.module }}}&#038;_wpnonce={{{ item.activate_nonce }}}"><?php _e( 'Activate', 'jetpack' ); ?></a></span>
108 <# } #>
109 </div>
110 </td>
111 </tr>
112 <#
113 });
114 } else {
115 #>
116 <tr class="no-modules-found">
117 <td colspan="2"><?php esc_html_e( 'No Modules Found' , 'jetpack' ); ?></td>
118 </tr>
119 <#
120 }
121 #>
122 </script>
123 <?php
124 }
125
126 function get_views() {
127 $modules = Jetpack_Admin::init()->get_modules();
128 $array_of_module_tags = wp_list_pluck( $modules, 'module_tags' );
129 $module_tags = call_user_func_array( 'array_merge', $array_of_module_tags );
130 $module_tags_unique = array_count_values( $module_tags );
131 ksort( $module_tags_unique );
132
133 $format = '<a href="%3$s"%4$s data-title="%1$s">%1$s <span class="count">(%2$s)</span></a>';
134 $title = __( 'All', 'jetpack' );
135 $count = count( $modules );
136 $url = esc_url( remove_query_arg( 'module_tag' ) );
137 $current = empty( $_GET['module_tag'] ) ? ' class="current all"' : ' class="all"';
138 $views = array(
139 'all' => sprintf( $format, $title, $count, $url, $current ),
140 );
141 foreach ( $module_tags_unique as $title => $count ) {
142 if ( 'Jumpstart' == $title ) {
143 continue;
144 }
145 $key = sanitize_title( $title );
146 $display_title = esc_html( wptexturize( $title ) );
147 $url = esc_url( add_query_arg( 'module_tag', urlencode( $title ) ) );
148 $current = '';
149 if ( ! empty( $_GET['module_tag'] ) && $title == $_GET['module_tag'] )
150 $current = ' class="current"';
151 $views[ $key ] = sprintf( $format, $display_title, $count, $url, $current );
152 }
153 return $views;
154 }
155
156 function views() {
157 $views = $this->get_views();
158
159 echo "<ul class='subsubsub'>\n";
160 foreach ( $views as $class => $view ) {
161 $views[ $class ] = "\t<li class='$class'>$view</li>";
162 }
163 echo implode( "\n", $views ) . "\n";
164 echo "</ul>";
165 }
166
167 function filter_displayed_table_items( $modules ) {
168 return array_filter( $modules, array( $this, 'is_module_displayed' ) );
169 }
170
171 static function is_module_available( $module ) {
172 if ( ! is_array( $module ) || empty( $module ) )
173 return false;
174
175 if ( Jetpack::is_development_mode() ) {
176 return ! ( $module['requires_connection'] );
177 } else {
178 return Jetpack::is_active();
179 }
180 }
181
182 static function is_module_displayed( $module ) {
183 // Handle module tag based filtering.
184 if ( ! empty( $_REQUEST['module_tag'] ) ) {
185 $module_tag = sanitize_text_field( $_REQUEST['module_tag'] );
186 if ( ! in_array( $module_tag, $module['module_tags'] ) )
187 return false;
188 }
189
190 // If nothing rejected it, include it!
191 return true;
192 }
193
194 static function sort_requires_connection_last( $module1, $module2 ) {
195 if ( $module1['requires_connection'] == $module2['requires_connection'] )
196 return 0;
197 if ( $module1['requires_connection'] )
198 return 1;
199 if ( $module2['requires_connection'] )
200 return -1;
201
202 return 0;
203 }
204
205 function get_columns() {
206 $columns = array(
207 'cb' => '<input type="checkbox" />',
208 'name' => __( 'Name', 'jetpack' ),
209 );
210 return $columns;
211 }
212
213 function get_bulk_actions() {
214 $actions = array(
215 'bulk-activate' => __( 'Activate', 'jetpack' ),
216 'bulk-deactivate' => __( 'Deactivate', 'jetpack' ),
217 );
218 return $actions;
219 }
220
221 function single_row( $item ) {
222 static $i = 0;
223 $row_class = ( ++$i % 2 ) ? ' alternate' : '';
224
225 if ( ! empty( $item['activated'] ) )
226 $row_class .= ' active';
227
228 if ( ! $this->is_module_available( $item ) )
229 $row_class .= ' unavailable';
230
231 echo '<tr class="jetpack-module' . esc_attr( $row_class ) . '" id="' . esc_attr( $item['module'] ) . '">';
232 $this->single_row_columns( $item );
233 echo '</tr>';
234 }
235
236 function get_table_classes() {
237 return array( 'table', 'table-bordered', 'wp-list-table', 'widefat', 'fixed', 'jetpack-modules' );
238 }
239
240 function column_cb( $item ) {
241 if ( ! $this->is_module_available( $item ) )
242 return '';
243
244 return sprintf( '<input type="checkbox" name="modules[]" value="%s" />', $item['module'] );
245 }
246
247 function column_icon( $item ) {
248 $badge_text = $free_text = '';
249 ob_start();
250 ?>
251 <a href="#TB_inline?width=600&height=550&inlineId=more-info-module-settings-modal" class="thickbox">
252 <div class="module-image">
253 <p><span class="module-image-badge"><?php echo $badge_text; ?></span><span class="module-image-free" style="display: none"><?php echo $free_text; ?></span></p>
254 </div>
255 </a>
256 <?php
257 return ob_get_clean();
258
259 }
260
261 function column_name( $item ) {
262 $actions = array(
263 'info' => sprintf( '<a href="%s">%s</a>', esc_url( '#' ), esc_html__( 'Module Info', 'jetpack' ) ),
264 );
265
266 if ( ! empty( $item['configurable'] ) ) {
267 $actions['configure'] = $item['configurable'];
268 }
269
270 if ( empty( $item['activated'] ) && $this->is_module_available( $item ) ) {
271 $url = wp_nonce_url(
272 Jetpack::admin_url( array(
273 'page' => 'jetpack',
274 'action' => 'activate',
275 'module' => $item['module'],
276 ) ),
277 'jetpack_activate-' . $item['module']
278 );
279 $actions['activate'] = sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Activate', 'jetpack' ) );
280 } elseif ( ! empty( $item['activated'] ) ) {
281 $url = wp_nonce_url(
282 Jetpack::admin_url( array(
283 'page' => 'jetpack',
284 'action' => 'deactivate',
285 'module' => $item['module'],
286 ) ),
287 'jetpack_deactivate-' . $item['module']
288 );
289 $actions['delete'] = sprintf( '<a href="%s">%s</a>', esc_url( $url ), esc_html__( 'Deactivate', 'jetpack' ) );
290 }
291
292 return $this->row_actions( $actions ) . wptexturize( $item['name'] );
293 }
294
295 function column_description( $item ) {
296 ob_start();
297 echo apply_filters( 'jetpack_short_module_description', $item['description'], $item['module'] );
298 do_action( 'jetpack_learn_more_button_' . $item['module'] );
299 echo '<div id="more-info-' . $item['module'] . '" class="more-info">';
300 if ( Jetpack::is_active() && has_action( 'jetpack_module_more_info_connected_' . $item['module'] ) ) {
301 do_action( 'jetpack_module_more_info_connected_' . $item['module'] );
302 } else {
303 do_action( 'jetpack_module_more_info_' . $item['module'] );
304 }
305 echo '</div>';
306 return ob_get_clean();
307 }
308
309 function column_module_tags( $item ) {
310 $module_tags = array();
311 foreach( $item['module_tags'] as $module_tag ) {
312 $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', urlencode( $module_tag ) ) ) );
313 }
314 return implode( ', ', $module_tags );
315 }
316
317 function column_default( $item, $column_name ) {
318 switch ( $column_name ) {
319 case 'icon':
320 case 'name':
321 case 'description':
322 break;
323 default:
324 return print_r( $item, true );
325 }
326 }
327
328 //Check if the info parameter provided in the URL corresponds to an actual module
329 function module_info_check( $info = false, $modules ) {
330 if ( false == $info ) {
331 return false;
332 } else if ( array_key_exists( $info, $modules ) ) {
333 return $info;
334 }
335 }
336
337 /**
338 * Core switched their `display_tablenav()` method to protected, so we can't access it directly.
339 * Instead, let's include an access function to make it doable without errors!
340 *
341 * @see https://github.com/WordPress/WordPress/commit/d28f6344de97616de8ece543ed290c4ba2383622
342 *
343 * @param string $which
344 *
345 * @return mixed
346 */
347 function unprotected_display_tablenav( $which = 'top' ) {
348 return $this->display_tablenav( $which );
349 }
350
351 }
352