38217-vm/wp-content/plugins/fusion-builder/inc/class-awb-studio-import.php
2026-02-05 17:08:59 +03:00

1693 lines
54 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Avada Studio
*
* @package Avada-Builder
* @since 3.5
*/
// Do not allow directly accessing this file.
if ( ! defined( 'ABSPATH' ) ) {
exit( 'Direct script access denied.' );
}
/**
* AWB Studio class.
*
* @since 3.5
*/
class AWB_Studio_Import {
/**
* The one, true instance of this object.
*
* @static
* @access private
* @since 3.0
* @var object
*/
private static $instance;
/**
* The studio data.
*
* @access public
* @var mixed
*/
public $data = null;
/**
* Whether to update existing posts when importing.
*
* @access public
* @var mixed
*/
public $update_post = false;
/**
* URL to fetch from.
*
* @access public
* @var string
*/
public $studio_url = 'https://avada.studio';
/**
* Import options.
*
* @access protected
* @var array
*/
protected $import_options = [
'type' => null,
'invert' => null,
'images' => null,
];
/**
* Class constructor.
*
* @since 3.0
* @access private
*/
private function __construct() {
if ( ! class_exists( 'AWB_Studio' ) || ! AWB_Studio::is_studio_enabled() ) {
return;
}
// Downloads and imports icons package.
add_filter( 'awb_studio_post_imported', [ $this, 'import_icons_package' ] );
// Import Studio Media from Builder (both live and backend).
add_action( 'wp_ajax_awb_studio_import_media', [ $this, 'ajax_import_media' ] );
}
/**
* Creates or returns an instance of this class.
*
* @static
* @access public
* @since 3.0
*/
public static function get_instance() {
// If an instance hasn't been created and set to $instance create an instance and set it to $instance.
if ( null === self::$instance ) {
self::$instance = new AWB_Studio_Import();
}
return self::$instance;
}
/**
* Set import options from global $_REQUEST array.
*
* @access public
* @since 3.7
* @return void
*/
public function set_import_options_from_request() {
if ( isset( $_REQUEST['overWriteType'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$this->import_options['type'] = sanitize_text_field( wp_unslash( $_REQUEST['overWriteType'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
}
if ( isset( $_REQUEST['shouldInvert'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$this->import_options['invert'] = sanitize_text_field( wp_unslash( $_REQUEST['shouldInvert'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
}
if ( isset( $_REQUEST['imagesImport'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$this->import_options['images'] = sanitize_text_field( wp_unslash( $_REQUEST['imagesImport'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
}
}
/**
* Set import options.
*
* @access public
* @since 3.7
* @param array $new_options array New options.
* @return void
*/
public function set_import_options( $new_options ) {
if ( isset( $new_options['type'] ) ) {
$this->import_options['type'] = $new_options['type'];
}
if ( isset( $new_options['invert'] ) ) {
$this->import_options['invert'] = $new_options['invert'];
}
if ( isset( $new_options['images'] ) ) {
$this->import_options['images'] = $new_options['images'];
}
}
/**
* Get import options.
*
* @access public
* @since 3.7
* @return array
*/
public function get_import_options() {
return $this->import_options;
}
/**
* Fetches studio content from REST API endpoint.
* Used to import studio content directly into to the page content.
*
* @access public
* @since 3.5
* @return array
*/
public function get_studio_content() {
$studio_data = AWB_Studio()->get_data();
$layout_id = (int) $_POST['fusion_layout_id']; // phpcs:ignore WordPress.Security
$category = isset( $_POST['category'] ) ? (string) esc_attr( $_POST['category'] ) : false; // phpcs:ignore WordPress.Security
$layout_data = [
'post_content' => '',
];
if ( $category ) {
if ( ! isset( $studio_data[ $category ] ) ) {
echo wp_json_encode( $layout_data );
wp_die();
}
$layout = $studio_data[ $category ][ 'item-' . $layout_id ];
} else {
if ( ! isset( $studio_data['fusion_template'] ) ) {
echo wp_json_encode( $layout_data );
wp_die();
}
$layout = $studio_data['fusion_template'][ 'item-' . $layout_id ];
}
// No layout found.
if ( ! is_array( $layout ) ) {
return $layout_data;
}
// Fetch studio object data.
$response = wp_remote_get( $this->studio_url . '/wp-json/wp/v2/' . $layout['post_type'] . '/' . $layout_id . '/' );
// TODO: better error handling.
if ( is_wp_error( $response ) ) {
return $layout_data;
}
$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
$response_body['content']['raw'] = isset( $response_body['content']['raw'] ) ? $response_body['content']['raw'] : '';
$post_meta = isset( $response_body['post_meta'] ) ? $response_body['post_meta'] : '';
// Colors & typography overwrite.
if ( isset( $response_body['post_meta'] ) ) {
$overwrite = $this->get_colors_and_typography_overwrite_map( $response_body );
$response_body['post_meta'] = $this->overwrite_colors_and_typography( $response_body['post_meta'], $overwrite );
}
if ( isset( $response_body['content']['raw'] ) ) {
// Process title typography.
if ( '' !== $post_meta ) {
$response_body['content']['raw'] = $this->process_title_typography( $response_body['content']['raw'], $post_meta );
}
$response_body['content']['raw'] = $this->overwrite_colors_and_typography( $response_body['content']['raw'], $overwrite );
// If placeholders are selected, replace images with them.
if ( 'dont-import-images' === $this->import_options['images'] ) {
$response_body = $this->replace_with_placeholders( $response_body );
}
}
if ( $post_meta && isset( $post_meta['_fusion'] ) ) {
$remove_keys = [ 'studio_replace_params', 'exclude_form_studio' ];
// Remove internal studio options.
foreach ( $remove_keys as $key ) {
if ( isset( $post_meta['_fusion'][ $key ] ) ) {
unset( $post_meta['_fusion'][ $key ] );
}
}
if ( empty( $post_meta['_fusion'] ) ) {
unset( $post_meta['_fusion'] );
}
}
// Basic content cleanup.
$response_body['content']['raw'] = $this->post_content_cleanup( $response_body['content']['raw'] );
return [
'post_id' => absint( $_POST['post_id'] ), // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
'post_content' => $response_body['content']['raw'],
'avada_media' => $response_body['avada_media'],
'custom_css' => isset( $response_body['custom_css'] ) ? $response_body['custom_css'] : '',
'post_meta' => $post_meta,
'mapping' => isset( $overwrite ) ? $overwrite : [],
];
}
/**
* Replace images in content with placeholders, also remove from media map.
*
* @access public
* @since 3.7
* @param string $content Post content to process.
* @param array $post_meta Post meta to check for typography size overrides.
* @return array
*/
public function process_title_typography( $content = '', $post_meta = [] ) {
// No fusion post meta data.
if ( ! isset( $post_meta['_fusion'] ) ) {
return $content;
}
// No title elements.
if ( false === strpos( $content, 'fusion_title' ) ) {
return $content;
}
$type = $this->import_options['type'];
$pattern = get_shortcode_regex( [ 'fusion_title' ] );
$meta = $post_meta['_fusion'];
// Replace all if heading for inherit, use font size value for as is.
return preg_replace_callback(
"/$pattern/",
function ( $m ) use ( $meta, $type ) {
$tag = $m[2];
$attr = shortcode_parse_atts( $m[3] );
// Not a heading tag.
if ( ! isset( $attr['size'] ) || 'div' === $attr['size'] ) {
return $m[0];
}
// Inherit, we just need to wipe out heading typo set variables.
if ( 'inherit' === $type ) {
$find = [
'"var(--awb-typography1-font-size)"',
'"var(--awb-typography1-font-family)"',
'"var(--awb-typography1-font-variant)"',
'"var(--awb-typography1-font-weight)"',
'"var(--awb-typography1-font-style)"',
'"var(--awb-typography1-line-height)"',
'"var(--awb-typography1-letter-spacing)"',
'"var(--awb-typography1-text-transform)"',
];
return str_replace( $find, '""', $m[0] );
}
// If we have a font size override set, then use that.
$meta_key = 'h' . $attr['size'] . '_size';
if ( isset( $meta[ $meta_key ] ) && '' !== $meta[ $meta_key ] ) {
return str_replace( 'font_size="var(--awb-typography1-font-size)"', 'font_size="' . $meta[ $meta_key ] . '"', $m[0] );
}
return $m[0];
},
$content
);
}
/**
* Gets colors and typography overwrite map.
*
* @access public
* @since 3.7
* @param array $data The item data.
* @return array
*/
public function get_colors_and_typography_overwrite_map( $data ) {
$overwrite_palette = $this->get_overwrite_palette( $data );
$overwrite_typography = $this->get_overwrite_typography( $data );
return array_merge( $overwrite_palette, $overwrite_typography );
}
/**
* Replace images with placeholders.
*
* @access public
* @since 3.7
* @param array $data Data of content and avada_media.
* @return array
*/
public function replace_images( $data = [] ) {
$data['content']['raw'] = $data['post_content'];
$data = $this->replace_with_placeholders( $data );
$data['post_content'] = $data['content']['raw'];
return $data;
}
/**
* Replace images in content with placeholders, also remove from media map.
*
* @access public
* @since 3.7
* @param array $data Data of content and avada_media.
* @return array
*/
public function replace_with_placeholders( $data = [] ) {
if ( ! isset( $data['avada_media']['images'] ) || ! isset( $data['content']['raw'] ) ) {
return $data;
}
// First lets create a replacement map for each image.
foreach ( (array) $data['avada_media']['images'] as $url => $this_data ) {
// If we have the image ID, we use that to lookup.
$id = isset( $this_data['image_id'] ) ? (int) $this_data['image_id'] : false;
$lookup = $id ? $id : $url;
$args = [
'timeout' => 30,
'user-agent' => 'avada-user-agent',
];
// Fetch the dimensions and color of the image.
$response = wp_remote_get( $this->studio_url . 'wp-json/studio/image/' . $lookup . '/', $args );
$image_data = [];
$defaults = [
'width' => '1067',
'height' => '667',
'color' => '#808080',
'var' => 'color3',
];
$image_data = [];
if ( ! is_wp_error( $response ) ) {
$response = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! empty( $response ) ) {
$image_data = $response;
}
}
// Merge so that we do not have empty dimensions.
$image_data = wp_parse_args( $image_data, $defaults );
// If it had an ID, just wipe it out.
if ( $id ) {
$data['content']['raw'] = str_replace( 'image_id="' . $id, 'image_id="', $data['content']['raw'] );
}
// Use variable closest to image luminance if its inherit mode.
if ( 'inherit' === $this->import_options['type'] ) {
$palette = fusion_get_option( 'color_palette' );
// Invert inherit, flip the var.
if ( 'do-invert' === $this->import_options['invert'] ) {
$flip = [
'color1' => 'color8',
'color2' => 'color7',
'color3' => 'color6',
'color4' => 'color5',
'color5' => 'color4',
'color6' => 'color3',
'color7' => 'color2',
'color8' => 'color1',
];
$image_data['var'] = str_replace( array_keys( $flip ), array_values( $flip ), $image_data['var'] );
}
// If var is set, use that as the color.
if ( isset( $palette[ $image_data['var'] ]['color'] ) ) {
$image_data['color'] = $palette[ $image_data['var'] ]['color'];
}
}
// Replace image URL with encoded placeholder image.
$data['content']['raw'] = str_replace( $url, $this->generate_dynamic_placeholder( $image_data ), $data['content']['raw'] );
}
// Skip all images from being downloaded.
$data['avada_media']['images'] = [];
return $data;
}
/**
* Checks if a string is a placeholder.
*
* @access public
* @since 7.7
* @param array $data The image data.
* @return string
*/
public function generate_dynamic_placeholder( $data = '' ) {
$text_color = 'rgba(0,0,0,0.5)';
$brightness_level = Fusion_Color::new_color( $data['color'] )->brightness;
if ( isset( $brightness_level['total'] ) && $brightness_level['total'] < 140 ) {
$text_color = 'rgba(255,255,255,0.5)';
}
$svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' . $data['width'] . '" height="' . $data['height'] . '" viewBox="0 0 ' . $data['width'] . ' ' . $data['height'] . '"><rect fill="' . $data['color'] . '" width="' . $data['width'] . '" height="' . $data['height'] . '"/><text fill="' . $text_color . '" font-family="sans-serif" font-size="30" dy="10.5" font-weight="bold" x="50%" y="50%" text-anchor="middle">' . $data['width'] . '×' . $data['height'] . '</text></svg>';
return 'data:image/svg+xml;utf8,' . rawurlencode( $svg );
}
/**
* Imports needed studio post assets.
*
* @access public
* @since 3.5
* @param array $layout Holds content and import assets data.
* @return array
*/
public function process_studio_content( $layout ) {
// Post content set.
$post_content = $layout['post_content'];
$layout_data = [];
$off_canvases = [];
$mapping = isset( $layout['overwrite'] ) ? $layout['overwrite'] : [];
$mapping = $this->is_json( $mapping ) ? json_decode( $mapping, true ) : $mapping;
if ( ! isset( $layout['post_id'] ) ) {
$layout['post_id'] = null;
}
// Check for other media to be imported.
if ( isset( $layout['avada_media'] ) && ! empty( $layout['avada_media'] ) ) {
// Import images if they are set.
if ( isset( $layout['avada_media']['images'] ) && ! empty( $layout['avada_media']['images'] ) && current_user_can( 'upload_files' ) ) {
foreach ( (array) $layout['avada_media']['images'] as $image_url => $replacements ) {
$existing_image = $this->find_existing_media( $image_url );
if ( $existing_image ) {
$image_id = $existing_image;
} else {
// We don't already have it, need to load it.
$image_id = media_sideload_image( $image_url, $layout['post_id'], null, 'id' ); // phpcs:ignore WordPress.Security
if ( ! is_wp_error( $image_id ) ) {
// Add flag to prevent duplicate imports.
$this->add_media_meta( $image_id, $image_url );
do_action( 'awb_studio_import_action', $image_id );
}
}
if ( ! is_wp_error( $image_id ) ) {
foreach ( (array) $replacements as $param_name => $old_value ) {
// Get ID if its mixed with size.
$old_id = (int) $old_value;
$new_value = str_replace( $old_id, $image_id, $old_value );
// Replace the old image ID with the new one.
$post_content = str_replace( $param_name . '="' . $old_value . '"', $param_name . '="' . $new_value . '"', $post_content );
}
$new_url = wp_get_attachment_url( $image_id );
} else {
foreach ( (array) $replacements as $param_name => $old_value ) {
// Replace the old image ID with the empty value.
$post_content = str_replace( $param_name . '="' . $old_value . '"', $param_name . '=""', $post_content );
}
$new_url = '';
}
// Replace the URL as well.
$post_content = str_replace( $image_url, $new_url, $post_content );
}
}
// handle multiple images.
if ( isset( $layout['avada_media']['multiple_images'] ) && ! empty( $layout['avada_media']['multiple_images'] ) && current_user_can( 'upload_files' ) ) {
foreach ( (array) $layout['avada_media']['multiple_images'] as $images_key => $multiple_images ) {
$images_key = explode( '-', $images_key );
$param_name = isset( $images_key[0] ) ? $images_key[0] : '';
$param_value = isset( $images_key[1] ) ? $images_key[1] : '';
$old_string = $param_name . '="' . $param_value . '"';
$new_ids = [];
foreach ( $multiple_images as $old_id => $image_url ) {
$existing_image = $this->find_existing_media( $image_url );
if ( $existing_image ) {
$image_id = $existing_image;
} else {
// We don't already have it, need to load it.
$image_id = media_sideload_image( $image_url, $layout['post_id'], null, 'id' ); // phpcs:ignore WordPress.Security
if ( ! is_wp_error( $image_id ) ) {
$new_ids[] = $image_id;
// Add flag to prevent duplicate imports.
$this->add_media_meta( $image_id, $image_url );
do_action( 'awb_studio_import_action', $image_id );
}
}
}
$new_string = $param_name . '="' . join( ',', $new_ids ) . '"';
$post_content = str_replace( $old_string, $new_string, $post_content );
}
}
// Import videos if they are set.
if ( isset( $layout['avada_media']['videos'] ) && ! empty( $layout['avada_media']['videos'] ) && current_user_can( 'upload_files' ) ) {
foreach ( $layout['avada_media']['videos'] as $video_url => $active ) {
$new_video_url = $this->import_video( $video_url );
// If import failed $new_video_url will be empty string.
$post_content = str_replace( $video_url, $new_video_url, $post_content );
}
}
// Import menus if they are set.
if ( isset( $layout['avada_media']['menus'] ) && ! empty( $layout['avada_media']['menus'] ) && current_user_can( 'manage_options' ) ) {
foreach ( $layout['avada_media']['menus'] as $menu_slug => $active ) {
if ( $active ) {
$new_menu = $this->import_menu( $menu_slug, $mapping );
}
// Can use new menu ID here is we want but slug is unchanged anyway.
}
}
// Import forms if they are set.
if ( isset( $layout['avada_media']['forms'] ) && ! empty( $layout['avada_media']['forms'] ) && current_user_can( 'manage_options' ) ) {
foreach ( $layout['avada_media']['forms'] as $form_post_id => $active ) {
$post_details = $this->import_post(
[
'post_id' => $form_post_id,
'post_type' => 'fusion_form',
],
[],
true,
$mapping
);
$new_form_post_id = $post_details['post_id'];
if ( $new_form_post_id ) {
$post_content = str_replace( 'form_post_id="' . $form_post_id . '"', 'form_post_id="' . $new_form_post_id . '"', $post_content );
}
}
}
// Import referenced off canvases if set.
if ( isset( $layout['avada_media']['off_canvases'] ) && ! empty( $layout['avada_media']['off_canvases'] ) && current_user_can( 'manage_options' ) && class_exists( 'AWB_Off_Canvas' ) && false !== AWB_Off_Canvas::is_enabled() ) {
foreach ( $layout['avada_media']['off_canvases'] as $off_canvas_id => $active ) {
$post_details = $this->import_post(
[
'post_id' => $off_canvas_id,
'post_type' => 'awb_off_canvas',
],
[],
true,
$mapping
);
$new_off_canvas_id = $post_details['post_id'];
$off_canvases[ $off_canvas_id ] = $new_off_canvas_id;
// Update dynamic data references.
if ( false !== strpos( $post_content, 'b2ZmX2NhbnZhc' ) && false !== strpos( $post_content, 'dynamic_params' ) ) {
preg_match_all( '/(?<=dynamic_params=")(.*?)(?=\")/', $post_content, $matches );
if ( ! empty( $matches ) ) {
foreach ( (array) $matches[0] as $match ) {
if ( false !== strpos( $match, 'b2ZmX2NhbnZhc' ) ) {
$dynamic_params = json_decode( base64_decode( $match ), true );
if ( is_array( $dynamic_params ) ) {
foreach ( $dynamic_params as $id => $data ) {
if ( isset( $data['off_canvas_id'] ) ) {
$dynamic_params['link']['off_canvas_id'] = isset( $off_canvases[ $dynamic_params['link']['off_canvas_id'] ] ) ? $off_canvases[ $dynamic_params['link']['off_canvas_id'] ] : $dynamic_params['link']['off_canvas_id'];
$update_contents = base64_encode( wp_json_encode( $dynamic_params ) );
}
}
$post_content = str_replace( $match, $update_contents, $post_content );
}
}
}
}
}
}
// Update menu references.
$menus = $post_data = isset( $_POST['data']['postData']['avada_media']['menus'] ) ? wp_unslash( $_POST['data']['postData']['avada_media']['menus'] ) : []; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
foreach ( $menus as $menu_slug => $active ) {
if ( $active ) {
$this->update_menu_off_canvas_references( $menu_slug, $off_canvases );
}
}
}
// Import post cards if they are set.
if ( isset( $layout['avada_media']['post_cards'] ) && ! empty( $layout['avada_media']['post_cards'] ) && current_user_can( 'manage_options' ) ) {
foreach ( $layout['avada_media']['post_cards'] as $post_card_post_id => $active ) {
$post_details = $this->import_post(
[
'post_id' => $post_card_post_id,
'post_type' => 'fusion_element',
],
[],
true,
$mapping
);
$new_post_card_post_id = $post_details['post_id'];
if ( $new_post_card_post_id ) {
$post_content = str_replace( 'post_card="' . $post_card_post_id . '"', 'post_card="' . $new_post_card_post_id . '"', $post_content );
}
}
}
// Import icons if they are set.
if ( isset( $layout['avada_media']['icons'] ) && ! empty( $layout['avada_media']['icons'] ) && current_user_can( 'upload_files' ) ) {
foreach ( $layout['avada_media']['icons'] as $icons_post_id => $icons_css_prefix ) {
$post_details = $this->import_post(
[
'post_id' => $icons_post_id,
'post_type' => 'fusion_icons',
]
);
if ( isset( $post_details['custom_icons'] ) ) {
if ( ! isset( $layout_data['custom_icons'] ) ) {
$layout_data['custom_icons'] = [];
}
$layout_data['custom_icons'][] = $post_details['custom_icons'];
}
}
}
}
// Set content.
$layout_data['post_content'] = apply_filters( 'content_edit_pre', $post_content, $layout['post_id'] );
if ( isset( $layout['custom_css'] ) && strlen( $layout['custom_css'] ) ) {
$layout_data['custom_css'] = $layout['custom_css'];
}
return $layout_data;
}
/**
* Find an media with the post meta.
*
* @access public
* @since 3.5
* @param string $media_url The media URL on studio server.
* @return mixed
*/
public function find_existing_media( $media_url ) {
global $wpdb;
return $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
$wpdb->prepare(
'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
WHERE `meta_key` = \'_avada_studio_media\'
AND `meta_value` = %s
;',
md5( $media_url )
)
);
}
/**
* Add a meta flag to attachment.
*
* @access public
* @since 3.0
* @param int $media_id The media ID in the database.
* @param string $media_url The media URL on studio server.
* @return mixed
*/
public function add_media_meta( $media_id, $media_url ) {
if ( ! $media_id ) {
return;
}
update_post_meta( $media_id, '_avada_studio_media', md5( $media_url ) );
}
/**
* Import a menu to compliment content.
*
* @since 3.0
* @param string $menu_slug The menu slug to import.
* @param array $mapping The mapping.
* @return mixed
*/
public function import_menu( $menu_slug, $mapping = '' ) {
$response = wp_remote_get( $this->studio_url . '/wp-json/studio/menu/' . $menu_slug );
// Check for error.
if ( is_wp_error( $response ) ) {
return false;
}
$data = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $data['nav_items'] ) ) {
return false;
}
// Create a new menu.
$menu_id = wp_create_nav_menu( $data['name'] );
if ( is_wp_error( $menu_id ) ) {
return false;
}
// Match old IDs to new, for hierarchy.
$id_matcher = [];
$sidebar_data = false;
foreach ( $data['nav_items'] as $nav_item ) {
// Replace old ID with new for parent.
if ( isset( $nav_item['post_meta']['menu-item-menu-item-parent'] ) && '' !== $nav_item['post_meta']['menu-item-menu-item-parent'] ) {
$parent_id = $nav_item['post_meta']['menu-item-menu-item-parent'];
if ( isset( $id_matcher[ $parent_id ] ) ) {
$nav_item['post_meta']['menu-item-parent-id'] = $id_matcher[ $parent_id ];
}
}
// Create menu item.
$nav_item_id = wp_update_nav_menu_item( $menu_id, 0, $nav_item['post_meta'] );
$old_item_id = (int) $nav_item['post']['ID'];
if ( ! is_wp_error( $nav_item_id ) ) {
// Match old to new ID.
$id_matcher[ $old_item_id ] = $nav_item_id;
// Update mega menu meta.
if ( isset( $nav_item['post_meta']['menu-item-fusion-megamenu'] ) ) {
$menu_item_meta = maybe_unserialize( $nav_item['post_meta']['menu-item-fusion-megamenu'] );
// Check for custom Mega Menu.
if ( isset( $nav_item['post']['fusion_megamenu_select'] ) ) {
$mega_menu = $this->import_post(
[
'post_id' => $nav_item['post']['fusion_megamenu_select'],
'post_type' => 'fusion_element',
],
[],
true,
$mapping
);
$new_mega_menu_post_id = $mega_menu['post_id'];
$nav_item['post_meta']['fusion_megamenu_select'] = $new_mega_menu_post_id;
$menu_item_meta['select'] = $new_mega_menu_post_id;
}
update_post_meta( $nav_item_id, '_menu_item_fusion_megamenu', $menu_item_meta );
}
// Add meta so we know menu item was imported as studio content.
update_post_meta( $nav_item_id, '_avada_studio_post', $old_item_id );
// If we have sidebar data.
if ( isset( $data['sidebars'] ) && ! empty( $data['sidebars'] ) ) {
$existing_sidebars = get_option( 'sbg_sidebars', [] );
$new_sidebars = $data['sidebars'];
$import_widgets = false;
foreach ( $new_sidebars as $sidebar_id => $sidebar_name ) {
// New sidebar, add it in.
if ( ! isset( $existing_sidebars[ $sidebar_id ] ) ) {
$import_widgets = true;
$existing_sidebars[ $sidebar_id ] = $sidebar_name;
register_sidebar(
[
'name' => $sidebar_name,
'id' => 'avada-custom-sidebar-' . $sidebar_id,
'before_widget' => '<div id="%1$s" class="widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<div class="heading"><h4 class="widget-title">',
'after_title' => '</h4></div>',
]
);
}
}
if ( $import_widgets && function_exists( 'fusion_import_widget_data' ) ) {
// Update custom option.
update_option( 'sbg_sidebars', $existing_sidebars );
// Import the widgets.
fusion_import_widget_data( wp_json_encode( $data['widgets'] ) );
}
}
}
}
return $menu_id;
}
/**
* Updates menu.
*
* @access public
* @since 3.6
* @param string $menu_slug The menu slug to import.
* @param array $off_canvases Referrenced off canvases in menu.
* @return void
*/
public function update_menu_off_canvas_references( $menu_slug, $off_canvases ) {
// Get menu items.
$nav_items = wp_get_nav_menu_items( $menu_slug );
if ( is_array( $nav_items ) && ! empty( $nav_items ) ) {
foreach ( $nav_items as $nav_item ) {
$meta = maybe_unserialize( get_post_meta( $nav_item->ID, '_menu_item_fusion_megamenu', true ) );
if ( isset( $meta['special_link'] ) && 'awb-off-canvas-menu-trigger' === $meta['special_link'] && ! empty( $meta['off_canvas_id'] ) && class_exists( 'AWB_Off_Canvas' ) && false !== AWB_Off_Canvas::is_enabled() ) {
$meta['off_canvas_id'] = isset( $off_canvases[ $meta['off_canvas_id'] ] ) ? $off_canvases[ $meta['off_canvas_id'] ] : $meta['off_canvas_id'];
update_post_meta( $nav_item->ID, '_menu_item_fusion_megamenu', $meta );
}
}
}
}
/**
* Find a a post with the post meta.
*
* @access public
* @since 3.5
* @param int|string $import_key The studio post ID or studio post import key.
* @return mixed
*/
public function find_existing_post( $import_key ) {
global $wpdb;
return $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery
$wpdb->prepare(
'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
WHERE `meta_key` = \'_avada_studio_import_key\'
AND `meta_value` = %s
;',
$import_key
)
);
}
/**
* Generate studio post's import key.
*
* @access protected
* @since 3.7
* @param int $studio_post_id The studio post ID.
* @return mixed
*/
protected function generate_post_import_key( $studio_post_id ) {
$import_key = $studio_post_id;
foreach ( $this->import_options as $key => $value ) {
if ( null !== $value ) {
$import_key .= '-' . $key . ':' . $value;
}
}
if ( $import_key !== $studio_post_id ) {
$import_key = md5( $import_key );
}
return $import_key;
}
/**
* Generate imported post title.
*
* @access protected
* @since 3.7
* @param string $post_title The post title..
* @return string
*/
protected function generate_post_title( $post_title ) {
$title_suffix = '';
if ( null !== $this->import_options['type'] && 'inherit' === $this->import_options['type'] ) {
$title_suffix .= ' L';
}
if ( null !== $this->import_options['images'] && 'dont-import-images' === $this->import_options['images'] ) {
$title_suffix .= ' P';
}
if ( null !== $this->import_options['invert'] && 'do-invert' === $this->import_options['invert'] ) {
$title_suffix .= ' I';
}
if ( '' !== $title_suffix ) {
$post_title .= ' (' . trim( $title_suffix ) . ')';
}
return $post_title;
}
/**
* Clean up anything unnecessary or required for better preview.
*
* @access public
* @since 3.7
* @param string $post_content Post content for content being imported.
* @return string
*/
public function post_content_cleanup( $post_content = '' ) {
return preg_replace( '/posts_by="(.*?)"|include_term_portfolio_category="(.*?)"/', '', $post_content );
}
/**
* Import a form to compliment content.
*
* @access public
* @since 3.5
* @param array $studio_post Studio post info.
* @param array $local_post Local post info.
* @param bool $import_media Should post media be imported with the content or not.
* @param array $replacements Array of colors & typography map to overwrite.
* @return mixed
*/
public function import_post( $studio_post = [], $local_post = [], $import_media = true, $replacements = [] ) {
$studio_post_id = isset( $studio_post['post_id'] ) ? $studio_post['post_id'] : 0;
$studio_post_type = isset( $studio_post['post_type'] ) ? $studio_post['post_type'] : '';
$post_id = isset( $local_post['post_id'] ) ? $local_post['post_id'] : 0;
$post_title = isset( $local_post['post_title'] ) ? $local_post['post_title'] : '';
$post_type = isset( $local_post['post_type'] ) ? $local_post['post_type'] : $studio_post_type;
$import_key = $this->generate_post_import_key( $studio_post_id );
$existing_post_id = $this->find_existing_post( $import_key );
if ( $post_id ) {
$existing_post_id = $post_id;
}
// Any additonal data that post might need.
$data = [];
$post_was_imported = false;
// Post is already imported.
if ( $existing_post_id && false === $this->update_post ) {
$imported_post_id = $existing_post_id;
$post_was_imported = true;
} else {
// TODO: better error handling.
if ( ! $studio_post_id ) {
return [ 'post_id' => false ];
}
$response = wp_remote_get( $this->studio_url . '/wp-json/wp/v2/' . $studio_post_type . '/' . $studio_post_id . '/' );
// TODO: better error handling.
if ( is_wp_error( $response ) ) {
return [ 'post_id' => false ];
}
$post_data = apply_filters( 'awb_studio_post_data', json_decode( wp_remote_retrieve_body( $response ), true ), $studio_post_id );
$post_data['post_content'] = isset( $post_data['post_content'] ) ? $post_data['post_content'] : $post_data['content']['raw'];
if ( '' === $post_title ) {
$post_title = isset( $post_data['post_title'] ) ? $post_data['post_title'] : $post_data['title']['rendered'];
}
// Check if this is a setup wizard import.
if ( $this->update_post ) {
if ( 'page' === $post_type ) {
// Change post type and set some page options.
$post_data['post_meta']['_fusion']['main_padding']['top'] = '0px';
$post_data['post_meta']['_fusion']['main_padding']['bottom'] = '0px';
$post_data['post_meta']['_fusion']['page_title_bar'] = 'no';
}
// Add in menu and logo.
$post_data = AWB_Setup_Wizard()->process_content( $post_data );
}
// Process title typography.
if ( isset( $post_data['post_meta']['_fusion'] ) && '' !== $post_data['post_meta']['_fusion'] ) {
$post_data['post_content'] = $this->process_title_typography( $post_data['post_content'], $post_data['post_meta'] );
}
// Colors & typography overwrite map.
if ( empty( $replacements ) ) {
$replacements = $this->get_colors_and_typography_overwrite_map( $post_data );
}
$post_data['post_content'] = $this->overwrite_colors_and_typography( $post_data['post_content'], $replacements );
$post_data['post_meta'] = $this->overwrite_colors_and_typography( $post_data['post_meta'], $replacements );
if ( 'dont-import-images' === $this->import_options['images'] ) {
$post_data = $this->replace_images( $post_data );
}
// Basic content cleanup.
$post_data['post_content'] = $this->post_content_cleanup( $post_data['post_content'] );
$post_insert_data = apply_filters(
'awb_studio_insert_post_data',
[
'post_title' => 'page' === $post_type ? $post_title : $this->generate_post_title( $post_title ),
'post_content' => $post_data['post_content'],
'post_type' => $post_type,
'post_status' => 'publish',
],
$studio_post_id
);
if ( $existing_post_id && true === $this->update_post ) {
$post_insert_data['ID'] = $existing_post_id;
$imported_post_id = wp_update_post( $post_insert_data, true );
} else {
$imported_post_id = wp_insert_post( $post_insert_data, true );
}
// TODO: better error handling.
if ( is_wp_error( $imported_post_id ) ) {
return [ 'post_id' => false ];
}
if ( true === $import_media ) {
$this->import_post_media( $imported_post_id, $post_insert_data['post_content'], $post_data['avada_media'], $replacements );
}
// Page means we always always want 100-width.
if ( 'page' === $post_insert_data['post_type'] ) {
update_post_meta( $imported_post_id, '_wp_page_template', '100-width.php' );
update_post_meta( $imported_post_id, 'fusion_builder_status', 'active' );
}
// Set post terms.
if ( isset( $post_data['terms'] ) && is_array( $post_data['terms'] ) ) {
foreach ( $post_data['terms'] as $term ) {
wp_set_object_terms( $imported_post_id, $term['slug'], $term['taxonomy'] );
}
}
// Custom CSS.
if ( isset( $post_data['custom_css'] ) && strlen( $post_data['custom_css'] ) ) {
update_post_meta( $imported_post_id, '_fusion_builder_custom_css', $post_data['custom_css'] );
}
// Set post meta.
if ( isset( $post_data['post_meta']['_fusion'] ) && '' !== $post_data['post_meta']['_fusion'] ) {
update_post_meta( $imported_post_id, '_fusion', $post_data['post_meta']['_fusion'] );
}
// Set font meta.
if ( isset( $post_data['fonts'] ) && is_array( $post_data['fonts'] ) ) {
update_post_meta( $imported_post_id, '_fusion_google_fonts', $post_data['fonts'] );
} elseif ( isset( $post_data['post_meta']['_fusion_google_fonts'] ) && '' !== $post_data['post_meta']['_fusion_google_fonts'] && is_array( $post_data['post_meta']['_fusion_google_fonts'] ) ) {
update_post_meta( $imported_post_id, '_fusion_google_fonts', $post_data['post_meta']['_fusion_google_fonts'] );
}
// Icons specific stuff.
if ( 'fusion_icons' === $studio_post_type ) {
$data['package_url'] = $post_data['avada_media']['package_url'];
}
update_post_meta( $imported_post_id, '_avada_studio_import_key', $import_key );
update_post_meta( $imported_post_id, '_avada_studio_post', $studio_post_id );
}
$post_details = [
'post_id' => $imported_post_id,
'data' => $data,
'was_imported' => $post_was_imported,
'avada_media' => isset( $post_data ) && ! empty( $post_data['avada_media'] ) ? $post_data['avada_media'] : [],
'mapping' => isset( $replacements ) ? $replacements : [],
];
$post_details = apply_filters( 'awb_studio_post_imported', $post_details );
return $post_details;
}
/**
* Overwrite colors & typography.
*
* @access public
* @since 3.7
* @param array|string $content The post content.
* @param array $overwrite The overwrite mapping array.
* @return array|string
*/
public function overwrite_colors_and_typography( $content, $overwrite ) {
if ( ! is_array( $content ) ) {
$content = str_replace( array_keys( $overwrite ), array_values( $overwrite ), $content );
return $this->remove_calc_in_hsla_and_get_rgba( $content );
}
$overwrite_array = [];
foreach ( $content as $key => $value ) {
$overwrite_array[ $key ] = $this->overwrite_colors_and_typography( $value, $overwrite );
}
return $overwrite_array;
}
/**
* Calculate calc() functions between 2 simple values inside hsla, and transform to valid rgba.
*
* After the global color variables are replaced with actual values, the
* ones inside calc will be like "calc(40% + 20%)", triggering errors after.
*
* @param string $content The content.
* @return string Will return rgba value of the color.
*/
private function remove_calc_in_hsla_and_get_rgba( $content ) {
$comma = '\s*,\s*';
$matches = [];
// Try to resolve calc() functions that appear after values are replaced in hsla.
preg_match_all(
'/hsla\s*\(\s*' . // begin of hsla function.
'(\d+)' . $comma . // hue.
'(\d+%|calc\(\s*\d+%\s*(?:\+|-)\s*\d+%\s*\))' . $comma . // saturation.
'(\d+%|calc\(\s*\d+%\s*(?:\+|-)\s*\d+%\s*\))' . $comma . // lightness.
'(\d+%|calc\(\s*\d+%\s*(?:\+|-)\s*\d+%\s*\))' . // alpha.
'\s*\)/i', // end of hsla.
$content,
$matches
);
if ( ! isset( $matches [4], $matches [0][0] ) ) {
return $content;
}
$to_search_calc_array = [];
$to_replace_calc_array = [];
foreach ( $matches[0] as $index => $full_hsla_match ) {
if ( strpos( $full_hsla_match, 'calc' ) === false ) {
continue;
}
$hue = $this->calculate_css_calc( $matches[1][ $index ], 'is_hue' );
$saturation = $this->calculate_css_calc( $matches[2][ $index ] );
$lightness = $this->calculate_css_calc( $matches[3][ $index ] );
$alpha = $this->calculate_css_calc( $matches[4][ $index ] );
$final_value = 'hsla(' . $hue . ',' . $saturation . ',' . $lightness . ',' . $alpha . ')';
array_push( $to_search_calc_array, $full_hsla_match );
array_push( $to_replace_calc_array, Fusion_Color::new_color( $final_value )->to_css( 'rgba' ) );
}
return str_replace( $to_search_calc_array, $to_replace_calc_array, $content );
}
/**
* Calculate a css "calc" function after the global is replaced with a static value.
*
* @param string $expression The expression to determine the value.
* @param string $type 'is_percent' when calculating between 2 percentages, 'is_hue' when calc hue.
* @return string
*/
private function calculate_css_calc( $expression, $type = 'is_percent' ) {
if ( strpos( $expression, 'calc' ) === false ) {
return $expression;
}
$matches = [];
$return_value = '';
preg_match( '/calc\s*\(\s*(\d+%?)\s*(\+|-)\s*(\d+%?)\s*\)/', $expression, $matches );
if ( ! count( $matches ) ) {
return $expression;
}
$first = floatval( $matches[1] );
$operand = $matches[2];
$second = floatval( $matches[3] );
if ( '+' === $operand ) {
$return_value = $first + $second;
} else {
$return_value = $first - $second;
}
if ( 'is_hue' === $type ) {
$return_value = round( $return_value, 2 ) % 360;
if ( $return_value < 0 ) {
$return_value = 360 - $return_value;
}
$return_value = (string) $return_value;
} else { // 'is_percent'(default) is_percent refers to hsla value percents, so it is between 0 and 100.
$return_value = max( min( 100, $return_value ), 0 );
$return_value = round( $return_value, 2 );
$return_value = $return_value . '%';
}
return $return_value;
}
/**
* Gets colors overwrite pallete.
*
* @access public
* @since 3.7
* @param array $post_data The current post data.
* @return array
*/
public function get_overwrite_palette( $post_data ) {
$overwrite_palette = [];
if ( empty( $this->import_options['type'] ) ) {
return $overwrite_palette;
}
if ( 'replace-pos' === $this->import_options['type'] ) {
$overwrite_palette = $this->get_overwrite_colors_from_pos( $post_data, $this->import_options['invert'] );
} elseif ( 'inherit' === $this->import_options['type'] && 'do-invert' === $this->import_options['invert'] ) {
$overwrite_palette = [
'--awb-color1' => '--awo-color1',
'--awb-color2' => '--awo-color2',
'--awb-color3' => '--awo-color3',
'--awb-color4' => '--awo-color4',
'--awb-color5' => '--awo-color5',
'--awb-color6' => '--awo-color6',
'--awb-color7' => '--awo-color7',
'--awb-color8' => '--awo-color8',
'--awo-color1' => '--awb-color8',
'--awo-color2' => '--awb-color7',
'--awo-color3' => '--awb-color6',
'--awo-color4' => '--awb-color5',
'--awo-color5' => '--awb-color4',
'--awo-color6' => '--awb-color3',
'--awo-color7' => '--awb-color2',
'--awo-color8' => '--awb-color1',
// Flip lightness manipulation from hsla.
'-l) -' => '-x) -',
'-l) +' => '-l) -',
'-x) -' => '-l) +',
// Flip blend mode on container.
'background_blend_mode="lighten' => 'xackground_blend_mode="lighten',
'background_blend_mode="multiply' => 'background_blend_mode="lighten',
'xackground_blend_mode="lighten' => 'background_blend_mode="multiply',
];
}
return $overwrite_palette;
}
/**
* Gets typography overwrite pallete.
*
* @access public
* @since 3.7
* @param array $post_data The current post data.
* @return array
*/
public function get_overwrite_typography( $post_data ) {
$overwrite_typography = [];
if ( 'replace-pos' === $this->import_options['type'] ) {
$overwrite_typography = $this->get_overwrite_typography_from_pos( $post_data );
}
return $overwrite_typography;
}
/**
* Gets overwrite pallete from POs meta.
*
* @access public
* @since 3.7
* @param array $post_data The current post data.
* @param string $invert If should invert or not.
* @return array
*/
public function get_overwrite_colors_from_pos( $post_data, $invert ) {
$new_colors = [];
if ( isset( $post_data['post_meta']['_fusion'] ) && '' !== $post_data['post_meta']['_fusion'] && is_array( $post_data['post_meta']['_fusion'] ) ) {
$fusion_meta = $post_data['post_meta']['_fusion'];
// If invert is selected.
if ( 'do-invert' === $invert ) {
for ( $start = 1, $end = 8; $start <= 8; $start++, $end-- ) {
if ( isset( $fusion_meta[ 'color' . $end . '_overwrite' ] ) ) {
if ( class_exists( 'Fusion_Color' ) ) {
$color_object = Fusion_Color::new_color( $fusion_meta[ 'color' . $end . '_overwrite' ] );
// HSLA.
$new_colors[ 'var(--awb-color' . $start . '-h)' ] = $color_object->hue;
$new_colors[ 'var(--awb-color' . $start . '-s)' ] = $color_object->saturation . '%';
$new_colors[ 'var(--awb-color' . $start . '-l)' ] = $color_object->lightness . '%';
$new_colors[ 'var(--awb-color' . $start . '-a)' ] = ( $color_object->alpha * 100 ) . '%';
}
$new_colors[ 'var(--awb-color' . $start . ')' ] = $fusion_meta[ 'color' . $end . '_overwrite' ];
}
}
} else {
for ( $i = 1; $i <= 8; $i++ ) {
if ( isset( $fusion_meta[ 'color' . $i . '_overwrite' ] ) ) {
if ( class_exists( 'Fusion_Color' ) ) {
$color_object = Fusion_Color::new_color( $fusion_meta[ 'color' . $i . '_overwrite' ] );
// HSLA.
$new_colors[ 'var(--awb-color' . $i . '-h)' ] = $color_object->hue;
$new_colors[ 'var(--awb-color' . $i . '-s)' ] = $color_object->saturation . '%';
$new_colors[ 'var(--awb-color' . $i . '-l)' ] = $color_object->lightness . '%';
$new_colors[ 'var(--awb-color' . $i . '-a)' ] = ( $color_object->alpha * 100 ) . '%';
}
$new_colors[ 'var(--awb-color' . $i . ')' ] = $fusion_meta[ 'color' . $i . '_overwrite' ];
}
}
}
}
return $new_colors;
}
/**
* Gets overwrite typography pallete from POs meta.
*
* @access public
* @since 3.7
* @param array $post_data The current post data.
* @return array
*/
public function get_overwrite_typography_from_pos( $post_data ) {
$new_typography = [];
if ( isset( $post_data['post_meta']['_fusion'] ) && '' !== $post_data['post_meta']['_fusion'] && is_array( $post_data['post_meta']['_fusion'] ) ) {
$fusion_meta = $post_data['post_meta']['_fusion'];
for ( $i = 1; $i <= 8; $i++ ) {
if ( isset( $fusion_meta[ 'typography' . $i . '_overwrite' ] ) ) {
$typography = $fusion_meta[ 'typography' . $i . '_overwrite' ];
$font_family_is_set = isset( $typography['font-family'] ) && '' !== $typography['font-family'];
// Font family.
if ( $font_family_is_set ) {
$new_typography[ 'var(--awb-typography' . $i . '-font-family)' ] = $typography['font-family'];
}
// Font weight.
if ( isset( $typography['font-weight'] ) && '' !== $typography['font-weight'] ) {
$new_typography[ 'var(--awb-typography' . $i . '-font-weight)' ] = $typography['font-weight'];
}
// Font style.
if ( isset( $typography['font-style'] ) && $font_family_is_set ) {
$style = $typography['font-style'];
if ( ! $style ) {
$style = 'normal';
}
$new_typography[ 'var(--awb-typography' . $i . '-font-style)' ] = $style;
}
// Font size.
if ( isset( $typography['font-size'] ) && '' !== $typography['font-size'] ) {
$new_typography[ 'var(--awb-typography' . $i . '-font-size)' ] = $typography['font-size'];
}
// Line height.
if ( isset( $typography['line-height'] ) && '' !== $typography['line-height'] ) {
$new_typography[ 'var(--awb-typography' . $i . '-line-height)' ] = $typography['line-height'];
}
// Letter Spacing.
if ( isset( $typography['letter-spacing'] ) && '' !== $typography['letter-spacing'] ) {
$new_typography[ 'var(--awb-typography' . $i . '-letter-spacing)' ] = $typography['letter-spacing'];
}
// Text transform.
if ( isset( $typography['text-transform'] ) && '' !== $typography['text-transform'] ) {
$new_typography[ 'var(--awb-typography' . $i . '-text-transform)' ] = $typography['text-transform'];
}
// Font variant.
if ( isset( $typography['variant'] ) && '' !== $typography['variant'] ) {
$new_typography[ 'var(--awb-typography' . $i . ')' ] = $typography['variant'];
}
}
}
}
return $new_typography;
}
/**
* Is string JSON?
*
* @access public
* @since 3.7
* @param string $string The string.
* @return boolean
*/
public function is_json( $string ) {
if ( is_array( $string ) ) {
return false;
}
json_decode( $string );
return JSON_ERROR_NONE === json_last_error();
}
/**
* Imports studio post's media and updates post content if needed.
*
* @param int $post_id Post ID.
* @param string $post_content Post Content.
* @param array $avada_media Avada Media array.
* @param array $overwrite Colors and typography overwrite mapping array.
* @return void
*/
public function import_post_media( $post_id, $post_content, $avada_media, $overwrite = [] ) {
// Check content and import necessary assets from studio site.
$processed_post_data = $this->process_studio_content(
[
'post_id' => $post_id,
'post_content' => $post_content,
'avada_media' => $avada_media,
'overwrite' => $overwrite,
]
);
// Update post content if it was changed.
if ( $processed_post_data['post_content'] !== $post_content ) {
wp_update_post(
[
'ID' => $post_id,
'post_content' => $processed_post_data['post_content'],
]
);
}
}
/**
* Imports icons package.
*
* @access public
* @since 3.5
* @param array $post_details Post details array, returned from import_post function.
* @return mixed null|array
*/
public function import_icons_package( $post_details ) {
// Post was already imported (and package processed) or something went wrong, either case zip package can't be imported.
if ( ! $post_details['post_id'] || ! isset( $post_details['was_imported'] ) || true === $post_details['was_imported'] || ! isset( $post_details['data']['package_url'] ) ) {
return $post_details;
}
// Fetch zip icon package and process it.
$imported_post_id = $post_details['post_id'];
// ZIP package URL.
$package_url = $post_details['data']['package_url'];
// Fetch icon package and add it to Media Library.
$file_array = [];
$file_array['name'] = wp_basename( $package_url );
// Download file to temp location.
$file_array['tmp_name'] = download_url( $package_url );
if ( is_wp_error( $file_array['tmp_name'] ) ) {
return;
}
$attachment_data = [
'post_title' => $file_array['name'],
];
$overrides['test_form'] = false;
$file_data = wp_handle_sideload( $file_array, $overrides );
if ( ! isset( $file_data['file'] ) ) {
return;
}
$attachment_id = wp_insert_attachment( $attachment_data, $file_data['file'], $imported_post_id );
// Flag imported zip package as studio media.
$this->add_media_meta( $attachment_id, $package_url );
// Set necessary post meta if attachment ID is passed.
$icon_set_meta = [
'attachment_id' => $attachment_id,
];
fusion_data()->post_meta( $imported_post_id )->set( 'custom_icon_set', $icon_set_meta );
// (Re)generate icon files.
Fusion_Custom_Icon_Set::get_instance()->regenerate_icon_files( $imported_post_id );
// WIP: begin.
$meta = fusion_data()->post_meta( $post_details['post_id'] )->get( 'custom_icon_set' );
if ( '' !== $meta ) {
$post_details['custom_icons'] = $meta;
$post_details['custom_icons']['name'] = get_the_title( $post_details['post_id'] );
$post_details['custom_icons']['post_id'] = $post_details['post_id'];
$post_details['custom_icons']['css_url'] = fusion_get_custom_icons_css_url( $post_details['post_id'] );
$post_details['custom_icons']['post_name'] = get_post_field( 'post_name', $post_details['post_id'] );
}
// WIP: end.
return $post_details;
}
/**
* Import a video to compliment content.
*
* @access public
* @since 3.5©
* @param string $video_url The video URL.
* @return mixed
*/
public function import_video( $video_url ) {
$existing_video = $this->find_existing_media( $video_url );
if ( $existing_video ) {
$new_video_url = $existing_video;
} else {
$new_video_url = '';
$file_array = [];
$file_array['name'] = wp_basename( $video_url );
// Download file to temp location.
$file_array['tmp_name'] = download_url( $video_url );
if ( is_wp_error( $file_array['tmp_name'] ) ) {
return;
}
if ( ! function_exists( 'media_handle_sideload' ) ) {
require_once ABSPATH . 'wp-admin/includes/media.php';
// Needed for wp_read_image_metadata().
require_once ABSPATH . 'wp-admin/includes/image.php';
}
$post_data = [
'post_title' => $file_array['name'],
];
$attachment_id = media_handle_sideload( $file_array, 0, '', $post_data );
if ( ! is_wp_error( $attachment_id ) ) {
$new_video_url = wp_get_attachment_url( $attachment_id );
$this->add_media_meta( $attachment_id, $new_video_url );
do_action( 'awb_studio_import_action', $attachment_id );
}
// Remove tmp file.
if ( file_exists( $file_array['tmp_name'] ) ) {
unlink( $file_array['tmp_name'] );
}
}
return $new_video_url;
}
/**
* Ajax callback, used to import Studio media (for example from builder screen).
*/
public function ajax_import_media() {
check_ajax_referer( 'fusion_load_nonce', 'fusion_load_nonce' );
$post_data = isset( $_POST['data']['postData'] ) ? wp_unslash( $_POST['data']['postData'] ) : []; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$media_import_key = isset( $_POST['data']['mediaImportKey'] ) ? sanitize_text_field( wp_unslash( $_POST['data']['mediaImportKey'] ) ) : '';
$mapping = isset( $_POST['data']['postData']['mapping'] ) ? $_POST['data']['postData']['mapping'] : []; // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput
// Set import options from $_REQUEST global array.
AWB_Studio_Import()->set_import_options_from_request();
if ( $media_import_key ) {
$layout = $this->process_studio_content(
[
'post_id' => $post_data['post_id'],
'post_content' => $post_data['post_content'],
'avada_media' => [ $media_import_key => $post_data['avada_media'][ $media_import_key ] ],
'overwrite' => $mapping,
]
);
$post_data['post_content'] = $layout['post_content'];
}
if ( isset( $layout['custom_icons'] ) ) {
$post_data['custom_icons'] = $layout['custom_icons'];
}
echo wp_json_encode( $post_data );
die();
}
/**
* Get post content.
*
* @access public
* @since 3.7
* @param array $id Studio post ID.
* @param string $type Studio post type.
* @return mixed
*/
public function get_post_content( $id, $type ) {
$response = wp_remote_get( $this->studio_url . '/wp-json/wp/v2/' . $type . '/' . $id . '/' );
// TODO: better error handling.
if ( is_wp_error( $response ) ) {
return false;
}
$post_data = apply_filters( 'awb_studio_post_data', json_decode( wp_remote_retrieve_body( $response ), true ), $id );
return isset( $post_data['post_content'] ) ? $post_data['post_content'] : $post_data['content']['raw'];
}
}
/**
* Instantiates the AWB_Studio_Import class.
* Make sure the class is properly set-up.
*
* @since 3.0
* @return AWB_Studio_Import
*/
function AWB_Studio_Import() { // phpcs:ignore WordPress.NamingConventions
return AWB_Studio_Import::get_instance();
}
AWB_Studio_Import();