To names for shortcodes * * @static * @access private * @since 5.0.0 * @var array */ private static $from_to_shortcode_names = []; /** * Constructor. * * @access public * @since 5.0.0 * @param string $avada_version The Avada Theme Version. * @param string $avada_option_name The option-name. */ public function __construct( $avada_version, $avada_option_name ) { if ( isset( $_GET['revert'] ) && '1' === $_GET['revert'] ) { self::$revert = true; } self::$avada_database_version = $avada_version; self::$avada_option_name = $avada_option_name; if ( self::needs_migration() ) { add_action( 'save_post', [ $this, 'save_post_actions' ], 999, 2 ); // Initialize the object. add_action( 'init', [ $this, 'init' ], 20 ); // Adds the admin page. add_action( 'admin_init', [ $this, 'render_migration_page' ] ); } } /** * Initializes the object. * * @access public * @since 5.0.0 * @return void */ public function init() { $this->set_posts_per_page(); $this->set_self_enclosing_shortcodes(); $this->set_shortcodes_for_conversion(); $this->set_columns_for_conversion(); $this->remove_conflicting_shortcodes(); $this->set_from_to_shortcode_names(); $this->migration_page_title = esc_html__( 'Avada Shortcode Conversion', 'Avada' ); if ( isset( $_GET['revert'] ) && '1' === $_GET['revert'] ) { $this->migration_page_title = esc_html__( 'Revert Avada Shortcode Conversion', 'Avada' ); } // Set the $option value. self::$option = get_option( self::$option_name, [] ); // Set number of posts that need conversion. self::$posts_to_convert = get_option( self::$option_name . '_number' ); $this->post_types(); $this->current_post_type(); // Early exit if no step is defined. if ( ! isset( $_GET['step'] ) ) { return; } if ( 'query' === $_GET['step'] ) { $this->total_posts(); $this->from_offset(); $this->to_offset(); $this->get_posts(); $this->save_post_ids(); } elseif ( 'convert' === $_GET['step'] ) { // Set number of slides that need conversion. $slides = wp_count_posts( 'slide' ); self::$slides_to_convert = 0; if ( $slides ) { $published = ( isset( $slides->publish ) ) ? $slides->publish : 0; $pending = ( isset( $slides->pending ) ) ? $slides->pending : 0; $draft = ( isset( $slides->draft ) ) ? $slides->draft : 0; $future = ( isset( $slides->future ) ) ? $slides->future : 0; $private = ( isset( $slides->private ) ) ? $slides->private : 0; self::$slides_to_convert = $published + $pending + $draft + $future + $private + 2; } // Make widgets count as one batch of posts. self::$widgets_to_convert = $this->get_posts_per_page(); if ( ! isset( $_GET['type'] ) ) { return; } if ( 'posts' === $_GET['type'] ) { $this->convert_posts(); } elseif ( 'slides' === $_GET['type'] ) { $this->convert_shortcode_names_in_fusion_slider(); $this->convert_shortcode_names_in_revslider(); $this->convert_shortcode_names_in_layerslider(); } elseif ( 'widgets' === $_GET['type'] ) { $this->convert_shortcode_names_in_widgets(); } elseif ( 'theme_options' === $_GET['type'] ) { $this->convert_shortcode_names_in_theme_options(); } } } /** * Determines if we should run the migration or not. * * @static * @access public * @since 5.0.0 * @return bool */ public static function needs_migration() { // Convert later was clicked on the splash screen. if ( is_admin() && isset( $_GET[ self::$slug ] ) && '0' === $_GET[ self::$slug ] && isset( $_GET['migrate_later'] ) && '1' === $_GET['migrate_later'] ) { update_option( self::$option_name . '_converted', '1' ); return false; } // Trigger migration on url visit. if ( is_admin() && isset( $_GET[ self::$slug ] ) && '1' === $_GET[ self::$slug ] ) { return true; } // Make sure that $avada_database_version is defined. if ( empty( self::$avada_database_version ) ) { self::$avada_database_version = get_option( 'avada_version', '' ); } if ( is_array( self::$avada_database_version ) ) { self::$avada_database_version = end( self::$avada_database_version ); } // If the 'avada_version' setting is empty, this is a fresh installation // so no migration is needed. if ( ! self::$avada_database_version || empty( self::$avada_database_version ) ) { return false; } if ( version_compare( self::$avada_database_version, '5.0.0', '<' ) && ! get_option( self::$option_name . '_converted' ) ) { return true; } return false; } /** * Redirects to the next step. * * @access private * @since 5.0.0 * @param bool $advance If true, redirection completes for slides and widgets. * @return void; */ private function next_step_redirection( $advance = false ) { // Set the post-type if not already set. if ( ! isset( $_GET['step'] ) || ! in_array( sanitize_text_field( wp_unslash( $_GET['step'] ) ), [ 'query', 'convert', 'done' ] ) ) { return; } $url = false; $query_finished = false; $posts_per_page = $this->get_posts_per_page(); if ( 'query' === $_GET['step'] ) { $post_type = $this->current_post_type; // TO becomes FROM. $from = $this->to_offset; // If the "from" value is equal or greater than the max number of posts // available for that post type, then move on to the next post-type. if ( $from >= $this->total_posts_count[ $post_type ] ) { $current_post_type_key = array_search( $post_type, $this->post_types ); if ( isset( $this->post_types[ $current_post_type_key + 1 ] ) ) { $post_type = $this->post_types[ $current_post_type_key + 1 ]; $from = 0; } else { $query_finished = true; update_option( self::$option_name . '_number', absint( count( self::$option ) ) ); } } // Calculate the TO var. $to = $from + $posts_per_page; if ( $to >= $this->total_posts_count[ $post_type ] ) { $to = $this->total_posts_count[ $post_type ]; } // Calculate the redirection URL. $revert = ( self::$revert ) ? '&revert=1' : ''; if ( ! $query_finished ) { $url = admin_url( 'index.php?' . self::$slug . '=1&step=query&from=' . $from . '&to=' . $to . '&post_type=' . $post_type . $revert ); } else { $url = admin_url( 'index.php?' . self::$slug . '=1&step=convert&type=posts&size=' . $posts_per_page . $revert ); } } elseif ( 'convert' === $_GET['step'] ) { $revert = ( self::$revert ) ? '&revert=1' : ''; if ( isset( $_GET['type'] ) && 'posts' === $_GET['type'] ) { if ( empty( self::$option ) ) { // It is now safe to remove the option. delete_option( self::$option_name ); delete_option( self::$option_name . '_number' ); $url = admin_url( 'index.php?' . self::$slug . '=1&step=convert&type=slides' . $revert ); } else { $url = admin_url( 'index.php?' . self::$slug . '=1&step=convert&type=posts&size=' . $posts_per_page . $revert ); } } elseif ( 'slides' === $_GET['type'] && $advance ) { $url = admin_url( 'index.php?' . self::$slug . '=1&step=convert&type=widgets' . $revert ); } elseif ( 'widgets' === $_GET['type'] && $advance ) { $url = admin_url( 'index.php?' . self::$slug . '=1&step=convert&type=theme_options' . $revert ); } elseif ( 'theme_options' === $_GET['type'] && $advance ) { $url = admin_url( 'index.php?' . self::$slug . '=1&step=done' . $revert ); } } elseif ( 'done' === $_GET['step'] ) { // Conversion is finished. update_option( self::$option_name . '_converted', '1' ); // If builder is disabled, set post types in settings to prevent defaults being used. $builder_status = get_option( 'avada_disable_builder', '1' ); if ( isset( $builder_status ) && '0' === $builder_status ) { $builder_settings = [ 'post_types' => ' ', ]; update_option( 'fusion_builder_settings', $builder_settings ); } } if ( $url ) { header( "Refresh:0; url=$url" ); } } /** * Sets the post-types we'll be checking against. * * @access private * @since 5.0.0 * @return void */ private function post_types() { $post_types = apply_filters( 'fusion_builder_shortcode_migration_post_types', [ 'page', 'post', 'avada_faq', 'avada_portfolio', 'product', 'tribe_events', ] ); foreach ( $post_types as $key => $post_type ) { if ( ! post_type_exists( $post_type ) ) { unset( $post_types[ $key ] ); } } $this->post_types = $post_types; } /** * Get the current post-type. * Sets the object's $current_post_type. * * @access private * @since 5.0.0 * @return void */ private function current_post_type() { // No need to proceed if we're not in the migration page. if ( ! $_GET || ! isset( $_GET[ self::$slug ] ) || '1' !== $_GET[ self::$slug ] ) { return; } if ( $_GET && isset( $_GET['post_type'] ) ) { $this->current_post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) ); } } /** * Gets the amount of posts per page for each step. * * @access private * @since 5.0.2 * @return int */ private function get_posts_per_page() { return self::$posts_per_page; } /** * Calculates and set the amount of posts per page for each step. * * @access private * @since 5.0.2 * @return void */ private function set_posts_per_page() { if ( function_exists( 'ini_get' ) ) { $max_execution_time = ini_get( 'max_execution_time' ); if ( '0' === $max_execution_time ) { $max_execution_time = 300; } $posts_per_page = round( $max_execution_time / 4 ); self::$posts_per_page = min( 75, max( 15, $posts_per_page ) ); } else { self::$posts_per_page = 15; } } /** * Get the total number of steps. * Sets the object's $total_posts. * * @access private * @since 5.0.0 * @return void */ private function total_posts() { // No need to proceed if we're not in the migration page. if ( ! $_GET || ! isset( $_GET[ self::$slug ] ) || '1' !== $_GET[ self::$slug ] ) { return; } // Set the $total_posts array. foreach ( $this->post_types as $post_type ) { $this->total_posts[ $post_type ] = false; if ( post_type_exists( $post_type ) ) { $posts_count = wp_count_posts( $post_type ); $this->total_posts[ $post_type ] = $posts_count; } } // Calculate the total number of posts available // and set the $total_posts_count. foreach ( $this->total_posts as $post_type => $post_statuses ) { // Make sure it's not empty or false. if ( $post_statuses ) { // Convert to array. $post_statuses = (array) $post_statuses; // Make sure the entry exists in the array. if ( ! isset( $this->total_posts_count[ $post_type ] ) ) { $this->total_posts_count[ $post_type ] = 0; } // Add count for all post statuses. foreach ( $post_statuses as $post_status ) { $this->total_posts_count[ $post_type ] += $post_status; } } } } /** * Set the object's $from_offset. * * @access private * @since 5.0.0 * @return void */ private function from_offset() { // No need to proceed if we're not in the migration page. if ( ! $_GET || ! isset( $_GET[ self::$slug ] ) || '1' !== $_GET[ self::$slug ] ) { return; } // No need to proceed if we don't have a post-type defined. if ( ! isset( $_GET['post_type'] ) ) { return; } if ( isset( $_GET['from'] ) ) { $this->from_offset = absint( $_GET['from'] ); } // Get the post-count for this post-type. // We'll use this to add a cap. $post_type_count = isset( $this->total_posts_count[ $this->current_post_type ] ) ? $this->total_posts_count[ $this->current_post_type ] : 0; if ( $this->from_offset > absint( $post_type_count ) ) { $this->from_offset = absint( $post_type_count ); } } /** * Set the object's $to_offset. * * @access private * @since 5.0.0 * @return void */ private function to_offset() { // No need to proceed if we're not in the migration page. if ( ! $_GET || ! isset( $_GET[ self::$slug ] ) || '1' !== $_GET[ self::$slug ] ) { return; } // No need to proceed if we don't have a post-type defined. if ( ! isset( $_GET['post_type'] ) ) { return; } if ( isset( $_GET['to'] ) ) { $this->to_offset = absint( $_GET['to'] ); } // Get the post-count for this post-type. // We'll use this to add a cap. $post_type_count = isset( $this->total_posts_count[ $this->current_post_type ] ) ? $this->total_posts_count[ $this->current_post_type ] : 0; if ( $this->to_offset > absint( $post_type_count ) ) { $this->to_offset = absint( $post_type_count ); } } /** * Queries the posts. * Sets the object's $posts. * * @access private * @since 5.0.0 * @return void */ private function get_posts() { // No need to proceed if we're not in the migration page. if ( ! $_GET || ! isset( $_GET[ self::$slug ] ) || '1' !== $_GET[ self::$slug ] ) { return; } $args = [ 'suppress_filters' => 1, 'posts_per_page' => $this->get_posts_per_page(), 'offset' => $this->from_offset, 'orderby' => 'date', 'order' => 'DESC', 'post_type' => $this->current_post_type, 'post_status' => 'any', ]; $this->posts = fusion_cached_get_posts( $args ); } /** * Finds posts that need converting. * * @access private * @since 5.0.0 * @return void */ private function save_post_ids() { if ( ! $this->posts ) { return; } $convert_post_ids = []; foreach ( $this->posts as $post ) { if ( self::$revert ) { $backed_up_content = get_post_meta( $post->ID, 'fusion_builder_content_backup', true ); if ( false !== strpos( $backed_up_content, 'fusion_' ) ) { $convert_post_ids[] = $post->ID; } } else { $page_template = get_page_template_slug( $post->ID ); $shortcodes_to_check_for = array_merge( self::$columns_for_conversion, self::$shortcodes_for_conversion ); foreach ( $shortcodes_to_check_for as $sc ) { if ( false !== strpos( $post->post_content, $sc ) || false !== strpos( $post->post_excerpt, $sc ) || 'faqs.php' === $page_template || false !== strpos( $page_template, 'portfolio' ) ) { $convert_post_ids[] = $post->ID; } } } } if ( ! empty( $convert_post_ids ) ) { $this->add_posts_to_setting( $convert_post_ids ); } } /** * Adds posts that need conversion to the db option. * * @access private * @since 5.0.0 * @param array $ids The post IDs. * @return void */ private function add_posts_to_setting( $ids ) { foreach ( $ids as $id ) { if ( ! in_array( $id, self::$option, true ) ) { self::$option[] = $id; } } update_option( self::$option_name, self::$option ); } /** * Removes post-IDs from the array of posts that need conversion. * * @access private * @since 5.0.0 * @param array $ids The post IDs. * @return void */ private function remove_posts_from_setting( $ids ) { foreach ( $ids as $id ) { $key = array_search( $id, self::$option ); if ( false !== $key ) { unset( $option[ $key ] ); } } update_option( self::$option_name, self::$option ); } /** * Migrates the content. * * @access private * @since 5.0.0 * @return void */ private function convert_posts() { // No need to proceed if we're not in the migration page. if ( ! $_GET || ! isset( $_GET[ self::$slug ] ) || '1' !== $_GET[ self::$slug ] ) { return; } // Get a slice of the array. $posts_per_page = $this->get_posts_per_page(); $slice = array_slice( self::$option, 0, $posts_per_page ); foreach ( $slice as $post_id ) { if ( self::$revert ) { // Revert. $this->revert_post_contents( $post_id ); } else { // Convert. $this->convert_post_contents( $post_id ); } // Remove item from the array. $key = array_search( $post_id, self::$option ); unset( self::$option[ $key ] ); } // Update the option, removing unset values. update_option( self::$option_name, self::$option ); } /** * Renders the migration page. * * @access public * @since 5.0.0 * @return void */ public function render_migration_page() { ob_start(); $this->get_migration_page_template(); exit; } /** * The migration-page template. * * @access public * @since 5.0.0 * @return void */ public function get_migration_page_template() { global $shortcode_tags; // Add script to redirect to next step. $this->next_step_redirection(); ?> > <?php echo esc_attr( $this->migration_page_title ); ?>
get_migration_page_welcome_message(); ?>
get_pre_action_heading_content(); ?>

get_migration_page_current_action(); ?>

get_migration_page_current_action_desc(); ?>
get_migration_page_progress_bar(); ?>
get_migration_page_more_info(); ?>
get_migration_page_buttons(); ?>
.avada-setup { padding: 2% 20%; background-color: #f2f2f2; font-family: "Noto Sans", Roboto, "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen-Sans", "Ubuntu", "Cantarell", "Helvetica Neue", sans-serif; font-weight:300; font-size: 1.1em; } .update-content { max-width: 1150px; margin: auto; } .avada-logo { margin-bottom: 25px; text-align: center; } .avada-logo img { max-width: 226.5px; height: auto; vertical-align: bottom; } .avada-version { vertical-align: bottom; } .avada-version-inner { display: inline-block; margin-left: 20px; padding: 5px 10px; background-color: #65bc7b; -webkit-border-radius: 3px; border-radius: 3px; color: #fff; } .avada-content-wrapper { -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 1px 1px 3px 1px rgba(0,0,0,.2); box-shadow: 1px 1px 3px 1px rgba(0,0,0,.2); } .avada-welcome-msg { padding: 25px 35px; line-height: 1.6em; background-color: #65bc7b; color: #fff; font-style: italic; text-align: center; } .avada-migration-link { color: #fff; } .avada-setup-content { padding: 30px 10%; background: #fff; } .fusion-builder-migration-progress-bar { display: block; height: 20px; width: 100%; margin: 1em 0; } .fusion-builder-migration-progress-bar[value] { -webkit-appearance: none; -moz-appearance: none; appearance: none; border: none; color: blue; } .fusion-builder-migration-progress-bar[value]::-webkit-progress-bar { background-color: #ccc; border-radius: 2px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset; } .fusion-builder-migration-progress-bar[value]::-webkit-progress-value { background-color: #65bc7b; -webkit-animation: animate-stripes 5s linear infinite; animation: animate-stripes 5s linear infinite; } progress[value]::-moz-progress-bar { background-color: #65bc7b; } .fusion-builder-migration-progress-bar::-webkit-progress-bar, .fusion-builder-migration-progress-bar, .fusion-builder-migration-progress-bar[value] { -webkit-animation: animate-stripes 5s linear infinite; animation: animate-stripes 5s linear infinite; } @-webkit-keyframes animate-stripes { 100% { background-position: -100px 0px; } } @keyframes animate-stripes { 100% { background-position: -100px 0px; } } .tasks-list { padding: 0; list-style: none; } .tasks-list li .content { color: #333; } .tasks-list li { color: #f2f2f2; } .tasks-list li:before { vertical-align: middle; font-family: dashicons; content: "\f147"; font-size: 1.4em } .tasks-list li.done { color: #65bc7b; } .tasks-list li.doing { color: #000; } .avada-button { display: inline-block; margin: 1.3em 0 0 0; padding: 1em 2em; background-color: #65bc7b; color: #fff; text-decoration: none; -webkit-border-radius: 3px; border-radius: 3px; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; transition: all 0.3s; } .avada-button.needs-update { background-color: #ef5350; } .avada-button:hover { background-color: #5aa86c; } .avada-button.needs-update:hover { background-color: #f44336; } .deny-conversion { background-color: #333333; } .deny-conversion:hover { background-color: #555555; } .avada-footer { padding: 23px 35px; background: #f2f2f2; font-size: 0.8em; text-align: right; } .avada-themefusion-link { color: #000; text-decoration: none; } .avada-separator { padding: 0 10px; } .avada-heart { padding-left: 5px; vertical-align: middle; } .avada-heart:after { font-family: dashicons; content: "\f487"; } .avada-overall-progress { display: -webkit-flex; display: flex; -weblit-justify-content: space-between; justify-content: space-between; margin-bottom: 30px; } .avada-progress-badge { height: 7px; width: 33%; background-color: #F2F2F2; } .avada-progress-badge.avada-filled { background-color: #65bc7b; } get_theme_version() ) ); } else { esc_html_e( 'This is the reversion process. Please see below for further information.', 'Avada' ); } } /** * Renders pre action heading content. * * @access private * @since 5.0.0 * @return void */ private function get_pre_action_heading_content() { $query_class = ''; $convert_class = ''; $done_class = ''; if ( isset( $_GET['step'] ) && 'query' === $_GET['step'] ) { $query_class = ' avada-filled'; } elseif ( isset( $_GET['step'] ) && 'convert' === $_GET['step'] ) { $query_class = ' avada-filled'; $convert_class = ' avada-filled'; } elseif ( isset( $_GET['step'] ) && 'done' === $_GET['step'] ) { $query_class = ' avada-filled'; $convert_class = ' avada-filled'; $done_class = ' avada-filled'; } ?>

get_normalized_theme_version() ) ); ?>

' . esc_attr__( 'download Avada 4.0.3 here', 'Avada' ) . '' ); ?>

get_theme_version() ) ); ?>

