123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- <?php
- /**
- * WPSEO plugin file.
- *
- * @package WPSEO\Frontend\Schema
- */
- /**
- * Class WPSEO_Schema
- *
- * Outputs schema code specific for Google's JSON LD stuff.
- *
- * @since 1.8
- */
- class WPSEO_Schema implements WPSEO_WordPress_Integration {
- /**
- * Holds the parsed blocks for the current page.
- *
- * @var array
- */
- private $parsed_blocks = [];
- /**
- * Holds context variables about the current page and site.
- *
- * @var WPSEO_Schema_Context
- */
- private $context;
- /**
- * Registers the hooks.
- */
- public function register_hooks() {
- add_action( 'wpseo_head', [ $this, 'json_ld' ], 91 );
- add_action( 'wpseo_json_ld', [ $this, 'generate' ], 1 );
- // This AMP hook is only used in Reader (formerly Classic) mode.
- add_action( 'amp_post_template_head', [ $this, 'json_ld' ], 9 );
- }
- /**
- * JSON LD output function that the functions for specific code can hook into.
- *
- * @since 1.8
- */
- public function json_ld() {
- $deprecated_data = [
- '_deprecated' => 'Please use the "wpseo_schema_*" filters to extend the Yoast SEO schema data - see the WPSEO_Schema class.',
- ];
- /**
- * Filter: 'wpseo_json_ld_output' - Allows disabling Yoast's schema output entirely.
- *
- * @api mixed If false or an empty array is returned, disable our output.
- */
- $return = apply_filters( 'wpseo_json_ld_output', $deprecated_data, '' );
- if ( $return === [] || $return === false ) {
- return;
- }
- // Remove the AMP hook that also outputs Schema metadata on AMP pages.
- remove_action( 'amp_post_template_head', 'amp_print_schemaorg_metadata' );
- do_action( 'wpseo_json_ld' );
- }
- /**
- * Outputs the JSON LD code in a valid JSON+LD wrapper.
- *
- * @since 10.2
- *
- * @return void
- */
- public function generate() {
- $graph = [];
- $this->context = new WPSEO_Schema_Context();
- $pieces = $this->get_graph_pieces();
- // Parse the Gutenberg blocks so we know whether to show pieces for those.
- $this->parse_blocks();
- foreach ( $pieces as $piece ) {
- $class = str_replace( 'wpseo_schema_', '', strtolower( get_class( $piece ) ) );
- /**
- * Filter: 'wpseo_schema_needs_<class name>' - Allows changing which graph pieces we output.
- *
- * @api bool $is_needed Whether or not to show a graph piece.
- */
- $is_needed = apply_filters( 'wpseo_schema_needs_' . $class, $piece->is_needed() );
- if ( ! $is_needed ) {
- continue;
- }
- $graph_piece = $piece->generate();
- /**
- * Filter: 'wpseo_schema_<class name>' - Allows changing graph piece output.
- *
- * @api array $graph_piece The graph piece to filter.
- */
- $graph_piece = apply_filters( 'wpseo_schema_' . $class, $graph_piece );
- if ( is_array( $graph_piece ) ) {
- $graph[] = $graph_piece;
- }
- }
- foreach ( $this->parsed_blocks as $block_type => $blocks ) {
- foreach ( $blocks as $block ) {
- /**
- * Filter: 'wpseo_schema_block_<block-type>' - Allows filtering graph output per block.
- *
- * @param WP_Block_Parser_Block $block The block.
- * @param WPSEO_Schema_Context $context A value object with context variables.
- *
- * @api array $graph Our Schema output.
- */
- $block_type = strtolower( $block['blockName'] );
- $graph = apply_filters( 'wpseo_schema_block_' . $block_type, $graph, $block, $this->context );
- }
- }
- WPSEO_Utils::schema_output( $graph, 'yoast-schema-graph yoast-schema-graph--main' );
- }
- /**
- * Gets all the graph pieces we need.
- *
- * @return array A filtered array of graph pieces.
- */
- private function get_graph_pieces() {
- $pieces = [
- new WPSEO_Schema_Organization( $this->context ),
- new WPSEO_Schema_Person( $this->context ),
- new WPSEO_Schema_Website( $this->context ),
- new WPSEO_Schema_MainImage( $this->context ),
- new WPSEO_Schema_WebPage( $this->context ),
- new WPSEO_Schema_Breadcrumb( $this->context ),
- new WPSEO_Schema_Article( $this->context ),
- new WPSEO_Schema_Author( $this->context ),
- new WPSEO_Schema_FAQ( $this->context ),
- new WPSEO_Schema_HowTo( $this->context ),
- ];
- /**
- * Filter: 'wpseo_schema_graph_pieces' - Allows adding pieces to the graph.
- *
- * @param WPSEO_Schema_Context $context An object with context variables.
- *
- * @api array $pieces The schema pieces.
- */
- return apply_filters( 'wpseo_schema_graph_pieces', $pieces, $this->context );
- }
- /**
- * Parse the blocks and pass them on to our head.
- */
- private function parse_blocks() {
- if ( ! function_exists( 'parse_blocks' ) ) {
- return;
- }
- if ( ! is_singular() ) {
- return;
- }
- $this->get_parsed_blocks();
- foreach ( array_keys( $this->parsed_blocks ) as $block_type ) {
- /**
- * Filter: 'wpseo_pre_schema_block_type_<block-type>' - Allows hooking things to change graph output based on the blocks on the page.
- *
- * @param string $block_type The block type.
- * @param array $blocks All the blocks of this block type.
- * @param WPSEO_Schema_Context $context A value object with context variables.
- */
- do_action( 'wpseo_pre_schema_block_type_' . $block_type, $this->parsed_blocks[ $block_type ], $this->context );
- }
- }
- /**
- * Parse the blocks and loop through them.
- */
- private function get_parsed_blocks() {
- $post = get_post();
- $parsed_blocks = parse_blocks( $post->post_content );
- foreach ( $parsed_blocks as $block ) {
- if ( ! isset( $this->parsed_blocks[ $block['blockName'] ] ) || ! is_array( $this->parsed_blocks[ $block['blockName'] ] ) ) {
- $this->parsed_blocks[ $block['blockName'] ] = [];
- }
- $this->parsed_blocks[ $block['blockName'] ][] = $block;
- }
- }
- }
|