PluginProbe
WP EXtra – One Click Optimize / trunk
WP EXtra – One Click Optimize vtrunk
8.7.1 8.6.8 8.7.0 trunk 5.9 8.0 8.5.0 8.5.4 8.5.5 8.6.0 8.6.1 8.6.2 8.6.3 8.6.5
wp-extra / src / Modules / Common / TOC / Schema.php

Schema.php in WP EXtra – One Click Optimize trunk, at src/Modules/Common/TOC/Schema.php

128 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * TOC Schema Module
4 *
5 * Generates JSON-LD SiteNavigationElement structured data and integrates with Yoast SEO schema graph.
6 *
7 * @package WPEXtra\Modules\Common\TOC
8 */
9
10 namespace WPEXtra\Modules\Common\TOC;
11
12 use WPEXtra\Helper;
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 class Schema {
19
20 /**
21 * Extracted heading nodes for current page request.
22 *
23 * @var array
24 */
25 private static $current_headings = array();
26
27 /**
28 * Initialize schema hooks.
29 */
30 public static function init() {
31 add_action( 'wp_footer', array( __CLASS__, 'output_json_ld' ), 20 );
32 add_filter( 'wpseo_schema_graph', array( __CLASS__, 'integrate_yoast_schema' ), 10, 2 );
33 }
34
35 /**
36 * Store current headings for schema generation.
37 *
38 * @param array $headings
39 */
40 public static function set_headings( array $headings ) {
41 self::$current_headings = $headings;
42 }
43
44 /**
45 * Flatten hierarchical tree into 1D list for schema items.
46 *
47 * @param array $tree
48 * @return array
49 */
50 private static function flatten_tree( array $tree ) {
51 $flat = array();
52 foreach ( $tree as $item ) {
53 $flat[] = array(
54 'id' => $item['id'],
55 'title' => $item['title'],
56 );
57 if ( ! empty( $item['children'] ) ) {
58 $flat = array_merge( $flat, self::flatten_tree( $item['children'] ) );
59 }
60 }
61 return $flat;
62 }
63
64 /**
65 * Output JSON-LD SiteNavigationElement in wp_footer if Yoast is not active.
66 */
67 public static function output_json_ld() {
68 if ( empty( self::$current_headings ) || defined( 'WPSEO_VERSION' ) ) {
69 return;
70 }
71
72 $permalink = get_permalink();
73 if ( ! $permalink ) {
74 return;
75 }
76
77 $items = self::flatten_tree( self::$current_headings );
78 $elements = array();
79
80 foreach ( $items as $index => $item ) {
81 $elements[] = array(
82 '@context' => 'https://schema.org',
83 '@type' => 'SiteNavigationElement',
84 'id' => $permalink . '#' . $item['id'],
85 'name' => $item['title'],
86 'url' => $permalink . '#' . $item['id'],
87 );
88 }
89
90 if ( ! empty( $elements ) ) {
91 echo "\n<!-- WP Extra Table of Contents Schema -->\n";
92 echo '<script type="application/ld+json">' . wp_json_encode( $elements, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "</script>\n";
93 }
94 }
95
96 /**
97 * Integrate TOC items with Yoast SEO schema graph.
98 *
99 * @param array $graph
100 * @param object $context
101 * @return array
102 */
103 public static function integrate_yoast_schema( $graph, $context ) {
104 if ( empty( self::$current_headings ) ) {
105 return $graph;
106 }
107
108 $permalink = get_permalink();
109 if ( ! $permalink ) {
110 return $graph;
111 }
112
113 $items = self::flatten_tree( self::$current_headings );
114
115 foreach ( $items as $item ) {
116 $graph[] = array(
117 '@context' => 'https://schema.org',
118 '@type' => 'SiteNavigationElement',
119 '@id' => $permalink . '#' . $item['id'],
120 'name' => $item['title'],
121 'url' => $permalink . '#' . $item['id'],
122 );
123 }
124
125 return $graph;
126 }
127 }
128