PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / pages / page-mainwp-plugins.php

page-mainwp-plugins.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.1, at pages/page-mainwp-plugins.php

3,208 lines 175.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Plugins Page.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class MainWP_Plugins
17 *
18 * @package MainWP\Dashboard\
19 *
20 * @uses \MainWP\Dashboard\MainWP_Install_Bulk
21 */
22 class MainWP_Plugins { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23
24 // phpcs:disable Generic.Metrics.CyclomaticComplexity -- This is the only way to achieve desired results, pull request solutions appreciated.
25
26 /**
27 * Get Class Name.
28 *
29 * @return string __CLASS__
30 */
31 public static function get_class_name() {
32 return __CLASS__;
33 }
34
35 /**
36 * MainWP Plugins sub-pages.
37 *
38 * @var array $subPages MainWP Plugins Sub Pages.
39 */
40 public static $subPages;
41
42 /**
43 * Plugins table.
44 *
45 * @var mixed $pluginsTable Plugins table.
46 */
47 public static $pluginsTable;
48
49 /** Instantiate Hooks. */
50 public static function init() {
51 /**
52 * This hook allows you to render the Plugins page header via the 'mainwp-pageheader-plugins' action.
53 *
54 * @link http://codex.mainwp.com/#mainwp-pageheader-plugins
55 *
56 * This hook is normally used in the same context of 'mainwp-getsubpages-plugins'
57 * @link http://codex.mainwp.com/#mainwp-getsubpages-plugins
58 *
59 * @see \MainWP_Plugins::render_header
60 */
61 add_action( 'mainwp-pageheader-plugins', array( static::get_class_name(), 'render_header' ) );
62
63 /**
64 * This hook allows you to render the Plugins page footer via the 'mainwp-pagefooter-plugins' action.
65 *
66 * @link http://codex.mainwp.com/#mainwp-pagefooter-plugins
67 *
68 * This hook is normally used in the same context of 'mainwp-getsubpages-plugins'
69 * @link http://codex.mainwp.com/#mainwp-getsubpages-plugins
70 *
71 * @see \MainWP_Plugins::render_footer
72 */
73 add_action( 'mainwp-pagefooter-plugins', array( static::get_class_name(), 'render_footer' ) );
74
75 add_action( 'mainwp_help_sidebar_content', array( static::get_class_name(), 'mainwp_help_content' ) );
76 }
77
78 /**
79 * Instantiate Main Plugins Menu.
80 *
81 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
82 */
83 public static function init_menu() {
84 add_submenu_page(
85 'mainwp_tab',
86 __( 'Plugins', 'mainwp' ),
87 '<span id="mainwp-Plugins">' . esc_html__( 'Plugins', 'mainwp' ) . '</span>',
88 'read',
89 'PluginsManage',
90 array(
91 static::get_class_name(),
92 'render',
93 )
94 );
95 if ( \mainwp_current_user_can( 'dashboard', 'install_plugins' ) ) {
96 $page = add_submenu_page(
97 'mainwp_tab',
98 __( 'Plugins', 'mainwp' ),
99 '<div class="mainwp-hidden">' . esc_html__( 'Install ', 'mainwp' ) . '</div>',
100 'read',
101 'PluginsInstall',
102 array(
103 static::get_class_name(),
104 'render_install',
105 )
106 );
107
108 add_action( 'load-' . $page, array( static::get_class_name(), 'load_page' ) );
109 }
110 add_submenu_page(
111 'mainwp_tab',
112 __( 'Plugins', 'mainwp' ),
113 '<div class="mainwp-hidden">' . esc_html__( 'Advanced Auto Updates', 'mainwp' ) . '</div>',
114 'read',
115 'PluginsAutoUpdate',
116 array(
117 static::get_class_name(),
118 'render_auto_update',
119 )
120 );
121 add_submenu_page(
122 'mainwp_tab',
123 __( 'Plugins', 'mainwp' ),
124 '<div class="mainwp-hidden">' . esc_html__( 'Ignored Updates', 'mainwp' ) . '</div>',
125 'read',
126 'PluginsIgnore',
127 array(
128 static::get_class_name(),
129 'render_ignore',
130 )
131 );
132 add_submenu_page(
133 'mainwp_tab',
134 __( 'Plugins', 'mainwp' ),
135 '<div class="mainwp-hidden">' . esc_html__( 'Abandoned Plugins', 'mainwp' ) . '</div>',
136 'read',
137 'PluginsAbandoned',
138 array(
139 static::get_class_name(),
140 'render_abandoned_plugins',
141 )
142 );
143 add_submenu_page(
144 'mainwp_tab',
145 __( 'Plugins', 'mainwp' ),
146 '<div class="mainwp-hidden">' . esc_html__( 'Ignored Abandoned', 'mainwp' ) . '</div>',
147 'read',
148 'PluginsIgnoredAbandoned',
149 array(
150 static::get_class_name(),
151 'render_ignored_abandoned',
152 )
153 );
154
155 /**
156 * Plugins Subpages
157 *
158 * Filters subpages for the Plugins page.
159 *
160 * @since Unknown
161 */
162 $sub_pages = apply_filters_deprecated( 'mainwp-getsubpages-plugins', array( array() ), '4.0.7.2', 'mainwp_getsubpages_plugins' ); // @deprecated Use 'mainwp_getsubpages_plugins' instead. NOSONAR - not IP.
163 static::$subPages = apply_filters( 'mainwp_getsubpages_plugins', $sub_pages );
164
165 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
166 foreach ( static::$subPages as $subPage ) {
167 if ( MainWP_Menu::is_disable_menu_item( 3, 'Plugins' . $subPage['slug'] ) ) {
168 continue;
169 }
170 add_submenu_page( 'mainwp_tab', $subPage['title'], '<div class="mainwp-hidden">' . $subPage['title'] . '</div>', 'read', 'Plugins' . $subPage['slug'], $subPage['callback'] );
171 }
172 }
173 static::init_left_menu( static::$subPages );
174 }
175
176 /**
177 * Load the Plugins Page.
178 *
179 * @uses \MainWP\Dashboard\MainWP_Plugins_Install_List_Table
180 */
181 public static function load_page() {
182 static::$pluginsTable = new MainWP_Plugins_Install_List_Table();
183 $pagenum = static::$pluginsTable->get_pagenum();
184
185 static::$pluginsTable->prepare_items();
186
187 $total_pages = static::$pluginsTable->get_pagination_arg( 'total_pages' );
188
189 if ( $pagenum > $total_pages && 0 < $total_pages ) {
190 wp_safe_redirect( esc_url_raw( add_query_arg( 'paged', $total_pages ) ) );
191 exit;
192 }
193 }
194
195 /**
196 * Instantiate Subpage "tabs".
197 *
198 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
199 */
200 public static function init_subpages_menu() {
201 ?>
202 <div id="menu-mainwp-Plugins" class="mainwp-submenu-wrapper" xmlns="http://www.w3.org/1999/html">
203 <div class="wp-submenu sub-open" >
204 <div class="mainwp_boxout">
205 <div class="mainwp_boxoutin"></div>
206 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsManage' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Manage Plugins', 'mainwp' ); ?></a>
207 <?php if ( \mainwp_current_user_can( 'dashboard', 'install_plugins' ) ) : ?>
208 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsInstall' ) ) : ?>
209 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsInstall' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Install Plugins', 'mainwp' ); ?></a>
210 <?php endif; ?>
211 <?php endif; ?>
212 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsAutoUpdate' ) ) : ?>
213 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsAutoUpdate' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Advanced Auto Updates', 'mainwp' ); ?></a>
214 <?php endif; ?>
215 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsIgnore' ) ) : ?>
216 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsIgnore' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Ignored Updates', 'mainwp' ); ?></a>
217 <?php endif; ?>
218 <?php if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsIgnoredAbandoned' ) ) : ?>
219 <a href="<?php echo esc_url( admin_url( 'admin.php?page=PluginsIgnoredAbandoned' ) ); ?>" class="mainwp-submenu"><?php esc_html_e( 'Ignored Abandoned', 'mainwp' ); ?></a>
220 <?php endif; ?>
221 <?php
222 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
223 foreach ( static::$subPages as $subPage ) {
224 if ( MainWP_Menu::is_disable_menu_item( 3, 'Plugins' . $subPage['slug'] ) ) {
225 continue;
226 }
227 ?>
228 <a href="<?php echo esc_url( admin_url( 'admin.php?page=Plugins' . $subPage['slug'] ) ); ?>" class="mainwp-submenu"><?php echo esc_html( $subPage['title'] ); ?></a>
229 <?php
230 }
231 }
232 ?>
233 </div>
234 </div>
235 </div>
236 <?php
237 }
238
239 /**
240 * Instantiate MainWP main menu Subpages menu.
241 *
242 * @param array $subPages Subpages array.
243 *
244 * @uses MainWP_Menu::add_left_menu()
245 * @uses MainWP_Menu::init_subpages_left_menu()
246 * @uses MainWP_Menu::is_disable_menu_item()
247 * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
248 */
249 public static function init_left_menu( $subPages = array() ) {
250 MainWP_Menu::add_left_menu(
251 array(
252 'title' => esc_html__( 'Plugins', 'mainwp' ),
253 'parent_key' => 'managesites',
254 'slug' => 'PluginsManage',
255 'href' => 'admin.php?page=PluginsManage',
256 'icon' => '<i class="plug icon"></i>',
257 'leftsub_order' => 5,
258 ),
259 1
260 );
261
262 $init_sub_subleftmenu = array(
263 array(
264 'title' => esc_html__( 'Manage Plugins', 'mainwp' ),
265 'parent_key' => 'PluginsManage',
266 'href' => 'admin.php?page=PluginsManage',
267 'slug' => 'PluginsManage',
268 'right' => '',
269 'leftsub_order_level2' => 1,
270 ),
271 array(
272 'title' => esc_html__( 'Install Plugins', 'mainwp' ),
273 'parent_key' => 'PluginsManage',
274 'href' => 'admin.php?page=PluginsInstall',
275 'slug' => 'PluginsInstall',
276 'right' => 'install_plugins',
277 'leftsub_order_level2' => 2,
278 ),
279 array(
280 'title' => esc_html__( 'Advanced Auto Updates', 'mainwp' ),
281 'parent_key' => 'PluginsManage',
282 'href' => 'admin.php?page=PluginsAutoUpdate',
283 'slug' => 'PluginsAutoUpdate',
284 'right' => '',
285 'leftsub_order_level2' => 3,
286 ),
287 array(
288 'title' => esc_html__( 'Ignored Updates', 'mainwp' ),
289 'parent_key' => 'PluginsManage',
290 'href' => 'admin.php?page=PluginsIgnore',
291 'slug' => 'PluginsIgnore',
292 'right' => '',
293 'leftsub_order_level2' => 4,
294 ),
295 array(
296 'title' => esc_html__( 'Abandoned Plugins', 'mainwp' ),
297 'parent_key' => 'PluginsManage',
298 'href' => 'admin.php?page=PluginsAbandoned',
299 'slug' => 'PluginsAbandoned',
300 'right' => '',
301 'leftsub_order_level2' => 4.1,
302 ),
303 array(
304 'title' => esc_html__( 'Ignored Abandoned', 'mainwp' ),
305 'parent_key' => 'PluginsManage',
306 'href' => 'admin.php?page=PluginsIgnoredAbandoned',
307 'slug' => 'PluginsIgnoredAbandoned',
308 'right' => '',
309 'leftsub_order_level2' => 5,
310 ),
311
312 );
313
314 MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'PluginsManage', 'Plugins' );
315
316 foreach ( $init_sub_subleftmenu as $item ) {
317 if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
318 continue;
319 }
320 MainWP_Menu::add_left_menu( $item, 2 );
321 }
322 }
323
324 /**
325 * Render MainWP Plugins Page Header.
326 *
327 * @param string $shownPage The page slug shown at this moment.
328 *
329 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
330 * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
331 * @uses \MainWP\Dashboard\MainWP_UI::render_page_navigation()
332 */
333 public static function render_header( $shownPage = '' ) { // phpcs:ignore -- NOSONAR - complex.
334
335 $params = array(
336 'title' => esc_html__( 'Plugins', 'mainwp' ),
337 );
338
339 MainWP_UI::render_top_header( $params );
340
341 $renderItems = array();
342 $renderItems[] = array(
343 'title' => esc_html__( 'Manage Plugins', 'mainwp' ),
344 'href' => 'admin.php?page=PluginsManage',
345 'active' => ( 'Manage' === $shownPage ) ? true : false,
346 );
347
348 if ( \mainwp_current_user_can( 'dashboard', 'install_plugins' ) && ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsInstall' ) ) {
349 $renderItems[] = array(
350 'title' => esc_html__( 'Install', 'mainwp' ),
351 'href' => 'admin.php?page=PluginsInstall',
352 'active' => ( 'Install' === $shownPage ) ? true : false,
353 );
354 }
355
356 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsAutoUpdate' ) ) {
357 $renderItems[] = array(
358 'title' => esc_html__( 'Advanced Auto Updates', 'mainwp' ),
359 'href' => 'admin.php?page=PluginsAutoUpdate',
360 'active' => ( 'AutoUpdate' === $shownPage ) ? true : false,
361 );
362 }
363
364 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsIgnore' ) ) {
365 $renderItems[] = array(
366 'title' => esc_html__( 'Ignored Updates', 'mainwp' ),
367 'href' => 'admin.php?page=PluginsIgnore',
368 'active' => ( 'Ignore' === $shownPage ) ? true : false,
369 );
370 }
371
372 if ( ! MainWP_Menu::is_disable_menu_item( 3, 'PluginsIgnoredAbandoned' ) ) {
373 $renderItems[] = array(
374 'title' => esc_html__( 'Ignored Abandoned', 'mainwp' ),
375 'href' => 'admin.php?page=PluginsIgnoredAbandoned',
376 'active' => ( 'IgnoreAbandoned' === $shownPage ) ? true : false,
377 );
378 }
379
380 if ( isset( static::$subPages ) && is_array( static::$subPages ) ) {
381 foreach ( static::$subPages as $subPage ) {
382 if ( MainWP_Menu::is_disable_menu_item( 3, 'Plugins' . $subPage['slug'] ) ) {
383 continue;
384 }
385
386 $item = array();
387 $item['title'] = $subPage['title'];
388 $item['href'] = 'admin.php?page=Plugins' . $subPage['slug'];
389 $item['active'] = ( $subPage['slug'] === $shownPage ) ? true : false;
390 $renderItems[] = $item;
391 }
392 }
393
394 MainWP_UI::render_page_navigation( $renderItems );
395 }
396
397 /**
398 * Method render_footer()
399 *
400 * Render MainWP Plugins Page Footer.
401 */
402 public static function render_footer() {
403 echo '</div>';
404 }
405
406 /**
407 * Render MainWP Plugins Page.
408 *
409 * @uses \MainWP\Dashboard\MainWP_Cache::get_cached_context()
410 * @uses \MainWP\Dashboard\MainWP_Cache::get_cached_result()
411 * @uses \MainWP\Dashboard\MainWP_UI::render_empty_bulk_actions()
412 */
413 public static function render() { // phpcs:ignore -- NOSONAR - complex.
414 $cachedSearch = MainWP_Cache::get_cached_context( 'Plugins' );
415 $selected_sites = array();
416 $selected_groups = array();
417 $selected_clients = array();
418
419 if ( null !== $cachedSearch ) {
420 if ( is_array( $cachedSearch['sites'] ) ) {
421 $selected_sites = $cachedSearch['sites'];
422 } elseif ( is_array( $cachedSearch['groups'] ) ) {
423 $selected_groups = $cachedSearch['groups'];
424 } elseif ( is_array( $cachedSearch['clients'] ) ) {
425 $selected_clients = $cachedSearch['clients'];
426 }
427 }
428 $cachedResult = MainWP_Cache::get_cached_result( 'Plugins' );
429
430 if ( isset( $_POST['select_mainwp_options_plugintheme_view'] ) && check_admin_referer( 'mainwp-admin-nonce' ) && is_array( $cachedResult ) && isset( $cachedResult['result'] ) ) {
431 unset( $cachedResult['result'] ); // clear cached results.
432 }
433
434 static::render_header( 'Manage' );
435 ?>
436
437 <div id="mainwp-manage-plugins" class="ui alt segment">
438 <div class="mainwp-main-content">
439 <div class="ui mini form mainwp-actions-bar">
440 <div class="ui stackable grid">
441 <div class="ui two column row">
442 <div class="middle aligned column">
443 <span id="mainwp-plugins-bulk-actions-wapper" style="margin-right:1rem">
444 <?php
445 if ( is_array( $cachedResult ) && isset( $cachedResult['bulk_actions'] ) ) {
446 echo $cachedResult['bulk_actions']; // phpcs:ignore WordPress.Security.EscapeOutput
447 }
448 ?>
449 </span>
450 <button id="mainwp-install-to-selected-sites" class="ui mini green basic button" style="display: none; "><?php esc_html_e( 'Install to Selected Site(s)', 'mainwp' ); ?></button>
451 <?php
452 /**
453 * Action: mainwp_plugins_actions_bar_left
454 *
455 * Fires at the left side of the actions bar on the Plugins screen, after the Bulk Actions menu.
456 *
457 * @since 4.0
458 */
459 do_action( 'mainwp_plugins_actions_bar_left' );
460 ?>
461 </div>
462 <div class="right aligned middle aligned column">
463 <?php static::render_select_manage_view(); ?>
464
465 <?php
466 /**
467 * Action: mainwp_plugins_actions_bar_right
468 *
469 * Fires at the right side of the actions bar on the Plugins screen.
470 *
471 * @since 4.0
472 */
473 do_action( 'mainwp_plugins_actions_bar_right' );
474 ?>
475 </div>
476 </div>
477 </div>
478 </div>
479 <div class="ui padded segment" id="mainwp-plugins-table-wrapper">
480 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-manage-plugins-info-message' ) ) : ?>
481 <div class="ui info message">
482 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-manage-plugins-info-message"></i>
483 <div class="header"><?php esc_html_e( 'How to Manage Plugins', 'mainwp' ); ?></div>
484 <div><?php echo esc_html__( 'Manage installed plugins on your child sites. Here you can activate, deactivate, and delete installed plugins.', 'mainwp' ); ?></div>
485 <div class="ui bulleted list">
486 <div class="item"><?php echo esc_html__( 'To Activate or Delete a specific plugin, you must search only for Inactive plugin on your child sites. If you search for Active or both Active and Inactive, the Activate and Delete actions will be disabled.', 'mainwp' ); ?></div>
487 <div class="item"><?php echo esc_html__( 'To Deactivate a specific plugin, you must search only for Active plugins on your child sites. If you search for Inactive or both Active and Inactive, the Deactivate action will be disabled.', 'mainwp' ); ?></div>
488 </div>
489 <div><?php
490 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
491 printf( esc_html__( 'For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp" target="_blank">', '</a> <i class="external alternate icon"></i>' );
492 ?></div>
493 </div>
494 <?php endif; ?>
495 <div id="mainwp-message-zone" class="ui message" style="display:none"></div>
496 <div id="mainwp-loading-plugins-row" class="ui active page dimmer" style="display:none">
497 <div class="ui text double loader"><?php esc_html_e( 'Loading...', 'mainwp' ); ?></div>
498 </div>
499 <div id="mainwp-plugins-main-content" <?php echo ( null !== $cachedSearch ) ? 'style="display: block;"' : ''; ?> >
500 <div id="mainwp-plugins-content">
501 <?php if ( is_array( $cachedResult ) && isset( $cachedResult['result'] ) ) : ?>
502 <?php echo $cachedResult['result']; // phpcs:ignore WordPress.Security.EscapeOutput ?>
503 <?php else : ?>
504 <?php MainWP_UI::render_empty_page_placeholder( __( 'No plugins loaded yet.', 'mainwp' ), __( 'Select one or more Child Sites and click the Show Plugins button to view installed plugins.', 'mainwp' ), '<em data-emoji=":compass:" class="big"></em>' ); ?>
505 <?php endif; ?>
506 </div>
507 </div>
508 </div>
509 </div>
510
511 <div class="mainwp-side-content mainwp-no-padding">
512 <?php
513 /**
514 * Action: mainwp_manage_plugins_sidebar_top
515 *
516 * Fires at the top of the sidebar on Manage themes.
517 *
518 * @since 4.1
519 */
520 do_action( 'mainwp_manage_plugins_sidebar_top' );
521 ?>
522
523 <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
524 <?php
525 /**
526 * Action: mainwp_manage_plugins_before_select_sites
527 *
528 * Fires before the Select Sites elemnt on Manage plugins.
529 *
530 * @since 4.1
531 */
532 do_action( 'mainwp_manage_plugins_before_select_sites' );
533 ?>
534 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
535 <div class="content active">
536 <?php
537 $sel_params = array(
538 'class' => 'mainwp_select_sites_box_left',
539 'selected_sites' => $selected_sites,
540 'selected_groups' => $selected_groups,
541 'selected_clients' => $selected_clients,
542 'show_client' => true,
543 );
544 MainWP_UI_Select_Sites::select_sites_box( $sel_params );
545 ?>
546 </div>
547 <?php
548 /**
549 * Action: mainwp_manage_plugins_after_select_sites
550 *
551 * Fires after the Select Sites elemnt on Manage plugins.
552 *
553 * @since 4.1
554 */
555 do_action( 'mainwp_manage_plugins_after_select_sites' );
556 ?>
557 </div>
558 <div class="ui fitted divider"></div>
559 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
560 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Status', 'mainwp' ); ?></div>
561 <div class="content active">
562 <?php
563 /**
564 * Action: mainwp_manage_plugins_before_search_options
565 *
566 * Fires before the Search Options elemnt on Manage plugins.
567 *
568 * @since 4.1
569 */
570 do_action( 'mainwp_manage_plugins_before_search_options' );
571 ?>
572
573 <div class="ui mini form">
574 <div class="field">
575 <select class="ui fluid dropdown" id="mainwp_plugins_search_by_status">
576 <option value=""><?php esc_html_e( 'Select status', 'mainwp' ); ?></option>
577 <option value="active" selected><?php esc_html_e( 'Active', 'mainwp' ); ?></option>
578 <option value="inactive"><?php esc_html_e( 'Inactive', 'mainwp' ); ?></option>
579 <option value="installed"><?php esc_html_e( 'Active & Inactive', 'mainwp' ); ?></option>
580 <option value="not_installed"><?php esc_html_e( 'Not installed', 'mainwp' ); ?></option>
581 </select>
582 </div>
583 </div>
584 <?php
585 /**
586 * Action: mainwp_manage_plugins_after_search_options
587 *
588 * Fires after the Search Options elemnt on Manage plugins.
589 *
590 * @since 4.1
591 */
592 do_action( 'mainwp_manage_plugins_after_search_options' );
593 ?>
594 </div>
595 </div>
596 <div class="ui fitted divider"></div>
597 <?php static::render_search_options(); ?>
598 <div class="ui fitted divider"></div>
599 <div class="mainwp-search-submit">
600 <?php
601 /**
602 * Action: mainwp_manage_plugins_before_submit_button
603 *
604 * Fires before the Submit Button elemnt on Manage plugins.
605 *
606 * @since 4.1
607 */
608 do_action( 'mainwp_manage_plugins_before_submit_button' );
609 ?>
610 <input type="button" name="mainwp-show-plugins" id="mainwp-show-plugins" class="ui green big fluid button" value="<?php esc_attr_e( 'Show Plugins', 'mainwp' ); ?>"/>
611 <?php
612 /**
613 * Action: mainwp_manage_plugins_after_submit_button
614 *
615 * Fires after the Submit Button elemnt on Manage plugins.
616 *
617 * @since 4.1
618 */
619 do_action( 'mainwp_manage_plugins_after_submit_button' );
620 ?>
621 </div>
622 <?php
623 /**
624 * Action: mainwp_manage_plugins_sidebar_bottom
625 *
626 * Fires at the bottom of the sidebar on Manage themes.
627 *
628 * @since 4.1
629 */
630 do_action( 'mainwp_manage_plugins_sidebar_bottom' );
631 ?>
632 </div>
633 <div style="clear:both"></div>
634 </div>
635 <script type="text/javascript">
636 jQuery( document ).ready( function ($) {
637 if($('#mainwp-plugins-content .mainwp-manage-plugins-reload-data').length){
638 mainwp_fetch_plugins();
639 }
640 } );
641 </script>
642 <?php
643 static::render_footer( 'Manage' );
644 }
645
646 /**
647 * Render MainWP plugins page search options.
648 *
649 * @uses \MainWP\Dashboard\MainWP_Cache::get_cached_context()
650 */
651 public static function render_search_options() {
652 $cachedSearch = MainWP_Cache::get_cached_context( 'Plugins' );
653 $statuses = isset( $cachedSearch['status'] ) ? $cachedSearch['status'] : array();
654 if ( $cachedSearch && isset( $cachedSearch['keyword'] ) ) {
655 $cachedSearch['keyword'] = trim( $cachedSearch['keyword'] );
656 }
657 $disabledNegative = ( null !== $cachedSearch ) && ! empty( $cachedSearch['keyword'] ) ? false : true;
658 $checkedNegative = ! $disabledNegative && ( null !== $cachedSearch ) && ! empty( $cachedSearch['not_criteria'] ) ? true : false;
659 ?>
660 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
661 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Search Options', 'mainwp' ); ?></div>
662 <div class="content active">
663 <div class="ui mini form">
664 <div class="field">
665 <div class="ui input fluid">
666 <input type="text" placeholder="<?php esc_attr_e( 'Plugin name', 'mainwp' ); ?>" id="mainwp_plugin_search_by_keyword" class="text" value="<?php echo ( null !== $cachedSearch ) ? esc_attr( $cachedSearch['keyword'] ) : ''; //phpcs:ignore -- escaped. ?>" />
667 </div>
668 </div>
669 <div class="ui hidden fitted divider"></div>
670 <div class="field">
671 <div class="ui toggle checkbox" data-tooltip="<?php esc_attr_e( 'Display sites not meeting the above search criteria.', 'mainwp' ); ?>" data-position="center left" data-inverted="">
672 <input type="checkbox" <?php echo $disabledNegative ? 'disabled' : ''; ?> <?php echo $checkedNegative ? 'checked="true"' : ''; ?> value="1" id="display_sites_not_meeting_criteria" />
673 <label for="display_sites_not_meeting_criteria"><?php esc_html_e( 'Exclude plugin', 'mainwp' ); ?></label>
674 </div>
675 </div>
676 </div>
677 </div>
678 </div>
679 <?php
680 if ( is_array( $statuses ) && ! empty( $statuses ) ) {
681 $status = '';
682 foreach ( $statuses as $st ) {
683 $status .= "'" . esc_html( $st ) . "',";
684 }
685 $status = rtrim( $status, ',' );
686 ?>
687 <script type="text/javascript">
688 jQuery( document ).ready( function () {
689 jQuery( '#mainwp_plugins_search_by_status' ).dropdown( 'set selected', [<?php echo $status; // phpcs:ignore -- safe output, to fix incorrect characters. ?>] );
690 } );
691 </script>
692 <?php
693 }
694 ?>
695 <script type="text/javascript">
696 jQuery( document ).on( 'keyup', '#mainwp_plugin_search_by_keyword', function () {
697 if( jQuery(this).val() != '' ){
698 jQuery( '#display_sites_not_meeting_criteria' ).prop("disabled", false);
699 } else {
700 jQuery( '#display_sites_not_meeting_criteria' ).closest('.checkbox').checkbox('set unchecked');
701 jQuery( '#display_sites_not_meeting_criteria' ).attr('disabled', 'true');
702 }
703 });
704 </script>
705 <?php
706 }
707
708 /**
709 * Render Plugins Table.
710 *
711 * @param mixed $keyword Search Terms.
712 * @param mixed $status active|inactive Whether the plugin is active or inactive.
713 * @param mixed $groups Selected Child Site Groups.
714 * @param mixed $sites Selected individual Child Sites.
715 * @param mixed $not_criteria Show not criteria result.
716 * @param mixed $clients Selected Clients.
717 * @param bool $not_fetchdata True|False fetch data or not.
718 *
719 * @return string Plugin Table.
720 *
721 * @uses MainWP_Cache::init_cache()
722 * @uses MainWP_Utility::ctype_digit()
723 * @uses MainWP_DB::instance()
724 * @uses MainWP_DB::free_result()
725 * @uses MainWP_DB::fetch_object()
726 * @uses MainWP_Utility::map_site()
727 * @uses MainWP_Utility::fetch_urls_authed()
728 * @uses MainWP_Utility::get_nice_url()
729 * @uses MainWP_Cache::add_result()
730 * @uses \MainWP\Dashboard\MainWP_Cache::init_cache()
731 * @uses \MainWP\Dashboard\MainWP_Cache::add_context()
732 * @uses \MainWP\Dashboard\MainWP_Cache::add_result()
733 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
734 * @uses \MainWP\Dashboard\MainWP_DB::query()
735 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
736 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_by_group_id()
737 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
738 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
739 * @uses \MainWP\Dashboard\MainWP_Plugins_Handler::get_class_name()
740 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
741 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
742 */
743 public static function render_table( $keyword, $status, $groups, $sites, $not_criteria, $clients, $not_fetchdata = false ) { // phpcs:ignore -- NOSONAR -Current complexity required to achieve desired results. Pull request solutions appreciated.
744 $keyword = trim( $keyword );
745 MainWP_Cache::init_cache( 'Plugins' );
746
747 $output = new \stdClass();
748 $output->errors = array();
749 $output->plugins = array();
750 $output->plugins_installed = array();
751 $output->status = $status;
752 $output->roll_items = array();
753 $error_results = '';
754
755 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
756 $data_fields[] = 'plugins';
757 $data_fields[] = 'rollback_updates_data';
758 $data_fields[] = 'site_info';
759
760 if ( ! $not_fetchdata ) {
761
762 if ( 1 === (int) get_option( 'mainwp_optimize', 1 ) || MainWP_Demo_Handle::is_demo_mode() ) {
763
764 $multi_kws = explode( ',', $keyword );
765 $multi_kws = array_filter( array_map( 'trim', $multi_kws ) );
766
767 if ( ! empty( $sites ) ) {
768 foreach ( $sites as $v ) {
769 if ( MainWP_Utility::ctype_digit( $v ) ) {
770 $website = MainWP_DB::instance()->get_website_by_id( $v, false, array( 'rollback_updates_data', 'site_info' ) );
771 $allPlugins = json_decode( $website->plugins, true );
772 $_count = count( $allPlugins );
773 $_count_installed = 0;
774 for ( $i = 0; $i < $_count; $i++ ) {
775 $plugin = $allPlugins[ $i ];
776 $is_active = 'active' === $status ? 1 : 0;
777 if ( ( 'active' === $status || 'inactive' === $status ) && $is_active !== (int) $plugin['active'] ) {
778 continue;
779 }
780
781 if ( ! empty( $keyword ) ) {
782 if ( $not_criteria ) {
783 if ( MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
784 continue;
785 }
786 } elseif ( ! MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
787 continue;
788 }
789 }
790
791 $plugin['websiteid'] = $website->id;
792 $plugin['websiteurl'] = $website->url;
793 $plugin['websitename'] = $website->name;
794 $plugin['site_info'] = $website->site_info;
795
796 $output->plugins[] = $plugin;
797 ++$_count_installed;
798 }
799
800 if ( 0 === $_count_installed && 'not_installed' === $status ) {
801 for ( $i = 0; $i < $_count; $i++ ) {
802 $plugin = $allPlugins[ $i ];
803 $plugin['websiteid'] = $website->id;
804 $plugin['websiteurl'] = $website->url;
805 $plugin['websitename'] = $website->name;
806 $plugin['site_info'] = $website->site_info;
807 $output->plugins_installed[] = $plugin;
808 }
809 }
810 $output->roll_items[ $website->id ] = MainWP_Updates_Helper::get_roll_update_plugintheme_items( 'plugin', $website->rollback_updates_data );
811 }
812 }
813 }
814
815 if ( '' !== $groups ) {
816 foreach ( $groups as $v ) {
817 if ( MainWP_Utility::ctype_digit( $v ) ) {
818 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $v, false, 'wp.url', false, false, null, null, array( 'extra_view' => array( 'site_info', 'rollback_updates_data' ) ) ) );
819 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
820 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
821 continue;
822 }
823 $allPlugins = json_decode( $website->plugins, true );
824 $_count = count( $allPlugins );
825 $_count_installed = 0;
826 for ( $i = 0; $i < $_count; $i++ ) {
827 $plugin = $allPlugins[ $i ];
828 $is_active = 'active' === $status ? 1 : 0;
829 if ( ( 'active' === $status || 'inactive' === $status ) && $is_active !== (int) $plugin['active'] ) {
830 continue;
831 }
832
833 if ( ! empty( $keyword ) ) {
834 if ( $not_criteria ) {
835 if ( MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
836 continue;
837 }
838 } elseif ( ! MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
839 continue;
840 }
841 }
842
843 $plugin['websiteid'] = $website->id;
844 $plugin['websiteurl'] = $website->url;
845 $plugin['websitename'] = $website->name;
846 $plugin['site_info'] = $website->site_info;
847
848 $output->plugins[] = $plugin;
849 ++$_count_installed;
850 }
851
852 if ( 0 === $_count_installed && 'not_installed' === $status ) {
853 for ( $i = 0; $i < $_count; $i++ ) {
854 $plugin = $allPlugins[ $i ];
855 $plugin['websiteid'] = $website->id;
856 $plugin['websiteurl'] = $website->url;
857 $plugin['websitename'] = $website->name;
858 $plugin['site_info'] = $website->site_info;
859 $output->plugins_installed[] = $plugin;
860 }
861 }
862 $output->roll_items[ $website->id ] = MainWP_Updates_Helper::get_roll_update_plugintheme_items( 'plugin', $website->rollback_updates_data );
863 }
864 MainWP_DB::free_result( $websites );
865 }
866 }
867 }
868
869 if ( '' !== $clients && is_array( $clients ) ) {
870 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
871 $clients,
872 array(
873 'select_data' => $data_fields,
874 'extra_view' => array( 'rollback_updates_data', 'site_info' ),
875 )
876 );
877 if ( $websites ) {
878 foreach ( $websites as $website ) {
879 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
880 continue;
881 }
882 $allPlugins = json_decode( $website->plugins, true );
883 $_count = count( $allPlugins );
884 $_count_installed = 0;
885 for ( $i = 0; $i < $_count; $i++ ) {
886 $plugin = $allPlugins[ $i ];
887
888 $is_active = ( 'active' === $status ) ? 1 : 0;
889
890 if ( ( ( 'active' === $status ) || ( 'inactive' === $status ) ) && ( $is_active !== (int) $plugin['active'] ) ) {
891 continue;
892 }
893
894 if ( ! empty( $keyword ) ) {
895 if ( $not_criteria ) {
896 if ( MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
897 continue;
898 }
899 } elseif ( ! MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
900 continue;
901 }
902 }
903
904 $plugin['websiteid'] = $website->id;
905 $plugin['websiteurl'] = $website->url;
906 $plugin['websitename'] = $website->name;
907 $plugin['site_info'] = $website->site_info;
908 $output->plugins[] = $plugin;
909 ++$_count_installed;
910 }
911 if ( 0 === $_count_installed && 'not_installed' === $status ) {
912 for ( $i = 0; $i < $_count; $i++ ) {
913 $plugin = $allPlugins[ $i ];
914 $plugin['websiteid'] = $website->id;
915 $plugin['websiteurl'] = $website->url;
916 $plugin['websitename'] = $website->name;
917 $plugin['site_info'] = $website->site_info;
918 $output->plugins_installed[] = $plugin;
919 }
920 }
921 $output->roll_items[ $website->id ] = MainWP_Updates_Helper::get_roll_update_plugintheme_items( 'plugin', $website->rollback_updates_data );
922 }
923 }
924 }
925 } else {
926 $dbwebsites = array();
927
928 if ( '' !== $sites ) {
929 foreach ( $sites as $v ) {
930 if ( MainWP_Utility::ctype_digit( $v ) ) {
931 $website = MainWP_DB::instance()->get_website_by_id( $v, false, array( 'rollback_updates_data', 'site_info' ) );
932
933 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
934 continue;
935 }
936
937 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
938 $website,
939 $data_fields
940 );
941 }
942 }
943 }
944
945 if ( '' !== $groups ) {
946 foreach ( $groups as $v ) {
947 if ( MainWP_Utility::ctype_digit( $v ) ) {
948 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_by_group_id( $v, false, 'wp.url', false, false, null, null, array( 'extra_view' => array( 'site_info', 'rollback_updates_data' ) ) ) );
949 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
950 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
951 continue;
952 }
953 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
954 $website,
955 $data_fields
956 );
957 }
958 MainWP_DB::free_result( $websites );
959 }
960 }
961 }
962
963 if ( '' !== $clients && is_array( $clients ) ) {
964 $websites = MainWP_DB_Client::instance()->get_websites_by_client_ids(
965 $clients,
966 array(
967 'select_data' => $data_fields,
968 'extra_view' => array( 'rollback_updates_data', 'site_info' ),
969 )
970 );
971 if ( $websites ) {
972 foreach ( $websites as $website ) {
973 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
974 continue;
975 }
976 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
977 $website,
978 $data_fields
979 );
980 }
981 }
982 }
983
984 $post_data = array(
985 'keyword' => $keyword,
986 );
987
988 if ( 'active' === $status || 'inactive' === $status ) {
989 $post_data['status'] = $status;
990 $post_data['filter'] = true;
991 } else {
992 $post_data['status'] = '';
993 $post_data['filter'] = false;
994 }
995
996 if ( 'not_installed' === $status ) {
997 $post_data['not_installed'] = true;
998 }
999
1000 $post_data['not_criteria'] = $not_criteria ? true : false;
1001 MainWP_Connect::fetch_urls_authed( $dbwebsites, 'get_all_plugins', $post_data, array( MainWP_Plugins_Handler::get_class_name(), 'plugins_search_handler' ), $output );
1002 // phpcs:disable WordPress.Security.EscapeOutput
1003 if ( ! empty( $output->errors ) ) {
1004 foreach ( $output->errors as $siteid => $error ) {
1005 $error_results .= MainWP_Utility::get_nice_url( $dbwebsites[ $siteid ]->url ) . ': ' . $error . ' <br/>';
1006 }
1007 }
1008 // phpcs:enable
1009 }
1010 }
1011
1012 MainWP_Cache::add_context(
1013 'Plugins',
1014 array(
1015 'keyword' => $keyword,
1016 'status' => $status,
1017 'sites' => ( '' !== $sites ) ? $sites : '',
1018 'groups' => ( '' !== $groups ) ? $groups : '',
1019 'clients' => ( '' !== $clients ) ? $clients : '',
1020 'not_criteria' => $not_criteria ? true : false,
1021 )
1022 );
1023
1024 $view_mode = static::get_manage_view();
1025
1026 $bulkActions = static::render_bulk_actions( $status );
1027 $roll_items_list = array();
1028 $plugins_list = array();
1029
1030 ob_start();
1031
1032 if ( ! empty( $error_results ) ) {
1033 // phpcs:disable WordPress.Security.EscapeOutput
1034 ?>
1035 <div class="ui message yellow"><?php echo $error_results; ?></div>
1036 <?php
1037 // phpcs:enable
1038 }
1039
1040 if ( 'not_installed' === $status ) {
1041 if ( empty( $output->plugins_installed ) ) {
1042 ?>
1043 <div class="ui message yellow <?php echo $not_fetchdata ? 'mainwp-manage-plugins-reload-data' : ''; ?>"><?php esc_html_e( 'No websites found.', 'mainwp' ); ?></div>
1044 <?php
1045 } else {
1046 $plugins_list = $output->plugins_installed;
1047 $roll_items_list = ! empty( $output->roll_items ) ? $output->roll_items : array();
1048 $view_mode = MAINWP_VIEW_PER_SITE;
1049 }
1050 } elseif ( empty( $output->plugins ) ) {
1051 ?>
1052 <div class="ui message yellow <?php echo $not_fetchdata ? 'mainwp-manage-plugins-reload-data' : ''; ?>"><?php esc_html_e( 'No plugins found.', 'mainwp' ); ?></div>
1053 <?php
1054 } else {
1055 $plugins_list = $output->plugins;
1056 $roll_items_list = ! empty( $output->roll_items ) ? $output->roll_items : array();
1057 }
1058
1059 if ( ! is_array( $roll_items_list ) ) {
1060 $roll_items_list = array();
1061 }
1062
1063 $sites = array();
1064 $sitePlugins = array();
1065 $pluginsNameSites = array();
1066 $muPlugins = array();
1067 $pluginsName = array();
1068 $pluginsMainWP = array();
1069 $pluginsRealVersion = array();
1070 $pluginsSlug = array();
1071
1072 if ( ! empty( $plugins_list ) ) {
1073
1074 foreach ( $plugins_list as $plugin ) {
1075 $slug_ver = esc_html( $plugin['slug'] . '_' . $plugin['version'] );
1076 $sites[ $plugin['websiteid'] ] = array(
1077 'websiteurl' => esc_html( $plugin['websiteurl'] ),
1078 'websitename' => $plugin['websitename'],
1079 'site_info' => $plugin['site_info'],
1080 );
1081
1082 $pluginsSlug[ $slug_ver ] = isset( $plugin['slug'] ) ? $plugin['slug'] : '';
1083 $muPlugins[ $slug_ver ] = isset( $plugin['mu'] ) ? esc_html( $plugin['mu'] ) : 0;
1084 $pluginsName[ $slug_ver ] = esc_html( $plugin['name'] );
1085
1086 $pluginsNameSites[ $plugin['name'] ][ $plugin['websiteid'] ][] = $slug_ver;
1087
1088 $pluginsMainWP[ $slug_ver ] = isset( $plugin['mainwp'] ) ? esc_html( $plugin['mainwp'] ) : 'F';
1089 $pluginsRealVersion[ $slug_ver ] = rawurlencode( $plugin['version'] );
1090
1091 if ( ! isset( $sitePlugins[ $plugin['websiteid'] ] ) || ! is_array( $sitePlugins[ $plugin['websiteid'] ] ) ) {
1092 $sitePlugins[ $plugin['websiteid'] ] = array();
1093 }
1094
1095 $sitePlugins[ $plugin['websiteid'] ][ $slug_ver ] = $plugin;
1096 }
1097
1098 ksort( $pluginsNameSites, SORT_STRING );
1099
1100 if ( MAINWP_VIEW_PER_PLUGIN_THEME === (int) $view_mode ) {
1101 static::render_manage_table( $sites, $pluginsSlug, $sitePlugins, $pluginsMainWP, $muPlugins, $pluginsName, $pluginsNameSites, $pluginsRealVersion, $roll_items_list );
1102 } else {
1103 static::render_manage_per_site_table( $sites, $pluginsSlug, $sitePlugins, $pluginsMainWP, $muPlugins, $pluginsName, $pluginsNameSites, $pluginsRealVersion, $roll_items_list );
1104 }
1105 MainWP_Updates::render_plugin_details_modal();
1106 MainWP_UI::render_modal_upload_icon();
1107 MainWP_Updates::render_changes_history_modal();
1108 }
1109
1110 $newOutput = ob_get_clean();
1111 $result = array(
1112 'result' => $newOutput,
1113 'bulk_actions' => $bulkActions,
1114 );
1115
1116 MainWP_Cache::add_result( 'Plugins', $result );
1117 return $result;
1118 }
1119
1120
1121 /**
1122 * Render Bulk Actions.
1123 *
1124 * @param mixed $status active|inactive|all.
1125 *
1126 * @return string Plugin Bulk Actions Menu.
1127 */
1128 public static function render_bulk_actions( $status ) {
1129 ob_start();
1130 ?>
1131 <select class="ui compact dropdown" id="mainwp-bulk-actions">
1132 <option value="none"><?php esc_html_e( 'Bulk actions', 'mainwp' ); ?></option>
1133 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
1134 <option value="ignore_updates" data-value="ignore_updates"><?php esc_html_e( 'Ignore updates', 'mainwp' ); ?></option>
1135 <?php endif; ?>
1136 <?php if ( \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) : ?>
1137 <?php if ( 'active' === $status ) : ?>
1138 <option value="deactivate" data-value="deactivate"><?php esc_html_e( 'Deactivate', 'mainwp' ); ?></option>
1139 <?php else : ?>
1140 <option value="deactivate" disabled data-value="deactivate"><?php esc_html_e( 'Deactivate', 'mainwp' ); ?><br/><span class="ui small text"><?php esc_html_e( 'To deactivate, view Active plugins.', 'mainwp' ); ?></span></option>
1141 <?php endif; ?>
1142 <?php endif; ?>
1143 <?php if ( 'inactive' === $status ) : ?>
1144 <?php if ( \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) : ?>
1145 <option value="activate" data-value="activate"><?php esc_html_e( 'Activate', 'mainwp' ); ?></option>
1146 <?php endif; ?>
1147 <?php if ( \mainwp_current_user_can( 'dashboard', 'delete_plugins' ) ) : ?>
1148 <option value="delete" data-value="delete"><?php esc_html_e( 'Delete', 'mainwp' ); ?></option>
1149 <?php endif; ?>
1150 <?php else : ?>
1151 <?php if ( \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) : ?>
1152 <option value="activate" disabled data-value="activate"><?php esc_html_e( 'Activate', 'mainwp' ); ?><br/><span class="ui small text"><?php esc_html_e( 'To activate, view Inactive plugins.', 'mainwp' ); ?></span></option>
1153 <?php endif; ?>
1154 <?php if ( \mainwp_current_user_can( 'dashboard', 'delete_plugins' ) ) : ?>
1155 <option value="delete" data-value="delete"><?php esc_html_e( 'Delete', 'mainwp' ); ?></option>
1156 <?php endif; ?>
1157 <?php endif; ?>
1158 <?php
1159 /**
1160 * Action: mainwp_plugins_bulk_action
1161 *
1162 * Adds a new action to the Manage Plugins bulk actions menu.
1163 *
1164 * @param string $status Status search parameter.
1165 *
1166 * @since 4.1
1167 */
1168 do_action( 'mainwp_plugins_bulk_action' );
1169 ?>
1170 </select>
1171
1172 <button class="ui mini basic button" href="javascript:void(0)" id="mainwp-do-plugins-bulk-actions"><?php esc_html_e( 'Apply', 'mainwp' ); ?></button>
1173 <span id="mainwp_bulk_action_loading"><i class="ui active inline loader tiny"></i></span>
1174 <?php
1175 return ob_get_clean();
1176 }
1177
1178 /**
1179 * Method get_manage_view().
1180 *
1181 * Get view mode.
1182 *
1183 * @param string $which plugin|theme.
1184 *
1185 * @return int view mode value.
1186 */
1187 public static function get_manage_view( $which = 'plugin' ) {
1188 if ( 'plugin' === $which ) {
1189 return get_user_option( 'mainwp_manage_plugin_view', MAINWP_VIEW_PER_PLUGIN_THEME );
1190 } else {
1191 return get_user_option( 'mainwp_manage_theme_view', MAINWP_VIEW_PER_PLUGIN_THEME );
1192 }
1193 }
1194
1195 /**
1196 * Method render_select_manage_view().
1197 *
1198 * Handle render view mode selection.
1199 *
1200 * @param string $which plugin|theme.
1201 *
1202 * @return void.
1203 */
1204 public static function render_select_manage_view( $which = 'plugin' ) {
1205
1206 $view_mode = static::get_manage_view( $which );
1207
1208 $hide_show_updates_per = apply_filters( 'mainwp_manage_plugin_theme_hide_show_updates_per', false, $which );
1209
1210 if ( ! $hide_show_updates_per ) {
1211 ?>
1212 <form method="post" action="" class="ui mini form right aligned">
1213 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
1214 <input type="hidden" name="whichview" value="<?php echo esc_attr( $which ); ?>" />
1215 <div class="ui mini stackable buttons">
1216 <button
1217 type="submit"
1218 name="select_mainwp_options_plugintheme_view"
1219 value="0"
1220 class="ui basic <?php echo esc_attr( MAINWP_VIEW_PER_PLUGIN_THEME === (int) $view_mode ? 'green' : '' ); ?> button">
1221 <?php echo esc_html( 'plugin' === $which ? esc_html__( 'Show Plugins per Item', 'mainwp' ) : esc_html__( 'Show Themes per Item', 'mainwp' ) ); ?>
1222 </button>
1223 <button
1224 type="submit"
1225 name="select_mainwp_options_plugintheme_view"
1226 value="1"
1227 class="ui basic <?php echo esc_attr( MAINWP_VIEW_PER_SITE === (int) $view_mode ? 'green' : '' ); ?> button">
1228 <?php echo esc_html( 'plugin' === $which ? esc_html__( 'Show Plugins per Site', 'mainwp' ) : esc_html__( 'Show Themes per Site', 'mainwp' ) ); ?>
1229 </button>
1230 </div>
1231 </form>
1232 <?php
1233 }
1234 }
1235
1236
1237 /**
1238 * Method render_manage_per_site_table()
1239 *
1240 * Render Manage Plugins Table.
1241 *
1242 * @param array $sites Child Sites array.
1243 * @param array $pluginsSlug Plugins slug array.
1244 * @param array $sitePlugins Site plugins array.
1245 * @param array $pluginsMainWP MainWP plugins array.
1246 * @param array $muPlugins Must use plugins array.
1247 * @param array $pluginsName Plugin names array.
1248 * @param array $pluginsNameSites Plugin names with Sites array.
1249 * @param array $pluginsRealVersion Latest plugin release version.
1250 * @param array $roll_list rool items list.
1251 */
1252 public static function render_manage_per_site_table( $sites, $pluginsSlug = array(), $sitePlugins = array(), $pluginsMainWP = array(), $muPlugins = array(), $pluginsName = array(), $pluginsNameSites = array(), $pluginsRealVersion = array(), $roll_list = array() ) { //phpcs:ignore -- NOSONAR - complex method.
1253
1254 $userExtension = MainWP_DB_Common::instance()->get_user_extension();
1255 $decodedIgnoredPlugins = json_decode( $userExtension->ignored_plugins, true );
1256 $trustedPlugins = json_decode( $userExtension->trusted_plugins, true );
1257 $is_demo = MainWP_Demo_Handle::is_demo_mode();
1258
1259 if ( ! is_array( $trustedPlugins ) ) {
1260 $trustedPlugins = array();
1261 }
1262
1263 $updateWebsites = array();
1264
1265 foreach ( $sites as $site_id => $info ) {
1266
1267 $plugin_upgrades = array();
1268 $website = MainWP_DB::instance()->get_website_by_id( $site_id, false, array( 'rollback_updates_data', 'site_info' ) );
1269
1270 if ( $website && ! $website->is_ignorePluginUpdates ) {
1271 $plugin_upgrades = json_decode( $website->plugin_upgrades, true );
1272 $decodedPremiumUpgrades = MainWP_DB::instance()->get_website_option( $website, 'premium_upgrades' );
1273 $decodedPremiumUpgrades = ! empty( $decodedPremiumUpgrades ) ? json_decode( $decodedPremiumUpgrades, true ) : array();
1274
1275 if ( is_array( $decodedPremiumUpgrades ) ) {
1276 foreach ( $decodedPremiumUpgrades as $crrSlug => $premiumUpgrade ) {
1277 $premiumUpgrade['premium'] = true;
1278
1279 if ( 'plugin' === $premiumUpgrade['type'] ) {
1280 if ( ! is_array( $plugin_upgrades ) ) {
1281 $plugin_upgrades = array();
1282 }
1283
1284 $premiumUpgrade = array_filter( $premiumUpgrade );
1285
1286 if ( ! isset( $plugin_upgrades[ $crrSlug ] ) ) {
1287 continue;
1288 }
1289 $plugin_upgrades[ $crrSlug ] = array_merge( $plugin_upgrades[ $crrSlug ], $premiumUpgrade );
1290 }
1291 }
1292 }
1293 $ignored_plugins = json_decode( $website->ignored_plugins, true );
1294 if ( is_array( $ignored_plugins ) ) {
1295 $plugin_upgrades = MainWP_Common_Functions::instance()->get_not_ignored_updates_themesplugins( $plugin_upgrades, $ignored_plugins );
1296
1297 }
1298
1299 if ( is_array( $decodedIgnoredPlugins ) ) {
1300 $plugin_upgrades = MainWP_Common_Functions::instance()->get_not_ignored_updates_themesplugins( $plugin_upgrades, $decodedIgnoredPlugins );
1301 }
1302 }
1303 $updateWebsites[ $site_id ] = $plugin_upgrades;
1304 }
1305
1306 /**
1307 * Action: mainwp_before_plugins_table
1308 *
1309 * Fires before the Plugins table.
1310 *
1311 * @since 4.1
1312 */
1313 do_action( 'mainwp_before_plugins_table' );
1314 ?>
1315
1316 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-plugins-bulk-actions-tip' ) ) : ?>
1317 <div class="ui message">
1318 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-plugins-bulk-actions-tip"></i>
1319 <div><em data-emoji=":bulb:" class="small"></em> <?php esc_html_e( 'Tip: Use Bulk Actions to activate, deactivate, or delete selected plugins.', 'mainwp' ); ?></div>
1320 </div>
1321 <?php endif; ?>
1322
1323 <div class="ui secondary segment main-master-checkbox">
1324 <div class="ui stackable grid">
1325 <div class="one wide left aligned middle aligned column">
1326 <span class="trigger-all-accordion"><span class="trigger-handle-arrow"><i class="caret right icon"></i><i class="caret down icon"></i></span></span>
1327 </div>
1328 <div class="one wide center aligned middle aligned column"><div class="ui checkbox main-master not-auto-init"><input type="checkbox"/><label></label></div></div>
1329 <div class="six wide middle aligned column"><?php esc_html_e( 'Website', 'mainwp' ); ?></div>
1330 <div class="two wide center aligned middle aligned column"></div>
1331 <div class="two wide center aligned middle aligned column"></div>
1332 <div class="two wide center aligned middle aligned column"></div>
1333 <div class="two wide right aligned middle aligned column"><?php esc_html_e( 'Plugins', 'mainwp' ); ?></div>
1334 </div>
1335 </div>
1336
1337 <div class="mainwp-manage-plugins-wrapper main-child-checkbox">
1338 <?php foreach ( $sites as $site_id => $website ) : ?>
1339 <?php
1340 $site_name = $website['websitename'];
1341 $site_url = $website['websiteurl'];
1342
1343 $wp_info = ! empty( $website['site_info'] ) ? json_decode( $website['site_info'], true ) : array();
1344 if ( ! is_array( $wp_info ) ) {
1345 $wp_info = array();
1346 }
1347 $use_tzformat = ! empty( $wp_info['format_datetime'] ) && is_array( $wp_info['format_datetime'] ) ? $wp_info['format_datetime'] : array();
1348 $offs = ! empty( $use_tzformat['gmt_offset'] ) ? intval( $use_tzformat['gmt_offset'] ) : 0;
1349 $offs_info = esc_html__( '- Timezone:', 'mainwp' ) . ' UTC' . ( $offs >= 0 ? '+' . $offs : $offs );
1350
1351 $slugVersions = isset( $sitePlugins[ $site_id ] ) ? $sitePlugins[ $site_id ] : array();
1352
1353 if ( ! is_array( $slugVersions ) ) {
1354 $slugVersions = array();
1355 }
1356
1357 $item_id = $site_id;
1358 $count_plugins = count( $slugVersions );
1359
1360 // phpcs:disable WordPress.Security.EscapeOutput
1361 ?>
1362 <div class="ui accordion mainwp-manage-plugin-accordion mainwp-manage-plugin-item main-child-checkbox" id="<?php echo esc_html( $item_id ); ?>">
1363 <div class="title master-checkbox">
1364 <div class="ui stackable grid">
1365 <div class="one wide left aligned middle aligned column"><i class="dropdown icon dropdown-trigger"></i></div>
1366 <div class="one wide center aligned middle aligned column">
1367 <div class="ui checkbox master">
1368 <input type="checkbox"/>
1369 <label></label>
1370 </div>
1371 </div>
1372 <div class="four wide middle aligned column"><a target="_blank" href="<?php MainWP_Site_Open::get_open_site_admin_link( $site_id, true ); //phpcs:ignore -- ok. ?>"><i class="sign in icon"></i></a> <a href="admin.php?page=managesites&dashboard=<?php echo intval( $site_id ); ?>"><?php echo esc_html( $site_name ); ?></a></div>
1373 <div class="two wide center aligned middle aligned column"></div>
1374 <div class="two wide center aligned middle aligned column"></div>
1375 <div class="two wide center aligned middle aligned column"></div>
1376 <div class="two wide center aligned middle aligned column"></div>
1377 <div class="two wide right aligned middle aligned column"><div class="ui label"><?php echo intval( $count_plugins ) . ' ' . esc_html( _n( 'Plugin', 'Plugins', intval( $count_plugins ), 'mainwp' ) ); ?></div></div>
1378 </div>
1379 </div>
1380 <div class="content child-checkbox">
1381 <?php
1382 // phpcs:enable
1383 foreach ( $slugVersions as $slug_ver => $plugin ) :
1384
1385 $plugin_title = wp_strip_all_tags( $pluginsName[ $slug_ver ] );
1386
1387 $plugin_slug = $pluginsSlug[ $slug_ver ];
1388 $trusted = in_array( $plugin_slug, $trustedPlugins ) ? true : false;
1389 $child_plugin = ( isset( $pluginsMainWP[ $slug_ver ] ) && 'T' === $pluginsMainWP[ $slug_ver ] ) ? true : false;
1390
1391 $plugin_mu = false;
1392
1393 $plugin_version = $sitePlugins[ $site_id ][ $slug_ver ]['version'];
1394
1395 $plugin_upgrades = isset( $updateWebsites[ $site_id ] ) ? $updateWebsites[ $site_id ] : array();
1396 if ( ! is_array( $plugin_upgrades ) ) {
1397 $plugin_upgrades = array();
1398 }
1399
1400 $upgradeInfo = isset( $plugin_upgrades[ $plugin_slug ] ) ? $plugin_upgrades[ $plugin_slug ] : false;
1401
1402 $new_version = '';
1403 if ( ! empty( $upgradeInfo ) && isset( $upgradeInfo['update']['new_version'] ) ) {
1404 $new_version = $upgradeInfo['update']['new_version'];
1405 }
1406
1407 if ( isset( $sitePlugins[ $site_id ][ $slug_ver ] ) && ( empty( $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) || 1 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) ) {
1408 $actived = true;
1409 if ( isset( $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) && 1 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) {
1410 $plugin_status = '<span class="ui tiny grey label"><i class="circle green icon"></i> ' . esc_html__( 'Active', 'mainwp' ) . '</span>';
1411 } elseif ( isset( $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) && 0 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) {
1412 $plugin_status = '<span class="ui tiny grey label"><i class="circle red icon"></i> ' . esc_html__( 'Inactive', 'mainwp' ) . '</span>';
1413 $actived = false;
1414 } else {
1415 $plugin_status = '';
1416 }
1417
1418 if ( isset( $sitePlugins[ $site_id ][ $slug_ver ] ) && ( 1 === (int) $muPlugins[ $slug_ver ] ) ) {
1419 $plugin_mu = true;
1420 }
1421
1422 if ( $plugin_mu ) {
1423 $actived = true; // always.
1424 }
1425
1426 $item_id = $slug_ver . '_' . $site_id;
1427 $item_id = strtolower( $item_id );
1428 $item_id = preg_replace( '/[[:space:]]+/', '_', $item_id );
1429
1430 $plugin_directory = MainWP_Utility::get_dir_slug( $plugin_slug );
1431 $details_link = self_admin_url( 'plugin-install.php?tab=plugin-information&wpplugin=' . intval( $site_id ) . '&plugin=' . rawurlencode( $plugin_directory ) . '&section=changelog' );
1432
1433 $el_id_ite_1 = $item_id;
1434
1435 $compatible_php = isset( $plugin_upgrade['wp_compatible'] ) ? $plugin_upgrade['wp_compatible'] : true;
1436 $compatible_wp = isset( $plugin_upgrade['php_compatible'] ) ? $plugin_upgrade['php_compatible'] : true;
1437
1438 ?>
1439 <div class="ui very compact stackable grid mainwp-manage-plugin-item-website" plugin-slug="<?php echo esc_attr( rawurlencode( $plugin_slug ) ); ?>" plugin-name="<?php echo esc_html( $plugin_title ); ?>" site-id="<?php echo intval( $site_id ); ?>" site-name="<?php echo esc_attr( $site_name ); ?>" site-url="<?php echo esc_attr( $site_url ); ?>" tz-info="<?php echo esc_attr( $offs_info ); ?>" id="<?php echo esc_attr( $el_id_ite_1 ); ?>">
1440 <div class="one wide center aligned middle aligned column"></div>
1441 <div class="one wide left aligned middle aligned column">
1442 <div class="ui checkbox child <?php echo 'mainwp-child' === $plugin_directory ? 'disabled' : ''; ?>">
1443 <input type="checkbox"
1444 <?php
1445 echo 'mainwp-child' === $plugin_directory ? 'disabled="disabled"' : 'class="mainwp-selected-plugin-site"';
1446 ?>
1447 ><label></label>
1448 </div>
1449 </div>
1450 <?php // phpcs:disable WordPress.Security.EscapeOutput ?>
1451 <div class="one wide center aligned middle aligned column"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); ?></div>
1452 <?php // phpcs:enable ?>
1453 <div class="two wide middle aligned column"><a class="open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>" target="_blank" ><?php echo esc_html( $plugin_title ); ?></a></div>
1454 <div class="two wide center aligned middle aligned column"><?php echo $plugin_status; //phpcs:ignore -- escaped. ?></div>
1455 <div class="two wide center aligned middle aligned column"><?php echo $trusted ? '<span class="ui tiny green label"><i class="locks icon"></i> ' . esc_html__( 'Trusted', 'mainwp' ) . '</span>' : '<span class="ui tiny red label"><i class="lock open icon"></i> ' . esc_html__( 'Not Trusted', 'mainwp' ) . '</span>'; ?></div>
1456 <div class="one wide center aligned middle aligned column"><?php echo $plugin_mu ? '<span class="ui small label"><i class="exclamation orange triangle icon"></i> MU</span>' : ''; ?></div>
1457 <div class="two wide left aligned middle aligned column current-version">
1458 <span class="ui small text">
1459 <?php echo esc_html( $plugin_version ); ?>
1460 <?php if ( ! empty( $new_version ) ) : ?>
1461 &rarr;
1462 <?php
1463 if ( ! empty( $roll_list[ $site_id ][ $plugin_slug ][ $new_version ] ) ) {
1464 echo MainWP_Updates_Helper::get_roll_msg( $roll_list[ $site_id ][ $plugin_slug ][ $new_version ], true, 'notice' ); //phpcs:ignore -- NOSONAR -- ok.
1465 }
1466 echo esc_html( $new_version );
1467 ?>
1468 <?php endif; ?>
1469 </span>
1470 </div>
1471
1472
1473
1474
1475 <div class="one wide right aligned middle aligned column update-column" updated="0">
1476 <?php if ( ! empty( $upgradeInfo ) && MainWP_Updates::user_can_update_plugins() ) : ?>
1477 <span data-position="top right" data-tooltip="<?php echo esc_attr__( 'Update ', 'mainwp' ) . esc_html( $plugin_title ) . ' ' . esc_attr__( 'plugin on this child site.', 'mainwp' ); ?>" data-inverted=""><a href="javascript:void(0)" class="ui mini green basic button <?php echo $is_demo ? 'disabled' : ''; ?>" onClick="return manage_plugins_upgrade( '<?php echo esc_js( rawurlencode( $plugin_slug ) ); ?>', <?php echo esc_attr( $site_id ); ?> )"><?php esc_html_e( 'Update', 'mainwp' ); ?></a></span>
1478 <?php endif; ?>
1479 </div>
1480 <div class="one wide center aligned middle aligned column"><a href="#" history-view="manage-plugins-per-sites" data-tooltip="<?php esc_attr_e( 'View history', 'mainwp' ); ?>" data-inverted="" data-possition="center left" class="mainwp-show-history ui mini basic grey icon button"><i class="history icon"></i></a></div>
1481 <div class="two wide center aligned middle aligned column column-actions">
1482 <div class="ui mini fluid buttons">
1483
1484 <?php if ( ! $child_plugin ) : ?>
1485 <?php if ( $actived ) { ?>
1486 <?php if ( ! $plugin_mu && \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) { ?>
1487 <a href="#" class="mainwp-manage-plugin-deactivate ui button" data-position="top right" data-tooltip="<?php echo esc_attr__( 'Deactivate ', 'mainwp' ) . esc_html( $plugin_title ) . ' ' . esc_attr__( 'plugin on this child site.', 'mainwp' ); ?>" data-inverted=""><?php esc_html_e( 'Deactivate', 'mainwp' ); ?></a>
1488 <?php } ?>
1489 <?php } else { ?>
1490 <?php if ( \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) { ?>
1491 <?php
1492 if ( $compatible_php && $compatible_wp ) {
1493 ?>
1494 <a href="#" class="mainwp-manage-plugin-activate ui green button" data-position="top right" data-tooltip="<?php echo esc_attr__( 'Activate ', 'mainwp' ) . esc_html( wp_strip_all_tags( $plugin_title ) ) . ' ' . esc_attr__( 'plugin on this child site.', 'mainwp' ); ?>" data-inverted=""><?php esc_html_e( 'Activate', 'mainwp' ); ?></a>
1495 <?php
1496 } else {
1497 static::render_incompatible_active( $compatible_php, $compatible_wp );
1498 ?>
1499 <?php } ?>
1500 <?php } ?>
1501 <?php } ?>
1502 <?php if ( ! $plugin_mu && \mainwp_current_user_can( 'dashboard', 'delete_plugins' ) ) { ?>
1503 <a href="#" class="mainwp-manage-plugin-delete ui button" data-position="top right" data-tooltip="<?php echo esc_attr__( 'Delete ', 'mainwp' ) . ' ' . esc_html( wp_strip_all_tags( $plugin_title ) ) . ' ' . esc_attr__( 'plugin from this child site.', 'mainwp' ); ?>" data-inverted=""><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1504 <?php } ?>
1505 <?php endif; ?>
1506 </div>
1507 </div>
1508 </div>
1509 <?php
1510
1511 }
1512 endforeach;
1513 ?>
1514 </div>
1515 </div>
1516 <?php endforeach; ?>
1517 </div>
1518
1519 <script type="text/javascript">
1520 jQuery(document).ready(function ($) {
1521 $( '.mainwp-manage-plugin-accordion' ).accordion( {
1522 "selector": {
1523 "trigger" : '.dropdown-trigger',
1524 }
1525 } );
1526 });
1527
1528 jQuery( '.trigger-all-accordion' ).on( 'click', function() { // not use document here.
1529 if ( jQuery( this ).hasClass( 'active' ) ) {
1530 jQuery( this ).removeClass( 'active' );
1531 jQuery( '.mainwp-manage-plugins-wrapper .ui.accordion div.title' ).each( function( i ) {
1532 if ( jQuery( this ).hasClass( 'active' ) ) {
1533 jQuery( this ).find('.dropdown-trigger').trigger( 'click' );
1534 }
1535 } );
1536 } else {
1537 jQuery( this ).addClass( 'active' );
1538 jQuery( '.mainwp-manage-plugins-wrapper .ui.accordion div.title' ).each( function( i ) {
1539 if ( !jQuery( this ).hasClass( 'active' ) ) {
1540 jQuery( this ).find('.dropdown-trigger').trigger( 'click' );
1541 }
1542 } );
1543 }
1544 return false;
1545 } );
1546
1547 jQuery(function($) {
1548 mainwp_master_checkbox_init($);
1549 mainwp_get_icon_start();
1550 mainwp_show_hide_install_to_selected_sites( 'plugin' );
1551 } );
1552
1553 </script>
1554
1555 <?php
1556 /**
1557 * Action: mainwp_after_plugins_table
1558 *
1559 * Fires after the Plugins table.
1560 *
1561 * @since 4.1
1562 */
1563 do_action( 'mainwp_after_plugins_table' );
1564 }
1565
1566
1567
1568 /**
1569 * Method render_manage_table()
1570 *
1571 * Render Manage Plugins Table.
1572 *
1573 * @param array $sites Child Sites array.
1574 * @param array $pluginsSlug Plugins slug array.
1575 * @param array $sitePlugins Site plugins array.
1576 * @param array $pluginsMainWP MainWP plugins array.
1577 * @param array $muPlugins Must use plugins array.
1578 * @param array $pluginsName Plugin names array.
1579 * @param array $pluginsNameSites Plugin names with Sites array.
1580 * @param array $pluginsRealVersion Latest plugin release version.
1581 * @param array $roll_list rool items list.
1582 */
1583 public static function render_manage_table( $sites, $pluginsSlug, $sitePlugins, $pluginsMainWP, $muPlugins, $pluginsName, $pluginsNameSites, $pluginsRealVersion, $roll_list = array() ) { //phpcs:ignore -- NOSONAR - complex method.
1584
1585 $userExtension = MainWP_DB_Common::instance()->get_user_extension();
1586 $decodedIgnoredPlugins = json_decode( $userExtension->ignored_plugins, true );
1587 $trustedPlugins = json_decode( $userExtension->trusted_plugins, true );
1588 $is_demo = MainWP_Demo_Handle::is_demo_mode();
1589
1590 if ( ! is_array( $trustedPlugins ) ) {
1591 $trustedPlugins = array();
1592 }
1593
1594 $updateWebsites = array();
1595
1596 foreach ( $sites as $site_id => $info ) {
1597
1598 $plugin_upgrades = array();
1599 $website = MainWP_DB::instance()->get_website_by_id( $site_id );
1600 if ( $website && ! $website->is_ignorePluginUpdates ) {
1601 $plugin_upgrades = json_decode( $website->plugin_upgrades, true );
1602 if ( ! is_array( $plugin_upgrades ) ) {
1603 $plugin_upgrades = array();
1604 }
1605 $decodedPremiumUpgrades = MainWP_DB::instance()->get_website_option( $website, 'premium_upgrades' );
1606 $decodedPremiumUpgrades = ! empty( $decodedPremiumUpgrades ) ? json_decode( $decodedPremiumUpgrades, true ) : array();
1607 if ( is_array( $decodedPremiumUpgrades ) ) {
1608 foreach ( $decodedPremiumUpgrades as $crrSlug => $premiumUpgrade ) {
1609 $premiumUpgrade['premium'] = true;
1610 if ( 'plugin' === $premiumUpgrade['type'] ) {
1611 $premiumUpgrade = array_filter( $premiumUpgrade );
1612
1613 if ( ! isset( $plugin_upgrades[ $crrSlug ] ) ) {
1614 continue;
1615 }
1616 $plugin_upgrades[ $crrSlug ] = array_merge( $plugin_upgrades[ $crrSlug ], $premiumUpgrade );
1617 }
1618 }
1619 }
1620 $ignored_plugins = json_decode( $website->ignored_plugins, true );
1621 if ( is_array( $ignored_plugins ) ) {
1622 $plugin_upgrades = MainWP_Common_Functions::instance()->get_not_ignored_updates_themesplugins( $plugin_upgrades, $ignored_plugins );
1623
1624 }
1625
1626 if ( is_array( $decodedIgnoredPlugins ) ) {
1627 $plugin_upgrades = MainWP_Common_Functions::instance()->get_not_ignored_updates_themesplugins( $plugin_upgrades, $decodedIgnoredPlugins );
1628 }
1629 }
1630 $updateWebsites[ $site_id ] = $plugin_upgrades;
1631 }
1632
1633 /**
1634 * Action: mainwp_before_plugins_table
1635 *
1636 * Fires before the Plugins table.
1637 *
1638 * @since 4.1
1639 */
1640 do_action( 'mainwp_before_plugins_table' );
1641 ?>
1642
1643 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-plugins-bulk-actions-tip' ) ) : ?>
1644 <div class="ui message">
1645 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-plugins-bulk-actions-tip"></i>
1646 <div><em data-emoji=":bulb:" class="small"></em> <?php esc_html_e( 'Tip: Use Bulk Actions to activate, deactivate, or delete selected plugins.', 'mainwp' ); ?></div>
1647 </div>
1648 <?php endif; ?>
1649
1650 <div class="ui secondary segment main-master-checkbox">
1651 <div class="ui stackable grid">
1652 <div class="one wide left aligned middle aligned column">
1653 <span class="trigger-all-accordion"><span class="trigger-handle-arrow"><i class="caret right icon"></i><i class="caret down icon"></i></span></span>
1654 </div>
1655 <div class="one wide center aligned middle aligned column"><div class="ui checkbox main-master not-auto-init"><input type="checkbox"/><label></label></div></div>
1656 <div class="one wide center aligned middle aligned column"></div>
1657 <div class="five wide middle aligned column"><?php esc_html_e( 'Plugin', 'mainwp' ); ?></div>
1658 <div class="two wide center aligned middle aligned column"></div>
1659 <div class="two wide right aligned middle aligned column"><?php esc_html_e( 'Latest Version', 'mainwp' ); ?></div>
1660 <div class="two wide center aligned middle aligned column"></div>
1661 <div class="two wide right aligned middle aligned column"><?php esc_html_e( 'Websites', 'mainwp' ); ?></div>
1662 </div>
1663 </div>
1664
1665 <div class="mainwp-manage-plugins-wrapper main-child-checkbox">
1666 <?php foreach ( $pluginsNameSites as $plugin_title => $pluginSites ) : ?>
1667 <?php
1668 $slugVersions = current( $pluginSites );
1669 $slug_ver_first = $slugVersions[0]; // get the first one [slug]_[version] to get plugin [slug].
1670 $plugin_slug_first = $pluginsSlug[ $slug_ver_first ];
1671 $plugin_directory = MainWP_Utility::get_dir_slug( $plugin_slug_first );
1672
1673 $plugin_status = '';
1674
1675 $item_id = strtolower( $plugin_title );
1676 $item_id = preg_replace( '/[[:space:]]+/', '_', $item_id );
1677
1678 $count_sites = count( $pluginSites );
1679
1680 reset( $pluginSites );
1681 $first_siteid = key( $pluginSites );
1682
1683 $details_link = self_admin_url( 'plugin-install.php?tab=plugin-information&wpplugin=' . intval( $first_siteid ) . '&plugin=' . rawurlencode( $plugin_directory ) . '&section=changelog' );
1684 $lastest_version = '';
1685 // phpcs:disable WordPress.Security.EscapeOutput
1686 ?>
1687 <div class="ui accordion mainwp-manage-plugin-accordion mainwp-manage-plugin-item main-child-checkbox" id="<?php echo esc_html( $item_id ); ?>">
1688 <div class="title master-checkbox">
1689 <div class="ui grid">
1690 <div class="one wide left aligned middle aligned column"><i class="dropdown icon dropdown-trigger"></i></div>
1691 <div class="one wide center aligned middle aligned column">
1692 <div class="ui checkbox <?php echo 'mainwp-child' === $plugin_directory ? 'disabled' : ''; ?> master"><input type="checkbox" <?php echo 'mainwp-child' === $plugin_directory ? 'disabled="disabled"' : ''; ?>><label></label></div>
1693 </div>
1694 <div class="one wide center aligned middle aligned column"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); // phpcs:ignore WordPress.Security.EscapeOutput ?></div>
1695 <div class="five wide middle aligned column"><a class="open-plugin-details-modal" href="<?php echo esc_url( $details_link ); ?>" target="_blank" ><?php echo esc_html( $plugin_title ); ?></a></div>
1696 <div class="two wide center aligned middle aligned column"></div>
1697 <div class="two wide right aligned middle aligned column lastest-version-info"></div>
1698 <div class="two wide center aligned middle aligned column"></div>
1699 <div class="two wide right aligned middle aligned column"><div class="ui label"><?php echo intval( $count_sites ) . ' ' . esc_html( _n( 'Site', 'Sites', intval( $count_sites ), 'mainwp' ) ); ?></div></div>
1700 </div>
1701 </div>
1702 <div class="content child-checkbox">
1703 <?php
1704 // phpcs:enable
1705 foreach ( $pluginSites as $site_id => $slugVersions ) :
1706 $site_name = $sites[ $site_id ]['websitename'];
1707 $site_url = $sites[ $site_id ]['websiteurl'];
1708
1709 $wp_info = ! empty( $sites[ $site_id ]['site_info'] ) ? json_decode( $sites[ $site_id ]['site_info'], true ) : array();
1710 if ( ! is_array( $wp_info ) ) {
1711 $wp_info = array();
1712 }
1713 $use_tzformat = ! empty( $wp_info['format_datetime'] ) && is_array( $wp_info['format_datetime'] ) ? $wp_info['format_datetime'] : array();
1714 $offs = ! empty( $use_tzformat['gmt_offset'] ) ? intval( $use_tzformat['gmt_offset'] ) : 0;
1715 $offs_info = esc_html__( '- Timezone:', 'mainwp' ) . ' UTC' . ( $offs >= 0 ? '+' . $offs : $offs );
1716
1717 foreach ( $slugVersions as $slug_ver ) :
1718
1719 $plugin_slug = $pluginsSlug[ $slug_ver ];
1720 $trusted = in_array( $plugin_slug, $trustedPlugins ) ? true : false;
1721 $child_plugin = ( isset( $pluginsMainWP[ $slug_ver ] ) && 'T' === $pluginsMainWP[ $slug_ver ] ) ? true : false;
1722
1723 $plugin_mu = false;
1724
1725 $plugin_version = $sitePlugins[ $site_id ][ $slug_ver ]['version'];
1726
1727 $plugin_upgrades = isset( $updateWebsites[ $site_id ] ) ? $updateWebsites[ $site_id ] : array();
1728 if ( ! is_array( $plugin_upgrades ) ) {
1729 $plugin_upgrades = array();
1730 }
1731
1732 $upgradeInfo = isset( $plugin_upgrades[ $plugin_slug ] ) ? $plugin_upgrades[ $plugin_slug ] : false;
1733
1734 $new_version = '';
1735 if ( ! empty( $upgradeInfo ) && isset( $upgradeInfo['update']['new_version'] ) ) {
1736 $new_version = $upgradeInfo['update']['new_version'];
1737 }
1738
1739 if ( '' === $lastest_version || version_compare( $plugin_version, $lastest_version, '>' ) ) {
1740 $lastest_version = $plugin_version;
1741 }
1742
1743 if ( '' !== $new_version && version_compare( $new_version, $lastest_version, '>' ) ) {
1744 $lastest_version = $new_version;
1745 }
1746
1747 if ( isset( $sitePlugins[ $site_id ][ $slug_ver ] ) && ( 0 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] || 1 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) ) {
1748 $actived = true;
1749 if ( isset( $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) && 1 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) {
1750 $plugin_status = '<span class="ui tiny grey label"><i class="circle green icon"></i> ' . esc_html__( 'Active', 'mainwp' ) . '</span>';
1751 } elseif ( isset( $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) && 0 === (int) $sitePlugins[ $site_id ][ $slug_ver ]['active'] ) {
1752 $plugin_status = '<span class="ui tiny grey label"><i class="circle red icon"></i> ' . esc_html__( 'Inactive', 'mainwp' ) . '</span>';
1753 $actived = false;
1754 } else {
1755 $plugin_status = '';
1756 }
1757
1758 if ( isset( $sitePlugins[ $site_id ][ $slug_ver ] ) && ( 1 === (int) $muPlugins[ $slug_ver ] ) ) {
1759 $plugin_mu = true;
1760 }
1761 if ( $plugin_mu ) {
1762 $actived = true; // always.
1763 }
1764 $item_id = $slug_ver . '_' . $site_id;
1765 $item_id = strtolower( $item_id );
1766 $item_id = preg_replace( '/[[:space:]]+/', '_', $item_id );
1767
1768 $el_id_ite_2 = $item_id;
1769
1770 $compatible_php = isset( $upgradeInfo['wp_compatible'] ) ? $upgradeInfo['wp_compatible'] : true;
1771 $compatible_wp = isset( $upgradeInfo['php_compatible'] ) ? $upgradeInfo['php_compatible'] : true;
1772
1773 ?>
1774 <div class="ui stackable grid very compact mainwp-manage-plugin-item-website" plugin-slug="<?php echo esc_attr( rawurlencode( $plugin_slug ) ); ?>" plugin-name="<?php echo esc_html( wp_strip_all_tags( $pluginsName[ $slug_ver ] ) ); ?>" site-id="<?php echo intval( $site_id ); ?>" site-name="<?php echo esc_attr( $site_name ); ?>" site-url="<?php echo esc_attr( $site_url ); ?>" tz-info="<?php echo esc_attr( $offs_info ); ?>" id="<?php echo esc_html( $el_id_ite_2 ); ?>">
1775 <div class="one wide left aligned middle aligned column"></div>
1776 <div class="one wide center aligned middle aligned column">
1777 <?php if ( $child_plugin ) : ?>
1778 <div class="ui disabled checkbox"><input type="checkbox" disabled="disabled"><label></label></div>
1779 <?php else : ?>
1780 <div class="ui checkbox child">
1781 <input type="checkbox" class="mainwp-selected-plugin-site" />
1782 <label></label>
1783 </div>
1784 <?php endif; ?>
1785 </div>
1786
1787 <div class="two wide middle aligned column"><a target="_blank" href="<?php MainWP_Site_Open::get_open_site_admin_link( $site_id, true ); //phpcs:ignore -- ok. ?>"><i class="sign in icon"></i></a> <a href="admin.php?page=managesites&dashboard=<?php echo intval( $site_id ); ?>"><?php echo esc_html( $site_name ); ?></a></div>
1788
1789 <div class="two wide center aligned middle aligned column"><?php echo $plugin_status; //phpcs:ignore -- escaped. ?></div>
1790
1791 <div class="two wide center aligned middle aligned column"><?php echo $trusted ? '<span class="ui tiny green label"><i class="lock icon"></i> ' . esc_html__( 'Trusted', 'mainwp' ) . '</span>' : '<span class="ui tiny red label"><i class="lock open icon"></i> ' . esc_html__( 'Not Trusted', 'mainwp' ) . '</span>'; ?></div>
1792
1793 <div class="one wide center aligned middle aligned column"><?php echo $plugin_mu ? '<span class="ui small label"><i class="exclamation orange triangle icon"></i> MU</span>' : ''; ?></div>
1794
1795 <div class="two wide center aligned middle aligned column current-version">
1796 <span class="ui small text">
1797 <?php echo esc_html( $plugin_version ); ?>
1798 <?php if ( ! empty( $new_version ) ) : ?>
1799 &rarr;
1800 <?php
1801 if ( ! empty( $roll_list[ $site_id ][ $plugin_slug ][ $new_version ] ) ) {
1802 echo MainWP_Updates_Helper::get_roll_msg( $roll_list[ $site_id ][ $plugin_slug ][ $new_version ], true, 'notice' ); //phpcs:ignore -- NOSONAR -- ok.
1803 }
1804 echo esc_html( $new_version );
1805 ?>
1806 <?php endif; ?>
1807 </span>
1808 </div>
1809
1810 <div class="two wide right aligned middle aligned column update-column" updated="0">
1811 <?php if ( ! empty( $upgradeInfo ) && MainWP_Updates::user_can_update_plugins() ) : ?>
1812 <span data-position="top right" data-tooltip="<?php echo esc_attr__( 'Update ', 'mainwp' ) . esc_html( $plugin_title ) . ' ' . esc_attr__( 'plugin on this child site.', 'mainwp' ); ?>" data-inverted="" ><a href="javascript:void(0)" class="ui mini green basic button <?php echo $is_demo ? 'disabled' : ''; ?>" onClick="return manage_plugins_upgrade( '<?php echo esc_js( rawurlencode( $plugin_slug ) ); ?>', <?php echo esc_attr( $site_id ); ?> )"><?php esc_html_e( 'Update', 'mainwp' ); ?></a></span>
1813 <?php endif; ?>
1814 </div>
1815
1816 <div class="one wide middle aligned center aligned column"><a href="#" history-view="manage-plugins-per-items" data-tooltip="<?php esc_attr_e( 'View history', 'mainwp' ); ?>" data-inverted="" data-possition="center left" class="mainwp-show-history ui mini icon basic grey button"><i class="history icon"></i></a></div>
1817
1818 <div class="two wide center aligned middle aligned column column-actions">
1819 <div class="ui mini fluid buttons">
1820 <?php if ( ! $child_plugin ) : ?>
1821 <?php if ( $actived ) { ?>
1822 <?php if ( ! $plugin_mu && \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) { ?>
1823 <a href="#" class="mainwp-manage-plugin-deactivate ui button <?php echo $is_demo ? 'disabled' : ''; ?>"><?php esc_html_e( 'Deactivate', 'mainwp' ); ?></a>
1824 <?php } ?>
1825 <?php } else { ?>
1826 <?php if ( \mainwp_current_user_can( 'dashboard', 'activate_deactivate_plugins' ) ) { ?>
1827 <?php
1828 if ( $compatible_php && $compatible_wp ) {
1829 ?>
1830 <a href="#" class="mainwp-manage-plugin-activate ui green button <?php echo $is_demo ? 'disabled' : ''; ?>" ><?php esc_html_e( 'Activate', 'mainwp' ); ?></a>
1831 <?php
1832 } else {
1833 static::render_incompatible_active( $compatible_php, $compatible_wp );
1834 ?>
1835 <?php } ?>
1836
1837 <?php } ?>
1838 <?php } ?>
1839 <?php if ( ! $plugin_mu && \mainwp_current_user_can( 'dashboard', 'delete_plugins' ) ) { ?>
1840 <a href="#" class="mainwp-manage-plugin-delete ui button <?php echo $is_demo ? 'disabled' : ''; ?>" data-position="top right" data-tooltip="<?php echo esc_attr__( 'Delete ', 'mainwp' ) . ' ' . esc_html( wp_strip_all_tags( $plugin_title ) ) . ' ' . esc_attr__( 'plugin from this child site.', 'mainwp' ); ?>" data-inverted=""><?php esc_html_e( 'Delete', 'mainwp' ); ?></a>
1841 <?php } ?>
1842 <?php endif; ?>
1843 </div>
1844 </div>
1845 </div>
1846 <?php
1847 }
1848 endforeach;
1849 ?>
1850 <span style="display:none" class="lastest-version-hidden" lastest-version="<?php echo esc_html( $lastest_version ); ?>"></span>
1851 <?php
1852 endforeach;
1853 ?>
1854 </div>
1855 </div>
1856 <?php endforeach; ?>
1857 </div>
1858
1859 <script type="text/javascript">
1860 jQuery(document).ready(function ($) {
1861 $( '.mainwp-manage-plugin-accordion' ).accordion( {
1862 "selector": {
1863 "trigger" : '.dropdown-trigger',
1864 }
1865 } );
1866 } );
1867
1868 jQuery( '.trigger-all-accordion' ).on( 'click', function() { // not use document here.
1869 if ( jQuery( this ).hasClass( 'active' ) ) {
1870 jQuery( this ).removeClass( 'active' );
1871 jQuery( '.mainwp-manage-plugins-wrapper .ui.accordion div.title' ).each( function( i ) {
1872 if ( jQuery( this ).hasClass( 'active' ) ) {
1873 jQuery( this ).find('.dropdown-trigger').trigger( 'click' );
1874 }
1875 } );
1876 } else {
1877 jQuery( this ).addClass( 'active' );
1878 jQuery( '.mainwp-manage-plugins-wrapper .ui.accordion div.title' ).each( function( i ) {
1879 if ( !jQuery( this ).hasClass( 'active' ) ) {
1880 jQuery( this ).find('.dropdown-trigger').trigger( 'click' );
1881 }
1882 } );
1883 }
1884 return false;
1885 } );
1886
1887
1888
1889 jQuery(function($) {
1890 $( '.lastest-version-hidden' ).each(function(){
1891 $(this).closest('.mainwp-manage-plugin-item').find('.lastest-version-info').html( $(this).attr('lastest-version') );
1892 });
1893 mainwp_master_checkbox_init($);
1894 mainwp_get_icon_start();
1895 mainwp_show_hide_install_to_selected_sites( 'plugin' );
1896 } );
1897
1898 </script>
1899
1900 <?php
1901 /**
1902 * Action: mainwp_after_plugins_table
1903 *
1904 * Fires after the Plugins table.
1905 *
1906 * @since 4.1
1907 */
1908 do_action( 'mainwp_after_plugins_table' );
1909 }
1910
1911 /**
1912 * Method render_incompatible_active().
1913 *
1914 * @param mixed $compatible_php Compatible php.
1915 * @param mixed $compatible_wp Compatible wp. *
1916 * @param mixed $echo_content Print content or not.
1917 *
1918 * @return string Message
1919 */
1920 public static function render_incompatible_active( $compatible_php, $compatible_wp, $echo_content = true ) {
1921 $msg = MainWP_Updates_Per_Item::get_incompatible_message( $compatible_php, $compatible_wp );
1922 if ( ! empty( $msg ) ) {
1923 $html = '<span class="ui button basic disabled" data-tooltip="' . esc_attr( $msg ) . '" data-position="left center" data-inverted="">' . esc_html__( 'Cannot Activate', 'mainwp' ) . '</span>';
1924 if ( $echo_content ) {
1925 echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1926 } else {
1927 return $html;
1928 }
1929 }
1930 return '';
1931 }
1932
1933
1934 /** Render Install Subpage. */
1935 public static function render_install() {
1936 static::render_header( 'Install' );
1937 static::render_plugins_table();
1938 static::render_footer( 'Install' );
1939 }
1940
1941
1942 /**
1943 * Render Install plugins Table.
1944 *
1945 * @uses \MainWP\Dashboard\MainWP_UI::render_modal_install_plugin_theme()
1946 *
1947 * @uses \MainWP\Dashboard\MainWP_Install_Bulk::render_upload()
1948 */
1949 public static function render_plugins_table() {
1950
1951 /**
1952 * Tab array.
1953 *
1954 * @global object
1955 */
1956 global $tab;
1957
1958 if ( ! \mainwp_current_user_can( 'dashboard', 'install_plugins' ) ) {
1959 \mainwp_do_not_have_permissions( esc_html__( 'install plugins', 'mainwp' ) );
1960 return;
1961 }
1962 ?>
1963
1964 <div class="ui alt segment" id="mainwp-install-plugins">
1965 <div class="mainwp-main-content">
1966 <div class="mainwp-actions-bar">
1967 <div class="ui stackable two column grid">
1968
1969 <div class="middle aligned column">
1970 <div class="ui mini stackable buttons">
1971 <a href="#" id="MainWPInstallBulkNavSearch" class="ui basic green button mainwp-bulk-install-tabs-header-btn" ><?php esc_html_e( 'Install from WordPress.org', 'mainwp' ); ?></a>
1972 <a href="#" id="MainWPInstallBulkNavUpload" class="ui basic button mainwp-bulk-install-tabs-header-btn" ><?php esc_html_e( 'Upload .zip file', 'mainwp' ); ?></a>
1973 <?php do_action( 'mainwp_install_plugin_theme_tabs_header_top', 'plugin' ); ?>
1974 </div>
1975 <?php
1976 /**
1977 * Install Plugins actions bar (right)
1978 *
1979 * Fires at the left side of the actions bar on the Install Plugins screen, after the Nav buttons.
1980 *
1981 * @since 4.0
1982 */
1983 do_action( 'mainwp_install_plugins_actions_bar_right' );
1984 ?>
1985 </div>
1986
1987 <div class="right aligned column">
1988 <div id="mainwp-search-plugins-form" class="ui search focus mainwp-bulk-install-showhide-content">
1989 <div class="ui icon mini input">
1990 <input id="mainwp-search-plugins-form-field" class="prompt" type="text" placeholder="<?php esc_attr_e( 'Search plugins...', 'mainwp' ); ?>" value="<?php echo isset( $_GET['s'] ) ? esc_html( sanitize_text_field( wp_unslash( $_GET['s'] ) ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized ?>">
1991 <i class="search icon"></i>
1992 <i class="remove icon"></i>
1993 </div>
1994 <div class="results"></div>
1995 </div>
1996 <script type="text/javascript">
1997 jQuery( document ).ready(function () {
1998 jQuery( '#mainwp-search-plugins-form-field' ).on( 'keypress', function(e) {
1999 let search = jQuery( '#mainwp-search-plugins-form-field' ).val();
2000 let sel_ids = jQuery( '#plugin_install_selected_sites' ).val();
2001 if ( '' != sel_ids )
2002 sel_ids = '&selected_sites=' + sel_ids;
2003 if ( 13 === e.which ) {
2004 location.href = 'admin.php?page=PluginsInstall&tab=search&s=' + encodeURIComponent(search) + sel_ids;
2005 }
2006 } );
2007 jQuery( '#mainwp-search-plugins-form .remove.icon' ).on( 'click', function(e) {
2008 location.href = 'admin.php?page=PluginsInstall';
2009 } );
2010 } );
2011 </script>
2012 <?php
2013 /**
2014 * Install Plugins actions bar (left)
2015 *
2016 * Fires at the left side of the actions bar on the Install Plugins screen, after the Search bar.
2017 *
2018 * @since 4.0
2019 */
2020 do_action( 'mainwp_install_plugins_actions_bar_left' );
2021 ?>
2022 </div>
2023
2024 </div>
2025 </div>
2026
2027
2028 <div class="ui padded segment">
2029 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-install-plugins-info-message' ) ) : ?>
2030 <div class="ui info message">
2031 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-install-plugins-info-message"></i>
2032 <div class="header"><?php esc_html_e( 'Install plugins on your child sites', 'mainwp' ); ?></div>
2033 <?php
2034 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
2035 printf( esc_html__( 'You can install plugins from the WordPress.org repository or by uploading a ZIP file. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp#install-plugins" target="_blank">', '</a> <i class="external alternate icon"></i>' );
2036 ?>
2037 </div>
2038 <?php endif; ?>
2039 <div id="mainwp-message-zone" class="ui message" style="display:none;"></div>
2040 <div class="mainwp-upload-plugin mainwp-bulk-install-showhide-content" style="display:none;">
2041 <?php MainWP_Install_Bulk::render_upload( 'plugin' ); ?>
2042 </div>
2043 <div class="mainwp-browse-plugins mainwp-bulk-install-showhide-content">
2044 <form id="plugin-filter" method="post">
2045 <?php MainWP_UI::generate_wp_nonce( 'mainwp-admin-nonce' ); ?>
2046 <?php static::$pluginsTable->display(); ?>
2047 </form>
2048 </div>
2049 <?php
2050 // @since 5.4.
2051 do_action( 'mainwp_bulk_install_tabs_content', 'plugin' );
2052
2053 MainWP_UI::render_modal_install_plugin_theme();
2054 MainWP_Updates::render_plugin_details_modal();
2055 ?>
2056 </div>
2057 </div>
2058 <?php
2059 $selected_sites = array();
2060
2061 if ( isset( $_GET['selected_sites'] ) && ! empty( $_GET['selected_sites'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2062 $selected_sites = explode( '-', sanitize_text_field( wp_unslash( $_GET['selected_sites'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitize ok.
2063 $selected_sites = array_map( 'intval', $selected_sites );
2064 $selected_sites = array_filter( $selected_sites );
2065 }
2066 ?>
2067 <div class="mainwp-side-content mainwp-no-padding">
2068 <?php do_action( 'mainwp_manage_plugins_sidebar_top' ); ?>
2069 <div class="mainwp-select-sites ui accordion mainwp-sidebar-accordion">
2070 <?php do_action( 'mainwp_manage_plugins_before_select_sites' ); ?>
2071 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Select Sites', 'mainwp' ); ?></div>
2072 <div class="content active">
2073 <?php
2074 $sel_params = array(
2075 'class' => 'mainwp_select_sites_box_left',
2076 'selected_sites' => $selected_sites,
2077 'show_client' => true,
2078 );
2079 MainWP_UI_Select_Sites::select_sites_box( $sel_params );
2080 ?>
2081 </div>
2082 <?php do_action( 'mainwp_manage_plugins_after_select_sites' ); ?>
2083 </div>
2084 <input type="hidden" id="plugin_install_selected_sites" name="plugin_install_selected_sites" value="<?php echo esc_html( implode( '-', $selected_sites ) ); ?>" />
2085 <div class="ui fitted divider"></div>
2086 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
2087 <?php do_action( 'mainwp_manage_plugins_before_search_options' ); ?>
2088 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Installation Options', 'mainwp' ); ?></div>
2089 <div class="content active">
2090 <div class="ui form">
2091 <div class="field">
2092 <label><?php esc_html_e( 'Activate after installation', 'mainwp' ); ?></label>
2093 <div class="ui toggle checkbox">
2094 <input type="checkbox" value="1" checked="checked" id="chk_activate_plugin" />
2095 <label for="chk_activate_plugin"></label>
2096 </div>
2097 <br />
2098 <span class="ui small grey text"><?php esc_html_e( 'If enabled, the plugin will be automatically activated after the installation.', 'mainwp' ); ?></span>
2099 </div>
2100 <div class="field">
2101 <label><?php esc_html_e( 'Overwrite existing version', 'mainwp' ); ?></label>
2102 <div class="ui toggle checkbox">
2103 <input type="checkbox" value="2" checked="checked" id="chk_overwrite" />
2104 <label for="chk_overwrite"></label>
2105 </div>
2106 <br />
2107 <span class="ui small grey text"><?php esc_html_e( 'If enabled and the plugin already installed on the sites, the already installed version will be overwritten.', 'mainwp' ); ?></span>
2108 </div>
2109 </div>
2110 </div>
2111 <?php do_action( 'mainwp_manage_plugins_after_search_options' ); ?>
2112 </div>
2113 <div class="ui fitted divider"></div>
2114 <div class="mainwp-search-submit">
2115 <?php do_action( 'mainwp_manage_plugins_before_submit_button' ); ?>
2116 <?php
2117 /**
2118 * Disables plugin installation
2119 *
2120 * Filters whether file modifications are allowed on the Dashboard site. If not, installation process will be disabled too.
2121 *
2122 * @since 4.1
2123 */
2124 $allow_install = apply_filters( 'file_mod_allowed', true, 'mainwp_install_plugin' );
2125 if ( $allow_install ) {
2126 ?>
2127 <input type="button" value="<?php esc_attr_e( 'Complete Installation', 'mainwp' ); ?>" class="ui green big fluid button" id="mainwp_plugin_bulk_install_btn" bulk-action="install" name="bulk-install">
2128 <?php
2129 }
2130 ?>
2131 <?php do_action( 'mainwp_manage_plugins_before_submit_button' ); ?>
2132 <?php
2133 // @since 5.4.
2134 do_action( 'mainwp_bulk_install_sidebar_submit_bottom', 'plugin' );
2135 ?>
2136 </div>
2137 <?php do_action( 'mainwp_manage_plugins_sidebar_bottom', 'install' ); ?>
2138 </div>
2139 <div class="ui clearing hidden divider"></div>
2140 </div>
2141 <script>
2142 jQuery( document ).ready( function () {
2143 mainwp_init_button_site_selection_dependency( 'mainwp_plugin_bulk_install_btn' );
2144 } );
2145 </script>
2146 <?php
2147 }
2148
2149 /**
2150 * Render Autoupdate SubPage.
2151 *
2152 * @uses \MainWP\Dashboard\MainWP_UI::render_modal_edit_notes()
2153 */
2154 public static function render_auto_update() { // phpcs:ignore -- NOSONAR -Current complexity is the only way to achieve desired results, pull request solutions appreciated.
2155
2156 $cachedAUSearch = isset( $_SESSION['MainWP_PluginsActiveStatus'] ) ? $_SESSION['MainWP_PluginsActiveStatus'] : null; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized --- ok.
2157
2158 static::render_header( 'AutoUpdate' );
2159
2160 if ( ! \mainwp_current_user_can( 'dashboard', 'trust_untrust_updates' ) ) {
2161 \mainwp_do_not_have_permissions( esc_html__( 'trust/untrust updates', 'mainwp' ) );
2162 } else {
2163 $snPluginAutomaticDailyUpdate = get_option( 'mainwp_pluginAutomaticDailyUpdate' );
2164
2165 if ( false === $snPluginAutomaticDailyUpdate ) {
2166 $snPluginAutomaticDailyUpdate = get_option( 'mainwp_automaticDailyUpdate' );
2167 update_option( 'mainwp_pluginAutomaticDailyUpdate', $snPluginAutomaticDailyUpdate );
2168 }
2169
2170 ?>
2171 <div class="ui alt segment" id="mainwp-plugin-auto-updates">
2172 <div class="mainwp-main-content">
2173 <div class="mainwp-actions-bar" <?php echo ! isset( $_SESSION['MainWP_PluginsActive'] ) ? 'style="display:none"' : ''; ?>>
2174 <div class="ui mini form stackable grid">
2175 <div class="ui two column row">
2176 <div class="left aligned column">
2177 <select id="mainwp-bulk-actions" name="bulk_action" class="ui mini selection dropdown">
2178 <option class="item" value=""><?php esc_html_e( 'Bulk Actions', 'mainwp' ); ?></option>
2179 <option class="item" value="trust">
2180 <?php esc_html_e( 'Mark as Trusted', 'mainwp' ); ?><br/>
2181 <span class="ui small grey text"><?php esc_html_e( 'Auto updated by your Dashboard', 'mainwp' ); ?></span>
2182 </option>
2183 <option class="item" value="untrust">
2184 <?php esc_html_e( 'Mark as Untrusted', 'mainwp' ); ?><br/>
2185 <span class="ui small grey text"><?php esc_html_e( 'Require manual updates', 'mainwp' ); ?></span>
2186 </option>
2187 <?php
2188 /**
2189 * Action: mainwp_plugins_auto_updates_bulk_action
2190 *
2191 * Adds new action to the bulk actions menu on Plugins Auto Updates.
2192 *
2193 * @since 4.1
2194 */
2195 do_action( 'mainwp_plugins_auto_updates_bulk_action' );
2196 ?>
2197 </select>
2198 <input type="button" name="" id="mainwp-bulk-trust-plugins-action-apply" class="ui mini basic button" value="<?php esc_attr_e( 'Apply', 'mainwp' ); ?>"/>
2199 </div>
2200 <div class="right aligned column"></div>
2201 </div>
2202 </div>
2203 </div>
2204
2205 <?php if ( isset( $_GET['message'] ) && 'saved' === $_GET['message'] ) : // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized ?>
2206 <div class="ui message green"><?php esc_html_e( 'Settings have been saved.', 'mainwp' ); ?></div>
2207 <?php endif; ?>
2208 <div id="mainwp-message-zone" class="ui message" style="display:none"></div>
2209 <div id="mainwp-auto-updates-plugins-content" class="ui padded segment">
2210 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-plugins-auto-updates-info-message' ) ) : ?>
2211 <div class="ui info message">
2212 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-plugins-auto-updates-info-message"></i>
2213 <div class="header"><?php esc_html_e( 'Automatically update only the plugins you trust!', 'mainwp' ); ?></div>
2214 <div><?php esc_html_e( 'The MainWP Advanced Auto Updates feature is a tool for your Dashboard to automatically update plugins that you trust to be updated without breaking your Child sites.', 'mainwp' ); ?></div>
2215 <div><?php esc_html_e( 'Only mark plugins as trusted if you are absolutely sure they can be automatically updated by your MainWP Dashboard without causing issues on the Child sites!', 'mainwp' ); ?></div>
2216 <div><strong><?php esc_html_e( 'Advanced Auto Updates a delayed approximately 24 hours from the update release. Ignored plugins can not be automatically updated.', 'mainwp' ); ?></strong></div>
2217 </div>
2218 <?php endif; ?>
2219 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-disable-auto-updates-info-message' ) ) : ?>
2220 <div class="ui message">
2221 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-disable-auto-updates-info-message"></i>
2222 <div><em data-emoji=":bulb:" class="small"></em> <?php
2223 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
2224 printf( esc_html__( 'Tip: Check out %1$show to disable the WordPress built in auto-updates feature%2$s.', 'mainwp' ), '<a href="https://mainwp.com/how-to-disable-automatic-plugin-and-theme-updates-on-your-child-sites/" target="_blank">', '</a>' ); // NOSONAR - noopener - open safe.
2225 ?></div>
2226 </div>
2227 <?php endif; ?>
2228 <div class="ui page dimmer">
2229 <div class="ui text double loader"><?php esc_html_e( 'Loading...', 'mainwp' ); ?></div>
2230 </div>
2231 <div id="mainwp-auto-updates-plugins-table-wrapper">
2232 <?php
2233 if ( isset( $_SESSION['MainWP_PluginsActive'] ) ) {
2234 static::render_all_active_table( $_SESSION['MainWP_PluginsActive'] ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2235 } else {
2236 MainWP_UI::render_empty_page_placeholder( __( 'No plugins loaded yet.', 'mainwp' ), __( 'Click Show Plugins button to view your installed plugins and manage their trust settings.', 'mainwp' ), '<em data-emoji=":compass:" class="big"></em>' );
2237 }
2238 ?>
2239 </div>
2240 </div>
2241 </div>
2242 <div class="mainwp-side-content mainwp-no-padding">
2243 <?php do_action( 'mainwp_manage_plugins_sidebar_top' ); ?>
2244 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
2245 <?php do_action( 'mainwp_manage_plugins_before_search_options' ); ?>
2246 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Plugin Status to Search', 'mainwp' ); ?></div>
2247 <div class="content active">
2248 <div class="ui mini form">
2249 <div class="field">
2250 <select class="ui fluid dropdown" id="mainwp_au_plugin_status">
2251 <option value="all" <?php echo ( null !== $cachedAUSearch && 'all' === $cachedAUSearch['plugin_status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Active and Inactive', 'mainwp' ); ?></option>
2252 <option value="active" <?php echo ( null !== $cachedAUSearch && 'active' === $cachedAUSearch['plugin_status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Active', 'mainwp' ); ?></option>
2253 <option value="inactive" <?php echo ( null !== $cachedAUSearch && 'inactive' === $cachedAUSearch['plugin_status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Inactive', 'mainwp' ); ?></option>
2254 </select>
2255 </div>
2256 </div>
2257 </div>
2258 <?php do_action( 'mainwp_manage_plugins_after_search_options' ); ?>
2259 </div>
2260 <div class="ui fitted divider"></div>
2261 <div class="mainwp-search-options ui accordion mainwp-sidebar-accordion">
2262 <div class="title active"><i class="dropdown icon"></i> <?php esc_html_e( 'Search Options', 'mainwp' ); ?></div>
2263 <div class="content active">
2264 <div class="ui mini form">
2265 <div class="field">
2266 <select class="ui fluid dropdown" id="mainwp_au_plugin_trust_status">
2267 <option value="all" <?php echo ( null !== $cachedAUSearch && 'all' === $cachedAUSearch['status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Trusted, Not trusted and Ignored', 'mainwp' ); ?></option>
2268 <option value="trust" <?php echo ( null !== $cachedAUSearch && 'trust' === $cachedAUSearch['status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Trusted', 'mainwp' ); ?></option>
2269 <option value="untrust" <?php echo ( null !== $cachedAUSearch && 'untrust' === $cachedAUSearch['status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Not trusted', 'mainwp' ); ?></option>
2270 <option value="ignored" <?php echo ( null !== $cachedAUSearch && 'ignored' === $cachedAUSearch['status'] ) ? 'selected' : ''; ?>><?php esc_html_e( 'Ignored', 'mainwp' ); ?></option>
2271 </select>
2272 </div>
2273 <div class="field">
2274 <div class="ui input fluid">
2275 <input type="text" placeholder="<?php esc_attr_e( 'Plugin name', 'mainwp' ); ?>" id="mainwp_au_plugin_keyword" class="text" value="<?php echo ( null !== $cachedAUSearch ) ? esc_attr( $cachedAUSearch['keyword'] ) : ''; ?>">
2276 </div>
2277 </div>
2278 </div>
2279 </div>
2280 </div>
2281 <div class="ui fitted divider"></div>
2282 <div class="mainwp-search-submit">
2283 <?php do_action( 'mainwp_manage_plugins_before_submit_button' ); ?>
2284 <a href="#" class="ui green big fluid button" id="mainwp_show_all_active_plugins"><?php esc_html_e( 'Show Plugins', 'mainwp' ); ?></a>
2285 <?php do_action( 'mainwp_manage_plugins_after_submit_button' ); ?>
2286 </div>
2287 <?php do_action( 'mainwp_manage_plugins_sidebar_bottom' ); ?>
2288 </div>
2289 </div>
2290 <?php
2291 MainWP_UI::render_modal_edit_notes( 'plugin' );
2292 }
2293 static::render_footer( 'AutoUpdate' );
2294 }
2295
2296 /**
2297 * Method render_all_active_table()
2298 *
2299 * Render all active Plugins table.
2300 *
2301 * @param null $output function output.
2302 *
2303 * @return void
2304 *
2305 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
2306 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension()
2307 * @uses \MainWP\Dashboard\MainWP_DB::query()
2308 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
2309 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
2310 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
2311 * @uses \MainWP\Dashboard\MainWP_Plugins_Handler::get_class_name()
2312 * @uses \MainWP\Dashboard\MainWP_Utility::map_site()
2313 * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
2314 */
2315 public static function render_all_active_table( $output = null ) { // phpcs:ignore -- NOSONAR - complex.
2316 $keyword = null;
2317 $search_status = 'all';
2318
2319 $data_fields = MainWP_System_Utility::get_default_map_site_fields();
2320
2321 if ( null === $output ) {
2322 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2323 $keyword = isset( $_POST['keyword'] ) && ! empty( $_POST['keyword'] ) ? sanitize_text_field( wp_unslash( $_POST['keyword'] ) ) : null;
2324 $search_status = isset( $_POST['status'] ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : 'all';
2325 $search_plugin_status = isset( $_POST['plugin_status'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_status'] ) ) : 'all';
2326 // phpcs:enable
2327
2328 $output = new \stdClass();
2329 $output->errors = array();
2330 $output->plugins = array();
2331 $output->plugins_installed = array(); // to fix.
2332
2333 if ( 1 === (int) get_option( 'mainwp_optimize', 1 ) || MainWP_Demo_Handle::is_demo_mode() ) {
2334 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
2335 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2336 $allPlugins = json_decode( $website->plugins, true );
2337 $_count = count( $allPlugins );
2338 for ( $i = 0; $i < $_count; $i++ ) {
2339 $plugin = $allPlugins[ $i ];
2340
2341 $all = true;
2342 if ( 'all' !== $search_plugin_status ) {
2343 $all = false;
2344 }
2345
2346 if ( ! $all && ( ( 1 === (int) $plugin['active'] && 'active' !== $search_plugin_status ) || ( 1 !== (int) $plugin['active'] && 'inactive' !== $search_plugin_status ) ) ) {
2347 continue;
2348 }
2349
2350 if ( ! empty( $keyword ) ) {
2351 $keyword = trim( $keyword );
2352 $multi_kws = explode( ',', $keyword );
2353 $multi_kws = array_filter( array_map( 'trim', $multi_kws ) );
2354 if ( ! MainWP_Utility::multi_find_keywords( $plugin['name'], $multi_kws ) ) {
2355 continue;
2356 }
2357 }
2358 $plugin['websiteid'] = $website->id;
2359 $plugin['websiteurl'] = $website->url;
2360 $output->plugins[] = $plugin;
2361 }
2362 }
2363 MainWP_DB::free_result( $websites );
2364 } else {
2365 $dbwebsites = array();
2366 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
2367 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2368 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
2369 continue;
2370 }
2371
2372 $dbwebsites[ $website->id ] = MainWP_Utility::map_site(
2373 $website,
2374 $data_fields
2375 );
2376 }
2377 MainWP_DB::free_result( $websites );
2378
2379 $post_data = array( 'keyword' => $keyword );
2380
2381 if ( 'active' === $search_plugin_status || 'inactive' === $search_plugin_status ) {
2382 $post_data['status'] = $search_plugin_status;
2383 $post_data['filter'] = true;
2384 } else {
2385 $post_data['status'] = '';
2386 $post_data['filter'] = false;
2387 }
2388 $output->status = $search_plugin_status;
2389 MainWP_Connect::fetch_urls_authed( $dbwebsites, 'get_all_plugins', $post_data, array( MainWP_Plugins_Handler::get_class_name(), 'plugins_search_handler' ), $output );
2390 // phpcs:disable WordPress.Security.EscapeOutput
2391 if ( ! empty( $output->errors ) ) {
2392 foreach ( $output->errors as $siteid => $error ) {
2393 echo MainWP_Utility::get_nice_url( $dbwebsites[ $siteid ]->url ) . ' - ' . $error . ' <br/>';
2394
2395 }
2396 echo '<div class="ui hidden divider"></div>';
2397
2398 if ( count( $output->errors ) === count( $dbwebsites ) ) {
2399 $_SESSION['MainWP_PluginsActive'] = $output;
2400 $_SESSION['MainWP_PluginsActiveStatus'] = array(
2401 'keyword' => $keyword,
2402 'status' => $search_status,
2403 'plugin_status' => $search_plugin_status,
2404 );
2405 return;
2406 }
2407 }
2408 // phpcs:enable
2409 }
2410
2411 $_SESSION['MainWP_PluginsActive'] = $output;
2412 $_SESSION['MainWP_PluginsActiveStatus'] = array(
2413 'keyword' => $keyword,
2414 'status' => $search_status,
2415 'plugin_status' => $search_plugin_status,
2416 );
2417 } elseif ( isset( $_SESSION['MainWP_PluginsActiveStatus'] ) ) {
2418 //phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
2419 $keyword = isset( $_SESSION['MainWP_PluginsActiveStatus']['keyword'] ) ? $_SESSION['MainWP_PluginsActiveStatus']['keyword'] : null;
2420 $search_status = isset( $_SESSION['MainWP_PluginsActiveStatus']['status'] ) ? $_SESSION['MainWP_PluginsActiveStatus']['status'] : null;
2421 $search_plugin_status = isset( $_SESSION['MainWP_PluginsActiveStatus']['plugin_status'] ) ? $_SESSION['MainWP_PluginsActiveStatus']['plugin_status'] : null;
2422 //phpcs:enable
2423 }
2424
2425 if ( 'inactive' !== $search_plugin_status && ( empty( $keyword ) || ( ! empty( $keyword ) && false !== stristr( 'MainWP Child', $keyword ) ) ) ) {
2426 $output->plugins[] = array(
2427 'slug' => 'mainwp-child/mainwp-child.php',
2428 'name' => 'MainWP Child',
2429 'active' => 1,
2430 );
2431 }
2432
2433 if ( empty( $output->plugins ) ) {
2434 ?>
2435 <div class="ui message yellow"><?php esc_html_e( 'No plugins found.', 'mainwp' ); ?></div>
2436 <?php
2437 return;
2438 }
2439
2440 $plugins = array();
2441 foreach ( $output->plugins as $plugin ) {
2442 $plugins[ $plugin['slug'] ] = $plugin;
2443 }
2444 asort( $plugins );
2445
2446 $userExtension = MainWP_DB_Common::instance()->get_user_extension();
2447 $decodedIgnoredPlugins = json_decode( $userExtension->ignored_plugins, true );
2448 $trustedPlugins = json_decode( $userExtension->trusted_plugins, true );
2449
2450 if ( ! is_array( $trustedPlugins ) ) {
2451 $trustedPlugins = array();
2452 }
2453 $trustedPluginsNotes = json_decode( $userExtension->trusted_plugins_notes, true );
2454 if ( ! is_array( $trustedPluginsNotes ) ) {
2455 $trustedPluginsNotes = array();
2456 }
2457 static::render_all_active_html( $plugins, $trustedPlugins, $search_status, $decodedIgnoredPlugins, $trustedPluginsNotes );
2458 MainWP_UI::render_modal_upload_icon();
2459 }
2460
2461
2462 /**
2463 * Method render_all_active_html()
2464 *
2465 * Render all active plugins html.
2466 *
2467 * @param array $plugins Plugins array.
2468 * @param array $trustedPlugins Trusted plugins array.
2469 * @param mixed $search_status trust|untrust|ignored.
2470 * @param array $decodedIgnoredPlugins Decoded ignored plugins array.
2471 * @param array $trustedPluginsNotes Trusted plugins notes.
2472 *
2473 * @uses \MainWP\Dashboard\MainWP_Utility::esc_content()
2474 */
2475 public static function render_all_active_html( $plugins, $trustedPlugins, $search_status, $decodedIgnoredPlugins, $trustedPluginsNotes ) { // phpcs:ignore -- NOSONAR - complex.
2476
2477 /**
2478 * Action: mainwp_plugins_before_auto_updates_table
2479 *
2480 * Fires before the Auto Update Plugins table.
2481 *
2482 * @since 4.1
2483 */
2484 do_action( 'mainwp_plugins_before_auto_updates_table' );
2485 ?>
2486 <table class="ui unstackable table" id="mainwp-all-active-plugins-table">
2487 <thead>
2488 <tr>
2489 <th scope="col" class="no-sort check-column collapsing"><span class="ui checkbox"><input id="cb-select-all-top" type="checkbox" /></span></th>
2490 <th scope="col" class="no-sort center aligned"></th>
2491 <th scope="col" data-priority="1"><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
2492 <th scope="col" class="collapsing center aligned"><?php esc_html_e( 'Status', 'mainwp' ); ?></th>
2493 <th scope="col" class="collapsing center aligned" data-priority="2"><?php esc_html_e( 'Trust Status', 'mainwp' ); ?></th>
2494 <th scope="col" class="collapsing center aligned"><?php esc_html_e( 'Ignored Status', 'mainwp' ); ?></th>
2495 <th scope="col" class="collapsing center aligned"></th>
2496 <th scope="col" class="collapsing center aligned"><?php esc_html_e( 'Notes', 'mainwp' ); ?></th>
2497 </tr>
2498 </thead>
2499 <tbody>
2500 <?php foreach ( $plugins as $slug => $plugin ) : ?>
2501 <?php
2502 $name = $plugin['name'];
2503 $wpid = isset( $plugin['websiteid'] ) ? intval( $plugin['websiteid'] ) : 0;
2504
2505 if ( ! empty( $search_status ) && 'all' !== $search_status ) {
2506 if ( 'trust' === $search_status && ! in_array( $slug, $trustedPlugins ) ) {
2507 continue;
2508 }
2509
2510 if ( 'untrust' === $search_status && in_array( $slug, $trustedPlugins ) ) {
2511 continue;
2512 }
2513
2514 if ( 'ignored' === $search_status && ! MainWP_Common_Functions::instance()->is_ignored_updates( $plugin, $decodedIgnoredPlugins, 'plugin' ) ) {
2515 continue;
2516 }
2517 }
2518 $esc_note = '';
2519 $strip_note = '';
2520 if ( isset( $trustedPluginsNotes[ $slug ] ) ) {
2521 $esc_note = MainWP_Utility::esc_content( $trustedPluginsNotes[ $slug ] );
2522 $strip_note = wp_strip_all_tags( $esc_note );
2523 }
2524
2525 $plugin_directory = dirname( $slug );
2526 ?>
2527 <?php // phpcs:disable WordPress.Security.EscapeOutput ?>
2528 <tr plugin-slug="<?php echo esc_attr( rawurlencode( $slug ) ); ?>" plugin-name="<?php echo esc_html( wp_strip_all_tags( $name ) ); ?>" <?php echo ( in_array( $slug, $trustedPlugins ) ) ? 'class=""' : 'class="active"'; ?>>
2529 <td class="check-column"><span class="ui checkbox"><input type="checkbox" name="plugin[]" value="<?php echo esc_attr( rawurlencode( $slug ) ); ?>"></span></td>
2530 <td class="collapsing"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); ?></td>
2531 <td><a href="<?php echo esc_url( admin_url() ) . 'plugin-install.php?tab=plugin-information&wpplugin=' . intval( $wpid ) . '&plugin=' . rawurlencode( dirname( $slug ) ); ?>" target="_blank" class="open-plugin-details-modal"><?php echo esc_html( $name ); ?></a></td>
2532 <td class="collapsing center aligned"><?php echo ( 1 === (int) $plugin['active'] ) ? '<span class="ui tiny grey label"><i class="circle green icon"></i> ' . esc_html__( 'Active', 'mainwp' ) . '</span>' : '<span class="ui tiny grey label"><i class="circle red icon"></i> ' . esc_html__( 'Inactive', 'mainwp' ) . '</span>'; //phpcs:ignore -- escaped. ?></td>
2533 <td class="collapsing center aligned"><?php echo ( in_array( $slug, $trustedPlugins ) ) ? '<span class="ui mini green label"><i class="lock green icon"></i> ' . esc_html__( 'Trusted', 'mainwp' ) . '</span>' : '<span class="ui mini red label"><i class="lock open red icon"></i> ' . esc_html__( 'Not Trusted', 'mainwp' ) . '</span>'; ?></td>
2534 <td class="collapsing center aligned"><?php echo MainWP_Common_Functions::instance()->is_ignored_updates( $plugin, $decodedIgnoredPlugins, 'plugin' ) ? '<span class="ui mini basic label">' . esc_html__( 'Ignored', 'mainwp' ) . '</span>' : ''; ?></td>
2535 <td class="collapsing center aligned"><?php echo MainWP_Common_Functions::instance()->is_ignored_updates( $plugin, $decodedIgnoredPlugins, 'plugin' ) ? '<span data-tooltip="Ignored plugins will not be automatically updated." data-inverted=""><i class="info red circle icon" ></i></span>' : ''; ?></td>
2536 <td class="collapsing center aligned">
2537 <?php if ( '' === $esc_note ) : ?>
2538 <a href="javascript:void(0)" class="mainwp-edit-plugin-note" ><i class="sticky note outline icon"></i></a>
2539 <?php else : ?>
2540 <a href="javascript:void(0)" class="mainwp-edit-plugin-note" data-tooltip="<?php echo substr( $strip_note, 0, 100 ); //phpcs:ignore -- escaped. ?>" data-position="center left" data-inverted=""><i class="sticky green note icon"></i></a>
2541 <?php endif; ?>
2542 <span style="display: none" class="esc-content-note"><?php echo $esc_note; //phpcs:ignore -- escaped. ?></span>
2543 </td>
2544 </tr>
2545 <?php // phpcs:enable ?>
2546 <?php endforeach; ?>
2547 </tbody>
2548 </table>
2549 <?php
2550 /**
2551 * Action: mainwp_plugins_after_auto_updates_table
2552 *
2553 * Fires after the Auto Update Plugins table.
2554 *
2555 * @since 4.1
2556 */
2557 do_action( 'mainwp_plugins_after_auto_updates_table' );
2558
2559 $table_features = array(
2560 'searching' => 'true',
2561 'stateSave' => 'true',
2562 'colReorder' => 'true',
2563 'info' => 'true',
2564 'paging' => 'false',
2565 'ordering' => 'true',
2566 'order' => '[ [ 2, "asc" ] ]',
2567 'responsive' => 'true',
2568 );
2569
2570 /**
2571 * Filter: mainwp_plugin_auto_updates_table_fatures
2572 *
2573 * Filters the Plugin Auto Updates table features.
2574 *
2575 * @since 4.1
2576 */
2577 $table_features = apply_filters( 'mainwp_plugin_auto_updates_table_fatures', $table_features );
2578 ?>
2579 <script type="text/javascript">
2580 jQuery( document ).ready( function() {
2581 let responsive = <?php echo esc_html( $table_features['responsive'] ); ?>;
2582 if( jQuery( window ).width() > 1140 ) {
2583 responsive = false;
2584 }
2585 jQuery( '#mainwp-all-active-plugins-table' ).DataTable( {
2586 "searching" : <?php echo esc_html( $table_features['searching'] ); ?>,
2587 "stateSave" : <?php echo esc_html( $table_features['stateSave'] ); ?>,
2588 "colReorder" : <?php echo $table_features['colReorder']; // phpcs:ignore -- specical chars. ?>,
2589 "info" : <?php echo esc_html( $table_features['info'] ); ?>,
2590 "paging" : <?php echo esc_html( $table_features['paging'] ); ?>,
2591 "ordering" : <?php echo esc_html( $table_features['ordering'] ); ?>,
2592 "order" : <?php echo $table_features['order']; // phpcs:ignore -- specical chars. ?>,
2593 "columnDefs": [ { "orderable": false, "targets": [ 0, 1, 6 ] } ],
2594 "responsive": responsive,
2595 } );
2596 } );
2597 </script>
2598
2599 <script type="text/javascript">
2600 jQuery( document ).ready( function () {
2601 jQuery( '.mainwp-ui-page .ui.checkbox:not(.not-auto-init)' ).checkbox();
2602 } );
2603 </script>
2604 <?php
2605 }
2606
2607 /**
2608 * Render Ignore Subpage.
2609 *
2610 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension()
2611 * @uses \MainWP\Dashboard\MainWP_DB::query()
2612 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
2613 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
2614 */
2615 public static function render_ignore() {
2616 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
2617 $userExtension = MainWP_DB_Common::instance()->get_user_extension();
2618 $decodedIgnoredPlugins = json_decode( $userExtension->ignored_plugins, true );
2619 $ignoredPlugins = is_array( $decodedIgnoredPlugins ) && ( ! empty( $decodedIgnoredPlugins ) );
2620
2621 $cnt = 0;
2622
2623 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2624 if ( $website->is_ignorePluginUpdates ) {
2625 continue;
2626 }
2627
2628 $tmpDecodedIgnoredPlugins = json_decode( $website->ignored_plugins, true );
2629
2630 if ( ! is_array( $tmpDecodedIgnoredPlugins ) || empty( $tmpDecodedIgnoredPlugins ) ) {
2631 continue;
2632 }
2633 ++$cnt;
2634 }
2635
2636 static::render_header( 'Ignore' );
2637 ?>
2638 <div id="mainwp-ignored-plugins" class="ui padded segment">
2639 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-ignored-plugins-info-message' ) ) : ?>
2640 <div class="ui info message">
2641 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-ignored-plugins-info-message"></i>
2642 <?php
2643 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
2644 printf( esc_html__( 'Manage plugins you have told your MainWP Dashboard to ignore updates on global or per site level. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/updates/manage-updates#ignore-plugin-updates" target="_blank">', '</a> <i class="external alternate icon"></i>' );
2645 ?>
2646 </div>
2647 <?php endif; ?>
2648 <?php
2649 /**
2650 * Action: mainwp_plugins_before_ignored_updates
2651 *
2652 * Fires on the top of the Ignored Plugin Updates page.
2653 *
2654 * @since 4.1
2655 */
2656 do_action( 'mainwp_plugins_before_ignored_updates', $ignoredPlugins, $websites );
2657 ?>
2658 <?php if ( ! empty( $ignoredPlugins ) ) : ?>
2659 <h3 class="ui header">
2660 <?php esc_html_e( 'Globally Ignored Plugins', 'mainwp' ); ?>
2661 <div class="sub header"><?php esc_html_e( 'These are plugins you have told your MainWP Dashboard to ignore updates on global level and not notify you about pending updates.', 'mainwp' ); ?></div>
2662 </h3>
2663 <?php static::render_global_ignored( $ignoredPlugins, $decodedIgnoredPlugins ); ?>
2664 <div class="ui hidden divider"></div>
2665 <?php endif; ?>
2666 <?php if ( $cnt > 0 ) : ?>
2667 <h3 class="ui header">
2668 <?php esc_html_e( 'Per Site Ignored Plugins', 'mainwp' ); ?>
2669 <div class="sub header"><?php esc_html_e( 'These are plugins you have told your MainWP Dashboard to ignore updates per site level and not notify you about pending updates.', 'mainwp' ); ?></div>
2670 </h3>
2671 <?php static::render_sites_ignored( $cnt, $websites ); ?>
2672 <?php endif; ?>
2673 <?php if ( empty( $ignoredPlugins ) && 0 === $cnt ) : ?>
2674 <?php MainWP_UI::render_empty_page_placeholder( __( 'No Ignored Updates', 'mainwp' ), __( 'All plugin updates are being tracked. When you choose to ignore updates for a specific plugin, they will appear here.', 'mainwp' ), '<em data-emoji=":compass:" class="big"></em>' ); ?>
2675 <?php endif; ?>
2676 <?php
2677 /**
2678 * Action: mainwp_plugins_after_ignored_updates
2679 *
2680 * Fires on the bottom of the Ignored Plugin Updates page.
2681 *
2682 * @since 4.1
2683 */
2684 do_action( 'mainwp_plugins_after_ignored_updates', $ignoredPlugins, $websites );
2685 ?>
2686 </div>
2687 <?php
2688 MainWP_Updates::render_plugin_details_modal();
2689 static::render_footer( 'Ignore' );
2690 }
2691
2692 /**
2693 * Method render_abandoned_plugins()
2694 *
2695 * Render abandoned plugins list.
2696 */
2697 public static function render_abandoned_plugins() {
2698 MainWP_Updates::render( 'abandoned_plugins' );
2699 }
2700
2701 /**
2702 * Method render_global_ignored()
2703 *
2704 * Render Global Ignored plugins list.
2705 *
2706 * @param bool $ignoredPlugins Ignored plugins array.
2707 * @param array $decodedIgnoredPlugins Decoded ignored plugins array.
2708 */
2709 public static function render_global_ignored( $ignoredPlugins, $decodedIgnoredPlugins ) { //phpcs:ignore -- NOSONAR - complex.
2710 ?>
2711 <table id="mainwp-globally-ignored-plugins" class="ui compact selectable table unstackable">
2712 <thead>
2713 <tr>
2714 <th scope="col" class="no-sort"></th>
2715 <th scope="col" ><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
2716 <th scope="col" ><?php esc_html_e( 'Plugin slug', 'mainwp' ); ?></th>
2717 <th scope="col" ><?php esc_html_e( 'Ignored version', 'mainwp' ); ?></th>
2718 <th scope="col" ></th>
2719 </tr>
2720 </thead>
2721 <tbody id="globally-ignored-plugins-list">
2722 <?php if ( $ignoredPlugins ) : ?>
2723 <?php // phpcs:disable WordPress.Security.EscapeOutput ?>
2724 <?php
2725 foreach ( $decodedIgnoredPlugins as $ignoredPlugin => $ignoredPluginName ) :
2726
2727 $ignore_name = 'N/A';
2728 $ignored_vers = array( 'all_versions' );
2729 if ( is_string( $ignoredPluginName ) ) {
2730 $ignore_name = $ignoredPluginName;
2731 } elseif ( is_array( $ignoredPluginName ) ) {
2732 $ignore_name = ! empty( $ignoredPluginName['Name'] ) ? $ignoredPluginName['Name'] : $ignore_name;
2733 $ig_vers = ! empty( $ignoredPluginName['ignored_versions'] ) ? $ignoredPluginName['ignored_versions'] : '';
2734 if ( ! empty( $ig_vers ) && is_array( $ig_vers ) && ! in_array( 'all_versions', $ig_vers ) ) {
2735 $ignored_vers = $ig_vers;
2736 }
2737 }
2738 ?>
2739 <?php $plugin_directory = dirname( $ignoredPlugin ); ?>
2740 <?php foreach ( $ignored_vers as $ignored_ver ) { ?>
2741 <tr plugin-slug="<?php echo esc_attr( rawurlencode( $ignoredPlugin ) ); ?>">
2742 <td class="collapsing"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); ?></td>
2743 <td><a href="<?php echo esc_url( admin_url() ) . 'plugin-install.php?tab=plugin-information&plugin=' . esc_html( rawurlencode( dirname( $ignoredPlugin ) ) ); ?>" target="_blank" class="open-plugin-details-modal"><?php echo esc_html( $ignore_name ); ?></a></td>
2744 <td><?php echo esc_html( $ignoredPlugin ); ?></td>
2745 <td><?php echo 'all_versions' === $ignored_ver ? esc_html__( 'All', 'mainwp' ) : esc_html( $ignored_ver ); ?></td>
2746 <td class="right aligned">
2747 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
2748 <a href="#" class="ui mini button" onClick="return updatesoverview_plugins_unignore_globally( '<?php echo esc_html( rawurlencode( $ignoredPlugin ) ); ?>', '<?php echo esc_js( rawurlencode( $ignored_ver ) ); ?>' )"><?php esc_html_e( 'Unignore', 'mainwp' ); ?></a>
2749 <?php endif; ?>
2750 </td>
2751 </tr>
2752 <?php } ?>
2753 <?php endforeach; ?>
2754 <?php // phpcs:enable ?>
2755 <?php endif; ?>
2756 </tbody>
2757 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
2758 <?php if ( $ignoredPlugins ) : ?>
2759 <tfoot class="full-width">
2760 <tr>
2761 <th scope="col" colspan="5">
2762 <a class="ui right floated small green labeled icon button" onClick="return updatesoverview_plugins_unignore_globally_all();" id="mainwp-unignore-globally-all">
2763 <i class="check icon"></i> <?php esc_html_e( 'Unignore All', 'mainwp' ); ?>
2764 </a>
2765 </th>
2766 </tr>
2767 </tfoot>
2768 <?php endif; ?>
2769 <?php endif; ?>
2770 </table>
2771 <script type="text/javascript">
2772 jQuery( document ).ready( function() {
2773 jQuery( '#mainwp-globally-ignored-plugins' ).DataTable( {
2774 "searching": false,
2775 "paging": false,
2776 "info": false,
2777 "responsive": true,
2778 "columnDefs": [ {
2779 "targets": 'no-sort',
2780 "orderable": false
2781 } ],
2782 "language": {
2783 "emptyTable": "<?php esc_html_e( 'No ignored plugins.', 'mainwp' ); ?>"
2784 }
2785 } );
2786 } );
2787 </script>
2788 <?php
2789 }
2790
2791 /**
2792 * Render Per Site Ignored table.
2793 *
2794 * @param mixed $cnt Plugin count.
2795 * @param mixed $websites Child Sites.
2796 *
2797 * @return void
2798 *
2799 * @uses \MainWP\Dashboard\MainWP_DB::data_seek()
2800 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
2801 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
2802 */
2803 public static function render_sites_ignored( $cnt, $websites ) { // phpcs:ignore -- NOSONAR - complex.
2804 ?>
2805 <table id="mainwp-per-site-ignored-plugins" class="ui unstackable compact selectable table ">
2806 <thead>
2807 <tr>
2808 <th scope="col" ><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
2809 <th scope="col" class="no-sort"></th>
2810 <th scope="col" ><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
2811 <th scope="col" ><?php esc_html_e( 'Plugin slug', 'mainwp' ); ?></th>
2812 <th scope="col" ><?php esc_html_e( 'Ignored version', 'mainwp' ); ?></th>
2813 <th scope="col" ></th>
2814 </tr>
2815 </thead>
2816 <tbody id="ignored-plugins-list">
2817 <?php if ( 0 < $cnt ) : ?>
2818 <?php
2819 MainWP_DB::data_seek( $websites, 0 );
2820
2821 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2822 if ( $website->is_ignorePluginUpdates ) {
2823 continue;
2824 }
2825
2826 $decodedIgnoredPlugins = json_decode( $website->ignored_plugins, true );
2827 if ( ! is_array( $decodedIgnoredPlugins ) || empty( $decodedIgnoredPlugins ) ) {
2828 continue;
2829 }
2830 $first = true;
2831 // phpcs:disable WordPress.Security.EscapeOutput
2832 foreach ( $decodedIgnoredPlugins as $ignoredPlugin => $ignoredPluginName ) {
2833
2834 $ignore_name = 'N/A';
2835 $ignored_vers = array( 'all_versions' );
2836 if ( is_string( $ignoredPluginName ) ) {
2837 $ignore_name = $ignoredPluginName;
2838 } elseif ( is_array( $ignoredPluginName ) ) {
2839 $ignore_name = ! empty( $ignoredPluginName['Name'] ) ? $ignoredPluginName['Name'] : $ignore_name;
2840 $ig_vers = ! empty( $ignoredPluginName['ignored_versions'] ) ? $ignoredPluginName['ignored_versions'] : '';
2841 if ( ! empty( $ig_vers ) && is_array( $ig_vers ) && ! in_array( 'all_versions', $ig_vers ) ) {
2842 $ignored_vers = $ig_vers;
2843 }
2844 }
2845 $plugin_directory = MainWP_Utility::get_dir_slug( rawurldecode( $ignoredPlugin ) );
2846 foreach ( $ignored_vers as $ignored_ver ) {
2847 ?>
2848 <tr site-id="<?php echo intval( $website->id ); ?>" plugin-slug="<?php echo esc_attr( rawurlencode( $ignoredPlugin ) ); ?>">
2849 <?php if ( $first ) : ?>
2850 <td><div><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a></div></td>
2851 <?php $first = false; ?>
2852 <?php else : ?>
2853 <td><div style="display:none;"><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a></div></td>
2854 <?php endif; ?>
2855 <td class="collapsing"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); ?></td>
2856 <td><a href="<?php echo esc_url( admin_url() ) . 'plugin-install.php?tab=plugin-information&wpplugin=' . intval( $website->id ) . '&plugin=' . esc_html( rawurlencode( $plugin_directory ) ); ?>" target="_blank" class="open-plugin-details-modal"><?php echo esc_html( $ignore_name ); ?></a></td>
2857 <td><?php echo esc_html( rawurldecode( $ignoredPlugin ) ); ?></td>
2858 <td><?php echo 'all_versions' === $ignored_ver ? esc_html__( 'All', 'mainwp' ) : esc_html( $ignored_ver ); ?></td>
2859 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
2860 <td class="right aligned"><a href="#" class="ui mini button" onClick="return updatesoverview_plugins_unignore_detail( '<?php echo esc_js( rawurlencode( $ignoredPlugin ) ); ?>', <?php echo intval( $website->id ); ?>, '<?php echo esc_js( rawurlencode( $ignored_ver ) ); ?>' )"> <?php esc_html_e( 'Unignore', 'mainwp' ); ?></a></td>
2861 <?php endif; ?>
2862 <?php } ?>
2863 </tr>
2864 <?php
2865 }
2866 // phpcs:enable
2867 }
2868
2869 MainWP_DB::free_result( $websites );
2870 ?>
2871 <?php endif; ?>
2872 </tbody>
2873 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
2874 <?php if ( 0 < $cnt ) : ?>
2875 <tfoot class="full-width">
2876 <tr>
2877 <th scope="col" colspan="6">
2878 <a class="ui right floated small green labeled icon button" onClick="return updatesoverview_plugins_unignore_detail_all();" id="mainwp-unignore-detail-all">
2879 <i class="check icon"></i> <?php esc_html_e( 'Unignore All', 'mainwp' ); ?>
2880 </a>
2881 </th>
2882 </tr>
2883 </tfoot>
2884 <?php endif; ?>
2885 <?php endif; ?>
2886 </table>
2887 <script type="text/javascript">
2888 jQuery( document ).ready( function() {
2889 jQuery( '#mainwp-per-site-ignored-plugins' ).DataTable( {
2890 "responsive": true,
2891 "searching": false,
2892 "paging": false,
2893 "info": false,
2894 "columnDefs": [ {
2895 "targets": 'no-sort',
2896 "orderable": false
2897 } ],
2898 "language": {
2899 "emptyTable": "<?php esc_html_e( 'No ignored plugins', 'mainwp' ); ?>"
2900 }
2901 } );
2902 } );
2903 </script>
2904 <?php
2905 }
2906
2907 /**
2908 * Render Ignored Abandoned Page.
2909 *
2910 * @uses \MainWP\Dashboard\MainWP_DB_Common::get_user_extension()
2911 * @uses \MainWP\Dashboard\MainWP_DB::query()
2912 * @uses \MainWP\Dashboard\MainWP_DB::get_sql_websites_for_current_user()
2913 * @uses \MainWP\Dashboard\MainWP_DB::get_website_option()
2914 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
2915 */
2916 public static function render_ignored_abandoned() {
2917 $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user() );
2918 $userExtension = MainWP_DB_Common::instance()->get_user_extension();
2919 $decodedIgnoredPlugins = json_decode( $userExtension->dismissed_plugins, true );
2920 $ignoredPlugins = is_array( $decodedIgnoredPlugins ) && ( ! empty( $decodedIgnoredPlugins ) );
2921 $cnt = 0;
2922 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
2923 $tmpDecodedDismissedPlugins = MainWP_DB::instance()->get_website_option( $website, 'plugins_outdate_dismissed' );
2924 $tmpDecodedDismissedPlugins = ! empty( $tmpDecodedDismissedPlugins ) ? json_decode( $tmpDecodedDismissedPlugins, true ) : array();
2925
2926 if ( ! is_array( $tmpDecodedDismissedPlugins ) || empty( $tmpDecodedDismissedPlugins ) ) {
2927 continue;
2928 }
2929 ++$cnt;
2930 }
2931
2932 static::render_header( 'IgnoreAbandoned' );
2933 ?>
2934 <div id="mainwp-ignored-abandoned-plugins" class="ui padded segment">
2935 <?php if ( MainWP_Utility::show_mainwp_message( 'notice', 'mainwp-ignored-abandoned-plugins-info-message' ) ) : ?>
2936 <div class="ui info message">
2937 <i class="close icon mainwp-notice-dismiss" notice-id="mainwp-ignored-abandoned-plugins-info-message"></i>
2938 <?php
2939 // translators: 1: Opening anchor tag. 2: Closing anchor tag.
2940 printf( esc_html__( 'Manage abandoned plugins you have told your MainWP Dashboard to ignore on global or per site level. For additional help, please check this %1$shelp documentation%2$s.', 'mainwp' ), '<a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp" target="_blank">', '</a> <i class="external alternate icon"></i> ' );
2941 ?>
2942 </div>
2943 <?php endif; ?>
2944 <?php
2945 /**
2946 * Action: mainwp_plugins_before_ignored_abandoned
2947 *
2948 * Fires on the top of the Ignored Plugins Abandoned page.
2949 *
2950 * @since 4.1
2951 */
2952 do_action( 'mainwp_plugins_before_ignored_abandoned', $ignoredPlugins, $websites );
2953 ?>
2954 <?php if ( ! empty( $ignoredPlugins ) ) : ?>
2955 <h3 class="ui header">
2956 <?php esc_html_e( 'Globally Ignored Abandoned Plugins', 'mainwp' ); ?>
2957 <div class="sub header"><?php esc_html_e( 'These are plugins you have told your MainWP Dashboard to ignore on global level even though they have passed your Abandoned Plugin Tolerance date', 'mainwp' ); ?></div>
2958 </h3>
2959 <?php static::render_global_ignored_abandoned( $ignoredPlugins, $decodedIgnoredPlugins ); ?>
2960 <div class="ui hidden divider"></div>
2961 <?php endif; ?>
2962 <?php if ( $cnt > 0 ) : ?>
2963 <h3 class="ui header">
2964 <?php esc_html_e( 'Per Site Ignored Abandoned Plugins', 'mainwp' ); ?>
2965 <div class="sub header"><?php esc_html_e( 'These are plugins you have told your MainWP Dashboard to ignore per site level even though they have passed your Abandoned Plugin Tolerance date', 'mainwp' ); ?></div>
2966 </h3>
2967 <?php static::render_sites_ignored_abandoned( $cnt, $websites ); ?>
2968 <?php endif; ?>
2969 <?php if ( empty( $ignoredPlugins ) && 0 === $cnt ) : ?>
2970 <?php MainWP_UI::render_empty_page_placeholder( __( 'No Ignored Abandoned Plugins', 'mainwp' ), __( 'All plugins are being monitored for abandonment. When you choose to ignore the abandoned status for a specific plugin, it will appear here.', 'mainwp' ), '<em data-emoji=":compass:" class="big"></em>' ); ?>
2971 <?php endif; ?>
2972 <?php
2973 /**
2974 * Action: mainwp_plugins_after_ignored_abandoned
2975 *
2976 * Fires on the bottom of the Ignored Plugins Abandoned page.
2977 *
2978 * @since 4.1
2979 */
2980 do_action( 'mainwp_plugins_after_ignored_abandoned', $ignoredPlugins, $websites );
2981 ?>
2982 </div>
2983 <?php
2984 static::render_footer( 'IgnoreAbandoned' );
2985 }
2986
2987 /**
2988 * Method render_global_ignored_abandoned()
2989 *
2990 * Render Global Ignored Abandoned table.
2991 *
2992 * @param array $ignoredPlugins Ignored plugins array.
2993 * @param array $decodedIgnoredPlugins Decoded dgnored plugins array.
2994 */
2995 public static function render_global_ignored_abandoned( $ignoredPlugins, $decodedIgnoredPlugins ) {
2996 ?>
2997 <table id="mainwp-globally-ignored-abandoned-plugins" class="ui compact selectable table unstackable">
2998 <thead>
2999 <tr>
3000 <th scope="col" class="no-sort">&nbsp;</th>
3001 <th scope="col" ><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
3002 <th scope="col" ><?php esc_html_e( 'Plugin slug', 'mainwp' ); ?></th>
3003 <th scope="col" ></th>
3004 </tr>
3005 </thead>
3006 <tbody id="ignored-globally-abandoned-plugins-list">
3007 <?php if ( $ignoredPlugins ) : ?>
3008 <?php
3009 // phpcs:disable WordPress.Security.EscapeOutput
3010 foreach ( $decodedIgnoredPlugins as $ignoredPlugin => $ignoredPluginName ) :
3011 $ignore_name = 'N/A';
3012 if ( is_string( $ignoredPluginName ) ) {
3013 $ignore_name = $ignoredPluginName;
3014 } elseif ( is_array( $ignoredPluginName ) && ! empty( $ignoredPluginName['Name'] ) ) {
3015 $ignore_name = $ignoredPluginName['Name'];
3016 }
3017
3018 $plugin_directory = MainWP_Utility::get_dir_slug( rawurldecode( $ignoredPlugin ) );
3019 ?>
3020 <tr plugin-slug="<?php echo esc_attr( rawurlencode( $ignoredPlugin ) ); ?>">
3021 <td class="collapsing"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); ?></td>
3022 <td><a href="<?php echo esc_url( admin_url() ) . 'plugin-install.php?tab=plugin-information&plugin=' . esc_html( rawurlencode( $plugin_directory ) ); ?>" target="_blank" class="open-plugin-details-modal"><?php echo esc_html( $ignore_name ); ?></a></td>
3023 <td><?php echo esc_html( $ignoredPlugin ); ?></td>
3024 <td class="right aligned">
3025 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
3026 <a href="#" class="ui mini button" onClick="return updatesoverview_plugins_abandoned_unignore_globally( '<?php echo esc_html( rawurlencode( $ignoredPlugin ) ); ?>' )"><?php esc_html_e( 'Unignore', 'mainwp' ); ?></a>
3027 <?php endif; ?>
3028 </td>
3029 </tr>
3030 <?php endforeach; ?>
3031 <?php // phpcs:enable ?>
3032 <?php endif; ?>
3033 </tbody>
3034 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
3035 <?php if ( $ignoredPlugins ) : ?>
3036 <tfoot class="full-width">
3037 <tr>
3038 <th scope="col" colspan="4">
3039 <a class="ui right floated small green labeled icon button" onClick="return updatesoverview_plugins_abandoned_unignore_globally_all();" id="mainwp-unignore-globally-all">
3040 <i class="check icon"></i> <?php esc_html_e( 'Unignore All', 'mainwp' ); ?>
3041 </a>
3042 </th>
3043 </tr>
3044 </tfoot>
3045 <?php endif; ?>
3046 <?php endif; ?>
3047 </table>
3048 <script type="text/javascript">
3049 jQuery( document ).ready( function() {
3050 jQuery( '#mainwp-globally-ignored-abandoned-plugins' ).DataTable( {
3051 "responsive": true,
3052 "searching": false,
3053 "paging": false,
3054 "info": false,
3055 "columnDefs": [ {
3056 "targets": 'no-sort',
3057 "orderable": false
3058 } ],
3059 "language": {
3060 "emptyTable": "<?php esc_html_e( 'No ignored abandoned plugins.', 'mainwp' ); ?>"
3061 }
3062 } );
3063 } );
3064 </script>
3065 <?php
3066 }
3067
3068 /**
3069 * Method render_sites_ignored_abandoned()
3070 *
3071 * Render Per Site Ignored Abandoned Table.
3072 *
3073 * @param int $cnt Plugins count.
3074 * @param object $websites The websites object.
3075 *
3076 * @uses \MainWP\Dashboard\MainWP_DB::get_website_option()
3077 * @uses \MainWP\Dashboard\MainWP_DB::fetch_object()
3078 * @uses \MainWP\Dashboard\MainWP_DB::free_result()
3079 */
3080 public static function render_sites_ignored_abandoned( $cnt, $websites ) { // phpcs:ignore -- NOSONAR - complex.
3081 ?>
3082 <table id="mainwp-per-site-ignored-abandoned-plugins" class="ui compact selectable table unstackable">
3083 <thead>
3084 <tr>
3085 <th scope="col" ><?php esc_html_e( 'Site', 'mainwp' ); ?></th>
3086 <th scope="col" class="no-sort">&nbsp;</th>
3087 <th scope="col" ><?php esc_html_e( 'Plugin', 'mainwp' ); ?></th>
3088 <th scope="col" ><?php esc_html_e( 'Plugin slug', 'mainwp' ); ?></th>
3089 <th scope="col" ></th>
3090 </tr>
3091 </thead>
3092 <tbody id="ignored-abandoned-plugins-list">
3093 <?php if ( 0 < $cnt ) : ?>
3094 <?php
3095 MainWP_DB::data_seek( $websites, 0 );
3096
3097 while ( $websites && ( $website = MainWP_DB::fetch_object( $websites ) ) ) {
3098 $decodedIgnoredPlugins = MainWP_DB::instance()->get_website_option( $website, 'plugins_outdate_dismissed' );
3099 $decodedIgnoredPlugins = ! empty( $decodedIgnoredPlugins ) ? json_decode( $decodedIgnoredPlugins, true ) : array();
3100
3101 if ( ! is_array( $decodedIgnoredPlugins ) || empty( $decodedIgnoredPlugins ) ) {
3102 continue;
3103 }
3104 $first = true;
3105 // phpcs:disable WordPress.Security.EscapeOutput
3106 foreach ( $decodedIgnoredPlugins as $ignoredPlugin => $ignoredPluginName ) {
3107 $ignore_name = 'N/A';
3108 if ( is_string( $ignoredPluginName ) ) {
3109 $ignore_name = $ignoredPluginName;
3110 } elseif ( is_array( $ignoredPluginName ) && ! empty( $ignoredPluginName['Name'] ) ) {
3111 $ignore_name = $ignoredPluginName['Name'];
3112 }
3113
3114 $plugin_directory = MainWP_Utility::get_dir_slug( rawurldecode( $ignoredPlugin ) );
3115 ?>
3116 <tr site-id="<?php echo esc_attr( $website->id ); ?>" plugin-slug="<?php echo esc_attr( rawurlencode( $ignoredPlugin ) ); ?>">
3117 <?php if ( $first ) : ?>
3118 <td>
3119 <a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a>
3120 </td>
3121 <?php $first = false; ?>
3122 <?php else : ?>
3123 <td><div style="display:none;"><a href="<?php echo esc_url( admin_url( 'admin.php?page=managesites&dashboard=' . $website->id ) ); ?>"><?php echo esc_html( stripslashes( $website->name ) ); ?></a></div></td>
3124 <?php endif; ?>
3125 <td class="collapsing"><?php echo MainWP_System_Utility::get_plugin_icon( $plugin_directory ); ?></td>
3126 <td><a href="<?php echo esc_url( admin_url() ) . 'plugin-install.php?tab=plugin-information&wpplugin=' . intval( $website->id ) . '&plugin=' . esc_html( rawurlencode( $plugin_directory ) ); ?>" target="_blank" class="open-plugin-details-modal"><?php echo esc_html( $ignore_name ); ?></a></td>
3127 <td><?php echo esc_html( $ignoredPlugin ); ?></td>
3128 <td class="right aligned"><a href="#" class="ui mini button" onClick="return updatesoverview_plugins_unignore_abandoned_detail( '<?php echo esc_html( rawurlencode( $ignoredPlugin ) ); ?>', <?php echo intval( $website->id ); ?> )"> <?php esc_html_e( 'Unignore', 'mainwp' ); ?></a></td>
3129 </tr>
3130 <?php
3131 }
3132 // phpcs:enable
3133 }
3134 MainWP_DB::free_result( $websites );
3135 ?>
3136 <?php endif; ?>
3137 </tbody>
3138 <?php if ( \mainwp_current_user_can( 'dashboard', 'ignore_unignore_updates' ) ) : ?>
3139 <?php if ( 0 < $cnt ) : ?>
3140 <tfoot class="full-width">
3141 <tr>
3142 <th scope="col" colspan="5">
3143 <a class="ui right floated small green labeled icon button" onClick="return updatesoverview_plugins_unignore_abandoned_detail_all();" id="mainwp-unignore-detail-all">
3144 <i class="check icon"></i> <?php esc_html_e( 'Unignore All', 'mainwp' ); ?>
3145 </a>
3146 </th>
3147 </tr>
3148 </tfoot>
3149 <?php endif; ?>
3150 <?php endif; ?>
3151 </table>
3152 <script type="text/javascript">
3153 jQuery( document ).ready( function() {
3154 jQuery( '#mainwp-per-site-ignored-abandoned-plugins' ).DataTable( {
3155 "responsive": true,
3156 "searching": false,
3157 "paging": false,
3158 "info": false,
3159 "columnDefs": [ {
3160 "targets": 'no-sort',
3161 "orderable": false
3162 } ],
3163 "language": {
3164 "emptyTable": "<?php esc_html_e( 'No ignored abandoned plugins.', 'mainwp' ); ?>"
3165 }
3166 } );
3167 } );
3168 </script>
3169 <?php
3170 }
3171
3172 /**
3173 * Method mainwp_help_content()
3174 *
3175 * Creates the MainWP Help Documentation List for the help component in the sidebar.
3176 */
3177 public static function mainwp_help_content() {
3178 // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
3179 if ( isset( $_GET['page'] ) && ( 'PluginsManage' === $_GET['page'] || 'PluginsInstall' === $_GET['page'] || 'PluginsAutoUpdate' === $_GET['page'] || 'PluginsIgnore' === $_GET['page'] || 'PluginsIgnoredAbandoned' === $_GET['page'] ) ) {
3180 ?>
3181 <p><?php esc_html_e( 'If you need help with managing plugins, please review following help documents', 'mainwp' ); ?></p>
3182 <div class="ui list">
3183 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp" target="_blank">Managing Plugins with MainWP</a></div>
3184 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp#install-plugins" target="_blank">Install Plugins</a></div>
3185 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp#activate-plugins" target="_blank">Activate Plugins</a></div>
3186 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp#delete-plugins" target="_blank">Delete Plugins</a></div>
3187 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/sites/plugins/managing-plugins-with-mainwp#update-plugins" target="_blank">Update Plugins</a></div>
3188 <?php
3189 /**
3190 * Action: mainwp_plugins_help_item
3191 *
3192 * Fires at the bottom of the help articles list in the Help sidebar on the Plugins page.
3193 *
3194 * Suggested HTML markup:
3195 *
3196 * <div class="item"><a href="Your custom URL">Your custom text</a></div>
3197 *
3198 * @since 4.1
3199 */
3200 do_action( 'mainwp_plugins_help_item' );
3201 ?>
3202 </div>
3203 <?php
3204 }
3205 // phpcs:enable
3206 }
3207 }
3208