PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.9
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.9
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / generators / schema / howto.php

howto.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.9, at src/generators/schema/howto.php

179 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Generators\Schema;
4
5 /**
6 * Returns schema HowTo data.
7 */
8 class HowTo extends Abstract_Schema_Piece {
9
10 /**
11 * Determines whether or not a piece should be added to the graph.
12 *
13 * @return bool
14 */
15 public function is_needed() {
16 return ! empty( $this->context->blocks['yoast/how-to-block'] );
17 }
18
19 /**
20 * Renders a list of questions, referencing them by ID.
21 *
22 * @return array Our Schema graph.
23 */
24 public function generate() {
25 $graph = [];
26
27 foreach ( $this->context->blocks['yoast/how-to-block'] as $index => $block ) {
28 $this->add_how_to( $graph, $block, $index );
29 }
30
31 return $graph;
32 }
33
34 /**
35 * Adds the duration of the task to the Schema.
36 *
37 * @param array $data Our How-To schema data.
38 * @param array $attributes The block data attributes.
39 */
40 private function add_duration( &$data, $attributes ) {
41 if ( empty( $attributes['hasDuration'] ) ) {
42 return;
43 }
44
45 $days = empty( $attributes['days'] ) ? 0 : $attributes['days'];
46 $hours = empty( $attributes['hours'] ) ? 0 : $attributes['hours'];
47 $minutes = empty( $attributes['minutes'] ) ? 0 : $attributes['minutes'];
48
49 if ( ( $days + $hours + $minutes ) > 0 ) {
50 $data['totalTime'] = \esc_attr( 'P' . $days . 'DT' . $hours . 'H' . $minutes . 'M' );
51 }
52 }
53
54 /**
55 * Adds the steps to our How-To output.
56 *
57 * @param array $data Our How-To schema data.
58 * @param array $steps Our How-To block's steps.
59 */
60 private function add_steps( &$data, $steps ) {
61 foreach ( $steps as $step ) {
62 $schema_id = $this->context->canonical . '#' . \esc_attr( $step['id'] );
63 $schema_step = [
64 '@type' => 'HowToStep',
65 'url' => $schema_id,
66 ];
67
68 if ( isset( $step['jsonText'] ) ) {
69 $json_text = $this->helpers->schema->html->sanitize( $step['jsonText'] );
70 }
71
72 if ( isset( $step['jsonName'] ) ) {
73 $json_name = $this->helpers->schema->html->smart_strip_tags( $step['jsonName'] );
74 }
75
76 if ( empty( $json_name ) ) {
77 if ( empty( $step['text'] ) ) {
78 continue;
79 }
80
81 $schema_step['text'] = '';
82
83 $this->add_step_image( $schema_step, $step );
84
85 // If there is no text and no image, don't output the step.
86 if ( empty( $json_text ) && empty( $schema_step['image'] ) ) {
87 continue;
88 }
89
90 if ( ! empty( $json_text ) ) {
91 $schema_step['text'] = $json_text;
92 }
93 }
94
95 elseif ( empty( $json_text ) ) {
96 $schema_step['text'] = $json_name;
97 }
98 else {
99 $schema_step['name'] = $json_name;
100
101 $this->add_step_description( $schema_step, $json_text );
102 $this->add_step_image( $schema_step, $step );
103 }
104
105 $data['step'][] = $schema_step;
106 }
107 }
108
109 /**
110 * Checks if we have a step description, if we do, add it.
111 *
112 * @param array $schema_step Our Schema output for the Step.
113 * @param string $json_text The step text.
114 */
115 private function add_step_description( &$schema_step, $json_text ) {
116 $schema_step['itemListElement'] = [
117 [
118 '@type' => 'HowToDirection',
119 'text' => $json_text,
120 ],
121 ];
122 }
123
124 /**
125 * Checks if we have a step image, if we do, add it.
126 *
127 * @param array $schema_step Our Schema output for the Step.
128 * @param array $step The step block data.
129 */
130 private function add_step_image( &$schema_step, $step ) {
131 foreach ( $step['text'] as $line ) {
132 if ( \is_array( $line ) && isset( $line['type'] ) && $line['type'] === 'img' ) {
133 $schema_step['image'] = $this->get_image_schema( \esc_url( $line['props']['src'] ) );
134 }
135 }
136 }
137
138 /**
139 * Generates the HowTo schema for a block.
140 *
141 * @param array $graph Our Schema data.
142 * @param array $block The How-To block content.
143 * @param int $index The index of the current block.
144 */
145 protected function add_how_to( &$graph, $block, $index ) {
146 $data = [
147 '@type' => 'HowTo',
148 '@id' => $this->context->canonical . '#howto-' . ( $index + 1 ),
149 'name' => $this->helpers->schema->html->smart_strip_tags( $this->helpers->post->get_post_title_with_fallback( $this->context->id ) ),
150 'mainEntityOfPage' => [ '@id' => $this->context->main_schema_id ],
151 'description' => '',
152 ];
153
154 if ( isset( $block['attrs']['jsonDescription'] ) ) {
155 $data['description'] = $this->helpers->schema->html->sanitize( $block['attrs']['jsonDescription'] );
156 }
157
158 $this->add_duration( $data, $block['attrs'] );
159 $this->add_steps( $data, $block['attrs']['steps'] );
160
161 $data = $this->helpers->schema->language->add_piece_language( $data );
162
163 $graph[] = $data;
164 }
165
166 /**
167 * Generates the image schema from the attachment $url.
168 *
169 * @param string $url Attachment url.
170 *
171 * @return array Image schema.
172 */
173 protected function get_image_schema( $url ) {
174 $schema_id = $this->context->canonical . '#schema-image-' . \md5( $url );
175
176 return $this->helpers->schema->image->generate_from_url( $schema_id, $url );
177 }
178 }
179