| @@ -1,8 +1,10 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Yoast\WP\SEO\Generators\Schema; |
| 4 | 4 | |
| 5 | +use Yoast\WP\SEO\Config\Schema_IDs; | |
| 6 | + | |
| 5 | 7 | /** |
| 6 | 8 | * Returns schema HowTo data. |
| 7 | 9 | */ |
| 8 | 10 | class HowTo extends Abstract_Schema_Piece { |
| @@ -35,8 +37,10 @@ | ||
| 35 | 37 | * Adds the duration of the task to the Schema. |
| 36 | 38 | * |
| 37 | 39 | * @param array $data Our How-To schema data. |
| 38 | 40 | * @param array $attributes The block data attributes. |
| 41 | + * | |
| 42 | + * @return void | |
| 39 | 43 | */ |
| 40 | 44 | private function add_duration( &$data, $attributes ) { |
| 41 | 45 | if ( empty( $attributes['hasDuration'] ) ) { |
| 42 | 46 | return; |
| @@ -55,8 +59,10 @@ | ||
| 55 | 59 | * Adds the steps to our How-To output. |
| 56 | 60 | * |
| 57 | 61 | * @param array $data Our How-To schema data. |
| 58 | 62 | * @param array $steps Our How-To block's steps. |
| 63 | + * | |
| 64 | + * @return void | |
| 59 | 65 | */ |
| 60 | 66 | private function add_steps( &$data, $steps ) { |
| 61 | 67 | foreach ( $steps as $step ) { |
| 62 | 68 | $schema_id = $this->context->canonical . '#' . \esc_attr( $step['id'] ); |
| @@ -110,10 +116,21 @@ | ||
| 110 | 116 | * Checks if we have a step description, if we do, add it. |
| 111 | 117 | * |
| 112 | 118 | * @param array $schema_step Our Schema output for the Step. |
| 113 | 119 | * @param string $json_text The step text. |
| 120 | + * | |
| 121 | + * @return void | |
| 114 | 122 | */ |
| 115 | 123 | private function add_step_description( &$schema_step, $json_text ) { |
| 124 | + // Decode HTML entities. | |
| 125 | + $json_text = \html_entity_decode( $json_text ); | |
| 126 | + // Remove the image from the text if it exists. Search and replace the img tag. | |
| 127 | + $json_text = \preg_replace( '/<img[^>]+>/i', '', $json_text ); | |
| 128 | + // Strip all HTML tags to ensure plain text for the JSON-LD output. | |
| 129 | + $json_text = \wp_strip_all_tags( $json_text ); | |
| 130 | + // Trim whitespace. | |
| 131 | + $json_text = \trim( $json_text ); | |
| 132 | + | |
| 116 | 133 | $schema_step['itemListElement'] = [ |
| 117 | 134 | [ |
| 118 | 135 | '@type' => 'HowToDirection', |
| 119 | 136 | 'text' => $json_text, |
| @@ -125,15 +142,27 @@ | ||
| 125 | 142 | * Checks if we have a step image, if we do, add it. |
| 126 | 143 | * |
| 127 | 144 | * @param array $schema_step Our Schema output for the Step. |
| 128 | 145 | * @param array $step The step block data. |
| 146 | + * | |
| 147 | + * @return void | |
| 129 | 148 | */ |
| 130 | 149 | 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'] ) ); | |
| 150 | + if ( isset( $step['images'] ) && \is_array( $step['images'] ) ) { | |
| 151 | + foreach ( $step['images'] as $image ) { | |
| 152 | + if ( isset( $image['type'] ) && $image['type'] === 'img' ) { | |
| 153 | + $schema_step['image'] = $this->get_image_schema( \esc_url( $image['props']['src'] ) ); | |
| 154 | + } | |
| 134 | 155 | } |
| 135 | 156 | } |
| 157 | + elseif ( isset( $step['text'] ) && \is_array( $step['text'] ) ) { | |
| 158 | + // Backwards compatibility for older How-To blocks. | |
| 159 | + foreach ( $step['text'] as $line ) { | |
| 160 | + if ( \is_array( $line ) && isset( $line['type'] ) && $line['type'] === 'img' ) { | |
| 161 | + $schema_step['image'] = $this->get_image_schema( \esc_url( $line['props']['src'] ) ); | |
| 162 | + } | |
| 163 | + } | |
| 164 | + } | |
| 136 | 165 | } |
| 137 | 166 | |
| 138 | 167 | /** |
| 139 | 168 | * Generates the HowTo schema for a block. |
| @@ -140,8 +169,10 @@ | ||
| 140 | 169 | * |
| 141 | 170 | * @param array $graph Our Schema data. |
| 142 | 171 | * @param array $block The How-To block content. |
| 143 | 172 | * @param int $index The index of the current block. |
| 173 | + * | |
| 174 | + * @return void | |
| 144 | 175 | */ |
| 145 | 176 | protected function add_how_to( &$graph, $block, $index ) { |
| 146 | 177 | $data = [ |
| 147 | 178 | '@type' => 'HowTo', |
| @@ -150,14 +181,21 @@ | ||
| 150 | 181 | 'mainEntityOfPage' => [ '@id' => $this->context->main_schema_id ], |
| 151 | 182 | 'description' => '', |
| 152 | 183 | ]; |
| 153 | 184 | |
| 185 | + if ( $this->context->has_article ) { | |
| 186 | + $data['mainEntityOfPage'] = [ '@id' => $this->context->main_schema_id . Schema_IDs::ARTICLE_HASH ]; | |
| 187 | + } | |
| 188 | + | |
| 154 | 189 | if ( isset( $block['attrs']['jsonDescription'] ) ) { |
| 155 | 190 | $data['description'] = $this->helpers->schema->html->sanitize( $block['attrs']['jsonDescription'] ); |
| 156 | 191 | } |
| 157 | 192 | |
| 158 | 193 | $this->add_duration( $data, $block['attrs'] ); |
| 159 | - $this->add_steps( $data, $block['attrs']['steps'] ); | |
| 194 | + | |
| 195 | + if ( isset( $block['attrs']['steps'] ) ) { | |
| 196 | + $this->add_steps( $data, $block['attrs']['steps'] ); | |
| 197 | + } | |
| 160 | 198 | |
| 161 | 199 | $data = $this->helpers->schema->language->add_piece_language( $data ); |
| 162 | 200 | |
| 163 | 201 | $graph[] = $data; |