--- a/wp-travel/app/build/admin-settings.asset.php
+++ b/wp-travel/app/build/admin-settings.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill', 'wp-primitives'), 'version' => 'f0c07ff08c0a34ad6c6e');
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill', 'wp-primitives'), 'version' => '06727d53b0b0af001826');
--- a/wp-travel/app/build/admin-setup-page.asset.php
+++ b/wp-travel/app/build/admin-setup-page.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill'), 'version' => 'f10fcaee3f7869de22ed');
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill'), 'version' => 'e614d4902e89ad1679d1');
--- a/wp-travel/app/build/admin-trip-options.asset.php
+++ b/wp-travel/app/build/admin-trip-options.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-date', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill', 'wp-primitives'), 'version' => '730a0bbb531673ced21d');
+<?php return array('dependencies' => array('lodash', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-date', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-polyfill', 'wp-primitives'), 'version' => 'ac2df25e443ca002b971');
--- a/wp-travel/app/build/admin.asset.php
+++ b/wp-travel/app/build/admin.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'c9c398aae7cd678360ee');
+<?php return array('dependencies' => array('wp-polyfill'), 'version' => 'ff0a4631c463de5805d6');
--- a/wp-travel/core/ajax/clone.php
+++ b/wp-travel/core/ajax/clone.php
@@ -24,6 +24,8 @@
}
+
+
/**
* Clone.
*
@@ -37,6 +39,17 @@
WP_Travel_Helpers_REST_API::response( $permission );
}
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to clone trips.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
+ }
+
// Nonce already verified above and data will be sanitize with wptravel_sanitize_array function.
$payload = wptravel_sanitize_array( $_POST ); // @phpcs:ignore
--- a/wp-travel/core/ajax/coupon.php
+++ b/wp-travel/core/ajax/coupon.php
@@ -30,8 +30,11 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
+
+
$payload = json_decode( file_get_contents( 'php://input' ) );
$payload = is_object( $payload ) ? (array) $payload : array();
$payload = wptravel_sanitize_array( $payload );
@@ -54,6 +57,18 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get coupon code.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$payload = WP_Travel::get_sanitize_request();
@@ -78,6 +93,18 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to update coupon.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$payload = json_decode( file_get_contents( 'php://input' ) );
--- a/wp-travel/core/ajax/enquiry.php
+++ b/wp-travel/core/ajax/enquiry.php
@@ -23,12 +23,24 @@
*/
public static function get_enquiry_details() {
- $user = wp_get_current_user();
+ // $user = wp_get_current_user();
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get trip enquiry.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$payload = WP_Travel::get_sanitize_request();
@@ -47,13 +59,25 @@
public static function update_enquiry_details() {
- $user = wp_get_current_user();
+ // $user = wp_get_current_user();
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to update trip enquiry.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$payload = json_decode( file_get_contents( 'php://input' ) );
--- a/wp-travel/core/ajax/payments.php
+++ b/wp-travel/core/ajax/payments.php
@@ -22,6 +22,18 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get payment details.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$payload = WP_Travel::get_sanitize_request();
--- a/wp-travel/core/ajax/pricings.php
+++ b/wp-travel/core/ajax/pricings.php
@@ -11,12 +11,22 @@
public static function get_pricings() {
- $user = wp_get_current_user();
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get trip pricing.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
/**
@@ -29,13 +39,22 @@
public static function remove_trip_pricing() {
- $user = wp_get_current_user();
-
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to remove trip pricing.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
/**
--- a/wp-travel/core/ajax/settings.php
+++ b/wp-travel/core/ajax/settings.php
@@ -7,20 +7,39 @@
public static function init() {
// get settings.
add_action( 'wp_ajax_wptravel_get_settings', array( __CLASS__, 'get_settings' ) );
- add_action( 'wp_ajax_nopriv_wptravel_get_settings', array( __CLASS__, 'get_settings' ) );
+ // add_action( 'wp_ajax_nopriv_wptravel_get_settings', array( __CLASS__, 'get_settings' ) );
// Update settings.
add_action( 'wp_ajax_wp_travel_update_settings', array( __CLASS__, 'update_settings' ) );
- add_action( 'wp_ajax_nopriv_wp_travel_update_settings', array( __CLASS__, 'update_settings' ) );
+ // add_action( 'wp_ajax_nopriv_wp_travel_update_settings', array( __CLASS__, 'update_settings' ) );
add_action( 'wp_ajax_wp_travel_reset_cached_page_list', array( __CLASS__, 'reset_cached_page_list' ) );
- add_action( 'wp_ajax_nopriv_wp_travel_reset_cached_page_list', array( __CLASS__, 'reset_cached_page_list' ) );
+ // add_action( 'wp_ajax_nopriv_wp_travel_reset_cached_page_list', array( __CLASS__, 'reset_cached_page_list' ) );
add_action( 'wp_ajax_wptravel_wpml_migrate', array( __CLASS__, 'force_migrate_wpml' ) );
- add_action( 'wp_ajax_nopriv_wptravel_wpml_migrate', array( __CLASS__, 'force_migrate_wpml' ) );
+ // add_action( 'wp_ajax_nopriv_wptravel_wpml_migrate', array( __CLASS__, 'force_migrate_wpml' ) );
}
public static function reset_cached_page_list() {
+
+
+ $permission = WP_Travel::verify_nonce();
+
+ if ( ! $permission || is_wp_error($permission) ) {
+ WP_Travel_Helpers_REST_API::response($permission);
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to reset page lists.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
+ }
delete_transient( 'wp_travel_cached_page_list' );
@@ -32,13 +51,22 @@
* Permission Check
*/
- $user = wp_get_current_user();
-
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get settings.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$response = WP_Travel_Helpers_Settings::get_settings();
@@ -51,12 +79,23 @@
/**
* Permission Check
*/
- $user = wp_get_current_user();
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error($permission) ) {
- return WP_Travel_Helpers_REST_API::response($permission);
+ WP_Travel_Helpers_REST_API::response($permission);
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to update settings.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
/**
@@ -106,16 +145,25 @@
* Permission Check
*/
- if ( ! current_user_can( 'manage_options' ) ) {
- return wp_send_json( array( 'result' => 'Authentication error' ) );
- }
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to migrate wmpl.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
+ }
+
+
$post_data = json_decode( file_get_contents( 'php://input' ), true ); // Added 2nd Parameter to resolve issue with objects.
$post_data = wptravel_sanitize_array( $post_data, true );
global $wpdb;
--- a/wp-travel/core/ajax/trip-dates.php
+++ b/wp-travel/core/ajax/trip-dates.php
@@ -10,13 +10,23 @@
public static function remove_trip_date() {
- $user = wp_get_current_user();
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to remove trip date.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
/**
--- a/wp-travel/core/ajax/trip-extras.php
+++ b/wp-travel/core/ajax/trip-extras.php
@@ -14,6 +14,18 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get trip extras.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$args = array();
@@ -32,12 +44,23 @@
public static function search_trip_extras() {
- $user = wp_get_current_user();
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to search trip extras.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$requests = WP_Travel::get_sanitize_request();
--- a/wp-travel/core/ajax/trip-pricing-categories-taxonomy.php
+++ b/wp-travel/core/ajax/trip-pricing-categories-taxonomy.php
@@ -10,14 +10,23 @@
}
public static function get_trip_pricing_categories_terms() {
-
- $user = wp_get_current_user();
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get trip pricing categories terms.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
$response = WP_Travel_Helpers_Trip_Pricing_Categories_Taxonomy::get_trip_pricing_categories_terms();
@@ -26,13 +35,23 @@
public static function get_trip_pricing_categories_term() {
- $user = wp_get_current_user();
-
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
+ }
+
+ if ( ! current_user_can( 'manage_options' ) ) {
+ WP_Travel_Helpers_REST_API::response(
+ new WP_Error(
+ 'forbidden',
+ __( 'You are not allowed to get trip categories term.', 'wp-travel' ),
+ array( 'status' => 403 )
+ )
+ );
+ exit;
}
WP_Travel::verify_nonce();
--- a/wp-travel/core/ajax/trips.php
+++ b/wp-travel/core/ajax/trips.php
@@ -45,9 +45,6 @@
public static function get_extra_gallery() {
- $user = wp_get_current_user();
-
-
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
$nonce_trip_extra = $_POST['nonce'];
$gallery_id = $_POST['id'];
@@ -76,9 +73,11 @@
if ( is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
} elseif ( false === $permission || null === $permission ) {
$error = WP_Travel_Helpers_Error_Codes::get_error( 'WP_TRAVEL_INVALID_PERMISSION' );
WP_Travel_Helpers_REST_API::response( $error );
+ exit;
}
// Nonce already verified.
@@ -88,6 +87,7 @@
if ( ! current_user_can( $post_type->cap->edit_post, $trip_id ) ) {
$error = WP_Travel_Helpers_Error_Codes::get_error( 'WP_TRAVEL_INVALID_PERMISSION' );
WP_Travel_Helpers_REST_API::response( $error );
+ exit;
}
/**
@@ -146,16 +146,15 @@
*/
public static function get_trip() {
- $user = wp_get_current_user();
-
-
$permission = self::get_trip_permission_check();
if ( is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
} elseif ( false === $permission || null === $permission ) {
$error = WP_Travel_Helpers_Error_Codes::get_error( 'WP_TRAVEL_INVALID_PERMISSION' );
WP_Travel_Helpers_REST_API::response( $error );
+ exit;
}
$trip_id = ! empty( $_GET['trip_id'] ) ? absint( $_GET['trip_id'] ) : 0;
@@ -223,9 +222,11 @@
if ( is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
} elseif ( false === $permission || null === $permission ) {
$error = WP_Travel_Helpers_Error_Codes::get_error( 'WP_TRAVEL_INVALID_PERMISSION' );
WP_Travel_Helpers_REST_API::response( $error );
+ exit;
}
/**
* Return list of filtered trips according to conditions. Nonce already checked.
@@ -257,17 +258,16 @@
/**
* Permission Check
*/
-
- $user = wp_get_current_user();
-
$permission = self::get_trips_permissions_check();
if ( is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
} elseif ( false === $permission || null === $permission ) {
$error = WP_Travel_Helpers_Error_Codes::get_error( 'WP_TRAVEL_INVALID_PERMISSION' );
WP_Travel_Helpers_REST_API::response( $error );
+ exit;
}
// Empty parameter. Nonce already verified.
@@ -302,6 +302,7 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
header( 'Content-Type: application/json' );
@@ -355,6 +356,7 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
header( 'Content-Type: application/json' );
@@ -377,6 +379,7 @@
if ( ! isset( $_REQUEST['_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_nonce'] ) ), 'wp_travel_nonce' ) ) {
$error = WP_Travel_Helpers_Error_Codes::get_error( 'WP_TRAVEL_INVALID_NONCE' );
return WP_Travel_Helpers_REST_API::response( $error );
+ exit;
}
return true;
--- a/wp-travel/core/ajax/view-mode.php
+++ b/wp-travel/core/ajax/view-mode.php
@@ -15,6 +15,7 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
$payload = WP_Travel::get_sanitize_request('post');
--- a/wp-travel/core/helpers/localize.php
+++ b/wp-travel/core/helpers/localize.php
@@ -369,13 +369,13 @@
$_wp_travel_admin['rankmath'] = class_exists( 'RankMath' );
$_wp_travel_admin['editor_trip_id'] = get_the_ID() ? get_the_ID() : '' ;
- $_wp_travel_admin['overview_ai_prompt'] = $settings['Trip_Overview_AI_Prompt'];
- $_wp_travel_admin['outline_ai_prompt'] = $settings['Trip_Outline_AI_Prompt'];
- $_wp_travel_admin['itinerary_ai_prompt'] = $settings['Trip_Itinerary_AI_Prompt'];
- $_wp_travel_admin['include_ai_prompt'] = $settings['Trip_Include_AI_Prompt'];
- $_wp_travel_admin['exclude_ai_prompt'] = $settings['Trip_Exclude_AI_Prompt'];
- $_wp_travel_admin['global_faq_ai_prompt'] = $settings['Trip_Global_FAQ_AI_Prompt'];
- $_wp_travel_admin['faq_ai_prompt'] = $settings['Trip_FAQ_AI_Prompt'];
+ $_wp_travel_admin['overview_ai_prompt'] = isset($settings['Trip_Overview_AI_Prompt']) ? $settings['Trip_Overview_AI_Prompt'] : '';
+ $_wp_travel_admin['outline_ai_prompt'] = isset($settings['Trip_Outline_AI_Prompt']) ? $settings['Trip_Outline_AI_Prompt'] : '';
+ $_wp_travel_admin['itinerary_ai_prompt'] = isset($settings['Trip_Itinerary_AI_Prompt']) ? $settings['Trip_Itinerary_AI_Prompt'] : '';
+ $_wp_travel_admin['include_ai_prompt'] = isset($settings['Trip_Include_AI_Prompt']) ? $settings['Trip_Include_AI_Prompt'] : '';
+ $_wp_travel_admin['exclude_ai_prompt'] = isset($settings['Trip_Exclude_AI_Prompt']) ? $settings['Trip_Exclude_AI_Prompt'] : '';
+ $_wp_travel_admin['global_faq_ai_prompt'] = isset($settings['Trip_Global_FAQ_AI_Prompt']) ? $settings['Trip_Global_FAQ_AI_Prompt'] : '';
+ $_wp_travel_admin['faq_ai_prompt'] = isset($settings['Trip_FAQ_AI_Prompt']) ? $settings['Trip_FAQ_AI_Prompt'] : '';
$_wp_travel_admin['price_per'] = 'unit';
--- a/wp-travel/core/helpers/rest-api.php
+++ b/wp-travel/core/helpers/rest-api.php
@@ -3,6 +3,7 @@
public static function response( $response ) {
if ( is_wp_error( $response ) ) {
wp_send_json_error( $response );
+ exit;
}
wp_send_json_success( $response );
}
--- a/wp-travel/inc/admin-review-notice.php
+++ b/wp-travel/inc/admin-review-notice.php
@@ -20,14 +20,14 @@
add_action( 'admin_notices', array( $this, 'wptravel_review_admin_notice' ) );
}
- add_action( 'wp_ajax_wptravel_review_later', array( $this, 'wptravel_review_later' ) );
- add_action( 'wp_ajax_nopriv_wptravel_review_later', array( $this, 'wptravel_review_later' ) );
+ // add_action( 'wp_ajax_wptravel_review_later', array( $this, 'wptravel_review_later' ) );
+ // add_action( 'wp_ajax_nopriv_wptravel_review_later', array( $this, 'wptravel_review_later' ) );
- add_action( 'wp_ajax_wptravel_gave_review_already', array( $this, 'wptravel_gave_review_already' ) );
- add_action( 'wp_ajax_nopriv_wptravel_gave_review_already', array( $this, 'wptravel_gave_review_already' ) );
+ // add_action( 'wp_ajax_wptravel_gave_review_already', array( $this, 'wptravel_gave_review_already' ) );
+ // add_action( 'wp_ajax_nopriv_wptravel_gave_review_already', array( $this, 'wptravel_gave_review_already' ) );
- add_action( 'wp_ajax_wptravel_review_now', array( $this, 'wptravel_review_now' ) );
- add_action( 'wp_ajax_nopriv_wptravel_review_now', array( $this, 'wptravel_review_now' ) );
+ // add_action( 'wp_ajax_wptravel_review_now', array( $this, 'wptravel_review_now' ) );
+ // add_action( 'wp_ajax_nopriv_wptravel_review_now', array( $this, 'wptravel_review_now' ) );
}
public function wptravel_review_admin_notice() {
@@ -72,13 +72,15 @@
$allowed_roles = array( 'editor', 'administrator', 'author' );
if ( !array_intersect( $allowed_roles, $user->roles ) ) {
- return wp_send_json( array( 'result' => 'Authentication error' ) );
+ wp_send_json( array( 'result' => 'Authentication error' ) );
+ exit;
}
$permission = WP_Travel::verify_nonce();
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
update_option( 'wptravel_review_notice_date', gmdate('Y/m/d', strtotime( gmdate('Y/m/d') . ' + 3 days') ) );
--- a/wp-travel/inc/admin/class-admin-demos.php
+++ b/wp-travel/inc/admin/class-admin-demos.php
@@ -0,0 +1,507 @@
+<?php
+
+require WP_TRAVEL_ABSPATH . '/inc/admin/importer/importer.php';
+
+class WP_Travel_Demos_Lists {
+
+ public function __construct() {
+
+ // Hook into the submenu filter
+ add_filter( 'wp_travel_submenus', [ $this, 'add_enquiry_settings_submenu' ] );
+
+ add_action( 'wp_ajax_wptravel_install_theme', [ $this, 'install_theme' ] );
+ add_action( 'wp_ajax_wptravel_activate_theme', [ $this, 'activate_theme' ] );
+ add_action( 'wp_ajax_wptravel_import_demo', [ $this, 'import_demo' ] );
+ }
+
+
+ /**
+ * Adds a custom submenu item to WP Travel admin.
+ */
+ public function add_enquiry_settings_submenu( $submenus ) {
+
+ $submenus['bookings']['demo_lists'] = array(
+ 'priority' => 145,
+ 'page_title' => 'Demos Lists',
+ 'menu_title' => 'Demo Sites',
+ 'menu_slug' => 'wp-travel-demos-lists',
+ 'callback' => [ __CLASS__, 'render_demo_lists_page' ],
+ );
+
+ return $submenus;
+ }
+
+ /* ---------------- AJAX: INSTALL THEME ---------------- */
+ public function install_theme() {
+
+ if ( ! check_ajax_referer( 'wptravel_demo_nonce', false, false ) ) {
+ wp_send_json_error( 'Invalid nonce.', 403 );
+ exit;
+ }
+
+ if ( ! current_user_can( 'install_themes' ) ) {
+ wp_send_json_error( 'Permission denied' );
+ exit;
+ }
+
+ $slug = sanitize_text_field( $_POST['slug'] );
+
+ if ( wp_get_theme( $slug )->exists() ) {
+ wp_send_json_success( 'Theme already installed' );
+ }
+
+ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
+
+ // 🔕 Silence output
+ $skin = new Automatic_Upgrader_Skin();
+ $upgrader = new Theme_Upgrader( $skin );
+
+ $result = $upgrader->install(
+ "https://downloads.wordpress.org/theme/{$slug}.zip"
+ );
+
+ if ( is_wp_error( $result ) ) {
+ wp_send_json_error( $result->get_error_message() );
+ exit;
+ }
+
+ wp_send_json_success();
+ }
+
+
+ /* ---------------- AJAX: ACTIVATE THEME ---------------- */
+ public function activate_theme() {
+
+ if ( ! check_ajax_referer( 'wptravel_demo_nonce', false, false ) ) {
+ wp_send_json_error( 'Invalid nonce.', 403 );
+ exit;
+ }
+
+ if ( ! current_user_can( 'switch_themes' ) ) {
+ wp_send_json_error( 'Permission denied' );
+ exit;
+ }
+
+ $slug = sanitize_text_field( $_POST['slug'] );
+ $theme = wp_get_theme( $slug );
+
+ if ( ! $theme->exists() ) {
+ wp_send_json_error( 'Theme not installed' );
+ exit;
+ }
+
+ switch_theme( $theme->get_stylesheet() );
+
+ wp_send_json_success();
+ }
+
+ /* ---------------- AJAX: IMPORT DEMO ---------------- */
+ public function import_demo() {
+
+ if ( ! check_ajax_referer( 'wptravel_demo_nonce', false, false ) ) {
+ wp_send_json_error( 'Invalid nonce.', 403 );
+ exit;
+ }
+
+ if ( ! current_user_can( 'import' ) ) {
+ wp_send_json_error( 'Permission denied' );
+ exit;
+ }
+
+ // Include required plugin functions
+ if ( ! function_exists('is_plugin_active') ) {
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
+ }
+ if ( ! function_exists('activate_plugin') ) {
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
+ }
+ if ( ! class_exists('Plugin_Upgrader') ) {
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
+ }
+ if ( ! function_exists('plugins_api') ) {
+ include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
+ }
+
+ // Plugin slug/path
+ $plugin_file = 'wp-travel-blocks/wp-travel-blocks.php';
+
+ // Check if plugin is installed & active
+ if ( ! is_plugin_active($plugin_file) ) {
+
+ // Try to install the plugin from WordPress.org
+ $api = plugins_api( 'plugin_information', [ 'slug' => 'wp-travel-blocks', 'fields' => ['sections'=>false] ] );
+ if ( is_wp_error($api) ) {
+ wp_send_json_error( 'Failed to get plugin info: ' . $api->get_error_message() );
+ exit;
+ }
+
+ $upgrader = new Plugin_Upgrader();
+ $installed = $upgrader->install( $api->download_link );
+
+ // Activate the plugin
+ $activate = activate_plugin($plugin_file);
+ if ( is_wp_error($activate) ) {
+ wp_send_json_error( 'Failed to activate wp-travel-blocks plugin: ' . $activate->get_error_message() );
+ exit;
+ }
+ }
+
+
+ // Get the demo slug from AJAX
+ $slug = sanitize_text_field( $_POST['slug'] );
+
+
+ if ( ! class_exists('WP_Importer') ) {
+ $class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
+ if ( file_exists( $class_wp_importer ) ) {
+ require $class_wp_importer;
+ }
+ }
+
+ // Download the XML file to a temporary location
+ $tmp_file = "https://wpdemo.wensolutions.com/demo-data/fse-demo/{$slug}/content.xml";
+
+ // Check for errors while downloading the file
+ if ( is_wp_error($tmp_file) ) {
+ wp_send_json_error( array( 'message' => 'Error downloading XML file: ' . $tmp_file->get_error_message() ) );
+ exit;
+ }
+
+ // Initialize the importer object
+ $importer = new WP_Demo_Import();
+
+ // Start the import process using the temporary downloaded file
+ $importer->import($tmp_file);
+
+ // Optionally, clean up the temporary file
+ @unlink($tmp_file);
+
+ wp_send_json_success( );
+ }
+
+ /**
+ * Renders the submenu page content.
+ */
+ public static function render_demo_lists_page() {
+
+ // 1. Get demo list from transient
+ $transient_key = 'wptravel_demo_lists';
+ $demo_list = get_transient( $transient_key );
+
+ if ( false === $demo_list ) {
+ $url = 'https://wpdemo.wensolutions.com/demo-data/fse-demo/demo.json';
+ $response = wp_remote_get( $url );
+
+ if ( is_wp_error( $response ) ) {
+ echo '<p>Unable to load demos.</p>';
+ return;
+ }
+
+ $demo_list = json_decode( wp_remote_retrieve_body( $response ), true );
+
+ // Cache for 12 hours
+ set_transient( $transient_key, $demo_list, 12 * HOUR_IN_SECONDS );
+ }
+ wp_nonce_field( 'wptravel_demo_nonce', 'wptravel_demo_nonce_field' );
+
+ ?>
+
+ <script>
+ window.wptravelDemo = {
+ nonce: document.getElementById('wptravel_demo_nonce_field').value
+ };
+ </script>
+
+ <div id="wptravel-demo-lists-page">
+ <h1 class="wp-heading-inline">Travel Demo Sites</h1>
+ <hr class="wp-header-end">
+
+ <div class="demo-grid">
+ <?php foreach ( $demo_list as $key => $demo ) : ?>
+ <div class="demo-item">
+
+ <img
+ src="https://wpdemo.wensolutions.com/demo-data/fse-demo/<?php echo esc_attr( $key ); ?>/screenshot.png"
+ alt="<?php echo esc_attr( $key ); ?>"
+ >
+
+ <h3 class="demo-title">
+ <?php echo esc_html( $demo['demo_name'] ); ?>
+ </h3>
+
+ <div class="demo-actions">
+ <button
+ class="button button-secondary wptravel-view-demo"
+ data-demo-url="https://wpdemo.wensolutions.com/<?php echo esc_attr( $key ); ?>"
+ data-demo-name="<?php echo esc_attr( $demo['demo_name'] ); ?>">
+ View Demo
+ </button>
+
+ <button class="wp-travel-theme-demo-import button button-primary" data-slug="<?php echo esc_attr( $key ); ?>">
+ Import Demo
+ </button>
+ </div>
+ </div>
+ <?php endforeach; ?>
+ </div>
+ </div>
+
+ <!-- ================= Modal ================= -->
+ <div id="wptravel-demo-modal">
+ <div class="modal-inner">
+
+ <div class="modal-header">
+ <h2 class="modal-title"></h2>
+ <div class="view-buttons">
+ <button class="view-btn" data-width="500">📱 Mobile</button>
+ <button class="view-btn" data-width="768">🖥 Tablet</button>
+ <button class="view-btn" data-width="1200">💻 Desktop</button>
+ </div>
+ <button class="modal-close" aria-label="Close">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div class="modal-loader">
+ <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" width="100" height="100" style="shape-rendering: auto; display: block; background: transparent;">
+ <g>
+ <path stroke="none" fill="#279b37" d="M10 50A40 40 0 0 0 90 50A40 42 0 0 1 10 50">
+ <animateTransform values="0 50 51;360 50 51" keyTimes="0;1" repeatCount="indefinite" dur="1s" type="rotate" attributeName="transform"></animateTransform>
+ </path>
+ </g>
+ </svg>
+ <p>Loading...</p>
+ </div>
+ <iframe src="" frameborder="0"></iframe>
+ </div>
+
+ </div>
+ </div>
+
+ <div id="wptravel-import-modal">
+ <div class="import-inner">
+ <h2>Importing Demo</h2>
+
+ <ul class="import-steps">
+ <li data-step="theme">
+ Installing Theme <span class="step-loader">⏳</span>
+ </li>
+ <li data-step="activate">Activating Theme <span>⏳</span></li>
+ <li data-step="demo">Importing Demo - it may take 15-20 minutes<span>⏳</span></li>
+ </ul>
+
+ <p class="import-done" style="display:none;">✅ Demo Imported Successfully</p>
+ </div>
+ </div>
+
+ <style>
+ #wptravel-import-modal {
+ position: fixed;
+ inset: 0;
+ background: rgba(0,0,0,.6);
+ display: none;
+ align-items: center;
+ justify-content: center;
+ z-index: 999999;
+ }
+
+ #wptravel-import-modal.active {
+ display: flex;
+ }
+
+ .import-inner {
+ background: #fff;
+ padding: 0 25px 25px 25px;
+ width: 500px;
+ border-radius: 8px;
+ }
+
+ .import-steps li {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+ font-size: 14px;
+ }
+
+ .import-steps li.done span {
+ color: green;
+ }
+
+ .step-loader {
+ display: inline-block;
+ animation: wptravel-spin 1s linear infinite;
+ }
+
+ @keyframes wptravel-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+ }
+
+ /* Stop spinning when done */
+ .import-steps li.done .step-loader {
+ animation: none;
+ }
+
+
+ </style>
+
+ <script>
+ (function () {
+
+ const importModal = document.getElementById('wptravel-import-modal');
+
+ function openImportModal() {
+ importModal.classList.add('active');
+ }
+
+ function markDone(step) {
+ const el = importModal.querySelector(`[data-step="${step}"]`);
+ if (el) {
+ el.classList.add('done');
+ el.querySelector('span').textContent = '✔';
+ }
+ }
+
+ document.querySelectorAll('.wp-travel-theme-demo-import').forEach(btn => {
+ btn.addEventListener('click', function () {
+
+ const slug = this.dataset.slug;
+ openImportModal();
+
+ // Step 1: Install Theme
+ fetch(ajaxurl, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ body: new URLSearchParams({
+ action: 'wptravel_install_theme',
+ slug: slug,
+ _wpnonce: wptravelDemo.nonce
+ })
+ })
+ .then(res => res.json())
+ .then(() => {
+ markDone('theme');
+
+ // Step 2: Activate Theme
+ return fetch(ajaxurl, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ body: new URLSearchParams({
+ action: 'wptravel_activate_theme',
+ slug: slug,
+ _wpnonce: wptravelDemo.nonce
+ })
+ });
+ })
+ .then(res => res.json())
+ .then(() => {
+ markDone('activate');
+ document.querySelector(`[data-step="demo"] span`).classList.add('step-loader');
+
+ // Step 3: Import Demo
+ return fetch(ajaxurl, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ body: new URLSearchParams({
+ action: 'wptravel_import_demo',
+ slug: slug,
+ _wpnonce: wptravelDemo.nonce
+ })
+ });
+ })
+ .then(() => {
+ // Mark the demo step as done
+ markDone('demo');
+
+ // Show the success message
+ const doneMsg = importModal.querySelector('.import-done');
+ doneMsg.style.display = 'block';
+ doneMsg.textContent = '✅ Demo Imported Successfully. Redirecting to homepage…';
+
+ // Redirect after 2 seconds (2000 ms)
+ setTimeout(() => {
+ window.location.href = '/'; // Replace '/' with your dashboard URL if needed
+ }, 2000);
+ });
+
+ });
+ });
+
+ })();
+ </script>
+
+ <!-- ================= JS ================= -->
+ <script>
+ (function () {
+ const modal = document.getElementById('wptravel-demo-modal');
+ const iframe = modal.querySelector('iframe');
+ const titleEl = modal.querySelector('.modal-title');
+ const closeBtn = modal.querySelector('.modal-close');
+ const loader = modal.querySelector('.modal-loader');
+ const viewBtns = modal.querySelectorAll('.view-btn');
+
+ function setIframeView(width) {
+ if (width >= 1200) {
+ iframe.style.width = '100%'; // full modal width
+ } else {
+ iframe.style.width = width + 'px'; // fixed width for mobile/tablet
+ }
+ iframe.style.maxWidth = '100%';
+ viewBtns.forEach(b => b.classList.remove('active'));
+ const btn = Array.from(viewBtns).find(b => b.dataset.width == width);
+ if(btn) btn.classList.add('active');
+ }
+
+ document.querySelectorAll('.wptravel-view-demo').forEach(function (btn) {
+ btn.addEventListener('click', function () {
+ iframe.style.display = 'none';
+ loader.style.display = 'flex';
+ titleEl.textContent = this.dataset.demoName;
+ modal.classList.add('active');
+
+ // Default view = Desktop
+ setIframeView(1200);
+
+ iframe.src = this.dataset.demoUrl;
+
+ const hideLoader = () => {
+ loader.style.display = 'none';
+ iframe.style.display = 'block';
+ };
+
+ iframe.onload = hideLoader;
+ setTimeout(hideLoader, 2500);
+ });
+ });
+
+ viewBtns.forEach(btn => {
+ btn.addEventListener('click', function () {
+ setIframeView(this.dataset.width);
+ });
+ });
+
+ function closeModal() {
+ iframe.src = '';
+ iframe.style.display = 'none';
+ loader.style.display = 'flex';
+ modal.classList.remove('active');
+ }
+
+ closeBtn.addEventListener('click', closeModal);
+
+ modal.addEventListener('click', function (e) {
+ if (e.target === modal) closeModal();
+ });
+
+ })();
+ </script>
+
+ <?php
+ }
+
+}
+
+new WP_Travel_Demos_Lists();
--- a/wp-travel/inc/admin/class-admin-enquiry.php
+++ b/wp-travel/inc/admin/class-admin-enquiry.php
@@ -74,10 +74,12 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error( 'Unauthorized', 403 );
+ exit;
}
$enquiry_id = absint( $_POST['enquiry_id'] ?? 0 );
@@ -97,11 +99,12 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error( 'Unauthorized', 403 );
- wp_die();
+ exit;
}
$args = [
@@ -169,16 +172,18 @@
if ( ! $permission || is_wp_error( $permission ) ) {
WP_Travel_Helpers_REST_API::response( $permission );
+ exit;
}
if ( ! is_super_admin() ) {
- wp_send_json_error( __( 'Permission denied.', 'text-domain' ) );
+ wp_send_json_error( __( 'Permission denied.', 'wp-travel' ) );
+ exit;
}
$enquiry_id = absint( $_POST['enquiry_id'] ?? 0 );
if ( ! $enquiry_id || get_post_type( $enquiry_id ) !== 'itinerary-enquiries' ) {
- wp_send_json_error( __( 'Invalid enquiry ID.', 'text-domain' ) );
+ wp_send_json_error( __( 'Invalid enquiry ID.', 'wp-travel' ) );
}
$deleted = wp_delete_post( $enquiry_id, true );
@@ -186,7 +191,7 @@
if ( $deleted ) {
wp_send_json_success();
} else {
- wp_send_json_error( __( 'Could not delete enquiry.', 'text-domain' ) );
+ wp_send_json_error( __( 'Could not delete enquiry.', 'wp-travel' ) );
}
}
}
--- a/wp-travel/inc/admin/importer/class-wp-import.php
+++ b/wp-travel/inc/admin/importer/class-wp-import.php
@@ -0,0 +1,1492 @@
+<?php
+/**
+ * WordPress Importer class for managing the import process of a WXR file
+ *
+ * @package WordPress
+ * @subpackage Importer
+ */
+
+/**
+ * WordPress importer class.
+ */
+
+class WP_Demo_Import extends WP_Importer {
+ var $max_wxr_version = 1.2; // max. supported WXR version
+
+ var $id; // WXR attachment ID
+
+ // information to import from WXR file
+ var $version;
+ var $authors = array();
+ var $posts = array();
+ var $terms = array();
+ var $categories = array();
+ var $tags = array();
+ var $base_url = '';
+
+ // mappings from old information to new
+ var $processed_authors = array();
+ var $author_mapping = array();
+ var $processed_terms = array();
+ var $processed_posts = array();
+ var $post_orphans = array();
+ var $processed_menu_items = array();
+ var $menu_item_orphans = array();
+ var $missing_menu_items = array();
+
+ var $fetch_attachments = true;
+ var $url_remap = array();
+ var $featured_images = array();
+
+ /**
+ * Registered callback function for the WordPress Importer
+ *
+ * Manages the three separate stages of the WXR import process
+ */
+ // function dispatch() {
+ // $this->header();
+
+ // $step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step'];
+ // switch ( $step ) {
+ // case 0:
+ // $this->greet();
+ // break;
+ // case 1:
+ // check_admin_referer( 'import-upload' );
+ // if ( $this->handle_upload() ) {
+ // $this->import_options();
+ // }
+ // break;
+ // case 2:
+ // check_admin_referer( 'import-wordpress' );
+ // $this->fetch_attachments = ( ! empty( $_POST['fetch_attachments'] ) && $this->allow_fetch_attachments() );
+ // $this->id = (int) $_POST['import_id'];
+ // $file = get_attached_file( $this->id );
+ // set_time_limit( 0 );
+ // $this->import( $file );
+ // break;
+ // }
+
+ // $this->footer();
+ // }
+
+ /**
+ * The main controller for the actual import stage.
+ *
+ * @param string $file Path to the WXR file for importing
+ */
+ function import( $file ) {
+
+ add_filter( 'import_post_meta_key', array( $this, 'is_valid_meta_key' ) );
+ add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
+
+ $this->import_start( $file );
+
+ $this->get_author_mapping();
+
+ wp_suspend_cache_invalidation( true );
+ $this->process_categories();
+ $this->process_tags();
+ $this->process_terms();
+ $this->process_posts();
+ wp_suspend_cache_invalidation( false );
+
+ // update incorrect/missing information in the DB
+ $this->backfill_parents();
+ $this->backfill_attachment_urls();
+ $this->remap_featured_images();
+
+ $this->import_end();
+ }
+
+ /**
+ * Parses the WXR file and prepares us for the task of processing parsed data
+ *
+ * @param string $file Path to the WXR file for importing
+ */
+ function import_start( $file ) {
+ // if ( ! is_file( $file ) ) {
+ // echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themepalace-fse-pro' ) . '</strong><br />';
+ // echo __( 'The file does not exist, please try again.', 'themepalace-fse-pro' ) . '</p>';
+ // $this->footer();
+ // die();
+ // }
+
+ $import_data = $this->parse( $file );
+
+
+ if ( is_wp_error( $import_data ) ) {
+ echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themepalace-fse-pro' ) . '</strong><br />';
+ echo esc_html( $import_data->get_error_message() ) . '</p>';
+ $this->footer();
+ die();
+ }
+
+ $this->version = $import_data['version'];
+ $this->get_authors_from_import( $import_data );
+ $this->posts = $import_data['posts'];
+ $this->terms = $import_data['terms'];
+ $this->categories = $import_data['categories'];
+ $this->tags = $import_data['tags'];
+ $this->base_url = esc_url( $import_data['base_url'] );
+
+ wp_defer_term_counting( true );
+ wp_defer_comment_counting( true );
+
+ do_action( 'import_start' );
+ }
+
+ /**
+ * Performs post-import cleanup of files and the cache
+ */
+ function import_end() {
+ wp_import_cleanup( $this->id );
+
+ wp_cache_flush();
+ foreach ( get_taxonomies() as $tax ) {
+ delete_option( "{$tax}_children" );
+ _get_term_hierarchy( $tax );
+ }
+
+ wp_defer_term_counting( false );
+ wp_defer_comment_counting( false );
+
+ do_action( 'import_end' );
+ }
+
+ /**
+ * Handles the WXR upload and initial parsing of the file to prepare for
+ * displaying author import options
+ *
+ * @return bool False if error uploading or invalid file, true otherwise
+ */
+ function handle_upload() {
+ $file = wp_import_handle_upload();
+
+ if ( isset( $file['error'] ) ) {
+ echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themepalace-fse-pro' ) . '</strong><br />';
+ echo esc_html( $file['error'] ) . '</p>';
+ return false;
+ } elseif ( ! file_exists( $file['file'] ) ) {
+ echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themepalace-fse-pro' ) . '</strong><br />';
+ printf( __( 'The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem.', 'themepalace-fse-pro' ), esc_html( $file['file'] ) );
+ echo '</p>';
+ return false;
+ }
+
+ $this->id = (int) $file['id'];
+ $import_data = $this->parse( $file['file'] );
+ if ( is_wp_error( $import_data ) ) {
+ echo '<p><strong>' . __( 'Sorry, there has been an error.', 'themepalace-fse-pro' ) . '</strong><br />';
+ echo esc_html( $import_data->get_error_message() ) . '</p>';
+ return false;
+ }
+
+ $this->version = $import_data['version'];
+ if ( $this->version > $this->max_wxr_version ) {
+ echo '<div class="error"><p><strong>';
+ printf( __( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'themepalace-fse-pro' ), esc_html( $import_data['version'] ) );
+ echo '</strong></p></div>';
+ }
+
+ $this->get_authors_from_import( $import_data );
+
+ return true;
+ }
+
+ /**
+ * Retrieve authors from parsed WXR data
+ *
+ * Uses the provided author information from WXR 1.1 files
+ * or extracts info from each post for WXR 1.0 files
+ *
+ * @param array $import_data Data returned by a WXR parser
+ */
+ function get_authors_from_import( $import_data ) {
+ if ( ! empty( $import_data['authors'] ) ) {
+ $this->authors = $import_data['authors'];
+ // no author information, grab it from the posts
+ } else {
+ foreach ( $import_data['posts'] as $post ) {
+ $login = sanitize_user( $post['post_author'], true );
+ if ( empty( $login ) ) {
+ printf( __( 'Failed to import author %s. Their posts will be attributed to the current user.', 'themepalace-fse-pro' ), esc_html( $post['post_author'] ) );
+ echo '<br />';
+ continue;
+ }
+
+ if ( ! isset( $this->authors[ $login ] ) ) {
+ $this->authors[ $login ] = array(
+ 'author_login' => $login,
+ 'author_display_name' => $post['post_author'],
+ );
+ }
+ }
+ }
+ }
+
+ /**
+ * Display pre-import options, author importing/mapping and option to
+ * fetch attachments
+ */
+ function import_options() {
+ $j = 0;
+ // phpcs:disable Generic.WhiteSpace.ScopeIndent.Incorrect
+ ?>
+ <form action="<?php echo admin_url( 'admin.php?import=wordpress&step=2' ); ?>" method="post">
+ <?php wp_nonce_field( 'import-wordpress' ); ?>
+ <input type="hidden" name="import_id" value="<?php echo $this->id; ?>" />
+
+ <?php if ( ! empty( $this->authors ) ) : ?>
+ <h3><?php _e( 'Assign Authors', 'themepalace-fse-pro' ); ?></h3>
+ <p><?php _e( 'To make it simpler for you to edit and save the imported content, you may want to reassign the author of the imported item to an existing user of this site, such as your primary administrator account.', 'themepalace-fse-pro' ); ?></p>
+ <?php if ( $this->allow_create_users() ) : ?>
+ <p><?php printf( __( 'If a new user is created by WordPress, a new password will be randomly generated and the new user’s role will be set as %s. Manually changing the new user’s details will be necessary.', 'themepalace-fse-pro' ), esc_html( get_option( 'default_role' ) ) ); ?></p>
+ <?php endif; ?>
+ <ol id="authors">
+ <?php foreach ( $this->authors as $author ) : ?>
+ <li><?php $this->author_select( $j++, $author ); ?></li>
+ <?php endforeach; ?>
+ </ol>
+ <?php endif; ?>
+
+ <?php if ( $this->allow_fetch_attachments() ) : ?>
+ <h3><?php _e( 'Import Attachments', 'themepalace-fse-pro' ); ?></h3>
+ <p>
+ <input type="checkbox" value="1" name="fetch_attachments" id="import-attachments" />
+ <label for="import-attachments"><?php _e( 'Download and import file attachments', 'themepalace-fse-pro' ); ?></label>
+ </p>
+ <?php endif; ?>
+
+ <p class="submit"><input type="submit" class="button" value="<?php esc_attr_e( 'Submit', 'themepalace-fse-pro' ); ?>" /></p>
+ </form>
+ <?php
+ // phpcs:enable Generic.WhiteSpace.ScopeIndent.Incorrect
+ }
+
+ /**
+ * Display import options for an individual author. That is, either create
+ * a new user based on import info or map to an existing user
+ *
+ * @param int $n Index for each author in the form
+ * @param array $author Author information, e.g. login, display name, email
+ */
+ function author_select( $n, $author ) {
+ _e( 'Import author:', 'themepalace-fse-pro' );
+ echo ' <strong>' . esc_html( $author['author_display_name'] );
+ if ( '1.0' != $this->version ) {
+ echo ' (' . esc_html( $author['author_login'] ) . ')';
+ }
+ echo '</strong><br />';
+
+ if ( '1.0' != $this->version ) {
+ echo '<div style="margin-left:18px">';
+ }
+
+ $create_users = $this->allow_create_users();
+ if ( $create_users ) {
+ echo '<label for="user_new_' . $n . '">';
+ if ( '1.0' != $this->version ) {
+ _e( 'or create new user with login name:', 'themepalace-fse-pro' );
+ $value = '';
+ } else {
+ _e( 'as a new user:', 'themepalace-fse-pro' );
+ $value = esc_attr( sanitize_user( $author['author_login'], true ) );
+ }
+ echo '</label>';
+
+ echo ' <input type="text" id="user_new_' . $n . '" name="user_new[' . $n . ']" value="' . $value . '" /><br />';
+ }
+
+ echo '<label for="imported_authors_' . $n . '">';
+ if ( ! $create_users && '1.0' == $this->version ) {
+ _e( 'assign posts to an existing user:', 'themepalace-fse-pro' );
+ } else {
+ _e( 'or assign posts to an existing user:', 'themepalace-fse-pro' );
+ }
+ echo '</label>';
+
+ echo ' ' . wp_dropdown_users(
+ array(
+ 'name' => "user_map[$n]",
+ 'id' => 'imported_authors_' . $n,
+ 'multi' => true,
+ 'show_option_all' => __( '- Select -', 'themepalace-fse-pro' ),
+ 'show' => 'display_name_with_login',
+ 'echo' => 0,
+ )
+ );
+
+ echo '<input type="hidden" name="imported_authors[' . $n . ']" value="' . esc_attr( $author['author_login'] ) . '" />';
+
+ if ( '1.0' != $this->version ) {
+ echo '</div>';
+ }
+ }
+
+ /**
+ * Map old author logins to local user IDs based on decisions made
+ * in import options form. Can map to an existing user, create a new user
+ * or falls back to the current user in case of error with either of the previous
+ */
+ function get_author_mapping() {
+ if ( ! isset( $_POST['imported_authors'] ) ) {
+ return;
+ }
+
+ $create_users = $this->allow_create_users();
+
+ foreach ( (array) $_POST['imported_authors'] as $i => $old_login ) {
+ // Multisite adds strtolower to sanitize_user. Need to sanitize here to stop breakage in process_posts.
+ $santized_old_login = sanitize_user( $old_login, true );
+ $old_id = isset( $this->authors[ $old_login ]['author_id'] ) ? intval( $this->authors[ $old_login ]['author_id'] ) : false;
+
+ if ( ! empty( $_POST['user_map'][ $i ] ) ) {
+ $user = get_userdata( intval( $_POST['user_map'][ $i ] ) );
+ if ( isset( $user->ID ) ) {
+ if ( $old_id ) {
+ $this->processed_authors[ $old_id ] = $user->ID;
+ }
+ $this->author_mapping[ $santized_old_login ] = $user->ID;
+ }
+ } elseif ( $create_users ) {
+ if ( ! empty( $_POST['user_new'][ $i ] ) ) {
+ $user_id = wp_create_user( $_POST['user_new'][ $i ], wp_generate_password() );
+ } elseif ( '1.0' != $this->version ) {
+ $user_data = array(
+ 'user_login' => $old_login,
+ 'user_pass' => wp_generate_password(),
+ 'user_email' => isset( $this->authors[ $old_login ]['author_email'] ) ? $this->authors[ $old_login ]['author_email'] : '',
+ 'display_name' => $this->authors[ $old_login ]['author_display_name'],
+ 'first_name' => isset( $this->authors[ $old_login ]['author_first_name'] ) ? $this->authors[ $old_login ]['author_first_name'] : '',
+ 'last_name' => isset( $this->authors[ $old_login ]['author_last_name'] ) ? $this->authors[ $old_login ]['author_last_name'] : '',
+ );
+ $user_id = wp_insert_user( $user_data );
+ }
+
+ if ( ! is_wp_error( $user_id ) ) {
+ if ( $old_id ) {
+ $this->processed_authors[ $old_id ] = $user_id;
+ }
+ $this->author_mapping[ $santized_old_login ] = $user_id;
+ } else {
+ printf( __( 'Failed to create new user for %s. Their posts will be attributed to the current user.', 'themepalace-fse-pro' ), esc_html( $this->authors[ $old_login ]['author_display_name'] ) );
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
+ echo ' ' . $user_id->get_error_message();
+ }
+ echo '<br />';
+ }
+ }
+
+ // failsafe: if the user_id was invalid, default to the current user
+ if ( ! isset( $this->author_mapping[ $santized_old_login ] ) ) {
+ if ( $old_id ) {
+ $this->processed_authors[ $old_id ] = (int) get_current_user_id();
+ }
+ $this->author_mapping[ $santized_old_login ] = (int) get_current_user_id();
+ }
+ }
+ }
+
+ /**
+ * Create new categories based on import information
+ *
+ * Doesn't create a new category if its slug already exists
+ */
+ function process_categories() {
+ $this->categories = apply_filters( 'wp_import_categories', $this->categories );
+
+ if ( empty( $this->categories ) ) {
+ return;
+ }
+
+ foreach ( $this->categories as $cat ) {
+ // if the category already exists leave it alone
+ $term_id = term_exists( $cat['category_nicename'], 'category' );
+ if ( $term_id ) {
+ if ( is_array( $term_id ) ) {
+ $term_id = $term_id['term_id'];
+ }
+ if ( isset( $cat['term_id'] ) ) {
+ $this->processed_terms[ intval( $cat['term_id'] ) ] = (int) $term_id;
+ }
+ continue;
+ }
+
+ $parent = empty( $cat['category_parent'] ) ? 0 : category_exists( $cat['category_parent'] );
+ $description = isset( $cat['category_description'] ) ? $cat['category_description'] : '';
+
+ $data = array(
+ 'category_nicename' => $cat['category_nicename'],
+ 'category_parent' => $parent,
+ 'cat_name' => wp_slash( $cat['cat_name'] ),
+ 'category_description' => wp_slash( $description ),
+ );
+
+ $id = wp_insert_category( $data, true );
+ if ( ! is_wp_error( $id ) && $id > 0 ) {
+ if ( isset( $cat['term_id'] ) ) {
+ $this->processed_terms[ intval( $cat['term_id'] ) ] = $id;
+ }
+ } else {
+ printf( __( 'Failed to import category %s', 'themepalace-fse-pro' ), esc_html( $cat['category_nicename'] ) );
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
+ echo ': ' . $id->get_error_message();
+ }
+ echo '<br />';
+ continue;
+ }
+
+ $this->process_termmeta( $cat, $id );
+ }
+
+ unset( $this->categories );
+ }
+
+ /**
+ * Create new post tags based on import information
+ *
+ * Doesn't create a tag if its slug already exists
+ */
+ function process_tags() {
+ $this->tags = apply_filters( 'wp_import_tags', $this->tags );
+
+ if ( empty( $this->tags ) ) {
+ return;
+ }
+
+ foreach ( $this->tags as $tag ) {
+ // if the tag already exists leave it alone
+ $term_id = term_exists( $tag['tag_slug'], 'post_tag' );
+ if ( $term_id ) {
+ if ( is_array( $term_id ) ) {
+ $term_id = $term_id['term_id'];
+ }
+ if ( isset( $tag['term_id'] ) ) {
+ $this->processed_terms[ intval( $tag['term_id'] ) ] = (int) $term_id;
+ }
+ continue;
+ }
+
+ $description = isset( $tag['tag_description'] ) ? $tag['tag_description'] : '';
+ $args = array(
+ 'slug' => $tag['tag_slug'],
+ 'description' => wp_slash( $description ),
+ );
+
+ $id = wp_insert_term( wp_slash( $tag['tag_name'] ), 'post_tag', $args );
+ if ( ! is_wp_error( $id ) ) {
+ if ( isset( $tag['term_id'] ) ) {
+ $this->processed_terms[ intval( $tag['term_id'] ) ] = $id['term_id'];
+ }
+ } else {
+ printf( __( 'Failed to import post tag %s', 'themepalace-fse-pro' ), esc_html( $tag['tag_name'] ) );
+ if ( defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
+ echo ': ' . $id->get_error_message();
+ }
+ echo '<br />';
+ continue;
+ }
+
+ $this->process_termmeta( $tag, $id['term_id'] );
+ }
+
+ unset( $this->tags );
+ }
+
+ /**
+ * Create new terms based on import information
+ *
+ * Doesn't create a term its slug already exists
+ */
+ function process_terms() {
+ $this->terms = apply_filters( 'wp_import_terms', $this->terms );
+
+ if ( empty( $this->terms ) ) {
+ return;
+ }
+
+ foreach ( $this->terms as $term ) {
+ // if the term already exists in the correct taxonomy leave it alone
+ $term_id = term_exists( $term['slug'], $term['term_taxonomy'] );
+ if ( $term_id ) {
+ if ( is_array( $term_id ) ) {
+ $term_id = $term_id['term_id'];
+ }
+ if ( isset( $t