Yoast\WP\SEO\Builders

Indexable_Builder::build │ public │ Yoast 1.0

Rebuilds an Indexable from scratch.

Метод класса: Indexable_Builder{}

Хуки из метода

Возвращает

Indexable|false. The resulting Indexable.

Использование

$Indexable_Builder = new Indexable_Builder();
$Indexable_Builder->build( $indexable, $defaults );
$indexable(Indexable) (обязательный)
The Indexable to (re)build.
$defaults(array<string, int|string>|null)
The object type of the Indexable.
По умолчанию: null

Код Indexable_Builder::build() Yoast 28.5

public function build( $indexable, $defaults = null ) {
	// Backup the previous Indexable, if there was one.
	$indexable_before = ( $indexable ) ? $this->deep_copy_indexable( $indexable ) : null;

	// Make sure we have an Indexable to work with.
	$indexable = $this->ensure_indexable( $indexable, $defaults );

	try {
		if ( $indexable->object_id === 0 ) {
			throw Not_Built_Exception::invalid_object_id( $indexable->object_id );
		}
		switch ( $indexable->object_type ) {

			case 'post':
				$indexable = $this->post_builder->build( $indexable->object_id, $indexable );

				// Save indexable, to make sure it can be queried when building related objects like the author indexable and hierarchy.
				$indexable = $this->indexable_helper->save_indexable( $indexable, $indexable_before );

				// For attachments, we have to make sure to patch any potentially previously cleaned up SEO links.
				if ( \is_a( $indexable, Indexable::class ) && $indexable->object_sub_type === 'attachment' ) {
					$this->link_builder->patch_seo_links( $indexable );
				}

				// Always rebuild the primary term.
				$this->primary_term_builder->build( $indexable->object_id );

				// Always rebuild the hierarchy; this needs the primary term to run correctly.
				$this->hierarchy_builder->build( $indexable );

				$this->maybe_build_author_indexable( $indexable->author_id );

				// The indexable is already saved, so return early.
				return $indexable;

			case 'user':
				$indexable = $this->author_builder->build( $indexable->object_id, $indexable );
				break;

			case 'term':
				$indexable = $this->term_builder->build( $indexable->object_id, $indexable );

				// Save indexable, to make sure it can be queried when building hierarchy.
				$indexable = $this->indexable_helper->save_indexable( $indexable, $indexable_before );

				$this->hierarchy_builder->build( $indexable );

				// The indexable is already saved, so return early.
				return $indexable;

			case 'home-page':
				$indexable = $this->home_page_builder->build( $indexable );
				break;

			case 'date-archive':
				$indexable = $this->date_archive_builder->build( $indexable );
				break;

			case 'post-type-archive':
				$indexable = $this->post_type_archive_builder->build( $indexable->object_sub_type, $indexable );
				break;

			case 'system-page':
				$indexable = $this->system_page_builder->build( $indexable->object_sub_type, $indexable );
				break;
		}

		return $this->indexable_helper->save_indexable( $indexable, $indexable_before );
	} catch ( Source_Exception $exception ) {
		if ( ! $this->is_type_with_no_id( $indexable->object_type ) && ! isset( $indexable->object_id ) ) {
			return false;
		}

		/**
		 * The current indexable could not be indexed. Create a placeholder indexable, so we can
		 * skip this indexable in future indexing runs.
		 *
		 * @var Indexable $indexable
		 */
		$indexable = $this->ensure_indexable(
			$indexable,
			[
				'object_id'   => $indexable->object_id,
				'object_type' => $indexable->object_type,
				'post_status' => 'unindexed',
				'version'     => 0,
			],
		);
		// If we already had an existing indexable, mark it as unindexed. We cannot rely on its validity anymore.
		$indexable->post_status = 'unindexed';
		// Make sure that the indexing process doesn't get stuck in a loop on this broken indexable.
		$indexable = $this->version_manager->set_latest( $indexable );

		return $this->indexable_helper->save_indexable( $indexable, $indexable_before );
	} catch ( Not_Built_Exception $exception ) {
		$this->logger->debug(
			$exception->getMessage(),
			[
				'object_id'       => $indexable->object_id,
				'object_type'     => $indexable->object_type,
				'object_sub_type' => $indexable->object_sub_type,
				'exception'       => \get_class( $exception ),
			],
		);

		return false;
	} catch ( Indexing_Failed_Exception $exception ) {
		// A nested build (e.g. the author indexable built during a post build) already logged the
		// failure, fired the action and wrapped the original error, so pass it through untouched
		// to keep the root failing object's identity and avoid reporting the failure twice.
		throw $exception;
	} catch ( Throwable $exception ) {
		$indexing_failed_exception = new Indexing_Failed_Exception(
			$indexable->object_id,
			$indexable->object_type,
			$indexable->object_sub_type,
			$exception,
		);

		$this->logger->error(
			$indexing_failed_exception->getMessage(),
			[
				'object_id'       => $indexable->object_id,
				'object_type'     => $indexable->object_type,
				'object_sub_type' => $indexable->object_sub_type,
				'exception'       => \get_class( $exception ),
			],
		);

		/**
		 * Fires when an indexable could not be built because of an unexpected error.
		 *
		 * This action lets third parties observe build failures themselves.
		 *
		 * @param int|null    $object_id       The object ID of the indexable that failed to build, or null for id-less object types.
		 * @param string      $object_type     The object type of the indexable that failed to build.
		 * @param string|null $object_sub_type The object sub type of the indexable that failed to build.
		 * @param Throwable   $exception       The error that caused the failure.
		 */
		\do_action(
			'wpseo_indexable_indexing_failed',
			$indexable->object_id,
			$indexable->object_type,
			$indexable->object_sub_type,
			$exception,
		);

		throw $indexing_failed_exception;
	}
}