PluginProbe
Post Grid Gutenberg Blocks – PostX / 5.1.0
Post Grid Gutenberg Blocks – PostX v5.1.0
5.1.1 5.1.0 5.0.41 5.0.39 5.0.38 5.0.37 5.0.36 5.0.35 5.0.34 5.0.33 5.0.32 5.0.31 5.0.30 5.0.29 5.0.28 5.0.27 5.0.26 5.0.25 5.0.23 5.0.24 5.0.22 5.0.21 5.0.20 5.0.19 5.0.18 All 240 releases
ultimate-post / classes / Importer.php

Importer.php in Post Grid Gutenberg Blocks – PostX 5.1.0, at classes/Importer.php

930 lines 30.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Importer System
5 *
6 * @package ULTP\Importer
7 * @since 4.0.0
8 */
9
10 namespace ULTP;
11
12 use ULTP\Includes\Durbin\DurbinClient;
13
14 defined( 'ABSPATH' ) || exit;
15
16 /**
17 * Importer class.
18 *
19 * Handles starter site import, plugin installation, and REST API endpoints for Ultimate Post.
20 *
21 * @package ULTP\Importer
22 * @since 4.0.0
23 */
24 class Importer {
25 /**
26 * Setup class.
27 *
28 * @since 4.0.0
29 * @return NULL No return value.
30 */
31 public function __construct() {
32 add_action( 'wp_ajax_install_required_plugin', array( $this, 'install_required_plugin_callback' ) );
33 add_action( 'rest_api_init', array( $this, 'get_starter_rest_endpoint_callback' ) );
34 }
35
36 /**
37 * Register REST API endpoints for starter import and related actions.
38 *
39 * @since 4.0.0
40 * @return void No return value.
41 */
42 public function get_starter_rest_endpoint_callback() {
43 register_rest_route(
44 'ultp/v3',
45 '/single_page_import/',
46 array(
47 array(
48 'methods' => 'POST',
49 'callback' => array( $this, 'single_page_import' ),
50 'permission_callback' => function () {
51 return current_user_can( 'edit_others_posts' );
52 },
53 'args' => array(),
54 ),
55 )
56 );
57 register_rest_route(
58 'ultp/v3',
59 '/deletepost_getnewsletters/',
60 array(
61 array(
62 'methods' => 'POST',
63 'callback' => array( $this, 'deletepost_getnewsletters' ),
64 'permission_callback' => function () {
65 return current_user_can( 'manage_options' );
66 },
67 'args' => array(),
68 ),
69 )
70 );
71 register_rest_route(
72 'ultp/v3',
73 '/starter_import_content/',
74 array(
75 array(
76 'methods' => 'POST',
77 'callback' => array( $this, 'starter_import_content_callback' ),
78 'permission_callback' => function () {
79 return current_user_can( 'manage_options' );
80 },
81 'args' => array(),
82 ),
83 )
84 );
85 register_rest_route(
86 'ultp/v3',
87 '/starter_dummy_post/',
88 array(
89 array(
90 'methods' => 'POST',
91 'callback' => array( $this, 'starter_dummy_post_callback' ),
92 'permission_callback' => function () {
93 return current_user_can( 'manage_options' );
94 },
95 'args' => array(),
96 ),
97 )
98 );
99 }
100
101 /**
102 * Handle plugin installation via AJAX.
103 *
104 * @since 4.0.0
105 * @return void No return value.
106 */
107 public function install_required_plugin_callback() {
108 if ( ! current_user_can( 'install_plugins' ) ) {
109 return wp_send_json_success( 'You are not allowed to install plugin' );
110 }
111 if ( ! isset( $_REQUEST['wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['wpnonce'] ) ), 'ultp-admin-nonce' ) ) {
112 return '';
113 }
114 if ( ! current_user_can( 'install_plugins' ) ) {
115 return wp_send_json_success( 'You are not allowed to install plugin' );
116 }
117
118 if ( ! function_exists( 'get_plugins' ) ) {
119 require_once ABSPATH . 'wp-admin/includes/plugin.php';
120 }
121 if ( ! function_exists( 'plugins_api' ) ) {
122 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
123 }
124 if ( ! class_exists( 'WP_Upgrader' ) ) {
125 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
126 }
127
128 $msg = '';
129
130 $all_plugins = get_plugins();
131 $plugin = isset( $_POST['plugin'] ) ? ultimate_post()->ultp_rest_sanitize_params( json_decode( wp_unslash( $_POST['plugin'] ) ) ) : null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON object; ->path must match an installed plugin key or is used as a WordPress.org slug.
132
133 if ( $plugin && isset( $all_plugins ) && is_array( $all_plugins ) && array_key_exists( $plugin->path, $all_plugins ) ) {
134 $activated_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core option filter.
135 if ( is_array( $activated_plugins ) && in_array( $plugin->path, $activated_plugins ) ) {
136 $msg = '_already_installed_activated';
137 } else {
138 $activate = activate_plugin( $plugin->path, '', false );
139 $msg = is_wp_error( $activate ) ? '_only_activated_error' : '_only_activated_success';
140 }
141 } else {
142 $upgrader = new \Plugin_Upgrader( new \WP_Ajax_Upgrader_Skin() );
143 if ( isset( $plugin->download ) ) {
144 // Download.
145 $link = $api->download;
146 } else {
147 // From Org.
148 $api = plugins_api(
149 'plugin_information',
150 array(
151 'slug' => explode( '/', $plugin->path )[0],
152 'fields' => array(
153 'short_description' => false,
154 'sections' => false,
155 'requires' => false,
156 'rating' => false,
157 'ratings' => false,
158 'downloaded' => false,
159 'last_updated' => false,
160 'added' => false,
161 'tags' => false,
162 'compatibility' => false,
163 'homepage' => false,
164 'donate_link' => false,
165 ),
166 )
167 );
168 $link = $api->download_link;
169 }
170 $installed = $upgrader->install( $link );
171 $activate = activate_plugin( $plugin->path, '', false );
172
173 $msg = is_wp_error( $activate ) ? $link : '_download_activation_success';
174 }
175
176 if ( $msg == '_download_activation_error' || $msg == '_only_activated_error' ) {
177 wp_send_json_error( $msg );
178 } else {
179 wp_send_json_success( $msg );
180 }
181 }
182
183 /**
184 * Starter dummy post callback.
185 *
186 * @since 4.0.0
187 *
188 * @param \WP_REST_Request $server The REST request object.
189 */
190 function starter_dummy_post_callback( $server ) {
191 $post = $server->get_params();
192 $api_endpoint = isset( $post['api_endpoint'] ) ? sanitize_text_field( $post['api_endpoint'] ) : '';
193 $import_dummy = isset( $post['importDummy'] ) ? sanitize_text_field( $post['importDummy'] ) : '';
194
195 // SSRF protection: Validate API endpoint
196 if ( ! $this->is_allowed_api_endpoint( $api_endpoint ) ) {
197 return rest_ensure_response(
198 array(
199 'success' => false,
200 'message' => __( 'Invalid API endpoint. Only trusted domains are allowed.', 'ultimate-post' ),
201 )
202 );
203 }
204
205 $response = wp_safe_remote_post(
206 $api_endpoint . '/wp-json/importer/site_all_posts',
207 array(
208 'method' => 'POST',
209 'timeout' => 120,
210 'body' => ultimate_post()->get_template_request_body(
211 array(
212 'type' => 'site_posts',
213 'ultp_ver' => ULTP_VER,
214 ),
215 'starter_posts'
216 ),
217 )
218 );
219 if ( is_wp_error( $response ) ) {
220 return rest_ensure_response(
221 array(
222 'success' => false,
223 'response_data' => $response,
224 )
225 );
226 }
227 $response_data = json_decode( $response['body'] );
228 if ( ! $response_data->success ) {
229 return rest_ensure_response(
230 array(
231 'success' => false,
232 'returns' => $response_data,
233 )
234 );
235 }
236
237 // Dummy Post and Taxonomy creation.
238 $importable_posts = $response_data->posts;
239 $created_posts = $import_dummy != 'no' ? $this->starter_pack_dummy_post_creation( $importable_posts ) : array();
240 return rest_ensure_response(
241 array(
242 'success' => true,
243 'created_posts' => $created_posts,
244 )
245 );
246 }
247
248
249 function starter_import_content_callback( $server ) {
250 $post = $server->get_params();
251 $api_endpoint = isset( $post['api_endpoint'] ) ? sanitize_text_field( $post['api_endpoint'] ) : '';
252 $installed_plugin = isset( $post['installPlugin'] ) ? sanitize_text_field( $post['installPlugin'] ) : '';
253
254 if ( ! $this->is_allowed_api_endpoint( $api_endpoint ) ) {
255 return rest_ensure_response(
256 array(
257 'success' => false,
258 'message' => __( 'Invalid API endpoint. Only trusted domains are allowed.', 'ultimate-post' ),
259 )
260 );
261 }
262
263 // draft existing builder template.
264 $builder_parsed_args = array(
265 'post_type' => 'ultp_builder',
266 'post_status' => 'publish',
267 'posts_per_page' => -1,
268 );
269 $builder_posts = new \WP_Query( $builder_parsed_args );
270 if ( is_array( $builder_posts->posts ) && ! empty( $builder_posts->posts ) ) {
271 foreach ( $builder_posts->posts as $post ) {
272 wp_update_post(
273 array(
274 'ID' => $post->ID,
275 'post_status' => 'draft',
276 )
277 );
278 }
279 }
280
281 $response = wp_safe_remote_post(
282 $api_endpoint . '/wp-json/importer/single',
283 array(
284 'method' => 'POST',
285 'timeout' => 120,
286 'body' => ultimate_post()->get_template_request_body(
287 array(
288 'ultp_ver' => ULTP_VER,
289 ),
290 'starter_content'
291 ),
292 )
293 );
294
295 if ( is_wp_error( $response ) ) {
296 return rest_ensure_response(
297 array(
298 'success' => false,
299 'response_data' => $response,
300 )
301 );
302 }
303 $response_data = json_decode( $response['body'] );
304 if ( ! $response_data->success ) {
305 return rest_ensure_response(
306 array(
307 'success' => false,
308 'response_data' => $response_data,
309 )
310 );
311 }
312
313 // site logo handle.
314 if ( ! get_option( 'site_logo', '' ) && isset( $response_data->site_logo ) && $response_data->site_logo ) {
315 update_option( 'site_logo', $this->upload_post_cat_media( $response_data->site_logo, '', 'Site Logo' ) );
316
317 if ( isset( $response_data->dark_logo ) && $response_data->dark_logo ) {
318 $dark_logo = $this->upload_post_cat_media( $response_data->dark_logo, '', 'Site Dark Logo' );
319 update_option( 'ultp_site_dark_logo', wp_get_attachment_url( $dark_logo ) );
320 }
321 }
322
323 // Templates Insertion.
324 $inserted_meta = array();
325 $inserted_pages = array();
326 $inserted_header_footer = array();
327 $importable_pages = $response_data->content;
328
329 $exclude_post_type = is_object( $post ) ? ( $post->excludepages ?? null ) : ( $post['excludepages'] ?? null );
330 $excludepages = json_decode( ultimate_post()->ultp_rest_sanitize_params( stripslashes( $exclude_post_type ) ), true );
331
332 if ( ! empty( $importable_pages ) ) {
333 foreach ( $importable_pages as $key => $val ) {
334 $title = $val->name;
335 if ( is_array( $excludepages ) && ! in_array( $title, $excludepages ) ) {
336 $post_type = $val->type;
337 $p_content = str_replace( array( 'u0022', 'u002d' ), array( '\u0022', '\u002d' ), $val->content );
338 $p_content = str_replace( array( 'u003c', 'u003e', 'currentPostId' ), array( '<', '>', 'current_PostId' ), $p_content );
339 $post_id = wp_insert_post(
340 array(
341 'post_title' => $title,
342 'post_type' => $post_type,
343 'post_status' => 'publish',
344 'post_content' => $p_content,
345 )
346 );
347 if ( $post_id ) {
348 update_post_meta( $post_id, '__ultp_starter_pack_post', true );
349 $inserted_pages[ $post_id ] = $title;
350
351 if ( isset( $val->ultp_template ) && $val->ultp_template === 'ultp_page_template' ) {
352 update_post_meta( $post_id, '_wp_page_template', 'ultp_page_template' );
353 }
354 if ( isset( $val->home_page ) && $val->home_page == 'home_page' ) {
355 if ( get_option( 'show_on_front', true ) != 'page' ) {
356 update_option( 'show_on_front', 'page' );
357 }
358 update_option( 'page_on_front', $post_id );
359 $inserted_header_footer['home_page'] = $post_id;
360 }
361 if ( isset( $val->ultp_builder_type ) && ( $val->ultp_builder_type == 'header' || $val->ultp_builder_type == 'footer' ) ) {
362 $inserted_header_footer[] = $post_id;
363 }
364 if ( $post_type == 'ultp_builder' && $val->ultp_builder_type ) {
365 $conditions_settings = get_option( 'ultp_builder_conditions', array() );
366 $conditions = $response_data->conditions;
367 $ultp_builder_type = $val->ultp_builder_type;
368 $ultp_builder_id = $val->id;
369 $ultp_builder_conditions = $conditions->$ultp_builder_type;
370 $ultp_builder_conditions = $ultp_builder_conditions->$ultp_builder_id;
371 $conditions_settings[ $ultp_builder_type ][ $post_id ] = $ultp_builder_conditions;
372
373 update_post_meta( $post_id, '__ultp_builder_type', $val->ultp_builder_type );
374 update_option( 'ultp_builder_conditions', $conditions_settings );
375 }
376 if ( isset( $val->meta ) && is_array( $val->meta ) ) {
377 foreach ( $val->meta as $k => $v ) {
378 update_post_meta( $post_id, $k, str_replace( array( 'u0022', 'u002d' ), array( '\u0022', '\u002d' ), $v ) );
379 }
380 }
381 if ( isset( $val->_ultp_css ) ) {
382 $this->save_post_block_css( $post_id, str_replace( array( 'u0022', 'u002d' ), array( '\u0022', '\u002d' ), $val->_ultp_css ), '' );
383 }
384 $inserted_meta[ $post_id ] = $val->_ultp_css;
385 }
386 }
387 }
388 }
389
390 // Menu Creation.
391 $menuCreated = array();
392 $menu_item_parent = array();
393 $response_menu = $response_data->menu;
394 if ( ! empty( $response_menu ) && is_array( $response_menu ) ) {
395 foreach ( $response_menu as $key => $menu ) {
396 $menu_exists = wp_get_nav_menu_object( $menu->title );
397 if ( $menu_exists ) {
398 wp_delete_term( $menu_exists->term_id, $menu_exists->taxonomy );
399 }
400 $menu_id = wp_create_nav_menu( $menu->title );
401 if ( isset( $menu->items ) && $menu_id && ! empty( $menu->items ) ) {
402 foreach ( $menu->items as $key => $v ) {
403 $inserted = array_search( $v->title, $inserted_pages );
404 if ( $inserted || $v->type == 'custom' || $v->type == 'category' ) {
405 if (
406 ( $v->type == 'category' && get_term_by( 'name', $v->title, 'category' ) )
407 || $v->type != 'category'
408 ) {
409 $item = array(
410 'menu-item-title' => $v->title,
411 'menu-item-status' => 'publish',
412 );
413 $item['menu-item-object'] = $v->type;
414 $item['menu-item-type'] = $v->post_type;
415 if ( isset( $v->menu_item_parent ) && $v->menu_item_parent ) {
416 $parent_id = $this->find_parent_nav_item( wp_get_nav_menu_items( $menu_id ), $v->menu_item_parent );
417 $menu_item_parent[ $v->title ] = $parent_id;
418 $item['menu-item-parent-id'] = $parent_id;
419 }
420 if ( $v->type == 'custom' ) {
421 $item['menu-item-url'] = $v->url ? $v->url : home_url( '/' );
422 } elseif ( $v->type == 'category' ) {
423 $fetched_term = get_term_by( 'name', $v->title, 'category' );
424 if ( $fetched_term ) {
425 $item['menu-item-object-id'] = $fetched_term->term_id;
426 }
427 } else {
428 $item['menu-item-object-id'] = $inserted;
429 }
430 wp_update_nav_menu_item( $menu_id, 0, $item );
431 }
432 }
433 }
434 update_term_meta( $menu_id, '__ultp_starter_pack_term', 'postx_term' );
435 $menuCreated[ $menu_id ] = $item;
436 }
437 }
438 }
439
440 // Navigation Creation for Header Footer Builder.
441 $navCreated = array();
442 $navigation = $response_data->navigation; // returned from importer site.
443 if ( ! empty( $inserted_header_footer ) && ! empty( $navigation ) ) {
444 foreach ( $inserted_header_footer as $key => $builderID ) {
445 $builder_post = get_post( $builderID );
446 $builder_post_content = $builder_post->post_content;
447 foreach ( $navigation as $key => $v ) {
448 $site_navID = $v->id;
449 if ( strpos( $builder_post_content, 'wp:navigation' ) > -1 && ( strpos( $builder_post_content, '{"ref":' . $site_navID . ',' ) > -1 || strpos( $builder_post_content, '{"ref":' . $site_navID . '}' ) > -1 ) ) {
450
451 $current_parsed_args = array(
452 'post_type' => 'wp_navigation',
453 'post_status' => 'publish',
454 'orderby' => 'date',
455 'order' => 'ASC',
456 'posts_per_page' => -1,
457 );
458 $navigation_current_posts = new \WP_Query( $current_parsed_args );
459 $navigation_current_posts = $navigation_current_posts->posts;
460
461 // check for currently same navigation exist or not.
462 $new_navID = '';
463 if ( ! $new_navID ) {
464 $menu_exists = wp_get_nav_menu_object( $v->post_title );
465 if ( $menu_exists ) {
466 $menu_blocks = \WP_Classic_To_Block_Menu_Converter::convert( $menu_exists );
467 $new_navID = wp_insert_post(
468 array(
469 'post_content' => $menu_blocks,
470 'post_title' => $menu_exists->name,
471 'post_name' => $menu_exists->slug,
472 'post_status' => 'publish',
473 'post_type' => 'wp_navigation',
474 )
475 );
476 update_post_meta( $new_navID, '__ultp_starter_pack_post', true );
477 }
478 }
479 if ( strpos( $builder_post_content, '{"ref":' . $site_navID . ',' ) > -1 ) {
480 $builder_post_content = str_replace( '{"ref":' . $site_navID . ',', '{"ref":' . $new_navID . ',', $builder_post_content );
481 } elseif ( strpos( $builder_post_content, '{"ref":' . $site_navID . '}' ) ) {
482 $builder_post_content = str_replace( '{"ref":' . $site_navID . '}', '{"ref":' . $new_navID . '}', $builder_post_content );
483 }
484
485 wp_update_post(
486 array(
487 'ID' => $builderID,
488 'post_content' => str_replace( array( 'u0022', 'u002d' ), array( '\u0022', '\u002d' ), $builder_post_content ),
489 )
490 );
491 $navCreated[] = $new_navID;
492 }
493 }
494 }
495 }
496
497 // Other Plugin Content creation.
498 $other_plugin_content = $response_data->other_plugin_content;
499 $contact_forms = $other_plugin_content->contact_form7;
500 $mc4wp = $other_plugin_content->mc4wp;
501 $wow_optin_template_id = isset( $other_plugin_content->wow_optin->id ) ? $other_plugin_content->wow_optin->id : 0;
502
503 // contact form 7 post create.
504 if ( is_array( $contact_forms ) && ! empty( $contact_forms ) ) {
505 foreach ( $contact_forms as $post ) {
506 $post_id = wp_insert_post(
507 array(
508 'post_title' => $post->post_title,
509 'post_type' => 'wpcf7_contact_form',
510 'post_status' => 'publish',
511 'post_content' => str_replace( array( 'u002d', '<[email protected]>' ), array( '\u002d', '' ), $post->post_content ),
512 )
513 );
514 update_post_meta( $post_id, '_form', $post->_form );
515 update_post_meta( $post_id, '_hash', $post->_hash );
516 update_post_meta( $post_id, '__ultp_starter_pack_post', true );
517 }
518 }
519
520 // mailchimp post create.
521 if ( ! empty( $inserted_pages ) && ! empty( $mc4wp ) ) {
522 foreach ( $inserted_pages as $id => $p_t ) {
523 $current_post = get_post( $id );
524 $current_post_content = $current_post->post_content;
525 foreach ( $mc4wp as $key => $v ) {
526 $parsed_args = array(
527 'post_type' => 'mc4wp-form',
528 'post_status' => 'publish',
529 'posts_per_page' => -1,
530 );
531 $mc4wp_forms_data = new \WP_Query( $parsed_args );
532 $mc4wp_forms_current_posts = $mc4wp_forms_data->posts;
533
534 $site_ID = $v->id;
535 if ( strpos( $current_post_content, '[mc4wp_form id=' . $site_ID . ']' ) > -1 ) {
536 $new_ID = '';
537 // check for same mailchimp post.
538 if ( ! empty( $mc4wp_forms_current_posts ) ) {
539 foreach ( $mc4wp_forms_current_posts as $key => $val ) {
540 if ( $val->post_title == $v->post_title ) {
541 $new_ID = $val->ID;
542 }
543 }
544 }
545 if ( ! $new_ID ) {
546 $new_ID = wp_insert_post(
547 array(
548 'post_title' => $v->post_title,
549 'post_type' => 'mc4wp-form',
550 'post_status' => 'publish',
551 'post_content' => $v->post_content,
552 )
553 );
554 update_post_meta( $new_ID, '__ultp_starter_pack_post', true );
555 }
556
557 $current_post_content = str_replace( '[mc4wp_form id=' . $site_ID . ']', '[mc4wp_form id=' . $new_ID . ']', $current_post_content );
558 wp_update_post(
559 array(
560 'ID' => $id,
561 'post_content' => str_replace( array( 'u0022', 'u002d' ), array( '\u0022', '\u002d' ), $current_post_content ),
562 )
563 );
564 }
565 }
566 }
567 }
568 $wow_optin_template_import_status = 'successfully working';
569
570 // $activated_plugins = $installed_plugin == 'yes' ? apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) : array();
571 // if ( in_array( 'optin/optin.php', $activated_plugins ) && $wow_optin_template_id && $installed_plugin == 'yes' ) {
572 // try {
573 // if ( class_exists( '\OPTN\Includes\Db', true ) && method_exists( '\OPTN\Includes\Db', 'get_instance' ) ) {
574 // $db_instance = \OPTN\Includes\Db::get_instance();
575 // if ( is_object( $db_instance ) && is_callable( array( $db_instance, 'activate_recipe' ) ) ) {
576 // $db_instance->activate_recipe(
577 // $wow_optin_template_id,
578 // array(
579 // 'disable_others' => true,
580 // )
581 // );
582 // }
583 // }
584 // } catch ( \Throwable $e ) {
585 // $wow_optin_template_import_status = 'have any problem to import Optin template.';
586 // }
587 // }
588 // $wow_optin_template_import_status
589 return rest_ensure_response(
590 array(
591 'success' => true,
592 'inserted_pages' => $inserted_pages,
593 'inserted_meta' => $inserted_meta,
594 'navCreated' => $navCreated,
595 'menuCreated' => $menuCreated,
596 'menu_item_parent' => $menu_item_parent,
597 'inserted_header_footer' => $inserted_header_footer,
598 'wow_optin_status' => $installed_plugin,
599 )
600 );
601 }
602
603
604 /**
605 * Find Menu Parent item
606 *
607 * @since 4.0.0
608 *
609 * @param array $menu_items Array of menu items.
610 * @param string $title Title of the parent menu item to find.
611 */
612 public function find_parent_nav_item( $menu_items, $title ) {
613 if ( $menu_items ) {
614 foreach ( $menu_items as $menu_item ) {
615 if ( $menu_item->title == $title ) {
616 return $menu_item->ID;
617 }
618 }
619 }
620 return 0;
621 }
622
623 /**
624 * Save CSS of pages
625 *
626 * Saves the provided CSS content for a specific post ID. Depending on the operation type,
627 * it can also handle deletion of the CSS.
628 *
629 * @since 4.0.0
630 *
631 * @param int $id The post ID.
632 * @param string $css The CSS content to save.
633 * @param string $type The operation type (e.g., 'delete').
634 * @throws Exception If the CSS cannot be saved or deleted.
635 */
636 public function save_post_block_css( $id, $css = '', $type = '' ) {
637 try {
638 global $wp_filesystem;
639 if ( ! $wp_filesystem ) {
640 require_once ABSPATH . 'wp-admin/includes/file.php';
641 }
642
643 $upload_dir_url = wp_upload_dir();
644 $dir = trailingslashit( $upload_dir_url['basedir'] ) . 'ultimate-post/';
645
646 $post_id = (int) $id;
647 $filename = "ultp-css-{$post_id}.css";
648 $ultp_block_css = $css;
649
650 if ( $ultp_block_css ) {
651 // Set Saving ID for Clean Cache.
652 ultimate_post()->set_setting( 'save_version', wp_rand( 1, 1000 ) );
653
654 update_post_meta( $post_id, '_ultp_active', 'yes' );
655
656 WP_Filesystem( false, $upload_dir_url['basedir'], true );
657 if ( ! $wp_filesystem->is_dir( $dir ) ) {
658 $wp_filesystem->mkdir( $dir );
659 }
660 if ( ! $wp_filesystem->put_contents( $dir . $filename, $ultp_block_css ) ) {
661 throw new Exception(__('CSS can not be saved due to permission!!!', 'ultimate-post')); //phpcs:ignore
662 }
663 update_post_meta( $post_id, '_ultp_css', $ultp_block_css );
664 return array(
665 'success' => true,
666 'message' => __( 'PostX css file has been updated.', 'ultimate-post' ),
667 );
668 }
669 if ( $type == 'delete' && file_exists( $dir . $filename ) ) {
670 wp_delete_file( $dir . $filename );
671 }
672 } catch ( Exception $e ) {
673 return array(
674 'success' => false,
675 'message' => $e->getMessage(),
676 );
677 }
678 }
679
680 /**
681 * Delete previos site import post/pages
682 *
683 * @since 4.0.0
684 *
685 * @param \WP_REST_Request $server The REST request object.
686 */
687 public function deletepost_getnewsletters( $server ) {
688 $post = $server->get_params();
689 $deletePrevious = isset( $post['deletePrevious'] ) ? sanitize_text_field( $post['deletePrevious'] ) : '';
690 $get_newsletter = isset( $post['get_newsletter'] ) ? sanitize_text_field( $post['get_newsletter'] ) : '';
691 $deleted_terms = array();
692 $deleted_posts = array();
693 if ( $deletePrevious == 'yes' ) {
694 $site_logo = get_option( 'site_logo', '' );
695 global $wpdb;
696 $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s", '__ultp_starter_pack_post' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- One-off cleanup before import; must read live data.
697 $terms = $wpdb->get_col( $wpdb->prepare( "SELECT term_id FROM {$wpdb->termmeta} WHERE meta_key = %s", '__ultp_starter_pack_term' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- One-off cleanup before import; must read live data.
698
699 if ( isset( $post_ids ) && is_array( $post_ids ) ) {
700 foreach ( $post_ids as $post_id ) {
701 if ( get_post_type( $post_id ) == 'ultp_builder' ) {
702 $conditions = get_option( 'ultp_builder_conditions', array() );
703 $builder_type = get_post_meta( $post_id, '__ultp_builder_type', true );
704 if ( isset( $conditions[ $builder_type ][ $post_id ] ) ) {
705 unset( $conditions[ $builder_type ][ $post_id ] );
706 update_option( 'ultp_builder_conditions', $conditions );
707 }
708 }
709 if ( $site_logo == $post_id ) {
710 update_option( 'site_logo', '' );
711 }
712 $deleted_posts[] = $post_id;
713 wp_delete_post( $post_id, true );
714 $this->save_post_block_css( $post_id, '', 'delete' );
715 }
716 }
717 if ( isset( $terms ) && is_array( $terms ) ) {
718 foreach ( $terms as $term_id ) {
719 $deleted_terms[] = $term_id;
720 $term = get_term( $term_id );
721 wp_delete_term( $term_id, $term->taxonomy );
722 }
723 }
724 }
725 if ( $get_newsletter == 'yes' ) {
726 DurbinClient::send( DurbinClient::ACTIVATE_ACTION );
727 }
728
729 return rest_ensure_response(
730 array(
731 'success' => true,
732 'term' => $deleted_terms,
733 'posts' => $deleted_posts,
734 )
735 );
736 }
737
738 /**
739 * Import Single Template
740 *
741 * @since 4.0.0
742 *
743 * @param \WP_REST_Request $server The REST request object.
744 */
745 public function single_page_import( $server ) {
746 $post = $server->get_params();
747 $id = isset( $post['ID'] ) ? sanitize_text_field( $post['ID'] ) : '';
748 $api_endpoint = isset( $post['api_endpoint'] ) ? sanitize_text_field( $post['api_endpoint'] ) : '';
749
750 if ( $id && $api_endpoint ) {
751 // SSRF protection: Validate API endpoint
752 if ( ! $this->is_allowed_api_endpoint( $api_endpoint ) ) {
753 return rest_ensure_response(
754 array(
755 'success' => false,
756 'message' => __( 'Invalid API endpoint. Only trusted domains are allowed.', 'ultimate-post' ),
757 )
758 );
759 }
760 $import_single = ultimate_post()->get_template_request_body(
761 array(
762 'id' => $id,
763 'type' => 'single',
764 'ultp_ver' => ULTP_VER,
765 ),
766 'single_page'
767 );
768 $response = wp_safe_remote_post(
769 $api_endpoint . '/wp-json/importer/single',
770 array(
771 'method' => 'POST',
772 'timeout' => 120,
773 'body' => $import_single,
774 )
775 );
776 if ( is_wp_error( $response ) ) {
777 return rest_ensure_response(
778 array(
779 'success' => false,
780 'response_data' => $response,
781 )
782 );
783 }
784 $response_data = json_decode( wp_remote_retrieve_body( $response ) );
785 if ( empty( $response_data->success ) || ! isset( $response_data->content[0] ) ) {
786 return rest_ensure_response(
787 array(
788 'success' => false,
789 )
790 );
791 }
792 $content = $response_data->content[0];
793 return rest_ensure_response(
794 array(
795 'success' => true,
796 'content' => $content,
797 )
798 );
799 }
800 }
801
802 /**
803 * Create dummy posts
804 *
805 * @since 4.0.0
806 *
807 * @param array $importable_posts Array of importable post objects.
808 */
809 public function starter_pack_dummy_post_creation( $importable_posts ) {
810 $added_posts = array();
811 if ( is_array( $importable_posts ) && ! empty( $importable_posts ) ) {
812 foreach ( $importable_posts as $post ) {
813 $post_id = wp_insert_post(
814 array(
815 'post_title' => $post->post_title,
816 'post_type' => 'post',
817 'post_status' => 'publish',
818 'post_content' => str_replace( 'u002d', '\u002d', $post->post_content ),
819 )
820 );
821 $image_id = $this->upload_post_cat_media( $post->img_src, $post_id, $post->post_title );
822 set_post_thumbnail( $post_id, $image_id );
823
824 update_post_meta( $post_id, '__ultp_starter_pack_post', true );
825 if ( isset( $post->_ultp_css ) && $post->_ultp_css ) {
826 $this->save_post_block_css( $post_id, str_replace( array( 'u0022', 'u002d' ), array( '\u0022', '\u002d' ), $post->_ultp_css ), '' );
827 }
828 $post_category = $post->post_category;
829 $k = 0;
830 $cat_ids = array();
831 if ( is_array( $post_category ) && ! empty( $post_category ) ) {
832 foreach ( $post_category as $i => $cat ) {
833 $cat_id = $this->starter_pack_dummy_taxonomy_creation( $cat->name, $cat->slug, $cat->img_src, 'category' );
834 wp_set_post_terms( $post_id, $cat_id, 'category', $k == 0 ? false : true );
835 ++$k;
836 $cat_ids[] = $cat_id;
837 }
838 }
839 $post_tags = $post->post_tags;
840 $tag_ids = array();
841 $j = 0;
842 if ( is_array( $post_tags ) && ! empty( $post_tags ) ) {
843 foreach ( $post_tags as $i => $tag ) {
844 $tag_id = wp_set_post_terms( $post_id, $tag->slug, 'post_tag', $j == 0 ? false : true );
845 if ( ! is_wp_error( $tag_id ) && is_array( $tag_id ) && isset( $tag_id[0] ) ) {
846 update_term_meta( $tag_id[0], '__ultp_starter_pack_term', 'postx_term' );
847 $tag_ids[] = $tag_id[0];
848 }
849 ++$j;
850 }
851 }
852 $added_posts[ $post_id ] = array(
853 'title' => $post->post_title,
854 'cat_id' => $cat_ids,
855 'tag_ids' => $tag_ids,
856 );
857 }
858 }
859 return $added_posts;
860 }
861
862 /**
863 * Create dummy category of posts
864 *
865 * @since 4.0.0
866 *
867 * @param STRING $name The name of the taxonomy term.
868 * @param STRING $slug The slug for the taxonomy term.
869 * @param STRING $img_src (Optional) The image source URL for the taxonomy term.
870 * @param STRING $taxonomy (Optional) The taxonomy type.
871 */
872 public function starter_pack_dummy_taxonomy_creation( $name, $slug, $img_src = '', $taxonomy = '' ) {
873 $new_taxonomy = get_term_by( 'slug', $slug, $taxonomy );
874 if ( ! $new_taxonomy ) {
875 $new_term = wp_insert_term(
876 $name,
877 $taxonomy,
878 array(
879 'slug' => $slug,
880 )
881 );
882 if ( $new_term ) {
883 if ( $img_src ) {
884 $image_id = $this->upload_post_cat_media( $img_src, '', $name );
885 update_term_meta( $new_term['term_id'], 'ultp_category_image', $image_id );
886 }
887 update_term_meta( $new_term['term_id'], '__ultp_starter_pack_term', 'postx_term' );
888
889 return $new_term['term_id'];
890 }
891 } else {
892 return $new_taxonomy->term_id;
893 }
894 }
895
896 /**
897 * Upload image for post/category
898 *
899 * @since 4.0.0
900 *
901 * @param STRING $src The source URL of the image.
902 * @param INT $post_id The post ID to attach the image to.
903 * @param STRING $title The title for the image.
904 */
905 public function upload_post_cat_media( $src, $post_id, $title ) {
906 if ( ! $src ) {
907 return 0;
908 }
909
910 require_once ABSPATH . 'wp-admin/includes/media.php';
911 require_once ABSPATH . 'wp-admin/includes/file.php';
912 require_once ABSPATH . 'wp-admin/includes/image.php';
913
914 $image_id = media_sideload_image( $src, $post_id, $title, 'id' );
915 update_post_meta( $image_id, '__ultp_starter_pack_post', true );
916 return $image_id;
917 }
918
919 /**
920 * Validate if the API endpoint is from an allowed domain (SSRF protection).
921 *
922 * @since 5.0.6
923 * @param string $url The URL to validate.
924 * @return bool True if allowed, false otherwise.
925 */
926 private function is_allowed_api_endpoint( $url ) {
927 return ultimate_post()->is_allowed_template_endpoint( $url );
928 }
929 }
930