PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.5.0
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.5.0
4.5.4 4.2.1 4.2.2 4.2.3 4.5.0 4.5.2 4.5.3 4.2.0 4.1.18 4.1.17 4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 All 146 releases
ultimate-post-kit / includes / setup-wizard / init.php

init.php in Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets 4.5.0, at includes/setup-wizard/init.php

637 lines 20.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimatePostKit\Includes;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 // Load the Remote Data Handler
10 require_once __DIR__ . '/class-remote-data-handler.php';
11
12 use UltimatePostKit\Admin\ModuleService;
13 use Elementor\Plugin;
14 /**
15 * Overwrite the feedback method in the WP_Upgrader_Skin
16 * to suppress the normal feedback.
17 */
18
19 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
20
21 class Quiet_Upgrader_Skin extends \WP_Upgrader_Skin {
22 /*
23 * Suppress normal upgrader feedback / output
24 */
25 public function feedback( $string, ...$args ) {
26 /* no output */
27 }
28 }
29
30
31 class Setup_Wizard {
32
33 // Singleton instance
34 private static $instance = null;
35
36 // Constructor
37 private function __construct() {
38 $this->init_hooks();
39 }
40
41 // Get instance
42 public static function get_instance() {
43 if ( self::$instance == null ) {
44 self::$instance = new self();
45 }
46 return self::$instance;
47 }
48
49 // Initialize hooks
50 private function init_hooks() {
51 add_action( 'wp_ajax_setup_wizard_install_plugins', array( $this, 'install_plugins' ) );
52 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
53 add_action( 'admin_init', array( $this, 'activate_default_widgets' ) );
54 add_action( 'admin_init', array( $this, 'maybe_display_setup_wizard' ) );
55 add_action( 'admin_init', array( $this, 'check_manual_wizard_request' ) );
56
57 // NOTE: WordPress manages plugin/translation updates. Do not add filters
58 // that interfere with the built-in update pipeline (wp.org Guideline).
59 }
60
61 // Check for manual wizard requests
62 public function check_manual_wizard_request() {
63 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check of a GET flag to decide whether to render the setup wizard screen, no form data processed.
64 $is_setup_wizard_request = isset($_GET['upk_setup_wizard']) && $_GET['upk_setup_wizard'] === 'show';
65
66 if ( $is_setup_wizard_request ) {
67 // Use the same approach as first activation - completely override the page
68 add_action('admin_head', function() {
69 ?>
70 <style>
71 html, body {
72 height: 100%;
73 margin: 0;
74 padding: 0;
75 overflow: hidden;
76 }
77 #wpwrap, #wpcontent, #wpbody, #wpbody-content {
78 height: 100%;
79 padding: 0;
80 margin: 0;
81 }
82 #adminmenumain, #wpadminbar {
83 display: none;
84 }
85 </style>
86 <script>
87 jQuery(document).ready(function($) {
88 $('body').addClass('bdt-setup-wizard-active');
89 });
90 </script>
91 <?php
92
93 // Display setup wizard using the same method as first activation
94 $this->display_page();
95 });
96 }
97 }
98
99 // Display wizard in fullscreen mode
100 public function display_wizard_fullscreen() {
101 ?>
102 <style>
103 html, body {
104 height: 100%;
105 margin: 0;
106 padding: 0;
107 overflow: hidden;
108 }
109 #wpwrap, #wpcontent, #wpbody, #wpbody-content {
110 height: 100%;
111 padding: 0;
112 margin: 0;
113 }
114 #adminmenumain, #wpadminbar {
115 display: none;
116 }
117 </style>
118 <?php
119 // Directly output the wizard content
120 add_action('admin_footer', function() {
121 echo '<div id="upk-setup-wizard-container">';
122 $this->display_page();
123 echo '</div>';
124 ?>
125 <script>
126 jQuery(document).ready(function($) {
127 $('body').addClass('bdt-setup-wizard-active');
128 // Hide all other content and show only our wizard
129 $('#wpbody-content').html($('#upk-setup-wizard-container').html());
130 $('#upk-setup-wizard-container').remove();
131 });
132 </script>
133 <?php
134 }, 999);
135 }
136
137 // Get wizard HTML content
138 public function get_wizard_html() {
139 ob_start();
140 ?>
141 <div class="bdt-setup-wizard-overlay upk-setup-wizard ">
142 <div class="bdt-setup-wizard content-loaded">
143 <?php
144 require_once plugin_dir_path( BDTUPK__FILE__ ) . 'includes/setup-wizard/views/render.php';
145 ?>
146 </div>
147 </div>
148 <?php
149 return ob_get_clean();
150 }
151
152 // Check if this is first activation and display setup wizard if needed
153 public function maybe_display_setup_wizard() {
154 // Only check for first activation here
155 if ( get_option( 'bdtupk_setup_wizard_completed' ) === false ) {
156 // Set the flag so it doesn't run again
157 update_option( 'bdtupk_setup_wizard_completed', true );
158
159 // Add a header to ensure proper full-page display
160 add_action('admin_head', function() {
161 ?>
162 <style>
163 html, body {
164 height: 100%;
165 margin: 0;
166 padding: 0;
167 overflow: hidden;
168 }
169 #wpwrap, #wpcontent, #wpbody, #wpbody-content {
170 height: 100%;
171 padding: 0;
172 margin: 0;
173 }
174 #adminmenumain, #wpadminbar {
175 display: none;
176 }
177 </style>
178 <script>
179 jQuery(document).ready(function($) {
180 $('body').addClass('bdt-setup-wizard-active');
181 });
182 </script>
183 <?php
184
185 // Display setup wizard
186 $this->display_page();
187 });
188 }
189 }
190
191 // Keep the admin_menu method for reference but not hooked
192 public function admin_menu() {
193 add_submenu_page(
194 'ultimate_post_kit_options',
195 esc_html__( 'Setup Wizard', 'ultimate-post-kit' ),
196 esc_html__( 'Setup Wizard', 'ultimate-post-kit' ),
197 'manage_options',
198 'ultimate-post-kit-setup-wizard',
199 array( $this, 'display_page' )
200 );
201 }
202
203 public function display_page() {
204 ?>
205 <div class="bdt-setup-wizard-overlay upk-setup-wizard">
206 <div class="bdt-setup-wizard content-loaded">
207 <?php
208 require_once plugin_dir_path( BDTUPK__FILE__ ) . 'includes/setup-wizard/views/render.php';
209 ?>
210 </div>
211 </div>
212 <?php
213 }
214
215 // Enqueue necessary scripts
216 public function enqueue_scripts() {
217
218 $direction_suffix = is_rtl() ? '.rtl' : '';
219
220 wp_enqueue_style('bdt-uikit', BDTUPK_ADMIN_ASSETS_URL . 'css/bdt-uikit' . $direction_suffix . '.css', [], '3.17.0');
221 wp_enqueue_script('bdt-uikit', BDTUPK_ADMIN_ASSETS_URL . 'js/bdt-uikit.min.js', ['jquery'], '3.17.0', true);
222
223 wp_register_script( 'upk-setup-wizard', plugins_url( 'assets/js/setup-wizard.js', __FILE__ ), array( 'jquery' ), '1.0.0', true );
224 wp_register_style( 'upk-setup-wizard', plugins_url( 'assets/css/setup-wizard.css', __FILE__ ), array(), '1.0.0' );
225
226 wp_enqueue_script( 'upk-setup-wizard' );
227 wp_enqueue_style( 'upk-setup-wizard' );
228
229 wp_localize_script(
230 'upk-setup-wizard',
231 'BDT_SetupWizard',
232 array(
233 'ajax_url' => admin_url( 'admin-ajax.php' ),
234 'nonce' => wp_create_nonce( 'setup_wizard_nonce' ),
235 'is_fullscreen' => true
236 )
237 );
238 }
239
240 public static function get_widget_map() {
241 $arr_obj = ModuleService::get_widget_settings(
242 function ( $settings ) {
243 $core_widgets = $settings['settings_fields']['ultimate_post_kit_active_modules'];
244 return $core_widgets;
245 }
246 );
247 return $arr_obj;
248 }
249
250 // Install plugins
251 public function install_plugins() {
252 check_ajax_referer( 'setup_wizard_nonce', 'nonce' );
253
254 $plugin_slugs = isset( $_POST['plugins'] ) ? map_deep( wp_unslash( $_POST['plugins'] ), 'sanitize_text_field' ) : array();
255
256 if ( empty( $plugin_slugs ) || ! is_array( $plugin_slugs ) ) {
257 wp_send_json_error( array( 'message' => 'Invalid plugins array' ) );
258 }
259
260 if ( ! current_user_can( 'install_plugins' ) ) {
261 wp_send_json_error( array( 'message' => 'Unauthorized' ) );
262 }
263
264 include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
265 include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
266 include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
267 include_once ABSPATH . 'wp-admin/includes/plugin.php';
268
269 // Replace new \Plugin_Installer_Skin with new Quiet_Upgrader_Skin when output needs to be suppressed.
270 $skin = new Quiet_Upgrader_Skin();
271 // $skin = new \Plugin_Installer_Skin( array( 'api' => $api ) );
272 $upgrader = new \Plugin_Upgrader( $skin );
273
274 // $upgrader = new \Plugin_Upgrader();
275
276 $installedPlugins = get_plugins();
277 $results = array();
278
279 foreach ( $plugin_slugs as $plugin_slug ) {
280 // skip when the plugin is already active
281 if (is_plugin_active($plugin_slug)) {
282 $results[] = array(
283 'slug' => $plugin_slug,
284 'success' => true,
285 'message' => 'Installed and activated successfully',
286 );
287 continue;
288 }
289
290 // Download the plugin if the plugin is not installed
291 if (!isset($installedPlugins[$plugin_slug])) {
292 $slug = explode('/', $plugin_slug)[0];
293 $api = plugins_api( 'plugin_information', array( 'slug' => $slug ) );
294
295 if ( is_wp_error( $api ) ) {
296 $results[] = array(
297 'slug' => $plugin_slug,
298 'success' => false,
299 'message' => $api->get_error_message(),
300 );
301 continue;
302 }
303
304 $result = $upgrader->install( $api->download_link );
305 if ( is_wp_error( $result ) ) {
306 $results[] = array(
307 'slug' => $plugin_slug,
308 'success' => false,
309 'message' => $result->get_error_message(),
310 );
311 continue;
312 }
313 }
314
315 // active the plugin
316 if ( is_plugin_inactive($plugin_slug) && current_user_can( 'activate_plugins' ) ) {
317 $activation_result = activate_plugin( $plugin_slug );
318 if ( is_wp_error( $activation_result ) ) {
319 $results[] = array(
320 'slug' => $slug,
321 'success' => false,
322 'message' => $activation_result->get_error_message(),
323 );
324 continue;
325 }
326
327 $results[] = array(
328 'slug' => $plugin_slug,
329 'success' => true,
330 'message' => 'Installed and activated successfully',
331 );
332 }
333 }
334
335 ob_clean();
336 wp_send_json_success( array( 'results' => $results ) );
337 wp_die();
338 }
339
340 /**
341 * Get the main plugin file path for a given slug.
342 *
343 * @param string $slug Plugin slug.
344 * @return string|false Plugin file path or false if not found.
345 */
346 private function get_plugin_file( $slug ) {
347 $plugins = get_plugins();
348
349 foreach ( $plugins as $file => $plugin ) {
350 if ( strpos( $file, $slug ) !== false ) {
351 return $file;
352 }
353 }
354
355 return false;
356 }
357
358 /**
359 * Activate default widgets in setup wizard
360 */
361 public function activate_default_widgets() {
362 // List of widgets to activate by default
363 $default_active_widgets = array(
364 'alex-grid',
365 'alice-grid',
366 'alter-carousel',
367 'banner',
368 'buzz-list',
369 'carbon-slider',
370 'featured-list',
371 'news-ticker',
372 'pholox-slider',
373 'timeline',
374 'category',
375 'social-count',
376 'tag-cloud'
377 );
378
379 // Get current active modules
380 $active_modules = get_option('ultimate_post_kit_active_modules', array());
381
382 // Make sure $active_modules is an array
383 if (!is_array($active_modules)) {
384 $active_modules = array();
385 }
386
387 // Check if active_modules option exists and is not empty
388 // If it's a new installation or option doesn't exist, we'll set our defaults
389 $modified = false;
390
391 foreach ($default_active_widgets as $widget) {
392 // Only set if not already defined (prevents overriding user settings on existing installations)
393 if (!isset($active_modules[$widget])) {
394 $active_modules[$widget] = 'on';
395 $modified = true;
396 }
397 }
398
399 // Update the option if changes were made
400 if ($modified) {
401 update_option('ultimate_post_kit_active_modules', $active_modules);
402 }
403 }
404 }
405
406 // Initialize the Setup Wizard
407 Setup_Wizard::get_instance();
408
409 use Elementor\TemplateLibrary\Source_Local;
410
411 add_action('wp_ajax_import_elementor_template', function () {
412 check_ajax_referer( 'setup_wizard_nonce', 'nonce' );
413
414 if ( ! current_user_can( 'manage_options' ) ) {
415 wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'ultimate-post-kit' ) ) );
416 wp_die();
417 }
418
419 $json_url = isset( $_POST['import_url'] ) ? esc_url_raw( wp_unslash( $_POST['import_url'] ) ) : '';
420
421 $response = wp_safe_remote_get($json_url, array(
422 'timeout' => 60,
423 'sslverify' => false
424 ));
425
426 if (is_wp_error($response)) {
427 wp_send_json_error(['message' => esc_html__('Failed to fetch template from URL.', 'ultimate-post-kit')]);
428 wp_die();
429 }
430
431 $sourceData = wp_remote_retrieve_body($response);
432 $sourceData2 = json_decode($sourceData, true);
433
434 if (!$sourceData2 || !is_array($sourceData2)) {
435 wp_send_json_error(['message' => esc_html__('Failed to fetch template from URL.', 'ultimate-post-kit')]);
436 wp_die();
437 }
438
439 $temp_file = wp_upload_dir()['path'] . '/elementor_import_' . time() . '.json';
440 file_put_contents($temp_file, $sourceData);
441
442 // Initialize Elementor's Template Importer
443 if (!class_exists('\Elementor\TemplateLibrary\Source_Local')) {
444 wp_delete_file($temp_file);
445 wp_send_json_error(['message' => esc_html__('Elementor is not installed or activated!', 'ultimate-post-kit')]);
446 wp_die();
447 }
448
449 $manager = new Source_Local();
450 $templateData = $manager->import_template('elementor_template', $temp_file);
451 wp_delete_file($temp_file); // Delete temp file after import
452
453 if (is_wp_error($templateData) || !is_array($templateData) || empty($templateData[0]['template_id'])) {
454 wp_send_json_error(['message' => esc_html__('Failed to import template!', 'ultimate-post-kit')]);
455 wp_die();
456 }
457
458 $template_id = $templateData[0]['template_id'];
459 $metaData = get_post_meta($template_id);
460
461 $page_title = isset($_POST['title']) ? sanitize_text_field(wp_unslash($_POST['title'])) : esc_html__("No Title", 'ultimate-post-kit');
462
463 // Validate Elementor Data
464 if (!isset($metaData['_elementor_data'][0])) {
465 wp_send_json_error(['message' => esc_html__('Elementor data not found in template.', 'ultimate-post-kit')]);
466 wp_die();
467 }
468
469 $_elementor_data = wp_slash($metaData['_elementor_data'][0]);
470
471 // Create New Page
472 $new_post_id = wp_insert_post([
473 'post_type' => 'page',
474 'post_status' => empty($page_title) ? 'draft' : 'publish',
475 'post_title' => $page_title,
476 'post_content' => '',
477 ]);
478
479 if (is_wp_error($new_post_id)) {
480 wp_send_json_error(['message' => esc_html__('Failed to create page!', 'ultimate-post-kit')]);
481 wp_die();
482 }
483
484 // Assign Elementor Template Data
485 update_post_meta($new_post_id, '_elementor_data', $_elementor_data);
486
487 // Import Page Settings if available
488 if (isset($metaData['_elementor_page_settings'][0])) {
489 $_elementor_page_settings = is_serialized($metaData['_elementor_page_settings'][0])
490 ? unserialize($metaData['_elementor_page_settings'][0], ['allowed_classes' => false])
491 : $metaData['_elementor_page_settings'][0];
492 update_post_meta($new_post_id, '_elementor_page_settings', $_elementor_page_settings);
493 }
494
495 update_post_meta($new_post_id, '_elementor_template_type', $sourceData2['type'] ?? '');
496 update_post_meta($new_post_id, '_elementor_edit_mode', 'builder');
497 // update_post_meta($new_post_id, '_wp_page_template', !empty($pageTemplate) ? $pageTemplate : 'elementor_header_footer');
498
499 wp_send_json_success([
500 'message' => esc_html__('The template was imported successfully.', 'ultimate-post-kit'),
501 'ids' => $new_post_id,
502 'edit_link' => admin_url('post.php?post=' . $new_post_id . '&action=elementor'),
503 ]);
504 }
505 );
506
507
508 add_action('wp_ajax_import_upk_elementor_bundle_template', function () {
509 check_ajax_referer('setup_wizard_nonce', 'nonce');
510
511 if ( ! current_user_can( 'manage_options' ) ) {
512 wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'ultimate-post-kit' ) ) );
513 wp_die();
514 }
515
516 $file_url = isset($_POST['import_url']) ? esc_url_raw(wp_unslash($_POST['import_url'])) : '';
517
518 if (!filter_var($file_url, FILTER_VALIDATE_URL) || 0 !== strpos($file_url, 'http')) {
519 wp_send_json_error(['message' => esc_html__('Invalid import URL', 'ultimate-post-kit')]);
520 }
521
522 $remote_zip_request = wp_safe_remote_get($file_url, array(
523 'timeout' => 60,
524 'sslverify' => false,
525 ));
526
527 if (is_wp_error($remote_zip_request)) {
528 wp_send_json_error(['message' => esc_html__('Failed to fetch template from URL.', 'ultimate-post-kit')]);
529 }
530
531
532 if (200 !== $remote_zip_request['response']['code']) {
533 wp_send_json_error(['message' => esc_html__('Failed to fetch template from URL.', 'ultimate-post-kit')]);
534 }
535
536 $kit_zip_path = Plugin::$instance->uploads_manager->create_temp_file($remote_zip_request['body'], 'kit.zip');
537
538 $app = Plugin::$instance->app;
539 if (!$app) {
540 wp_send_json_error(['message' => esc_html__('Elementor app not available', 'ultimate-post-kit')]);
541 }
542
543 $import_export_module = $app->get_component('import-export');
544
545 try {
546 $result = $import_export_module->upload_kit($kit_zip_path, 'local');
547 $manifest = $result['manifest'] ?? [];
548 $plugins = $manifest['plugins'];
549
550 $missingPlugins = [];
551 foreach ($plugins as $plugin) {
552 $pluginSlug = $plugin['plugin'].".php";
553 if (is_plugin_inactive($pluginSlug)) {
554 $missingPlugins[] = $plugin;
555 }
556 }
557
558 if (count($missingPlugins)) {
559 wp_send_json_error([
560 'plugins' => $missingPlugins,
561 'message' => esc_html__('Missing plugins', 'ultimate-post-kit'),
562 ]);
563 }
564
565 $tmp_folder_id = $result['session'];
566 $includes = [];
567 $selectedCustomPostTypes = [];
568
569 if (isset($manifest['templates'])) {
570 $includes[] = 'templates';
571 }
572
573 if (isset($manifest['content'])) {
574 $includes[] = 'content';
575 }
576
577 if (isset($manifest['site-settings'])) {
578 $includes[] = 'settings';
579 }
580
581 if (isset($manifest['custom-post-type-title'])) {
582 $selectedCustomPostTypes = array_keys($manifest['custom-post-type-title']);
583 }
584
585 $settings = [
586 'id' => '',
587 'session' => $tmp_folder_id,
588 'include' => $includes,
589 'overrideConditions' => [],
590 'selectedCustomPostTypes' => $selectedCustomPostTypes,
591 ];
592
593 $import = $import_export_module->import_kit($tmp_folder_id, $settings, true);
594
595 Plugin::$instance->uploads_manager->enable_unfiltered_files_upload();
596
597 wp_send_json_success($import);
598 } catch (\Throwable $e) {
599 wp_send_json_error(['message' => esc_html__('Import failed: ', 'ultimate-post-kit') . esc_html($e->getMessage())]);
600 }
601 });
602
603 add_action('wp_ajax_import_upk_elementor_bundle_runner_template', function () {
604 check_ajax_referer('setup_wizard_nonce', 'nonce');
605
606 if ( ! current_user_can( 'manage_options' ) ) {
607 wp_send_json_error( array( 'message' => esc_html__( 'Unauthorized', 'ultimate-post-kit' ) ) );
608 wp_die();
609 }
610
611 $runner = isset($_POST['runner']) ? sanitize_text_field(wp_unslash($_POST['runner'])) : '';
612 $sessionId = isset($_POST['sessionId']) ? sanitize_text_field(wp_unslash($_POST['sessionId'])) : '';
613
614 if (!$runner || !$sessionId) {
615 wp_send_json_error(['message' => esc_html__('Required Param Is Missing.', 'ultimate-post-kit')]);
616 }
617
618 $app = Plugin::$instance->app;
619 if (!$app) {
620 wp_send_json_error(['message' => esc_html__('Elementor app not available.', 'ultimate-post-kit')]);
621 }
622
623 try {
624 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged, WordPress.PHP.IniSet.max_execution_time_Disallowed -- raise the limit only for this admin-triggered template import, which can exceed the default.
625 @ini_set('max_execution_time', 60 * 5);
626
627 $import_export_module = $app->get_component('import-export');
628 $import = $import_export_module->import_kit_by_runner($sessionId, $runner);
629
630 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- hooking into Elementor's own action, not a plugin-defined hook.
631 do_action('elementor/import-export/import-kit/runner/after-run', $import);
632 wp_send_json_success($import);
633 } catch (\Throwable $throwable) {
634 wp_send_json_error(['message' => $throwable->getMessage()]);
635 }
636 });
637