PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / 22.7.0
WPSSO Core – Complete Schema Markup and Meta Tags v22.7.0
22.7.0 22.6.1 22.6.0 22.5.3 22.5.2 22.5.1 22.4.0 22.3.0 22.2.1 22.2.0 22.1.3 22.1.2 22.1.1 22.1.0 22.0.0 21.13.3 21.13.2 trunk 21.13.1
wpsso / lib / schema-graph.php

schema-graph.php in WPSSO Core – Complete Schema Markup and Meta Tags 22.7.0, at lib/schema-graph.php

227 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * License: GPLv3
4 * License URI: https://www.gnu.org/licenses/gpl.txt
5 * Copyright 2012-2026 Jean-Sebastien Morisset (https://wpsso.com/)
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9
10 die( 'These aren\'t the droids you\'re looking for.' );
11 }
12
13 if ( ! defined( 'WPSSO_PLUGINDIR' ) ) {
14
15 die( 'Do. Or do not. There is no try.' );
16 }
17
18 if ( ! class_exists( 'WpssoSchemaGraph' ) ) {
19
20 class WpssoSchemaGraph {
21
22 private static $graph_context = 'https://schema.org';
23 private static $graph_type = 'graph';
24 private static $graph_data = array();
25
26 public function __construct() {}
27
28 public static function get_type_url() {
29
30 return self::$graph_context . '/' . self::$graph_type;
31 }
32
33 public static function add_data( $data ) {
34
35 static $home_url = null;
36
37 if ( null === $home_url ) { // Optimize and call just once.
38
39 $home_url = untrailingslashit( get_home_url() );
40 }
41
42 if ( empty( $data[ '@id' ] ) ) {
43
44 self::$graph_data[] = $data;
45
46 return true;
47
48 } else {
49
50 $val =& $data[ '@id' ];
51
52 if ( 0 === strpos( $val, $home_url ) ) {
53
54 $val = str_replace( $home_url, '', $val ); // Shorten the @id value, if possible.
55 }
56
57 if ( ! isset( self::$graph_data[ $val ] ) ) { // If not already added.
58
59 if ( count( $data ) > 1 ) { // Ignore arrays with only an @id.
60
61 self::$graph_data[ $val ] = $data;
62
63 return true;
64 }
65 }
66 }
67
68 return false;
69 }
70
71 public static function get_json_reset_data() {
72
73 $json_data = self::get_json();
74
75 self::reset_data();
76
77 return $json_data;
78 }
79
80 public static function get_json() {
81
82 $json_data = array(
83 '@context' => self::$graph_context,
84 '@graph' => array_values( self::$graph_data ), // Exclude the associative array key values.
85 );
86
87 self::clean_json( $json_data );
88
89 return $json_data;
90 }
91
92 public static function reset_data() {
93
94 self::$graph_data = array();
95 }
96
97 /*
98 * Recursively remove null values, empty strings, and empty arrays.
99 */
100 public static function clean_json( array &$arr ) {
101
102 foreach ( $arr as $key => $value ) {
103
104 if ( null === $value ) { // Null value.
105
106 unset( $arr[ $key ] );
107
108 } elseif ( '' === $value ) { // Empty string.
109
110 unset( $arr[ $key ] );
111
112 } elseif ( array() === $value ) { // Empty array.
113
114 unset( $arr[ $key ] );
115
116 } elseif ( is_array( $value ) ) {
117
118 self::clean_json( $arr[ $key ] );
119 }
120 }
121 }
122
123 public static function optimize_json( array &$json_data ) { // Pass by reference is OK.
124
125 static $optim_data = array();
126 static $recur_level = null;
127 static $id_anchor = null;
128 static $home_url = null;
129
130 if ( isset( $json_data[ '@graph' ] ) ) { // Top level of json.
131
132 $recur_level = 0;
133
134 } elseif ( null !== $recur_level ) {
135
136 $recur_level++;
137 }
138
139 if ( $recur_level > 32 ) { // Just in case.
140
141 return;
142 }
143
144 if ( null === $id_anchor ) { // Optimize and call just once.
145
146 $id_anchor = WpssoSchema::get_id_anchor();
147 }
148
149 if ( null === $home_url ) { // Optimize and call just once.
150
151 $home_url = untrailingslashit( get_home_url() );
152 }
153
154 foreach ( $json_data as $key => &$val ) {
155
156 if ( is_array( $val ) ) {
157
158 self::optimize_json( $val );
159
160 } elseif ( '@id' === $key ) {
161
162 if ( 0 === strpos( $val, $home_url ) ) {
163
164 $val = str_replace( $home_url, '', $val ); // Shorten the @id value, if possible.
165 }
166
167 if ( count( $json_data ) > 1 ) { // Ignore arrays with a single element (ie. the @id property).
168
169 if ( false !== strpos( $val, $id_anchor ) ) { // Only optimize our own @ids.
170
171 if ( empty( $optim_data[ $val ] ) ) {
172
173 $optim_data[ $val ] = $json_data;
174
175 foreach ( $optim_data[ $val ] as $new_key => &$new_val ) {
176
177 if ( is_array( $new_val ) ) {
178
179 self::optimize_json( $new_val );
180 }
181 }
182 }
183
184 $json_data = array( $key => $val );
185 }
186 }
187
188 break;
189 }
190 }
191
192 if ( isset( $json_data[ '@graph' ] ) ) { // Top level of json.
193
194 $merged_graph = array_merge( array_values( $optim_data ), $json_data[ '@graph' ] );
195
196 /*
197 * Reset the static variables after merging the new data.
198 */
199 $optim_data = array();
200 $recur_level = null;
201
202 /*
203 * Cleanup any empty @id arrays.
204 */
205 foreach ( $merged_graph as $num => $val ) {
206
207 if ( is_array( $val ) ) { // Just in case.
208
209 if ( ! empty( $val[ '@id' ] ) && 1 === count( $val ) ) {
210
211 unset( $merged_graph[ $num ] );
212 }
213 }
214 }
215
216 $json_data[ '@graph' ] = $merged_graph;
217
218 unset( $merged_graph, $num, $val );
219
220 } elseif ( null !== $recur_level ) {
221
222 $recur_level--;
223 }
224 }
225 }
226 }
227