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