2_P100-1998,swaplfnlibm-12712-s390ibm-16804_X110-1999,swaplfnlibm-16804-s390ebcdic-xml-usgsm-03.38-2000GSM0338ibm-1004_P100-1995ibm-1004ibm-1008_P100-1995ibm-1008ibm-1009_P100-1995ibm-1009ibm-1010_P100-1995ibm-1010NF_Z_62-010iso-ir-69ISO646-FRfrcsISO69Frenchibm-1011_P100-1995ibm-1011DIN_66003iso-ir-21deISO646-DEcsISO21Germanibm-1012_P100-1995ibm-1012ITiso-ir-15ISO646-ITcsISO15Italianibm-1013_P100-1995ibm-1013BS_4730iso-ir-4ISO646-GBgbukcsISO4UnitedKingdomibm-1014_P100-1995ibm-1014ES2iso-ir-85ISO646-ES2csISO85Spanish2ibm-1015_P100-1995ibm-1015PT2iso-ir-84ISO646-PT2csISO84Portuguese2ibm-1016_P100-1995ibm-1016NS_4551-1iso-ir-60ISO646-NOnocsISO60DanishNorwegiancsISO60Norwegian1ibm-1017_P100-1995ibm-1017ibm-1018_P100-1995ibm-1018SEN_850200_Biso-ir-10FIISO646-FIISO646-SEsecsISO10Swedishibm-1019_P100-1995ibm-1019ibm-1020_P100-2003ibm-1020CSA_Z243.4-1985-1iso-ir-121ISO646-CAcsa7-1cacsISO121Canadian1ibm-1021_P100-2003ibm-1021ibm-1023_P100-2003ibm-1023ESiso-ir-17ISO646-EScsISO17Spanishibm-1027_P100-1995ibm-1027x-IBM1027ibm-1041_P100-1995ibm-1041x-IBM1041ibm-1043_P100-1995ibm-1043x-IBM1043ibm-1046_X110-1999ibm-1046x-IBM1046x-IBM1046Sibm-1088_P100-1995ibm-1088x-IBM1088ibm-1100_P100-2003ibm-1100DEC-MCSdeccsDECMCSibm-1101_P100-2003ibm-1101ibm-1102_P100-2003ibm-1102ibm-1103_P100-2003ibm-1103ibm-1104_P100-2003ibm-1104NF_Z_62-010_1973iso-ir-25ISO646-FR1csISO25Frenchibm-1105_P100-2003ibm-1105ibm-1106_P100-2003ibm-1106ibm-1107_P100-2003ibm-1107DS_2089ISO646-DKdkcsISO646Danishibm-1127_P100-2004ibm-1127ibm-1161_P100-1999ibm-1161ibm-1163_P100-1999ibm-1163ibm-1165_P101-2000ibm-1165ibm-1166_P100-2002ibm-1166ibm-1167_P100-2002ibm-1167KOI8-RUx-KOI8_RUibm-1174_X100-2007ibm-1174KZ-1048STRK1048-2002RK1048csKZ1048ibm-1277_P100-1995ibm-1277ibm-13125_P100-1997ibm-13125ibm-13140_P101-2000ibm-13140ibm-13218_P100-1996ibm-13218ibm-1350_P110-1997ibm-1350x-eucJP-OpeneucJP-Openibm-1351_P110-1997ibm-1351x-IBM1351ibm-1362_P110-1999ibm-1362x-IBM1362ibm-13676_P102-2001ibm-13676ibm-1380_P100-1995ibm-1380x-IBM1380ibm-1381_P110-1999ibm-1381cp13811381x-IBM1381ibm-1382_P100-1995ibm-1382x-IBM1382ibm-17221_P100-2001ibm-17221ibm-17248_X110-1999ibm-17248ibm-21344_P101-2000ibm-21344ibm-21427_P100-1999ibm-21427ibm-256_P100-1995ibm-256ibm-259_P100-1995ibm-259IBM-SymbolscsIBMSymbolsibm-274_P100-2000ibm-274IBM274EBCDIC-BECP274csIBM274ibm-275_P100-1995ibm-275IBM275EBCDIC-BRcp275csIBM275ibm-286_P100-2003ibm-286EBCDIC-AT-DE-AcsEBCDICATDEAibm-293_P100-1995ibm-293ibm-300_P120-2006ibm-300x-IBM300ibm-301_P110-1997ibm-301x-IBM301ibm-33058_P100-2000ibm-33058ibm-425_P101-2000ibm-425ibm-4930_P110-1999ibm-4930ibm-4933_P100-2002ibm-4933ibm-4948_P100-1995ibm-4948ibm-4951_P100-1995ibm-4951ibm-4952_P100-1995ibm-4952ibm-4960_P100-1995ibm-4960ibm-5039_P11A-1998ibm-5039ibm-5048_P100-1995ibm-5048ibm-5049_P100-1995ibm-5049ibm-5067_P100-1995ibm-5067ibm-5104_X110-1999ibm-5104ibm-5233_P100-2011ibm-5233ibm-806_P100-1998ibm-806ibm-808_P100-1999ibm-808x-IBM808ibm-833_P100-1995ibm-833x-IBM833ibm-834_P100-1995ibm-834x-IBM834ibm-835_P100-1995ibm-835x-IBM835ibm-836_P100-1995ibm-836x-IBM836ibm-837_P100-2011ibm-837x-IBM837ibm-848_P100-1999ibm-848ibm-849_P100-1999ibm-849ibm-859_P100-1999ibm-859x-IBM859ibm-8612_P100-1995ibm-8612ibm-872_P100-1999ibm-872ibm-880_P100-1995ibm-880IBM880cp880EBCDIC-CyrilliccsIBM880windows-20880ibm-896_P100-1995ibm-896ibm-897_P100-1995ibm-897JIS_X0201X0201csHalfWidthKatakanax-IBM897ibm-9027_P100-1999ibm-9027ibm-9048_P100-1998ibm-9048ibm-905_P100-1995ibm-905IBM905CP905ebcdic-cp-trcsIBM905windows-20905ibm-9056_P100-1995ibm-9056ibm-9061_P100-1999ibm-9061ibm-9145_P110-1997ibm-9145ibm-9238_X110-1999ibm-elementor = true ) { Plugin::$instance->modules_manager ->get_modules( 'dev-tools' ) ->deprecation ->deprecated_function( __METHOD__, '3.1.0', 'Plugin::$instance->documents->get( $post_id )->set_is_build_with_elementor( $is_elementor )' ); $document = Plugin::$instance->documents->get( $post_id ); if ( ! $document ) { return; } $document->set_is_built_with_elementor( $is_elementor ); } /** * Render element plain content. * * When saving data in the editor, this method renders recursively the plain * content containing only the content and the HTML. No CSS data. * * @since 2.0.0 * @access private * * @param array $element_data Element data. */ private function render_element_plain_content( $element_data ) { if ( 'widget' === $element_data['elType'] ) { /** @var Widget_Base $widget */ $widget = Plugin::$instance->elements_manager->create_element_instance( $element_data ); if ( $widget ) { $widget->render_plain_content(); } } if ( ! empty( $element_data['elements'] ) ) { foreach ( $element_data['elements'] as $element ) { $this->render_element_plain_content( $element ); } } } /** * Save plain text. * * Retrieves the raw content, removes all kind of unwanted HTML tags and saves * the content as the `post_content` field in the database. * * @since 1.9.0 * @access public * * @param int $post_id Post ID. */ public function save_plain_text( $post_id ) { // Switch $dynamic_tags to parsing mode = remove. $dynamic_tags = Plugin::$instance->dynamic_tags; $parsing_mode = $dynamic_tags->get_parsing_mode(); $dynamic_tags->set_parsing_mode( Manager::MODE_REMOVE ); $plain_text = $this->get_plain_text( $post_id ); wp_update_post( [ 'ID' => $post_id, 'post_content' => $plain_text, ] ); // Restore parsing mode. $dynamic_tags->set_parsing_mode( $parsing_mode ); } /** * Iterate data. * * Accept any type of Elementor data and a callback function. The callback * function runs recursively for each element and his child elements. * * @since 1.0.0 * @access public * * @param array $data_container Any type of elementor data. * @param callable $callback A function to iterate data by. * @param array $args Array of args pointers for passing parameters in & out of the callback * * @return mixed Iterated data. */ public function iterate_data( $data_container, $callback, $args = [] ) { if ( isset( $data_container['elType'] ) ) { if ( ! empty( $data_container['elements'] ) ) { $data_container['elements'] = $this->iterate_data( $data_container['elements'], $callback, $args ); } return call_user_func( $callback, $data_container, $args ); } foreach ( $data_container as $element_key => $element_value ) { $element_data = $this->iterate_data( $data_container[ $element_key ], $callback, $args ); if ( null === $element_data ) { continue; } $data_container[ $element_key ] = $element_data; } return $data_container; } /** * Safely copy Elementor meta. * * Make sure the original page was built with Elementor and the post is not * auto-save. Only then copy elementor meta from one post to another using * `copy_elementor_meta()`. * * @since 1.9.2 * @access public * * @param int $from_post_id Original post ID. * @param int $to_post_id Target post ID. */ public function safe_copy_elementor_meta( $from_post_id, $to_post_id ) { // It's from WP-Admin & not from Elementor. if ( ! did_action( 'elementor/db/before_save' ) ) { $from_document = Plugin::$instance->documents->get( $from_post_id ); if ( ! $from_document || ! $from_document->is_built_with_elementor() ) { return; } // It's an exited Elementor auto-save if ( get_post_meta( $to_post_id, '_elementor_data', true ) ) { return; } } $this->copy_elementor_meta( $from_post_id, $to_post_id ); } /** * Copy Elementor meta. * * Duplicate the data from one post to another. * * Consider using `safe_copy_elementor_meta()` method instead. * * @since 1.1.0 * @access public * * @param int $from_post_id Original post ID. * @param int $to_post_id Target post ID. */ public function copy_elementor_meta( $from_post_id, $to_post_id ) { $from_post_meta = get_post_meta( $from_post_id ); $core_meta = [ '_wp_page_template', '_thumbnail_id', ]; foreach ( $from_post_meta as $meta_key => $values ) { // Copy only meta with the `_elementor` prefix if ( 0 === strpos( $meta_key, '_elementor' ) || in_array( $meta_key, $core_meta, true ) ) { $value = $values[0]; // The elementor JSON needs slashes before saving if ( '_elementor_data' === $meta_key ) { $value = wp_slash( $value ); } else { $value = maybe_unserialize( $value ); } // Don't use `update_post_meta` that can't handle `revision` post type update_metadata( 'post', $to_post_id, $meta_key, $value ); } } } /** * Is built with Elementor. * * Check whether the post was built with Elementor. * * @since 1.0.10 * @deprecated 3.2.0 Use `Plugin::$instance->documents->get( $post_id )->is_built_with_elementor()` instead. * @access public * * @param int $post_id Post ID. * * @return bool Whether the post was built with Elementor. */ public function is_built_with_elementor( $post_id ) { Plugin::$instance->modules_manager ->get_modules( 'dev-tools' ) ->deprecation ->deprecated_function( __METHOD__, '3.2.0', 'Plugin::$instance->documents->get( $post_id )->is_built_with_elementor()' ); $document = Plugin::$instance->documents->get( $post_id ); if ( ! $document ) { return false; } return $document->is_built_with_elementor(); } /** * Switch to post. * * Change the global WordPress post to the requested post. * * @since 1.5.0 * @access public * * @param int $post_id Post ID to switch to. */ public function switch_to_post( $post_id ) { $post_id = absint( $post_id ); // If is already switched, or is the same post, return. if ( get_the_ID() === $post_id ) { $this->switched_post_data[] = false; return; } $this->switched_post_data[] = [ 'switched_id' => $post_id, 'original_id' => get_the_ID(), // Note, it can be false if the global isn't set ]; $GLOBALS['post'] = get_post( $post_id ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited setup_postdata( $GLOBALS['post'] ); } /** * Restore current post. * * Rollback to the previous global post, rolling back from `DB::switch_to_post()`. * * @since 1.5.0 * @access public */ public function restore_current_post() { $data = array_pop( $this->switched_post_data ); // If not switched, return. if ( ! $data ) { return; } // It was switched from an empty global post, restore this state and unset the global post if ( false === $data['original_id'] ) { unset( $GLOBALS['post'] ); return; } $GLOBALS['post'] = get_post( $data['original_id'] ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited setup_postdata( $GLOBALS['post'] ); } /** * Switch to query. * * Change the WordPress query to a new query with the requested * query variables. * * @since 2.0.0 * @access public * * @param array $query_vars New query variables. * @param bool $force_global_post */ public function switch_to_query( $query_vars, $force_global_post = false ) { global $wp_query; $current_query_vars = $wp_query->query; // If is already switched, or is the same query, return. if ( $current_query_vars === $query_vars ) { $this->switched_data[] = false; return; } $new_query = new \WP_Query( $query_vars ); $switched_data = [ 'switched' => $new_query, 'original' => $wp_query, ]; if ( ! empty( $GLOBALS['post'] ) ) { $switched_data['post'] = $GLOBALS['post']; } $this->switched_data[] = $switched_data; $wp_query = $new_query; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited // Ensure the global post is set only if needed unset( $GLOBALS['post'] ); if ( isset( $new_query->posts[0] ) ) { if ( $force_global_post || $new_query->is_singular() ) { $GLOBALS['post'] = $new_query->posts[0]; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited setup_postdata( $GLOBALS['post'] ); } } if ( $new_query->is_author() ) { $GLOBALS['authordata'] = get_userdata( $new_query->get( 'author' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } } /** * Restore current query. * * Rollback to the previous query, rolling back from `DB::switch_to_query()`. * * @since 2.0.0 * @access public */ public function restore_current_query() { $data = array_pop( $this->switched_data ); // If not switched, return. if ( ! $data ) { return; } global $wp_query; $wp_query = $data['original']; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited // Ensure the global post/authordata is set only if needed. unset( $GLOBALS['post'] ); unset( $GLOBALS['authordata'] ); if ( ! empty( $data['post'] ) ) { $GLOBALS['post'] = $data['post']; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited setup_postdata( $GLOBALS['post'] ); } if ( $wp_query->is_author() ) { $GLOBALS['authordata'] = get_userdata( $wp_query->get( 'author' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } } /** * Get plain text. * * Retrieve the post plain text. * * @since 1.9.0 * @access public * * @param int $post_id Post ID. * * @return string Post plain text. */ public function get_plain_text( $post_id ) { $document = Plugin::$instance->documents->get( $post_id ); $data = $document ? $document->get_elements_data() : []; return $this->get_plain_text_from_data( $data ); } /** * Get plain text from data. * * Retrieve the post plain text from any given Elementor data. * * @since 1.9.2 * @access public * * @param array $data Post ID. * * @return string Post plain text. */ public function get_plain_text_from_data( $data ) { ob_start(); if ( $data ) { foreach ( $data as $element_data ) { $this->render_element_plain_content( $element_data ); } } $plain_text = ob_get_clean(); // Remove unnecessary tags. $plain_text = preg_replace( '/<\/?div[^>]*\>/i', '', $plain_text ); $plain_text = preg_replace( '/<\/?span[^>]*\>/i', '', $plain_text ); $plain_text = preg_replace( '#(.*?)#is', '', $plain_text ); $plain_text = preg_replace( '/]*><\\/i[^>]*>/', '', $plain_text ); $plain_text = preg_replace( '/ class=".*?"/', '', $plain_text ); // Remove empty lines. $plain_text = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $plain_text ); $plain_text = trim( $plain_text ); return $plain_text; } }