given data as JSON. * We temporarily change the floating point precision in order to prevent rounding errors. * Otherwise e.g. 4.9 could be output as 4.90000004. * * @since 4.2.7 * * @param mixed $data The data. * @param int $flags The flags. * @return string The JSON output. */ public function wpJsonEncode( $data, $flags = 0 ) { $originalPrecision = false; $originalSerializePrecision = false; if ( version_compare( PHP_VERSION, '7.1', '>=' ) ) { $originalPrecision = ini_get( 'precision' ); $originalSerializePrecision = ini_get( 'serialize_precision' ); ini_set( 'precision', 17 ); ini_set( 'serialize_precision', -1 ); } $json = wp_json_encode( $data, $flags ); if ( version_compare( PHP_VERSION, '7.1', '>=' ) ) { ini_set( 'precision', $originalPrecision ); ini_set( 'serialize_precision', $originalSerializePrecision ); } return $json; } /** * Returns the post title or a placeholder if there isn't one. * * @since 4.3.0 * * @param int $postId The post ID. * @return string The post title. */ public function getPostTitle( $postId ) { static $titles = []; if ( isset( $titles[ $postId ] ) ) { return $titles[ $postId ]; } $post = aioseo()->helpers->getPost( $postId ); if ( ! is_a( $post, 'WP_Post' ) ) { $titles[ $postId ] = __( '(no title)' ); // phpcs:ignore AIOSEO.Wp.I18n.MissingArgDomain return $titles[ $postId ]; } $title = $post->post_title; $title = $title ? $title : __( '(no title)' ); // phpcs:ignore AIOSEO.Wp.I18n.MissingArgDomain $titles[ $postId ] = aioseo()->helpers->decodeHtmlEntities( $title ); return $titles[ $postId ]; } /** * Checks whether the post status should be considered viewable. * This function is a copy of the WordPress core function is_post_status_viewable() which was introduced in WP 5.7. * * @since 4.5.0 * * @param string|\stdClass $postStatus The post status name or object. * @return bool Whether the post status is viewable. */ public function isPostStatusViewable( $postStatus ) { if ( is_scalar( $postStatus ) ) { $postStatus = get_post_status_object( $postStatus ); if ( ! $postStatus ) { return false; } } if ( ! is_object( $postStatus ) || $postStatus->internal || $postStatus->protected ) { return false; } return $postStatus->publicly_queryable || ( $postStatus->_builtin && $postStatus->public ); } /** * Checks whether the given post is publicly viewable. * This function is a copy of the WordPress core function is_post_publicly_viewable() which was introduced in WP 5.7. * * @since 4.5.0 * * @param int|\WP_Post $post Optional. Post ID or post object. Defaults to global $post. * @return boolean Whether the post is publicly viewable or not. */ public function isPostPubliclyViewable( $post = null ) { $post = get_post( $post ); if ( empty( $post ) ) { return false; } $postType = get_post_type( $post ); $postStatus = get_post_status( $post ); return is_post_type_viewable( $postType ) && $this->isPostStatusViewable( $postStatus ); } /** * Only register a legacy widget if the WP version is lower than 5.8 or the widget is being used. * The "Block-based Widgets Editor" was released in WP 5.8, so for WP versions below 5.8 it's okay to register them. * The main purpose here is to avoid blocks and widgets with the same name to be displayed on the Customizer, * like e.g. the "Breadcrumbs" Block and Widget. * * @since 4.3.9 * * @param string $idBase The base ID of a widget created by extending WP_Widget. * @return bool Whether the legacy widget can be registered. */ public function canRegisterLegacyWidget( $idBase ) { global $wp_version; // phpcs:ignore Squiz.NamingConventions.ValidVariableName if ( version_compare( $wp_version, '5.8', '<' ) || // phpcs:ignore Squiz.NamingConventions.ValidVariableName is_active_widget( false, false, $idBase ) || aioseo()->standalone->pageBuilderIntegrations['elementor']->isPluginActive() ) { return true; } return false; } /** * Parses blocks for a given post. * * @since 4.6.8 * * @param \WP_Post|int $post The post or post ID. * @param bool $flattenBlocks Whether to flatten the blocks. * @return array The parsed blocks. */ public function parseBlocks( $post, $flattenBlocks = true ) { if ( ! is_a( $post, 'WP_Post' ) ) { $post = aioseo()->helpers->getPost( $post ); } static $parsedBlocks = []; if ( isset( $parsedBlocks[ $post->ID ] ) ) { return $parsedBlocks[ $post->ID ]; } $parsedBlocks = parse_blocks( $post->post_content ); if ( $flattenBlocks ) { $parsedBlocks = $this->flattenBlocks( $parsedBlocks ); } $parsedBlocks[ $post->ID ] = $parsedBlocks; return $parsedBlocks[ $post->ID ]; } /** * Flattens the given blocks. * * @since 4.6.8 * * @param array $blocks The blocks. * @return array The flattened blocks. */ public function flattenBlocks( $blocks ) { $flattenedBlocks = []; foreach ( $blocks as $block ) { if ( ! empty( $block['innerBlocks'] ) ) { // Flatten inner blocks first. $innerBlocks = $this->flattenBlocks( $block['innerBlocks'] ); unset( $block['innerBlocks'] ); // Add the current block to the result. $flattenedBlocks[] = $block; // Add the flattened inner blocks to the result. $flattenedBlocks = array_merge( $flattenedBlocks, $innerBlocks ); } else { // If no inner blocks, just add the block to the result. $flattenedBlocks[] = $block; } } return $flattenedBlocks; } /** * Checks if the Classic eEditor is active and if the Block Editor is disabled in its settings. * * @since 4.7.3 * * @return bool Whether the Classic Editor is active. */ public function isClassicEditorActive() { include_once ABSPATH . 'wp-admin/includes/plugin.php'; if ( ! is_plugin_active( 'classic-editor/classic-editor.php' ) ) { return false; } return 'classic' === get_option( 'classic-editor-replace' ); } }