' . esc_attr__( 'Avada 4.0.3', 'Avada' ) . '' ); ?>

get_theme_version() ) ); ?>

current_post_type ), absint( $this->from_offset ), absint( $this->to_offset ), absint( $this->total_posts_count[ $this->current_post_type ] ) ); ?>

get_posts_per_page(); if ( isset( $_GET['type'] ) && 'posts' === $_GET['type'] ) { $still_to_convert = count( self::$option ) + $posts_per_page + self::$slides_to_convert + self::$widgets_to_convert; } elseif ( isset( $_GET['type'] ) && 'slides' === $_GET['type'] ) { $still_to_convert = self::$slides_to_convert + self::$widgets_to_convert + self::$theme_options_to_convert; } elseif ( isset( $_GET['type'] ) && 'widgets' === $_GET['type'] ) { $still_to_convert = self::$widgets_to_convert + self::$theme_options_to_convert; } else { $still_to_convert = self::$theme_options_to_convert; } ?> ' . esc_attr__( 'Avada 4.0.3', 'Avada' ) . '' ); ?> get_posts_per_page(); if ( isset( $_GET['type'] ) && 'posts' === $_GET['type'] ) { $still_to_convert = count( self::$option ) + $posts_per_page + self::$slides_to_convert + self::$widgets_to_convert; } elseif ( isset( $_GET['type'] ) && 'slides' === $_GET['type'] ) { $still_to_convert = self::$slides_to_convert + self::$widgets_to_convert; } else { $still_to_convert = self::$widgets_to_convert; } ?> get_posts_per_page(); ?> =' ); } $fusion_builder_latest = false; if ( defined( 'FUSION_BUILDER_VERSION' ) ) { $fusion_builder_latest = version_compare( FUSION_BUILDER_VERSION, $bundled_plugins['fusion-builder']['version'], '>=' ); } ?> $shortcode ) { if ( isset( $shortcode_tags[ $shortcode ] ) && ( ! is_array( $shortcode_tags[ $shortcode ] ) || ( is_object( $shortcode_tags[ $shortcode ][0] ) && false === strpos( get_class( $shortcode_tags[ $shortcode ][0] ), 'FusionSC' ) ) ) ) { unset( self::$shortcodes_for_conversion[ $key ] ); } } } /** * Setup the from -> to array for shortcode names. * * @access private * @since 5.0.0 * @return void */ private function set_from_to_shortcode_names() { $from_to_shortcode_names = []; foreach ( self::$shortcodes_for_conversion as $shortcode ) { if ( 'accordian' === $shortcode ) { $from_to_shortcode_names[ '[' . $shortcode . ' ' ] = '[fusion_accordion '; $from_to_shortcode_names[ '[' . $shortcode . ']' ] = '[fusion_accordion]'; $from_to_shortcode_names[ '[/' . $shortcode . ']' ] = '[/fusion_accordion]'; } elseif ( 'recent_works' === $shortcode ) { $from_to_shortcode_names[ '[' . $shortcode . ' ' ] = '[fusion_portfolio '; $from_to_shortcode_names[ '[' . $shortcode . ']' ] = '[fusion_portfolio]'; $from_to_shortcode_names[ '[/' . $shortcode . ']' ] = '[/fusion_portfolio]'; } elseif ( 'tabs' === $shortcode || 'tab' === $shortcode ) { $from_to_shortcode_names[ '[' . $shortcode . ' ' ] = '[fusion_old_' . $shortcode . ' '; $from_to_shortcode_names[ '[/' . $shortcode . ']' ] = '[/fusion_old_' . $shortcode . ']'; } elseif ( 'vimeo' === $shortcode || 'youtube' === $shortcode ) { $from_to_shortcode_names[ '[' . $shortcode . ' ' ] = '[fusion_' . $shortcode . ' '; $from_to_shortcode_names[ '[/' . $shortcode . ']' ] = ''; } else { $from_to_shortcode_names[ '[' . $shortcode . ' ' ] = '[fusion_' . $shortcode . ' '; $from_to_shortcode_names[ '[' . $shortcode . ']' ] = '[fusion_' . $shortcode . ']'; $from_to_shortcode_names[ '[/' . $shortcode . ']' ] = '[/fusion_' . $shortcode . ']'; } } self::$from_to_shortcode_names = $from_to_shortcode_names; } /** * 1. backup post content as post meta "fusion_builder_content_backup". * 2. replace old shortcodes with new ones. * 3. insert fusion_builder_row where needed. * 4. search page content for opening [ tags. if is not a section add appropriate shortcodes. * 5. insert missing columns shortcode inside fusion_builder_row where needed. * 6. run verification check. check opened & closed tags ( section, row, column ). * 7. add completed post meta flag. * * @access private * @since 5.0.0 * @param string $id A post ID. * @return void */ private function convert_post_contents( $id = '' ) { if ( ! empty( $id ) ) { // Check for "converted" post meta. $content = get_post( $id ); // If we're not on a page with content, early exit. if ( ! is_object( $content ) || ! property_exists( $content, 'post_content' ) ) { return; } $post_content = $content->post_content; $post_excerpt = $content->post_excerpt; $page_template = get_page_template_slug( $id ); $contents = []; if ( ! empty( $post_content ) || 'faqs.php' === $page_template || false !== strpos( $page_template, 'portfolio' ) ) { $contents['post_content'] = $post_content; } if ( ! empty( $post_excerpt ) ) { $contents['post_excerpt'] = $post_excerpt; } $page_converted = get_post_meta( $id, 'fusion_builder_converted', true ); $builder_status = get_post_meta( $id, 'fusion_builder_status', true ); // Backup page content if it was not converted previously. if ( 'yes' !== $page_converted ) { // Backup page content as post meta. update_post_meta( $id, 'fusion_builder_content_backup', $post_content ); } // Update post content. $updated_post = [ 'ID' => $id, ]; $string_from_to = [ // Fullwidth container. '[/fullwidth]' => '[/fusion_builder_row][/fusion_builder_container]', // Columns. '[one_full' => '[fusion_builder_column type="1_1"', '[/one_full]' => '[/fusion_builder_column]', '[one_half' => '[fusion_builder_column type="1_2"', '[/one_half]' => '[/fusion_builder_column]', '[two_third' => '[fusion_builder_column type="2_3"', '[/two_third]' => '[/fusion_builder_column]', '[two_fifth' => '[fusion_builder_column type="2_5"', '[/two_fifth]' => '[/fusion_builder_column]', '[/one_third]' => '[/fusion_builder_column]', '[one_third' => '[fusion_builder_column type="1_3"', '[/five_sixth]' => '[/fusion_builder_column]', '[five_sixth' => '[fusion_builder_column type="5_6"', '[/four_fifth]' => '[/fusion_builder_column]', '[four_fifth' => '[fusion_builder_column type="4_5"', '[/one_fifth]' => '[/fusion_builder_column]', '[one_fifth' => '[fusion_builder_column type="1_5"', '[/one_fourth]' => '[/fusion_builder_column]', '[one_fourth' => '[fusion_builder_column type="1_4"', '[/three_fifth]' => '[/fusion_builder_column]', '[three_fifth' => '[fusion_builder_column type="3_5"', '[/three_fourth]' => '[/fusion_builder_column]', '[three_fourth' => '[fusion_builder_column type="3_4"', '[/one_sixth]' => '[/fusion_builder_column]', '[one_sixth' => '[fusion_builder_column type="1_6"', ]; foreach ( $contents as $content_type => $content ) { // For Visual Composer only. $new_string_from_to = $string_from_to; if ( false !== strpos( $content, '[vc_row]' ) ) { unset( $new_string_from_to['[/fullwidth]'] ); } // Replace old layout shortcodes with new ones. $content = strtr( $content, $new_string_from_to ); // Replace old element shortcodes with new ones. $content = $this->convert_shortcode_names( $content ); // Add trailing slashes to self enclosing shortcodes. $content = $this->add_shortcode_trailing_slash( $content ); if ( 'post_content' === $content_type && false === strpos( $content, '[vc_row]' ) ) { // Pricing shortcode inside text shortcode fix. // TODO: expand to include woo, layer, etc ? $second_string_from_to = [ '[fusion_text][fusion_pricing_table' => '[fusion_pricing_table', '[/fusion_pricing_table][/fusion_text]' => '[/fusion_pricing_table]', ]; $content = strtr( $content, $second_string_from_to ); $needle = '[fullwidth'; $last_pos = -1; $position_change = 0; $positions = []; // Get all positions of [fullwidth shortcode. while ( ( $last_pos = strpos( $content, $needle, $last_pos + 1 ) ) !== false ) { $positions[] = $last_pos; } foreach ( $positions as $position ) { // Fullwidth tag closing position. $section_close_position = strpos( $content, ']', $position + $position_change ); // Insert [fusion_builder_row] shortcode. $content = substr_replace( $content, '][fusion_builder_row]', $section_close_position, 1 ); // Change in position. $position_change = $position_change + 20; } // Replace old [fullwidth shortcode with new [fusion_builder_section. $third_string_from_to = [ '[fullwidth' => '[fusion_builder_container', ]; $content = strtr( $content, $third_string_from_to ); // Convert outer elements and columns. $content = $this->convert_outside_elements( $content ); // Convert rows. $content = $this->convert_rows( $content ); } if ( 'faqs.php' === $page_template ) { $content .= $this->convert_faqs_template( $id ); } elseif ( false !== strpos( $page_template, 'portfolio' ) ) { $content .= $this->convert_portfolio_template( $id, $page_template ); } // Convert container paddings. if ( '100-width.php' === $page_template ) { $content = $this->convert_container_paddings( $content, $id ); } // For each content type, add converted contents to update array. $updated_post[ $content_type ] = $content; } $updated = wp_update_post( add_magic_quotes( $updated_post ), true ); if ( is_wp_error( $updated ) ) { $errors = $updated->get_error_messages(); update_post_meta( $id, 'fusion_builder_converted', $errors ); } else { update_post_meta( $id, 'fusion_builder_converted', 'yes' ); } } } /** * 1. Revert content * 2. Remove extra post-meta that was added during migration. * * @access private * @since 5.0.0 * @param string $id A post ID. * @return void */ private function revert_post_contents( $id = '' ) { // Early exit if post-ID is not defined. if ( empty( $id ) ) { return; } // Get the backed-up content. $backed_up_content = get_post_meta( $id, 'fusion_builder_content_backup', true ); // Do not procced if the post was not previously converted. $converted = get_post_meta( $id, 'fusion_builder_converted', true ); if ( 'yes' !== $converted ) { return; } // Do not proceed if the backed-up content does not exist or is empty. if ( ! is_string( $backed_up_content ) || empty( $backed_up_content ) ) { return; } // Get the post object. $post = get_post( $id ); $reverted_post = (array) $post; // Revert content. $reverted_post['post_content'] = $backed_up_content; // Update post. wp_update_post( $reverted_post, true ); // Cleanup post-meta. delete_post_meta( $id, 'fusion_builder_content_backup' ); delete_post_meta( $id, 'fusion_builder_converted' ); } /** * Adds / before closing bracket of self enclosing shortcodes. * * @since 5.0.0 * @param string $content Content of a specific post. * @return string The updated post content. */ private function add_shortcode_trailing_slash( $content ) { $positions = []; $position_change = 0; $last_pos = -1; // Get all positions of self enclosing shortcode beginnings. if ( '' !== $content ) { foreach ( self::$self_enclosing_shortcodes as $key => $needle ) { while ( ( $last_pos = strpos( $content, '[' . $needle, $last_pos + 1 ) ) !== false ) { $allowed_chars = [ ' ', ']' ]; if ( in_array( substr( $content, $last_pos + strlen( $needle ) + 1, 1 ), $allowed_chars ) ) { $positions[] = $last_pos; } } } // Sort to make sure we go through them in order. asort( $positions ); foreach ( $positions as $position ) { // Get closing position. $section_close_position = strpos( $content, ']', $position + $position_change ); // Insert /]. if ( '/]' !== substr( $content, $section_close_position - 1, 2 ) ) { $content = substr_replace( $content, '/]', $section_close_position, 1 ); } // Change in position. $position_change++; } } return $content; } /** * Convert old Avada shortcode names to new Avada Builder names. * * @since 5.0.0 * @param string $content Content of a specific post. * @return string The updated post content. */ private function convert_shortcode_names( $content ) { $content = strtr( $content, self::$from_to_shortcode_names ); // Also convert needed shortcode attributes. $content = $this->convert_shortcode_attributes( $content ); return $content; } /** * Convert old Avada shortcode attributes to new Avada Builder attributes. * * @since 5.0.0 * @param string $content Content of a specific post. * @return string The updated post content. */ private function convert_shortcode_attributes( $content ) { $string_from_to = [ 'grid-with-excerpts' => 'grid-with-text', 'style_type="single"' => 'style_type="single solid"', 'style_type="double"' => 'style_type="double solid"', 'style_type="underline"' => 'style_type="underline solid"', ]; $content = strtr( $content, $string_from_to ); return $content; } /** * Convert FusionBuilder rows. * * @since 5.0.0 * @param string $content Content of a specific post. * @return string The updated post content. */ private function convert_rows( $content ) { $needle = '[fusion_builder_row]'; $last_pos = -1; $position_change = 0; $positions = []; // Get all positions of [fusion_builder_row shortcode. while ( ( $last_pos = strpos( $content, $needle, $last_pos + 1 ) ) !== false ) { $positions[] = $last_pos; } // For each row. foreach ( $positions as $position ) { $position = $position + $position_change; $row_closing_position = strpos( $content, '[/fusion_builder_row]', $position ); // Search within this range/row. $range = $row_closing_position - $position + 1; // Row content. $row_content = substr( $content, $position + strlen( $needle ), $range ); $original_row_content = $row_content; $element_needle = '['; $row_last_pos = -1; $row_position_change = 0; $element_positions = []; $main_column_opened = false; $inner_column_opened = false; $inner_columns_total_width = 0; $outside_column_element = false; $outside_column_element_close_position = 0; $element_position_change = 0; // Get all positions for shortcode opening tag "[". while ( ( $row_last_pos = strpos( $row_content, $element_needle, $row_last_pos + 1 ) ) !== false ) { $element_positions[] = $row_last_pos; } foreach ( $element_positions as $element_position ) { $shortcode_name = substr( $row_content, $element_position + $element_position_change, 40 ); $shortcode_name_space = strtok( $shortcode_name, ' ' ); $shortcode_name_bracket = strtok( $shortcode_name, ']' ); if ( strlen( $shortcode_name_space ) < strlen( $shortcode_name_bracket ) ) { $shortcode_name = $shortcode_name_space; } else { $shortcode_name = $shortcode_name_bracket; } // If it's a column that is opened. if ( '[fusion_builder_column' === $shortcode_name ) { if ( $main_column_opened ) { if ( $outside_column_element && $outside_column_element_close_position && $element_position + $element_position_change > $outside_column_element_close_position ) { // Close column. $row_content = substr_replace( $row_content, '[/fusion_builder_column]', $element_position + $element_position_change, 0 ); $outside_column_element = false; $element_position_change = $element_position_change + 24; $outside_column_element_close_position = 0; } else { $inner_row_container = ''; $inner_row_container_position_change = 0; if ( ! $inner_column_opened ) { if ( 0 === $inner_columns_total_width ) { $inner_row_container = '[fusion_builder_row_inner]'; $inner_row_container_position_change = 26; } $column_width = explode( '_', substr( $row_content, $element_position + $element_position_change + strlen( $shortcode_name ) + 7, 3 ) ); $column_width = $column_width[0] / $column_width[1]; $inner_columns_total_width += $column_width; } $row_content = substr_replace( $row_content, $inner_row_container . '[fusion_builder_column_inner', $element_position + $element_position_change, strlen( $shortcode_name ) ); $element_position_change += $inner_row_container_position_change + 6; $outside_column_element_close_position += $inner_row_container_position_change + 6; $inner_column_opened = true; } } $main_column_opened = true; // If it's a column that is closed. } elseif ( '[/fusion_builder_column' === $shortcode_name ) { if ( $main_column_opened && $inner_column_opened ) { $inner_row_container = ''; $inner_row_container_position_change = 0; if ( 1 <= $inner_columns_total_width ) { $inner_row_container = '[/fusion_builder_row_inner]'; $inner_row_container_position_change = 27; $inner_columns_total_width = 0; } $row_content = substr_replace( $row_content, '[/fusion_builder_column_inner]' . $inner_row_container, $element_position + $element_position_change, strlen( $shortcode_name ) + 1 ); $element_position_change += $inner_row_container_position_change + 6; $outside_column_element_close_position += $inner_row_container_position_change + 6; $inner_column_opened = false; } elseif ( $main_column_opened ) { $main_column_opened = false; } } elseif ( '[/fusion_builder_row' === $shortcode_name ) { // If end of row. if ( $main_column_opened ) { $row_content = substr_replace( $row_content, '[/fusion_builder_column]', $element_position + $element_position_change, 0 ); $main_column_opened = false; $element_position_change = $element_position_change + 24; } } elseif ( 1 !== strpos( $shortcode_name, '/' ) ) { // If it's an element opening tag. $set_outside_column_element_close_position = false; $shortcode_name = substr( $row_content, $element_position + $element_position_change, 40 ); $shortcode_name_space = strtok( $shortcode_name, ' ' ); $shortcode_name_bracket = strtok( $shortcode_name, ']' ); if ( strlen( $shortcode_name_space ) < strlen( $shortcode_name_bracket ) ) { $shortcode_name = str_replace( '[', '', $shortcode_name_space ); } else { $shortcode_name = str_replace( '[', '', $shortcode_name_bracket ); } // This is an element, add column. if ( ! $main_column_opened ) { $column_open_tag = '[fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"]'; $row_content = substr_replace( $row_content, $column_open_tag, $element_position + $element_position_change, 0 ); // Change in position. $element_position_change = $element_position_change + strlen( $column_open_tag ); $set_outside_column_element_close_position = true; } elseif ( $main_column_opened && $outside_column_element_close_position && $element_position + $element_position_change > $outside_column_element_close_position ) { $column_close_open_tag = '[/fusion_builder_column][fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"]'; if ( 'fusion_button' === $shortcode_name || 'fusion_fontawesome' === $shortcode_name || 'fusion_imageframe' === $shortcode_name || 'fusion_separator' === $shortcode_name || 'fusion_text' === $shortcode_name ) { $column_close_open_tag = ''; } $row_content = substr_replace( $row_content, $column_close_open_tag, $element_position + $element_position_change, 0 ); // Change in position. $element_position_change = $element_position_change + strlen( $column_close_open_tag ); $set_outside_column_element_close_position = true; } if ( $set_outside_column_element_close_position ) { $main_column_opened = true; $outside_column_element = true; $shortcode_name = str_replace( '[', '', $shortcode_name ); if ( in_array( $shortcode_name, self::$self_enclosing_shortcodes ) ) { $outside_column_element_close_position = strpos( $row_content, '/]', $element_position + $element_position_change ); } else { $outside_column_element_close_position = strpos( $row_content, '[/' . $shortcode_name . ']', $element_position + $element_position_change ); } $set_outside_column_element_close_position = false; } } } // Replace unprocessed row content with processed one. $content = substr_replace( $content, $row_content, $position + 20, strlen( $original_row_content ) ); // Get character difference between processed and unprocessed row content. $content_difference = strlen( $row_content ) - strlen( $original_row_content ); $position_change = $position_change + $content_difference; } return $content; } /** * Convert content outside of FusionBuilder rows. * * @since 5.0.0 * @param string $content Content of a specific post. * @return string The updated post content. */ private function convert_outside_elements( $content ) { // Check for elements outside of fullwidth section. $element_needle = '['; $last_pos = -1; $element_position_change = 0; $element_positions = []; $section_opened = false; $column_opened = false; // Get all positions for shortcode opening tag "[". while ( ( $last_pos = strpos( $content, $element_needle, $last_pos + 1 ) ) !== false ) { $element_positions[] = $last_pos; } foreach ( $element_positions as $key => $element_position ) { $section_needle = '[fusion_builder_container'; $check_for_section = substr( $content, $element_position + $element_position_change, strlen( $section_needle ) ); // If it's a section that is opened. if ( $check_for_section === $section_needle ) { if ( $section_opened ) { // Close section. $close_section_tag = '[/fusion_builder_row][/fusion_builder_container]'; $content = substr_replace( $content, $close_section_tag, $element_position + $element_position_change, 0 ); $section_opened = false; $element_position_change = $element_position_change + strlen( $close_section_tag ); } $section_opened = true; // If section is closed. } elseif ( '[/fusion_builder_containe' === $check_for_section ) { $section_opened = false; // This is an element. Add column. } else { if ( ! $section_opened ) { $shortcode_name = substr( $content, $element_position + $element_position_change, 40 ); $shortcode_name_space = strtok( $shortcode_name, ' ' ); $shortcode_name_bracket = strtok( $shortcode_name, ']' ); if ( strlen( $shortcode_name_space ) < strlen( $shortcode_name_bracket ) ) { $shortcode_name = str_replace( '[', '', $shortcode_name_space ); } else { $shortcode_name = str_replace( '[', '', $shortcode_name_bracket ); } // Convert section separator with negative margins. if ( 'fusion_separator' === $shortcode_name ) { $section_top_margin = ''; $section_bottom_margin = ''; if ( isset( $element_positions[ $key + 1 ] ) ) { $end_position = $element_positions[ $key + 1 ]; } else { $end_position = strlen( $content ); } $separator_tag_length = $end_position - $element_position; $separator_tag = substr( $content, $element_position + $element_position_change, $separator_tag_length ); preg_match( '/(top=["\'](.*?)["\'])/', $separator_tag, $top ); preg_match( '/(bottom=["\'](.*?)["\'])/', $separator_tag, $bottom ); preg_match( '/(top_margin=["\'](.*?)["\'])/', $separator_tag, $top_margin ); preg_match( '/(bottom_margin=["\'](.*?)["\'])/', $separator_tag, $bottom_margin ); preg_match( '/(style=["\'](.*?)["\'])/', $separator_tag, $style ); if ( isset( $top_margin[2] ) ) { $section_top_margin = self::validate_shortcode_attr_value( $top_margin[2], 'px' ); $separator_tag = str_replace( $top_margin[0], '', $separator_tag ); } if ( isset( $bottom_margin[2] ) ) { $section_bottom_margin = self::validate_shortcode_attr_value( $bottom_margin[2], 'px' ); $separator_tag = str_replace( $bottom_margin[0], '', $separator_tag ); } if ( isset( $top[2] ) ) { $section_top_margin = $top[2]; $separator_tag = str_replace( $top[0], '', $separator_tag ); if ( ! isset( $bottom[2] ) && isset( $stlye[2] ) && 'none' !== $style[2] ) { $section_bottom_margin = self::validate_shortcode_attr_value( $top[2], 'px' ); } } if ( isset( $bottom[2] ) ) { $section_bottom_margin = self::validate_shortcode_attr_value( $bottom[2], 'px' ); $separator_tag = str_replace( $bottom[0], '', $separator_tag ); } $section_top_margin = ' margin_top="' . $section_top_margin . '"'; $section_bottom_margin = ' margin_bottom="' . $section_bottom_margin . '"'; // Open and close tags. $wrapped_shortcode = '[fusion_builder_container hundred_percent="yes" overflow="visible"' . $section_top_margin . $section_bottom_margin . ' background_color="rgba(255,255,255,0)"][fusion_builder_row]'; $wrapped_shortcode .= $separator_tag; $wrapped_shortcode .= '[/fusion_builder_row][/fusion_builder_container]'; $content = substr_replace( $content, '', $element_position + $element_position_change, $separator_tag_length ); $content = substr_replace( $content, $wrapped_shortcode, $element_position + $element_position_change, 0 ); $section_opened = false; $element_position_change = $element_position_change + strlen( $wrapped_shortcode ) - $separator_tag_length; } else { // Open section. $open_section_tag = '[fusion_builder_container hundred_percent="yes" overflow="visible"][fusion_builder_row]'; $content = substr_replace( $content, $open_section_tag, $element_position + $element_position_change, 0 ); $section_opened = true; $element_position_change = $element_position_change + strlen( $open_section_tag ); } } } } // Close section if it was not closed. if ( $section_opened ) { $content .= '[/fusion_builder_row][/fusion_builder_container]'; $section_opened = false; } return $content; } /** * Convert FAQ page template to FAQ shortcode element. * * @since 5.0.0 * @param string $id The page ID. * @return string The faq shortcode. */ private function convert_faqs_template( $id ) { $section_open_tag = '[fusion_builder_container hundred_percent="yes" overflow="visible"][fusion_builder_row]'; $column_open_tag = '[fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"]'; $faq_tag = '[fusion_faq filters="" featured_image="" cats_slug="" exclude_cats="" hide_on_mobile="small-visibility,medium-visibility,large-visibility" class="" id="" /]'; $column_close_tag = '[/fusion_builder_column]'; $section_close_tag = '[/fusion_builder_row][/fusion_builder_container]'; $backup_options = get_option( 'avada_500_backup_page_templates_faqs', [] ); if ( self::$revert ) { if ( in_array( $id, $backup_options ) ) { update_post_meta( $id, '_wp_page_template', 'faqs.php' ); } } else { // Backup template. if ( ! in_array( $id, $backup_options ) ) { $backup_options[] = $id; update_option( 'avada_500_backup_page_templates_faqs', $backup_options ); } // Reset the page template. update_post_meta( $id, '_wp_page_template', 'default' ); } return $section_open_tag . $column_open_tag . $faq_tag . $column_close_tag . $section_close_tag; } /** * Convert portfolio page templates to portfolio shortcode element. * * @since 5.0.0 * @param string $id The page ID. * @param string $template_name The page template. * @return string The faq shortcode. */ private function convert_portfolio_template( $id, $template_name ) { // Wrapping tags. $section_open_tag = '[fusion_builder_container hundred_percent="yes" overflow="visible"][fusion_builder_row]'; $column_open_tag = '[fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"]'; $column_close_tag = '[/fusion_builder_column]'; $section_close_tag = '[/fusion_builder_row][/fusion_builder_container]'; // Layout. $layout = 'grid'; if ( false !== strpos( $template_name, 'text' ) ) { $layout = 'grid-with-text'; } // Columns. $columns_mapping = [ 'one' => '1', 'two' => '2', 'three' => '3', 'grid' => '3', 'four' => '4', 'five' => '5', 'six' => '6', ]; $template_name_array = explode( '-', $template_name ); $columns = $columns_mapping[ $template_name_array[1] ]; // Cat slugs. $term_ids = fusion_get_page_option( 'pyre_portfolio_category', $id ); $cat_slugs = ''; // No categories selected. if ( is_array( $term_ids ) ) { // Multiple categories selected. if ( 1 !== count( $term_ids ) || '0' !== $term_ids[0] ) { $cat_slugs = []; // "All Categories" is selected together with others if ( isset( $term_ids[0] ) && '0' === $term_ids[0] ) { unset( $term_ids[0] ); $term_ids = array_values( $term_ids ); } foreach ( $term_ids as $term_id ) { $term = get_term( $term_id, 'portfolio_category' ); $cat_slugs[] = $term->slug; } $cat_slugs = implode( ',', $cat_slugs ); } } // Image size. $image_size = fusion_get_page_option( 'portfolio_featured_image_size', $id ); if ( 'cropped' === $image_size ) { $image_size = 'fixed'; } elseif ( 'full' === $image_size ) { $image_size = 'auto'; } // Column spacing. $column_spacing = fusion_get_page_option( 'pyre_portfolio_column_spacing', $id ); if ( ! $column_spacing ) { $column_spacing = Avada()->settings->get( 'portfolio_column_spacing' ); } $excerpt_length = fusion_get_page_option( 'pyre_portfolio_excerpt', $id ); if ( ! $excerpt_length ) { $excerpt_length = Avada()->settings->get( 'excerpt_length_portfolio' ); } // If single grid, make sure to set to grid with text, text on side. if ( '1' === $columns && 'grid' === $layout ) { $layout = 'grid-with-text'; } // Construct the portfolio shortcode. $portfolio_vars = [ 'content_length' => str_replace( '_', '-', fusion_get_page_option( 'pyre_portfolio_content_length', $id ) ), 'layout' => $layout, 'portfolio_title_display' => fusion_get_page_option( 'pyre_portfolio_title_display', $id ), 'portfolio_text_alignment' => fusion_get_page_option( 'pyre_portfolio_text_alignment', $id ), 'portfolio_layout_padding' => fusion_get_page_option( 'pyre_portfolio_layout_padding', $id ), 'excerpt_length' => $excerpt_length, 'cat_slug' => $cat_slugs, 'filters' => str_replace( '_', '-', fusion_get_page_option( 'pyre_portfolio_filters', $id ) ), 'boxed_text' => fusion_get_page_option( 'pyre_portfolio_text_layout', $id ), 'picture_size' => $image_size, 'columns' => $columns, 'column_spacing' => $column_spacing, 'number_posts' => Avada()->settings->get( 'portfolio_items' ), 'strip_html' => 'default', 'pagination_type' => 'default', 'one_column_text_position' => ( 'portfolio-one-column.php' === $template_name ) ? 'floated' : 'below', ]; $portfolio_tag = '[fusion_portfolio '; foreach ( $portfolio_vars as $attribute_name => $value ) { $portfolio_tag .= $attribute_name . '="' . $value . '" '; } $portfolio_tag .= '/]'; $backup_options = get_option( 'avada_500_backup_page_templates_portfolio', [] ); if ( self::$revert ) { foreach ( $backup_options as $page_id => $template_args ) { if ( $page_id != $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons continue; } foreach ( $template_args as $page_template => $pyre_portfolio_width_100 ) { update_post_meta( $page_id, '_wp_page_template', $page_template ); if ( true === $pyre_portfolio_width_100 ) { update_post_meta( $page_id, 'pyre_portfolio_width_100', 'yes' ); } } } } else { $page_template = get_page_template_slug( $id ); // Backup the page template. if ( ! isset( $backup_options[ $id ] ) ) { $backup_options[ $id ] = []; } $pyre_portfolio_width_100 = fusion_get_page_option( 'pyre_portfolio_width_100', $id ); $backup_options[ $id ][ $page_template ] = ( 'yes' === $pyre_portfolio_width_100 ); update_option( 'avada_500_backup_page_templates_portfolio', $backup_options ); // Set the page template correctly. $page_width = $pyre_portfolio_width_100; if ( 'yes' === $page_width ) { update_post_meta( $id, '_wp_page_template', '100-width.php' ); } else { update_post_meta( $id, '_wp_page_template', 'default' ); } } // Remove the 100% width setting, as it is not valid on normal pages. delete_post_meta( $id, 'pyre_portfolio_width_100' ); return $section_open_tag . $column_open_tag . $portfolio_tag . $column_close_tag . $section_close_tag; } /** * Convert Avada Slider post meta. * * @since 5.0.0 * @return void */ private function convert_shortcode_names_in_fusion_slider() { $post_meta_to_convert = [ 'pyre_heading', 'pyre_caption', 'pyre_button_1', 'pyre_button_2' ]; $backup_data = get_option( 'avada_500_backup_fusion_slider_data', [] ); $args = [ 'post_type' => 'slide', 'post_status' => [ 'publish', 'pending', 'draft', 'future', 'private' ], 'posts_per_page' => -1, ]; $query = new WP_Query( $args ); if ( $query->have_posts() ) { while ( $query->have_posts() ) : $query->the_post(); global $post; if ( self::$revert ) { foreach ( $backup_data as $post_id => $post_data ) { foreach ( $post_data as $post_meta_name => $post_meta_content ) { update_post_meta( $post_id, $post_meta_name, $post_meta_content ); } } } else { foreach ( $post_meta_to_convert as $post_meta_name ) { $post_meta_content = get_post_meta( $post->ID, $post_meta_name, true ); // Convert element shortcodes. $converted_post_meta = $this->convert_shortcode_names( $post_meta_content ); if ( $converted_post_meta != $post_meta_content ) { // phpcs:ignore WordPress.PHP.StrictComparisons // Backup data. if ( ! isset( $backup_data[ $post->ID ] ) ) { $backup_data[ $post->ID ] = []; } $backup_data[ $post->ID ][ $post_meta_name ] = $post_meta_content; // Update converted post meta. update_post_meta( $post->ID, $post_meta_name, $converted_post_meta ); } } update_option( 'avada_500_backup_fusion_slider_data', $backup_data ); } endwhile; wp_reset_postdata(); } $this->next_step_redirection( true ); } /** * Convert Slider Revolution text layers. * * @since 5.0.0 * @return void */ private function convert_shortcode_names_in_revslider() { if ( class_exists( 'RevSliderFront' ) ) { $slider_object = new RevSliderSlider(); $sliders_array = $slider_object->getArrSliders(); foreach ( $sliders_array as $slider ) { $slides = $slider->getSlidesFromGallery(); foreach ( $slides as $slide ) { $layers = $slide->getLayers(); // The backup option. $backup_options = get_option( 'avada_500_backup_revslider', [] ); if ( self::$revert ) { // Revert options? if ( ! empty( $backup_options ) ) { foreach ( $backup_options as $key => $layer_text ) { $layers[ $key ]['text'] = $layer_text; } } } else { // Backup and convert options. foreach ( $layers as $key => $layer ) { // Convert data. $converted_data = $this->convert_shortcode_names( $layer['text'] ); // Backup data. if ( $converted_data !== $layer['text'] ) { $backup_options[ $key ] = $layer['text']; } $layers[ $key ]['text'] = $converted_data; } update_option( 'avada_500_backup_revslider', $backup_options ); } $slide->setLayersRaw( $layers ); $slide->saveLayers(); } } } } /** * Convert Layer Slider data. * * @since 5.0.0 * @return void */ private function convert_shortcode_names_in_layerslider() { if ( class_exists( 'LS_Sliders' ) ) { // Find all sliders. $sliders = LS_Sliders::find(); // The backup options. $backup_options = get_option( 'avada_500_backup_layerslider', [] ); foreach ( $sliders as $slider ) { if ( self::$revert ) { if ( ! empty( $backup_options ) ) { foreach ( $backup_options as $id => $layer ) { foreach ( $layer as $layerkey => $sublayer ) { foreach ( $sublayer as $sublayerkey => $sublayercontent ) { $slider['data']['layers'][ $layerkey ]['sublayers'][ $sublayerkey ]['html'] = $sublayercontent; } } } } } else { // Loop through each slider, checking for layers and converting. if ( isset( $slider['data']['layers'] ) ) { foreach ( $slider['data']['layers'] as $layerkey => $layer ) { if ( isset( $layer['sublayers'] ) ) { foreach ( $layer['sublayers'] as $sublayerkey => $sublayer ) { if ( isset( $sublayer['media'] ) && ( 'text' === $sublayer['media'] || 'html' === $sublayer['media'] ) ) { // If the sub layer is of type text, then convert html contents or revert depending on the process. $converted_data = $this->convert_shortcode_names( $sublayer['html'] ); // If there is a difference, then backup the data. if ( $converted_data !== $sublayer['html'] ) { if ( ! isset( $backup_options[ $slider['id'] ] ) ) { $backup_options[ $slider['id'] ] = []; } if ( ! isset( $backup_options[ $slider['id'] ][ $layerkey ] ) ) { $backup_options[ $slider['id'] ][ $layerkey ] = []; } $backup_options[ $slider['id'] ][ $layerkey ][ $sublayerkey ] = $sublayer['html']; update_option( 'avada_500_backup_layerslider', $backup_options ); } // Update data. $slider['data']['layers'][ $layerkey ]['sublayers'][ $sublayerkey ]['html'] = $converted_data; } } } } } // Save the backed-up data. update_option( 'avada_500_backup_layerslider', $backup_options ); } $id = $slider['id']; $title = $slider['data']['properties']['title']; $data = $slider['data']; $slug = ( isset( $slider['data']['properties']['slug'] ) ) ? $slider['data']['properties']['slug'] : ''; // Update slider with changed content. LS_Sliders::update( $id, $title, $data, $slug ); } } } /** * Convert content inside of text widgets. * * @since 5.0.0 * @return void */ private function convert_shortcode_names_in_widgets() { global $wp_registered_sidebars, $wp_registered_widgets; $sidebars_widgets = wp_get_sidebars_widgets(); foreach ( $sidebars_widgets as $sidebar_id => $sidebar ) { if ( ! empty( $sidebar ) ) { foreach ( $sidebar as $widget_id ) { $option_name = false; if ( isset( $wp_registered_widgets[ $widget_id ] ) && isset( $wp_registered_widgets[ $widget_id ]['callback'] ) && isset( $wp_registered_widgets[ $widget_id ]['callback'][0] ) ) { $option_name = $wp_registered_widgets[ $widget_id ]['callback'][0]->option_name; } // Change text widget and black studio TinyMCE widget. Fix for #4253. if ( 'widget_text' === $option_name || 'widget_black-studio-tinymce' === $option_name ) { if ( self::$revert ) { // Revert backup. $backed_up_options = get_option( 'avada_500_backup_widget_text', [] ); if ( ! empty( $backed_up_options ) ) { update_option( 'widget_text', $backed_up_options ); $this->next_step_redirection( true ); } } else { // Convert. $key = $wp_registered_widgets[ $widget_id ]['params'][0]['number']; $widget_data = get_option( $option_name ); if ( isset( $widget_data[ $key ]['text'] ) ) { $widget_content = $widget_data[ $key ]['text']; } else { $widget_content = ''; } // Backup data. $backup_options = get_option( 'avada_500_backup_widget_text', [] ); if ( empty( $backup_options ) ) { update_option( 'avada_500_backup_widget_text', $widget_data ); } // Then convert shortcodes. $widget_content = $this->convert_shortcode_names( $widget_content ); $string_from_to = [ // Fullwidth container. '[/fullwidth]' => '[/fusion_builder_row][/fusion_builder_container]', // Columns. '[one_full' => '[fusion_builder_column type="1_1"', '[/one_full]' => '[/fusion_builder_column]', '[one_half' => '[fusion_builder_column type="1_2"', '[/one_half]' => '[/fusion_builder_column]', '[two_third' => '[fusion_builder_column type="2_3"', '[/two_third]' => '[/fusion_builder_column]', '[two_fifth' => '[fusion_builder_column type="2_5"', '[/two_fifth]' => '[/fusion_builder_column]', '[/one_third]' => '[/fusion_builder_column]', '[one_third' => '[fusion_builder_column type="1_3"', '[/five_sixth]' => '[/fusion_builder_column]', '[five_sixth' => '[fusion_builder_column type="5_6"', '[/four_fifth]' => '[/fusion_builder_column]', '[four_fifth' => '[fusion_builder_column type="4_5"', '[/one_fifth]' => '[/fusion_builder_column]', '[one_fifth' => '[fusion_builder_column type="1_5"', '[/one_fourth]' => '[/fusion_builder_column]', '[one_fourth' => '[fusion_builder_column type="1_4"', '[/three_fifth]' => '[/fusion_builder_column]', '[three_fifth' => '[fusion_builder_column type="3_5"', '[/three_fourth]' => '[/fusion_builder_column]', '[three_fourth' => '[fusion_builder_column type="3_4"', '[/one_sixth]' => '[/fusion_builder_column]', '[one_sixth' => '[fusion_builder_column type="1_6"', ]; // Replace old layout shortcodes with new ones. $widget_content = strtr( $widget_content, $string_from_to ); // Handle [fullwidth] shortcodes. $needle = '[fullwidth'; $last_pos = -1; $position_change = 0; $positions = []; // Get all positions of [fullwidth shortcode. while ( false !== ( $last_pos = strpos( $widget_content, $needle, $last_pos + 1 ) ) ) { $positions[] = $last_pos; } foreach ( $positions as $position ) { // Fullwidth tag closing position. $section_close_position = strpos( $widget_content, ']', $position + $position_change ); // Insert [fusion_builder_row] shortcode. $widget_content = substr_replace( $widget_content, '][fusion_builder_row]', $section_close_position, 1 ); // Change in position. $position_change = $position_change + 20; } // Replace old [fullwidth shortcode with new [fusion_builder_section. $string_from_to = [ '[fullwidth' => '[fusion_builder_container', ]; $widget_content = strtr( $widget_content, $string_from_to ); // Handle columns. $needle = 'fusion_builder_column'; $last_pos = -1; $position_change = 0; $positions = []; $row_open = false; // Get all positions of opening and closing column tag. while ( ( $last_pos = strpos( $widget_content, $needle, $last_pos + 1 ) ) !== false ) { $positions[] = $last_pos; } // For each column, opening and closing tag. foreach ( $positions as $position ) { $position = $position + $position_change; // Check if opening or closing and if row is open yet. $tag_type = ( '[/' === substr( $widget_content, $position - 2, 2 ) ) ? 'closing' : 'opening'; $column_next = strpos( substr( $widget_content, $position + 20, 30 ), '[fusion_builder_column' ); $existing_row = strpos( substr( $widget_content, $position - 30, 30 ), '[fusion_builder_row]' ); $existing_row_closed = strpos( substr( $widget_content, $position + 20, 30 ), '[/fusion_builder_row]' ); if ( $existing_row ) { $row_open = true; } if ( 'opening' === $tag_type && ! $row_open ) { $row_open = true; $position_change = $position_change + 20; $widget_content = substr_replace( $widget_content, '[fusion_builder_row][fusion_builder_column', $position - 1, 22 ); } if ( 'closing' === $tag_type && $row_open && ! $column_next && ! $existing_row_closed ) { $row_open = false; $position_change = $position_change + 21; $widget_content = substr_replace( $widget_content, '[/fusion_builder_column][/fusion_builder_row]', $position - 2, 24 ); } } if ( isset( $widget_data[ $key ]['text'] ) ) { $widget_data[ $key ]['text'] = $widget_content; } update_option( $option_name, $widget_data ); } } } } } $this->next_step_redirection( true ); } /** * Validate shortcode attribute value. * * @static * @access private * @since 1.0 * @param string $value The value. * @param string $accepted_unit The accepted unit. * @return value */ private static function validate_shortcode_attr_value( $value, $accepted_unit ) { $validated_value = ''; if ( '' !== $value ) { $value = trim( $value ); $unit = preg_replace( '/[\d-]+/', '', $value ); $numerical_value = preg_replace( '/[a-z,%]/', '', $value ); if ( empty( $accepted_unit ) ) { $validated_value = $numerical_value; } else { if ( empty( $unit ) ) { // Add unit if it's required. $validated_value = $numerical_value . $accepted_unit; } else { // If unit was found use original value. BC support. $validated_value = $value; } } } return $validated_value; } /** * Convert content inside theme options. * * @since 5.0.0 * @return void */ private function convert_shortcode_names_in_theme_options() { $option_name = self::$avada_option_name; $options = get_option( $option_name, [] ); // Revert options? if ( self::$revert ) { $backed_up_options = get_option( $option_name . '_500_backup', [] ); if ( ! $backed_up_options && 'fusion_options' === $option_name ) { $backed_up_options = get_option( 'avada_theme_options_500_backup', false ); } if ( ! empty( $backed_up_options ) ) { update_option( $option_name, $backed_up_options ); } } else { // Backup options. update_option( $option_name . '_500_backup', $options ); // Now that we got the options, we need to loop through them // and convert shortcodes in them. foreach ( $options as $key => $value ) { // Only convert options that are strings, not empty, // and contain the '[' character. if ( is_string( $value ) && ! empty( $value ) && false !== strpos( $value, '[' ) ) { $options[ $key ] = $this->convert_shortcode_names( $value ); } } // Update the options. update_option( $option_name, $options ); } // Is this a multilingual site? // If it is, then we need to convert options on a per-language basis. $available_languages = Fusion_Multilingual::get_available_languages(); if ( ! empty( $available_languages ) ) { foreach ( $available_languages as $language ) { // The option name. $option_name = self::$avada_option_name . '_' . $language; // Get the options for that language. $options = get_option( $option_name, [] ); if ( self::$revert ) { $backed_up_options = get_option( $option_name . '_500_backup', [] ); if ( ! empty( $backed_up_options ) ) { update_option( $option_name, $backed_up_options ); } } else { // Backup options. update_option( $option_name . '_500_backup', $options ); // Now that we got the options, we need to loop through them // and convert shortcodes in them. foreach ( $options as $key => $value ) { // Only convert options that are strings, not empty, // and contain the '[' character. if ( is_string( $value ) && ! empty( $value ) && false !== strpos( $value, '[' ) ) { $options[ $key ] = $this->convert_shortcode_names( $value ); } } // Update the options. update_option( $option_name, $options ); } } } $this->next_step_redirection( true ); } /** * Convert container paddings. * * @since 5.0.0 * @param string $content The page contents. * @param string $id The page id. * @return string $content The page contents. */ private function convert_container_paddings( $content, $id ) { $needle = '[fusion_builder_container'; $last_pos = -1; $position_change = 0; $positions = []; // Get all positions of [fullwidth shortcode. while ( ( $last_pos = strpos( $content, $needle, $last_pos + 1 ) ) !== false ) { $positions[] = $last_pos; } foreach ( $positions as $position ) { // Fullwidth tag closing position. $section_close_position = strpos( $content, ']', $position + $position_change ); // Shortcode attributes. $attributes = substr( $content, $position + $position_change, $section_close_position - $position + $position_change ); foreach ( [ 'left', 'right' ] as $direction ) { if ( strpos( $attributes, 'padding' . $direction . '=' ) ) { $content = substr_replace( $content, 'padding_' . $direction . '=', $position + $position_change + strpos( $attributes, 'padding' . $direction . '=' ), strlen( 'padding' . $direction . '=' ) ); $position_change = $position_change++; } } // If not 100% internal, check for 0px padding and convert to empty. if ( ! strpos( $attributes, 'hundred_percent="yes"' ) ) { foreach ( [ 'left', 'right' ] as $direction ) { if ( strpos( $attributes, 'padding_' . $direction . '="0px"' ) ) { $content = substr_replace( $content, 'padding_' . $direction . '="" ', $position + $position_change + strpos( $attributes, 'padding_' . $direction . '="0px"' ), strlen( 'padding_' . $direction . '="0px"' ) ); } } } else { // If it is 100% internal, look for empty, replace with either PO/TO left and right padding. foreach ( [ 'left', 'right' ] as $direction ) { $padding_value = fusion_get_option( 'hundredp_padding' ); // If no padding left present, then we need to add it. if ( ! strpos( $attributes, 'padding_' . $direction . '="' ) ) { $content = substr_replace( $content, ' padding_' . $direction . '="' . $padding_value . '" ', $section_close_position, 0 ); $position_change = $position_change + strlen( 'padding_' . $direction . '=" ' . $padding_value . '" ' ); // If there is a padding left, but its empty, we need to add value. } elseif ( strpos( $attributes, 'padding_' . $direction . '=""' ) ) { $content = substr_replace( $content, 'padding_' . $direction . '="' . $padding_value . '"', $position + $position_change + strpos( $attributes, 'padding_' . $direction . '=""' ), strlen( 'padding_' . $direction . '=""' ) ); $position_change = $position_change + strlen( $padding_value ); } } } } return $content; } /** * Takes care of removing backup data. * * @access public * @since 5.0.0 * @param int $limit The number of posts to process. */ public static function cleanup_backups( $limit = 20 ) { // The step of the migration. // If on 0 then process options, // otherwise set it to the ID of the post we left off. $from = get_option( 'avada_migration_cleanup_id', 0 ); if ( 0 >= $from ) { // Check the backup options. $backup_options = [ 'avada_500_backup_page_templates_faqs', 'avada_500_backup_page_templates_portfolio', 'avada_500_backup_fusion_slider_data', 'avada_500_backup_revslider', 'avada_500_backup_layerslider', 'avada_500_backup_layerslider', 'avada_500_backup_widget_text', Avada::get_option_name() . '_500_backup', ]; // Delete backup options. foreach ( $backup_options as $option ) { delete_option( $option ); } update_option( 'avada_migration_cleanup_id', 1 ); } else { // The post types we'll need to check. $post_types = apply_filters( 'fusion_builder_shortcode_migration_post_types', [ 'page', 'post', 'avada_faq', 'avada_portfolio', 'product', 'tribe_events', ] ); foreach ( $post_types as $key => $post_type ) { if ( ! post_type_exists( $post_type ) ) { unset( $post_types[ $key ] ); } } // Build the query array. $args = [ 'posts_per_page' => $limit, 'offset' => $from, 'orderby' => 'ID', 'order' => 'ASC', 'post_type' => $post_types, 'post_status' => 'any', ]; // The query to get posts that meet our criteria. $posts = fusion_cached_get_posts( $args ); if ( $posts ) { // Remove backup data for those posts. foreach ( $posts as $post ) { delete_post_meta( $post->ID, 'fusion_builder_content_backup' ); } // Get the ID of the last post // and update the 'avada_migration_cleanup_id' option. $last_post = (array) end( $posts ); if ( isset( $last_post['ID'] ) ) { // Update the value so that the next step starts where we left off. update_option( 'avada_migration_cleanup_id', ( absint( $last_post['ID'] ) + 1 ) ); } else { // No post found, we're finished. delete_option( 'scheduled_avada_fusionbuilder_migration_cleanups' ); delete_option( 'avada_migration_cleanup_id' ); } } else { // No posts found, we're finished. delete_option( 'scheduled_avada_fusionbuilder_migration_cleanups' ); delete_option( 'avada_migration_cleanup_id' ); } } } /** * WPML Hack. * * @param int $pidd The post ID. * @param WP_Post $post The post object. */ public function save_post_actions( $pidd, $post ) { global $wpml_root_page_actions, $wpml_post_translations; if ( $wpml_root_page_actions ) { remove_action( 'save_post', [ $wpml_root_page_actions, 'wpml_home_url_save_post_actions' ], 0, 2 ); } if ( $wpml_post_translations ) { remove_action( 'save_post', [ $wpml_post_translations, 'save_post_actions' ], 100, 2 ); } } } /* Omit closing PHP tag to avoid "Headers already sent" issues. */