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

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

870 lines 45.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Extension Page
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class MainWP_Extensions
17 */
18 class MainWP_Extensions { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
19
20 /**
21 * Method get_class_name()
22 *
23 * Get Class Name.
24 *
25 * @return object Class name.
26 */
27 public static function get_class_name() {
28 return __CLASS__;
29 }
30
31 /**
32 * Instantiate action hooks.
33 *
34 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::get_class_name()
35 */
36 public static function init() {
37 /**
38 * This hook allows you to render the Extensions page header via the 'mainwp-pageheader-extensions' action.
39 *
40 * @link http://codex.mainwp.com/#mainwp-pageheader-extensions
41 *
42 * @see \MainWP_Extensions::render_header
43 */
44 add_action( 'mainwp-pageheader-extensions', array( static::get_class_name(), 'render_header' ) ); // @deprecated Use 'mainwp_pageheader_extensions' instead.
45 add_action( 'mainwp_pageheader_extensions', array( static::get_class_name(), 'render_header' ) );
46
47 /**
48 * This hook allows you to render the Extensions page footer via the 'mainwp-pagefooter-extensions' action.
49 *
50 * @link http://codex.mainwp.com/#mainwp-pagefooter-extensions
51 *
52 * @see \MainWP_Extensions::render_footer
53 */
54 add_action( 'mainwp-pagefooter-extensions', array( static::get_class_name(), 'render_footer' ) ); // @deprecated Use 'mainwp_pagefooter_extensions' instead.
55 add_action( 'mainwp_pagefooter_extensions', array( static::get_class_name(), 'render_footer' ) );
56
57 add_action( 'mainwp_help_sidebar_content', array( static::get_class_name(), 'mainwp_help_content' ) );
58
59 add_filter( 'mainwp-extensions-apigeneratepassword', array( MainWP_Extensions_Handler::get_class_name(), 'gen_api_password' ), 10, 3 );
60 add_filter( 'mainwp_extensions_apigeneratepassword', array( MainWP_Extensions_Handler::get_class_name(), 'gen_api_password' ), 10, 3 );
61 }
62
63 /**
64 * Method init_menu()
65 *
66 * Instantiate Extensions Menu.
67 *
68 * @uses \MainWP\Dashboard\MainWP_Api_Manager::get_activation_info()
69 * @uses \MainWP\Dashboard\MainWP_Extensions_View::init_menu()
70 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
71 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::polish_ext_name()
72 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::added_on_menu()
73 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::get_extensions()
74 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
75 */
76 public static function init_menu() { // phpcs:ignore -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
77 if ( ! MainWP_Menu::is_disable_menu_item( 2, 'Extensions' ) ) {
78 MainWP_Extensions_View::init_menu();
79 }
80
81 $save_extensions = array();
82
83 /**
84 * Get extensions
85 *
86 * Adds extension to MainWP system.
87 *
88 * @since 4.1
89 */
90 $init_extensions = array();
91 $init_extensions = apply_filters_deprecated( 'mainwp-getextensions', array( $init_extensions ), '4.0.7.2', 'mainwp_getextensions' ); // NOSONAR - not IP.
92 $init_extensions = apply_filters( 'mainwp_getextensions', $init_extensions );
93
94 $all_available_extensions = MainWP_Extensions_View::get_available_extensions( 'all' );
95
96 $activations_cached = get_option( 'mainwp_extensions_all_activation_cached', array() );
97
98 if ( ! is_array( $activations_cached ) ) {
99 $activations_cached = array();
100 }
101
102 $is_cached = ! empty( $activations_cached ) ? true : false;
103
104 $extraHeaders = array(
105 'IconURI' => 'Icon URI',
106 'SupportForumURI' => 'Support Forum URI',
107 'DocumentationURI' => 'Documentation URI',
108 );
109
110 $extsPages = array();
111
112 $compatible_v4_checks = array(
113 'advanced-uptime-monitor-extension/advanced-uptime-monitor-extension.php',
114 'mainwp-article-uploader-extension/mainwp-article-uploader-extension.php',
115 'mainwp-backwpup-extension/mainwp-backwpup-extension.php',
116 'boilerplate-extension/boilerplate-extension.php',
117 'mainwp-branding-extension/mainwp-branding-extension.php',
118 'mainwp-bulk-settings-manager/mainwp-bulk-settings-manager.php',
119 'mainwp-clean-and-lock-extension/mainwp-clean-and-lock-extension.php',
120 'mainwp-client-reports-extension/mainwp-client-reports-extension.php',
121 'mainwp-clone-extension/mainwp-clone-extension.php',
122 'mainwp-code-snippets-extension/mainwp-code-snippets-extension.php',
123 'mainwp-comments-extension/mainwp-comments-extension.php',
124 'mainwp-favorites-extension/mainwp-favorites-extension.php',
125 'mainwp-file-uploader-extension/mainwp-file-uploader-extension.php',
126 'mainwp-google-analytics-extension/mainwp-google-analytics-extension.php',
127 'mainwp-maintenance-extension/mainwp-maintenance-extension.php',
128 'mainwp-piwik-extension/mainwp-piwik-extension.php',
129 'mainwp-post-dripper-extension/mainwp-post-dripper-extension.php',
130 'mainwp-rocket-extension/mainwp-rocket-extension.php',
131 'mainwp-sucuri-extension/mainwp-sucuri-extension.php',
132 'mainwp-team-control/mainwp-team-control.php',
133 'mainwp-updraftplus-extension/mainwp-updraftplus-extension.php',
134 'mainwp-url-extractor-extension/mainwp-url-extractor-extension.php',
135 'mainwp-woocommerce-shortcuts-extension/mainwp-woocommerce-shortcuts-extension.php',
136 'mainwp-woocommerce-status-extension/mainwp-woocommerce-status-extension.php',
137 'mainwp-wordfence-extension/mainwp-wordfence-extension.php',
138 'wordpress-seo-extension/wordpress-seo-extension.php',
139 'mainwp-page-speed-extension/mainwp-page-speed-extension.php',
140 'mainwp-ithemes-security-extension/mainwp-ithemes-security-extension.php',
141 'mainwp-post-plus-extension/mainwp-post-plus-extension.php',
142 'mainwp-staging-extension/mainwp-staging-extension.php',
143 'mainwp-custom-post-types/mainwp-custom-post-types.php',
144 'mainwp-buddy-extension/mainwp-buddy-extension.php',
145 'mainwp-vulnerability-checker-extension/mainwp-vulnerability-checker-extension.php',
146 'mainwp-timecapsule-extension/mainwp-timecapsule-extension.php',
147 'activity-log-mainwp/activity-log-mainwp.php',
148 );
149 include_once ABSPATH . '/wp-admin/includes/plugin.php'; // NOSONAR - WP compatible.
150
151 $deactivated_imcompatible = array();
152 foreach ( $init_extensions as $extension ) {
153 $slug = plugin_basename( $extension['plugin'] );
154 $plugin_data = get_plugin_data( $extension['plugin'], true, false );
155 $file_data = get_file_data( $extension['plugin'], $extraHeaders );
156
157 if ( ! isset( $plugin_data['Name'] ) || ( '' === $plugin_data['Name'] ) ) {
158 continue;
159 }
160
161 if ( in_array( $slug, $compatible_v4_checks ) ) {
162 $check_minver = '3.99999';
163 if ( 'advanced-uptime-monitor-extension/advanced-uptime-monitor-extension.php' === $slug ) {
164 $check_minver = '4.6.2';
165 } elseif ( 'activity-log-mainwp/activity-log-mainwp.php' === $slug ) {
166 $check_minver = '1.0.5';
167 }
168
169 if ( isset( $plugin_data['Version'] ) && version_compare( $plugin_data['Version'], $check_minver, '<' ) ) {
170 $deactivated_imcompatible[] = $plugin_data['Name'];
171 deactivate_plugins( $slug, true );
172 continue;
173 }
174 }
175
176 $extension['slug'] = $slug;
177
178 if ( ! isset( $extension['name'] ) ) {
179 $extension['name'] = $plugin_data['Name'];
180 }
181 $extension['version'] = $plugin_data['Version'];
182 $extension['description'] = $plugin_data['Description'];
183 $extension['author'] = $plugin_data['Author'];
184 $extension['icon'] = isset( $extension['icon'] ) ? trim( $extension['icon'] ) : '';
185 $extension['iconURI'] = $file_data['IconURI'];
186 $extension['SupportForumURI'] = $file_data['SupportForumURI'];
187 $extension['DocumentationURI'] = $file_data['DocumentationURI'];
188 $extension['page'] = 'Extensions-' . str_replace( ' ', '-', ucwords( str_replace( '-', ' ', dirname( $slug ) ) ) );
189
190 if ( isset( $extension['apiManager'] ) && $extension['apiManager'] ) {
191
192 $api_slug = dirname( $slug );
193
194 if ( $is_cached ) {
195 $options = isset( $activations_cached[ $api_slug ] ) ? $activations_cached[ $api_slug ] : array();
196 } else {
197 $options = MainWP_Api_Manager::instance()->get_activation_info( $api_slug );
198 $activations_cached[ $api_slug ] = $options;
199 }
200
201 if ( ! is_array( $options ) ) {
202 $options = array();
203 }
204
205 $extension['api_key'] = isset( $options['api_key'] ) ? $options['api_key'] : '';
206 $extension['activated_key'] = isset( $options['activated_key'] ) ? $options['activated_key'] : 'Deactivated';
207 $extension['deactivate_checkbox'] = isset( $options['deactivate_checkbox'] ) ? $options['deactivate_checkbox'] : 'off';
208 $extension['product_id'] = isset( $options['product_id'] ) ? $options['product_id'] : '';
209 $extension['instance_id'] = isset( $options['instance_id'] ) ? $options['instance_id'] : '';
210 $extension['software_version'] = isset( $options['software_version'] ) ? $options['software_version'] : '';
211 $extension['mainwp_version'] = isset( $options['mainwp_version'] ) ? $options['mainwp_version'] : '';
212
213 if ( isset( $options['product_item_id'] ) ) {
214 $extension['product_item_id'] = $options['product_item_id'];
215 }
216 }
217
218 $ext_slug = dirname( $slug );
219 if ( isset( $all_available_extensions[ $ext_slug ] ) ) {
220 $extension['type'] = $all_available_extensions[ $ext_slug ]['type']; // to fix.
221 }
222
223 $save_extensions[] = $extension;
224 if ( \mainwp_current_user_can( 'extension', dirname( $slug ) ) ) {
225 $callback = isset( $extension['callback'] ) ? $extension['callback'] : '';
226 $menu_name = MainWP_Extensions_Handler::polish_ext_name( $extension );
227 if ( MainWP_Extensions_Handler::added_on_menu( $slug ) ) {
228 $_page = add_submenu_page( 'mainwp_tab', $extension['name'], $menu_name, 'read', $extension['page'], $callback );
229 } else {
230 $_page = add_submenu_page( 'mainwp_tab', $extension['name'], '<div class="mainwp-hidden">' . $extension['name'] . '</div>', 'read', $extension['page'], $callback );
231 }
232
233 if ( isset( $extension['on_load_callback'] ) && ! empty( $extension['on_load_callback'] ) ) {
234 add_action( 'load-' . $_page, $extension['on_load_callback'] );
235 }
236
237 $_item = array(
238 'title' => $menu_name,
239 'slug' => $extension['page'],
240 'href' => isset( $extension['href'] ) ? $extension['href'] : '',
241 );
242
243 $extsPages[] = $_item;
244 }
245 }
246
247 if ( ! empty( $deactivated_imcompatible ) ) {
248 set_transient( 'mainwp_transient_deactivated_incomtible_exts', $deactivated_imcompatible );
249 }
250
251 MainWP_Utility::update_option( 'mainwp_extensions', $save_extensions );
252 MainWP_Extensions_Handler::get_extensions( true ); // forced reload.
253
254 if ( ! $is_cached ) {
255 update_option( 'mainwp_extensions_all_activation_cached', $activations_cached );
256 }
257 static::init_left_menu( $extsPages );
258 }
259
260 /**
261 * Method init_left_menu()
262 *
263 * Initiate top level Extensions Menues.
264 *
265 * @param array $extPages List of extension pages.
266 * @uses \MainWP\Dashboard\MainWP_Menu::is_disable_menu_item()
267 * @uses \MainWP\Dashboard\MainWP_Menu::add_left_menu()
268 * @uses \MainWP\Dashboard\MainWP_Menu::init_subpages_left_menu()
269 */
270 public static function init_left_menu( $extPages ) {
271 $subPages = array();
272 if ( ! MainWP_Menu::is_disable_menu_item( 2, 'Extensions' ) ) {
273 MainWP_Menu::add_left_menu(
274 array(
275 'title' => esc_html__( 'Add-ons', 'mainwp' ),
276 'parent_key' => 'mainwp_tab',
277 'slug' => 'Extensions',
278 'href' => 'admin.php?page=Extensions',
279 'icon' => '<i class="box icon"></i>',
280 ),
281 0
282 );
283
284 $init_sub_subleftmenu = array(
285 array(
286 'title' => esc_html__( 'Manage Add-ons', 'mainwp' ),
287 'parent_key' => 'Extensions',
288 'href' => 'admin.php?page=Extensions',
289 'slug' => 'Extensions',
290 'right' => '',
291 ),
292 );
293
294 MainWP_Menu::init_subpages_left_menu( $subPages, $init_sub_subleftmenu, 'Extensions', 'Extensions' );
295
296 foreach ( $init_sub_subleftmenu as $item ) {
297 if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
298 continue;
299 }
300 MainWP_Menu::add_left_menu( $item, 2 );
301 }
302
303 if ( ! empty( $extPages ) ) {
304
305 $init_sub_subleftmenu = array();
306 $slug = '';
307 MainWP_Menu::init_subpages_left_menu( $extPages, $init_sub_subleftmenu, 'Extensions', $slug );
308
309 foreach ( $init_sub_subleftmenu as $item ) {
310 if ( MainWP_Menu::is_disable_menu_item( 3, $item['slug'] ) ) {
311 continue;
312 }
313 MainWP_Menu::add_left_menu( $item, 2 );
314 }
315 }
316 }
317 }
318
319 /**
320 * Method init_subpages_menu()
321 *
322 * Initiate Extensions Subpage Menu.
323 *
324 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::get_extensions()
325 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::added_on_menu()
326 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::polish_ext_name()
327 */
328 public static function init_subpages_menu() {
329 $exts = MainWP_Extensions_Handler::get_extensions();
330 if ( empty( $exts ) ) {
331 return;
332 }
333 $html = '';
334 foreach ( $exts as $extension ) {
335 if ( defined( 'MWP_TEAMCONTROL_PLUGIN_SLUG' ) && ( MWP_TEAMCONTROL_PLUGIN_SLUG === $extension['slug'] ) && ! \mainwp_current_user_can( 'extension', dirname( MWP_TEAMCONTROL_PLUGIN_SLUG ) ) ) {
336 continue;
337 }
338 if ( MainWP_Extensions_Handler::added_on_menu( $extension['slug'] ) ) {
339 continue;
340 }
341 $menu_name = MainWP_Extensions_Handler::polish_ext_name( $extension );
342
343 if ( isset( $extension['direct_page'] ) ) {
344 $html .= '<a href="' . esc_url( admin_url( 'admin.php?page=' . $extension['direct_page'] ) ) . '" class="mainwp-submenu">' . $menu_name . '</a>';
345 } else {
346 $html .= '<a href="' . esc_url( admin_url( 'admin.php?page=' . $extension['page'] ) ) . '" class="mainwp-submenu">' . $menu_name . '</a>';
347 }
348 }
349 if ( empty( $html ) ) {
350 return;
351 }
352 ?>
353 <div id="menu-mainwp-Extensions" class="mainwp-submenu-wrapper" xmlns="http://www.w3.org/1999/html">
354 <div class="wp-submenu sub-open" style="">
355 <div class="mainwp_boxout mainwp-submenu-wide">
356 <div class="mainwp_boxoutin"></div>
357 <?php echo $html; // phpcs:ignore WordPress.Security.EscapeOutput ?>
358 </div>
359 </div>
360 </div>
361 <?php
362 }
363
364
365 /**
366 * Method ajax_get_purchased_extensions()
367 *
368 * Get purchased MainWP Extensions.
369 *
370 * @uses \MainWP\Dashboard\MainWP_Api_Manager::get_purchased_extension()
371 * @uses \MainWP\Dashboard\MainWP_Api_Manager::check_response_for_intall_errors()
372 * @uses \MainWP\Dashboard\MainWP_Extensions_View::get_available_extensions()
373 * @uses \MainWP\Dashboard\MainWP_Extensions_View::get_extension_groups()
374 * @uses \MainWP\Dashboard\MainWP_Post_Handler::secure_request()
375 * @uses \MainWP\Dashboard\MainWP_Extensions_Handler::get_extensions()
376 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
377 */
378 public static function ajax_get_purchased_extensions() { // phpcs:ignore -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
379
380 MainWP_Post_Handler::instance()->secure_request( 'mainwp_extension_getpurchased' );
381
382 $api_key = isset( $_POST['api_key'] ) ? trim( wp_unslash( $_POST['api_key'] ) ) : false; // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
383
384 $all_available_extensions_compatible_api_response = array();
385 $all_free_pro_exts = array();
386 $all_org_exts = array();
387 $map_extensions_group = array();
388 $purchased_data = array();
389
390 $all_groups = MainWP_Extensions_View::get_extension_groups();
391
392 $grouped_exts = array(
393 'others' => '',
394 'all' => '',
395 );
396
397 foreach ( MainWP_Extensions_View::get_available_extensions( 'all' ) as $ext ) {
398 $all_available_extensions_compatible_api_response[ $ext['product_id'] ] = $ext;
399 $map_extensions_group[ $ext['product_id'] ] = current( $ext['group'] );
400 if ( 'free' === $ext['type'] || 'pro' === $ext['type'] ) {
401 $all_free_pro_exts[ $ext['product_id'] ] = $ext['product_id'];
402 } elseif ( 'org' === $ext['type'] ) {
403 $all_org_exts[ $ext['product_id'] ] = $ext['product_id'];
404 }
405 }
406
407 $extensions = MainWP_Extensions_Handler::get_extensions();
408 $installed_softwares = array();
409
410 foreach ( $extensions as $extension ) {
411 if ( isset( $extension['type'] ) ) {
412 if ( 'free' === $extension['type'] || 'pro' === $extension['type'] ) {
413 if ( isset( $extension['product_id'] ) && ! empty( $extension['product_id'] ) ) {
414 $installed_softwares[ $extension['product_id'] ] = $extension['product_id'];
415 }
416 } elseif ( 'org' === $extension['type'] ) {
417 $ext_slug = dirname( $extension['slug'] );
418 $installed_softwares[ $ext_slug ] = $ext_slug;
419 }
420 }
421 }
422
423 $all_disabled_extensions = MainWP_Extensions_Handler::get_extensions_disabled( true );
424
425 foreach ( $all_disabled_extensions as $ext ) {
426 $installed_softwares[ $ext['product_id'] ] = $ext['product_id'];
427 }
428
429 $not_purchased_exts = $all_free_pro_exts;
430 $not_installed_org_exts = array_diff_key( $all_org_exts, $installed_softwares );
431 $installing_exts = $not_installed_org_exts;
432
433 if ( ! empty( $api_key ) ) {
434
435 $data = MainWP_Api_Manager::instance()->get_purchased_extension( $api_key );
436
437 $result = json_decode( $data, true );
438 $return = array();
439
440 if ( is_array( $result ) ) {
441 if ( isset( $result['success'] ) && $result['success'] ) {
442 $purchased_data = ( isset( $result['purchased_data'] ) && is_array( $result['purchased_data'] ) ) ? $result['purchased_data'] : array();
443 $not_purchased_exts = array_diff_key( $all_free_pro_exts, $purchased_data );
444 $installing_exts = array_diff_key( $purchased_data, $installed_softwares );
445 $installing_exts = array_merge( $installing_exts, $not_installed_org_exts );
446 } elseif ( isset( $result['error'] ) ) {
447 $return = array( 'error' => $result['error'] );
448 }
449 } else {
450 $apisslverify = get_option( 'mainwp_api_sslVerifyCertificate' );
451 if ( 1 === $apisslverify ) {
452 MainWP_Utility::update_option( 'mainwp_api_sslVerifyCertificate', 0 );
453 $return['retry_action'] = 1;
454 }
455 }
456
457 if ( ! empty( $return ) ) {
458 wp_send_json( $return );
459 }
460 }
461
462 foreach ( $all_available_extensions_compatible_api_response as $product_id => $ext ) {
463
464 $item_html = '';
465 $error = '';
466 $ext_source_label = '';
467 $type = '';
468 $notice = '';
469 $add_on_model = '';
470 $model = $ext['model'];
471
472 if ( 'extension' === $model ) {
473 $add_on_model = 'addon-extension';
474 } elseif ( 'integration' === $model ) {
475 $add_on_model = 'addon-integration';
476 }
477
478 $item_slug = MainWP_Utility::get_dir_slug( $ext['slug'] );
479
480 $privacy = '<a href="#" class="extension-privacy-info-link" base-slug="' . esc_attr( $item_slug ) . '" style="text-decoration:none"> <i class="fingerprint small icon"></i></a>';
481
482 $new = '';
483
484 $software_title = MainWP_Extensions_Handler::polish_string_name( $ext['title'] );
485
486 if ( ! empty( $ext['type'] ) ) {
487 $type = $ext['type'];
488 if ( 'free' === $type ) {
489 $ext_source_label = '<span class="ui mini green label">FREE</span>';
490 } elseif ( 'pro' === $type ) {
491 $ext_source_label = '<span class="ui mini blue label">PRO</span>';
492 } elseif ( 'org' === $type ) {
493 $ext_source_label = '<span class="ui mini grey label">.ORG</span>';
494 }
495 }
496
497 if ( isset( $ext['release_date'] ) && ( time() - $ext['release_date'] < MONTH_IN_SECONDS ) ) {
498 $new = '<span class="ui mini green label">NEW!</span>';
499 }
500
501 if ( 'MainWP WordPress SEO Extension' === $product_id || 'seopress-for-mainwp' === $product_id ) {
502 $notice = ' <i class="info circle small icon"></i>';
503 }
504
505 $ext_source_label .= '&nbsp;';
506
507 if ( isset( $installing_exts[ $product_id ] ) ) {
508
509 $product_info = isset( $installing_exts[ $product_id ] ) ? $installing_exts[ $product_id ] : array();
510 if ( ! is_array( $product_info ) ) {
511 $product_info = array();
512 }
513
514 if ( 'free' === $type || 'pro' === $type ) {
515
516 if ( $product_info && isset( $product_info['package'] ) && ! empty( $product_info['package'] ) ) {
517
518 /**
519 * API Manager Upgrade URL
520 *
521 * Filters the Upgrade URL for extensions.
522 *
523 * @since Unknown
524 * @ignore
525 */
526 $package_url = apply_filters( 'mainwp_api_manager_upgrade_package_url', $product_info['package'], $product_info );
527
528 $item_html = '
529 <div class="item extension extension-to-install ' . esc_attr( $add_on_model ) . '" download-link="' . esc_url( $package_url ) . '" plugin-slug="" product-id="' . esc_attr( $product_id ) . '" software-title="' . esc_attr( $software_title ) . '" slug="' . esc_attr( $ext['slug'] ) . '">
530 <div class="ui stackable grid">
531 <div class="two column row">
532 <div class="column"><span class="ui checkbox"><input type="checkbox" status="queue"><label>' . $ext_source_label . '<strong><a href="' . esc_url( $ext['link'] ) . '" target="_blank">' . esc_html( $software_title ) . '</a>' . $privacy . ' ' . $notice . ' ' . $new . '</strong></label></span></div>
533 <div class="right aligned column"><span class="installing-extension" status="queue"></span></div>
534 </div>
535 </div>
536 </div>';
537
538 } elseif ( isset( $product_info['error'] ) && ! empty( $product_info['error'] ) ) {
539 $error = MainWP_Api_Manager::instance()->check_response_for_intall_errors( $product_info, $software_title );
540 } else {
541 $error = esc_html__( 'Undefined error occurred. Please try again.', 'mainwp' );
542 }
543
544 if ( ! empty( $error ) ) {
545 $item_html = '
546 <div class="item extension ' . esc_attr( $add_on_model ) . '" product-id="' . esc_attr( $product_id ) . '" software-title="' . esc_attr( $software_title ) . '">
547 <div class="ui stackable grid">
548 <div class="two column row">
549 <div class="column"><span class="ui checkbox"><input type="checkbox" disabled="disabled"><label>' . $ext_source_label . ' <a href="' . esc_url( $ext['link'] ) . '" target="_blank">' . esc_html( $software_title ) . '</a>' . $privacy . ' ' . $notice . ' ' . $new . '</label></span></div>
550 <div class="right aligned column"><span data-tooltip="' . $error . '" data-inverted="" data-position="left center"><i class="times red icon"></i></span></div>
551 </div>
552 </div>
553 </div>';
554 }
555 } elseif ( 'org' === $type ) {
556 $item_html = '
557 <div class="item extension extension-to-install ' . esc_attr( $add_on_model ) . '" download-link="" plugin-slug="' . esc_attr( $ext['slug'] ) . '" product-id="' . esc_attr( $product_id ) . '" software-title="' . esc_attr( $software_title ) . '" slug="' . esc_attr( $ext['slug'] ) . '">
558 <div class="ui stackable grid">
559 <div class="two column row">
560 <div class="column"><span class="ui checkbox"><input type="checkbox" status="queue"><label>' . $ext_source_label . '<strong><a href="' . esc_url( $ext['link'] ) . '" target="_blank">' . esc_html( $software_title ) . '</a>' . $privacy . ' ' . $notice . ' ' . $new . '</strong></label></span></div>
561 <div class="right aligned column"><span class="installing-extension" status="queue"></span></div>
562 </div>
563 </div>
564 </div>';
565 }
566 } elseif ( isset( $not_purchased_exts[ $product_id ] ) ) {
567 if ( 'free' === $type || 'pro' === $type ) {
568 $item_html = '
569 <div class="item extension ' . esc_attr( $add_on_model ) . '" product-id="' . esc_attr( $product_id ) . '" software-title="' . esc_attr( $software_title ) . '" slug="' . esc_attr( $ext['slug'] ) . '">
570 <div class="ui stackable grid">
571 <div class="two column row">
572 <div class="column"><span class="ui checkbox"><input type="checkbox" disabled="disabled"><label>' . $ext_source_label . ' <a href="' . esc_url( $ext['link'] ) . '" target="_blank">' . esc_html( $software_title ) . '</a>' . $privacy . ' ' . $notice . ' ' . $new . '</label></span></div>
573 <div class="right aligned column"><a href="' . $ext['link'] . '" target="_blank" data-tooltip="' . esc_html__( 'Add-on not purchased. Click to find out more.', 'mainwp' ) . '" data-position="left center" data-inverted=""><i class="info blue icon"></i></a></div>
574 </div>
575 </div>
576 </div>';
577 } elseif ( 'org' === $type ) {
578 $item_html = '
579 <div class="item extension ' . esc_attr( $add_on_model ) . '" product-id="' . esc_attr( $product_id ) . '" software-title="' . esc_attr( $software_title ) . '" slug="' . esc_attr( $ext['slug'] ) . '">
580 <div class="ui stackable grid">
581 <div class="two column row">
582 <div class="column"><span class="ui checkbox"><input type="checkbox" disabled="disabled"><label>' . $ext_source_label . ' <a href="' . esc_url( $ext['link'] ) . '" target="_blank">' . esc_html( $software_title ) . '</a>' . $privacy . ' ' . $notice . ' ' . $new . '</label></span></div>
583 <div class="right aligned column"><a href="' . $ext['url'] . '" target="_blank" data-tooltip="' . esc_attr__( 'Add-on not installed. Click to find out more.', 'mainwp' ) . '" data-position="left center" data-inverted=""><i class="info blue icon"></i></a></div>
584 </div>
585 </div>
586 </div>';
587 }
588 } elseif ( isset( $installed_softwares[ $product_id ] ) ) {
589 $item_html = '
590 <div class="item extension ' . esc_attr( $add_on_model ) . '" product-id="' . esc_attr( $product_id ) . '" software-title="' . esc_attr( $software_title ) . '" slug="' . esc_attr( $ext['slug'] ) . '">
591 <div class="ui stackable grid">
592 <div class="two column row">
593 <div class="column"><span data-tooltip="' . esc_attr__( 'Already installed', 'mainwp' ) . '" data-inverted="" data-position="right center"><span class="ui checkbox"><input type="checkbox" disabled="disabled"><label>' . $ext_source_label . ' <a href="' . esc_url( $ext['link'] ) . '" target="_blank">' . esc_html( $software_title ) . '</a> ' . $notice . '</label></label></span>' . $privacy . ' ' . $new . '</div>
594 <div class="right aligned column"><span data-tooltip="' . esc_attr__( 'Already installed', 'mainwp' ) . '" data-inverted="" data-position="left center"><i class="grey box icon"></i></span></div>
595 </div>
596 </div>
597 </div>';
598 }
599
600 $group_id = isset( $map_extensions_group[ $product_id ] ) ? $map_extensions_group[ $product_id ] : false;
601 if ( ! empty( $group_id ) && isset( $all_groups[ $group_id ] ) ) {
602 if ( isset( $grouped_exts[ $group_id ] ) ) {
603 $grouped_exts[ $group_id ] .= $item_html;
604 } else {
605 $grouped_exts[ $group_id ] = $item_html;
606 }
607 } else {
608 $grouped_exts['others'] .= $item_html;
609 }
610 $grouped_exts['all'] .= $item_html;
611 }
612
613 $html = '<div class="mainwp-installing-extensions">';
614
615 if ( empty( $installing_exts ) && count( $purchased_data ) === count( $all_free_pro_exts ) ) {
616 $html .= '<div class="ui message">' . esc_html__( 'All purchased add-ons already installed.', 'mainwp' ) . '</div>';
617 } else {
618 $html .= '<div class="ui icon message">';
619 $html .= '<em data-emoji=":bulb:" class="medium"></em>';
620 $html .= '<div class="content">';
621 $html .= '<div class="header">' . esc_html__( 'Install Only What You Need', 'mainwp' ) . '</div>';
622 $html .= '<p>';
623 $html .= esc_html__( 'For a cleaner dashboard and better focus, start with only the add-ons you need right now. You can always install more later.', 'mainwp' );
624 $html .= '</p>';
625 $html .= '</div>';
626 $html .= '</div>';
627
628 $html .= '<div class="ui hidden divider"></div>';
629
630 $html .= '<div id="mainwp-bulk-activating-extensions-status" class="ui message" style="display:none;"></div>';
631
632 $html .= '<div class="ui secondary green pointing tabular stackable menu" id="mainwp-install-extensions-menu">';
633 foreach ( $all_groups as $gr_id => $gr_name ) {
634 if ( isset( $grouped_exts[ $gr_id ] ) ) {
635 $html .= '<a class="item" data-tab="' . $gr_id . '">' . $gr_name . '</a>';
636 }
637 }
638
639 if ( isset( $grouped_exts['others'] ) && ! empty( $grouped_exts['others'] ) ) {
640 $html .= '<a class="item" data-tab="other">' . esc_html__( 'Other', 'mainwp' ) . '</a>';
641 }
642
643 $html .= '</div>';
644
645 $html .= '<div class="ui grid">';
646 $html .= '<div class="eight wide left aligned middle aligned column">';
647 $html .= esc_html__( 'Show: ', 'mainwp' );
648 $html .= '<div class="ui checkbox"><input type="checkbox" checked="" id="mainwp-standalone-extensions-filer" name="mainwp-standalone-extensions-filer"><label><strong>' . esc_html__( 'Extensions', 'mainwp' ) . '</label></div>';
649 $html .= '&nbsp;&nbsp; <div class="ui checkbox"><input type="checkbox" checked="" id="mainwp-api-extensions-filer" name="mainwp-api-extensions-filer"><label>' . esc_html__( 'Integrations', 'mainwp' ) . '</label></div>';
650 $html .= '&nbsp;&nbsp;&nbsp;&nbsp;<span class="ui small grey text" data-tooltip="' . esc_attr__( 'Extensions add Dashboard features without third-party dependencies. Integrations connect your Dashboard to third-party tools you use.', 'mainwp' ) . '" data-position="right center" data-inverted=""><i class="question circle icon"></i> ' . esc_html__( 'What\'s the difference?', 'mainwp' ) . '</span>';
651 $html .= '</div>';
652 $html .= '<div class="eight wide right aligned middle aligned column">';
653 $html .= '<div id="mainwp-search-extensions-install" class="ui fluid search">
654 <div class="ui icon mini input">
655 <input class="prompt" id="mainwp-search-extensions-install-input" type="text" placeholder="' . esc_attr__( 'Find add-on...', 'mainwp' ) . '">
656 <i class="search icon"></i>
657 </div>
658 </div>';
659 $html .= '</div>';
660 $html .= '</div>';
661
662 $html .= '<div class="ui divider"></div>';
663
664 $html .= '<div id="mainwp-extensions-search-results" style="display:none;">';
665 $html .= '<div class="ui middle aligned divided list">';
666 $html .= $grouped_exts['all'];
667 $html .= '</div>';
668 $html .= '</div>';
669
670 foreach ( $all_groups as $gr_id => $gr_name ) {
671 if ( isset( $grouped_exts[ $gr_id ] ) && 'all' !== $gr_id ) {
672 $html .= '<div class="ui tab" data-tab="' . $gr_id . '">';
673 $html .= '<div class="ui middle aligned divided list">';
674 $html .= $grouped_exts[ $gr_id ];
675 $html .= '</div>';
676 $html .= '</div>';
677 }
678 }
679
680 if ( isset( $grouped_exts['others'] ) && ! empty( $grouped_exts['others'] ) ) {
681 $html .= '<div class="ui tab" data-tab="other">';
682 $html .= '<div class="ui middle aligned divided list">';
683 $html .= $grouped_exts['others'];
684 $html .= '</div>';
685 $html .= '</div>';
686 }
687
688 }
689
690 $html .= '<div class="ui hidden divider"></div>';
691
692 $html .= '<div class="ui secondary vertically fitted segment">';
693 $html .= '<div class="ui horizontal mini list">';
694 $html .= '<div class="item"><span class="ui mini green label">FREE</span> ' . esc_html__( 'Free add-on by MainWP', 'mainwp' ) . '</div>';
695 $html .= '<div class="item"><span class="ui mini blue label">PRO</span> ' . esc_html__( 'Premium add-on by MainWP', 'mainwp' ) . '</div>';
696 $html .= '<div class="item"><span class="ui mini grey label">.ORG</span> ' . esc_html__( 'Free add-on by a third party (WP.org)', 'mainwp' ) . '</div>';
697 $html .= '<div class="item"><i class="info circle icon"></i> ' . esc_html__( 'Requires the matching plugin on too.', 'mainwp' ) . '</div>';
698 $html .= '<div class="item"><i class="fingerprint icon"></i> ' . esc_html__( 'Add-on privacy info.', 'mainwp' ) . '</div>';
699 $html .= '</div>';
700 $html .= '</div>';
701
702 $html .= '<script>jQuery( "#mainwp-install-extensions-menu .item" ).tab();</script>';
703 $html .= '<script type="text/javascript">
704 jQuery( document ).ready( function () {
705 let $menu = jQuery( "#mainwp-install-extensions-menu" );
706 let $modal = jQuery( "#mainwp-get-purchased-extensions-modal" );
707 let $searchInput = jQuery( "#mainwp-search-extensions-install-input" );
708 let $searchResults = jQuery( "#mainwp-extensions-search-results" );
709 let $tabsContainer = $modal.find( ".ui.tab[data-tab]" );
710
711 $searchResults.find( "input[type=\"checkbox\"]" ).removeAttr( "status" );
712
713 function syncToTabs( productId, checked ) {
714 $tabsContainer.find( ".extension-to-install[product-id=\"" + productId + "\"] input[type=\"checkbox\"]" ).prop( "checked", checked );
715 }
716
717 function syncToSearch( productId, checked ) {
718 $searchResults.find( ".extension-to-install[product-id=\"" + productId + "\"] input[type=\"checkbox\"]" ).prop( "checked", checked );
719 }
720
721 $searchResults.on( "change", "input[type=\"checkbox\"]", function () {
722 let productId = jQuery( this ).closest( ".extension-to-install" ).attr( "product-id" );
723 syncToTabs( productId, jQuery( this ).prop( "checked" ) );
724 } );
725
726 $tabsContainer.on( "change", "input[type=\"checkbox\"]", function () {
727 let productId = jQuery( this ).closest( ".extension-to-install" ).attr( "product-id" );
728 syncToSearch( productId, jQuery( this ).prop( "checked" ) );
729 } );
730
731 function exitSearchMode() {
732 $searchResults.hide();
733 $searchResults.find( ".item.extension" ).show();
734 $tabsContainer.css( "display", "" );
735 $menu.find( ".item" ).first().trigger( "click" );
736 }
737
738 $searchInput.on( "keyup", function () {
739 let searchQuery = jQuery( this ).val().toLowerCase();
740
741 if ( searchQuery.length > 0 ) {
742 $menu.find( ".item.active" ).removeClass( "active" );
743 $tabsContainer.css( "display", "none" );
744 $searchResults.show();
745 $searchResults.find( ".item.extension" ).each( function () {
746 let extensionTitle = jQuery( this ).attr( "software-title" ).toLowerCase();
747 jQuery( this ).toggle( extensionTitle.indexOf( searchQuery ) > -1 );
748 } );
749 } else {
750 exitSearchMode();
751 }
752 } );
753
754 $menu.on( "click", ".item", function () {
755 if ( $searchResults.is( ":visible" ) ) {
756 $searchInput.val( "" );
757 $searchResults.hide();
758 $searchResults.find( ".item.extension" ).show();
759 $tabsContainer.css( "display", "" );
760 }
761 } );
762 jQuery( "#mainwp-standalone-extensions-filer" ).on( "change", function () {
763 jQuery( "#mainwp-get-purchased-extensions-modal .ui.list .item.extension.addon-extension" ).toggle( 200 );
764 } );
765 jQuery( "#mainwp-api-extensions-filer" ).on( "change", function () {
766 jQuery( "#mainwp-get-purchased-extensions-modal .ui.list .item.extension.addon-integration" ).toggle( 200 );
767 } );
768 } );
769 </script>';
770
771 if ( ! empty( $installing_exts ) ) {
772 $html .= '<p>
773 <span class="extension_api_loading">
774 <i class="ui active inline loader tiny" style="display: none;"></i><span class="status hidden"></span>
775 </span>
776 </p> ';
777 }
778
779 $html .= '</div>';
780 $return = array(
781 'result' => 'SUCCESS',
782 'data' => $html,
783 );
784
785 wp_send_json( $return );
786 }
787
788 /**
789 * Method render_header()
790 *
791 * Render page header.
792 *
793 * @param string $shownPage The page slug shown at this moment.
794 *
795 * @uses \MainWP\Dashboard\MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook()
796 * @uses \MainWP\Dashboard\MainWP_Extensions_View::render_header()
797 */
798 public static function render_header( $shownPage = '' ) {
799 MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook();
800 MainWP_Extensions_View::render_header( $shownPage );
801 }
802
803 /**
804 * Method render_footer()
805 *
806 * Render page footer.
807 *
808 * @param string $shownPage The page slug shown at this moment.
809 *
810 * @uses \MainWP\Dashboard\MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook()
811 * @uses \MainWP\Dashboard\MainWP_Extensions_View::render_footer()
812 */
813 public static function render_footer( $shownPage ) {
814 MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook();
815 MainWP_Extensions_View::render_footer( $shownPage );
816 }
817
818 /**
819 * Method render()
820 *
821 * Render page content.
822 *
823 * @uses \MainWP\Dashboard\MainWP_Extensions_View::render()
824 * @uses \MainWP\Dashboard\MainWP_UI::render_top_header()
825 */
826 public static function render() {
827
828 $params = array(
829 'title' => esc_html__( 'Add-ons', 'mainwp' ),
830 );
831 MainWP_UI::render_top_header( $params );
832
833 MainWP_Extensions_View::render();
834 echo '</div>';
835 }
836
837 /**
838 * Method mainwp_help_content()
839 *
840 * Creates the MainWP Help Documentation List for the help component in the sidebar.
841 */
842 public static function mainwp_help_content() {
843 if ( isset( $_GET['page'] ) && 'Extensions' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
844 ?>
845 <p><?php esc_html_e( 'If you need help with your MainWP Add-ons, please review following help documents', 'mainwp' ); ?></p>
846 <div class="ui list">
847 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/dashboard/overview/manage-extensions" target="_blank"><i class="fa fa-book"></i> What are the MainWP Add-ons</a></div> <?php // NOSONAR - noopener - open safe. ?>
848 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/dashboard/overview/manage-extensions#order-add-ons" target="_blank"><i class="fa fa-book"></i> Order Add-on(s)</a></div> <?php // NOSONAR - noopener - open safe. ?>
849 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/dashboard/overview/manage-extensions#install-add-ons" target="_blank"><i class="fa fa-book"></i> Install Add-on(s)</a></div> <?php // NOSONAR - noopener - open safe. ?>
850 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/dashboard/overview/manage-extensions#activate-add-ons" target="_blank"><i class="fa fa-book"></i> Activate Add-on(s) API</a></div> <?php // NOSONAR - noopener - open safe. ?>
851 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/dashboard/overview/manage-extensions#update-add-ons" target="_blank"><i class="fa fa-book"></i> Updating Add-on(s)</a></div> <?php // NOSONAR - noopener - open safe. ?>
852 <div class="item"><i class="external alternate icon"></i> <a href="https://docs.mainwp.com/dashboard/overview/manage-extensions#remove-unneeded-add-ons" target="_blank"><i class="fa fa-book"></i> Remove Add-on(s)</a></div> <?php // NOSONAR - noopener - open safe. ?>
853 </div>
854 <?php
855 /**
856 * Action: mainwp_extensions_help_item
857 *
858 * Fires at the bottom of the help articles list in the Help sidebar on the Extensions page.
859 *
860 * Suggested HTML markup:
861 *
862 * <div class="item"><a href="Your custom URL">Your custom text</a></div>
863 *
864 * @since 5.2
865 */
866 do_action( 'mainwp_extensions_help_item' );
867 }
868 }
869 }
870