PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.5
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
← All changes | src/builders/indexable-builder.php +71 -6 27.828.5 View file →
@@ -1,11 +1,14 @@
1 1 <?php
2 2
3 3 namespace Yoast\WP\SEO\Builders;
4 4
5 +use Throwable;
6 +use Yoast\WP\SEO\Exceptions\Indexable\Indexing_Failed_Exception;
5 7 use Yoast\WP\SEO\Exceptions\Indexable\Not_Built_Exception;
6 8 use Yoast\WP\SEO\Exceptions\Indexable\Source_Exception;
7 9 use Yoast\WP\SEO\Helpers\Indexable_Helper;
10 +use Yoast\WP\SEO\Loggers\Logger;
8 11 use Yoast\WP\SEO\Models\Indexable;
9 12 use Yoast\WP\SEO\Repositories\Indexable_Repository;
10 13 use Yoast\WP\SEO\Services\Indexables\Indexable_Version_Manager;
11 14
@@ -107,8 +110,15 @@
107 110 */
108 111 protected $version_manager;
109 112
110 113 /**
114 + * The logger.
115 + *
116 + * @var Logger
117 + */
118 + protected $logger;
119 +
120 + /**
111 121 * Returns the instance of this class constructed through the ORM Wrapper.
112 122 *
113 123 * @param Indexable_Author_Builder $author_builder The author builder for creating missing indexables.
114 124 * @param Indexable_Post_Builder $post_builder The post builder for creating missing indexables.
@@ -121,8 +131,9 @@
121 131 * @param Primary_Term_Builder $primary_term_builder The primary term builder for creating primary terms for posts.
122 132 * @param Indexable_Helper $indexable_helper The indexable helper.
123 133 * @param Indexable_Version_Manager $version_manager The indexable version manager.
124 134 * @param Indexable_Link_Builder $link_builder The link builder for creating missing SEO links.
135 + * @param Logger $logger The logger.
125 136 */
126 137 public function __construct(
127 138 Indexable_Author_Builder $author_builder,
128 139 Indexable_Post_Builder $post_builder,
@@ -134,9 +145,10 @@
134 145 Indexable_Hierarchy_Builder $hierarchy_builder,
135 146 Primary_Term_Builder $primary_term_builder,
136 147 Indexable_Helper $indexable_helper,
137 148 Indexable_Version_Manager $version_manager,
138 - Indexable_Link_Builder $link_builder
149 + Indexable_Link_Builder $link_builder,
150 + Logger $logger
139 151 ) {
140 152 $this->author_builder = $author_builder;
141 153 $this->post_builder = $post_builder;
142 154 $this->term_builder = $term_builder;
@@ -148,8 +160,9 @@
148 160 $this->primary_term_builder = $primary_term_builder;
149 161 $this->indexable_helper = $indexable_helper;
150 162 $this->version_manager = $version_manager;
151 163 $this->link_builder = $link_builder;
164 + $this->logger = $logger;
152 165 }
153 166
154 167 /**
155 168 * Sets the indexable repository. Done to avoid circular dependencies.
@@ -253,10 +266,10 @@
253 266
254 267 /**
255 268 * Ensures we have a valid indexable. Creates one if false is passed.
256 269 *
257 - * @param Indexable|false $indexable The indexable.
258 - * @param array $defaults The initial properties of the Indexable.
270 + * @param Indexable|false $indexable The indexable.
271 + * @param array<string, int|string> $defaults The initial properties of the Indexable.
259 272 *
260 273 * @return Indexable The indexable.
261 274 */
262 275 protected function ensure_indexable( $indexable, $defaults = [] ) {
@@ -301,15 +314,15 @@
301 314 protected function is_type_with_no_id( $type ) {
302 315 return \in_array( $type, [ 'home-page', 'date-archive', 'post-type-archive', 'system-page' ], true );
303 316 }
304 317
305 - // phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.Missing -- Exceptions are handled by the catch statement in the method.
318 + // phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.Missing -- Most exceptions are handled in the method; the unexpected-error catch deliberately re-throws after firing the failure hook.
306 319
307 320 /**
308 321 * Rebuilds an Indexable from scratch.
309 322 *
310 - * @param Indexable $indexable The Indexable to (re)build.
311 - * @param array|null $defaults The object type of the Indexable.
323 + * @param Indexable $indexable The Indexable to (re)build.
324 + * @param array<string, int|string>|null $defaults The object type of the Indexable.
312 325 *
313 326 * @return Indexable|false The resulting Indexable.
314 327 */
315 328 public function build( $indexable, $defaults = null ) {
@@ -406,9 +419,61 @@
406 419 $indexable = $this->version_manager->set_latest( $indexable );
407 420
408 421 return $this->indexable_helper->save_indexable( $indexable, $indexable_before );
409 422 } catch ( Not_Built_Exception $exception ) {
423 + $this->logger->debug(
424 + $exception->getMessage(),
425 + [
426 + 'object_id' => $indexable->object_id,
427 + 'object_type' => $indexable->object_type,
428 + 'object_sub_type' => $indexable->object_sub_type,
429 + 'exception' => \get_class( $exception ),
430 + ],
431 + );
432 +
410 433 return false;
434 + } catch ( Indexing_Failed_Exception $exception ) {
435 + // A nested build (e.g. the author indexable built during a post build) already logged the
436 + // failure, fired the action and wrapped the original error, so pass it through untouched
437 + // to keep the root failing object's identity and avoid reporting the failure twice.
438 + throw $exception;
439 + } catch ( Throwable $exception ) {
440 + $indexing_failed_exception = new Indexing_Failed_Exception(
441 + $indexable->object_id,
442 + $indexable->object_type,
443 + $indexable->object_sub_type,
444 + $exception,
445 + );
446 +
447 + $this->logger->error(
448 + $indexing_failed_exception->getMessage(),
449 + [
450 + 'object_id' => $indexable->object_id,
451 + 'object_type' => $indexable->object_type,
452 + 'object_sub_type' => $indexable->object_sub_type,
453 + 'exception' => \get_class( $exception ),
454 + ],
455 + );
456 +
457 + /**
458 + * Fires when an indexable could not be built because of an unexpected error.
459 + *
460 + * This action lets third parties observe build failures themselves.
461 + *
462 + * @param int|null $object_id The object ID of the indexable that failed to build, or null for id-less object types.
463 + * @param string $object_type The object type of the indexable that failed to build.
464 + * @param string|null $object_sub_type The object sub type of the indexable that failed to build.
465 + * @param Throwable $exception The error that caused the failure.
466 + */
467 + \do_action(
468 + 'wpseo_indexable_indexing_failed',
469 + $indexable->object_id,
470 + $indexable->object_type,
471 + $indexable->object_sub_type,
472 + $exception,
473 + );
474 +
475 + throw $indexing_failed_exception;
411 476 }
412 477 }
413 478
414 479 // phpcs:enable