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-themes.php

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

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