PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 4.6.0.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v4.6.0.1
6.2.3 6.2.2 6.2.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 All 156 releases
mainwp / pages / page-mainwp-themes.php

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

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