Skip to content

Commit

Permalink
Merge pull request #20074 from Yoast/feature/di-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
thijsoo authored Jun 20, 2023
2 parents 68928cd + c091e0c commit 4e9f987
Show file tree
Hide file tree
Showing 14 changed files with 607 additions and 8 deletions.
85 changes: 78 additions & 7 deletions config/dependency-injection/loader-pass.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Yoast\WP\SEO\Integrations\Integration_Interface;
use Yoast\WP\SEO\Loader;
use Yoast\WP\SEO\Routes\Route_Interface;

use Yoast\WP\SEO\Conditionals\Conditional;
/**
* A pass is a step in the compilation process of the container.
*
Expand All @@ -22,8 +22,7 @@
class Loader_Pass implements CompilerPassInterface {

/**
* Checks all definitions to ensure all classes implementing the Integration interface
* are registered with the Loader class.
* Checks all definitions to ensure all classes implementing the Integration interface are registered with the Loader class.
*
* @param ContainerBuilder $container The container.
*/
Expand Down Expand Up @@ -56,16 +55,42 @@ private function process_definition( Definition $definition, Definition $loader_
try {
$reflect = new ReflectionClass( $class );
$path = $reflect->getFileName();
if ( \strpos( $path, 'src' . \DIRECTORY_SEPARATOR . 'analytics' ) && ! \strpos( $path, 'missing-indexables-collector' ) && ! \strpos( $path, 'to-be-cleaned-indexables-collector' )
) {
$definition->setPublic( false );
if ( strpos( $path, 'wordpress-seo/src/helpers' )
|| strpos( $path, 'wordpress-seo/src/actions' )
|| strpos( $path, 'wordpress-seo/src/builders' )
|| strpos( $path, 'wordpress-seo/src/config' )
|| strpos( $path, 'wordpress-seo/src/context' )
|| strpos( $path, 'wordpress-seo/src/generators' )
|| strpos( $path, 'wordpress-seo/src/surfaces' )
|| strpos( $path, 'wordpress-seo/src/integrations' )
|| strpos( $path, 'wordpress-seo/src/loggers' )
|| strpos( $path, 'wordpress-seo/src/memoizers' )
|| strpos( $path, 'wordpress-seo/src/models' )
|| strpos( $path, 'wordpress-seo/src/presentations' )
|| strpos( $path, 'wordpress-seo/src/repositories' )
|| strpos( $path, 'wordpress-seo/src/services' )
|| strpos( $path, 'wordpress-seo/src/values' )
|| strpos( $path, 'wordpress-seo/src/wrappers' )
|| strpos( $path, 'wordpress-seo/src/wordpress' )
|| strpos( $path, 'wordpress-seo/src/loader' )
) {
$definition->setPublic( true );
}
} catch ( \Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
// Catch all for non-existing classes.
}

if ( $this->should_make_public( $definition ) ) {
$definition->setPublic( true );
}

if ( is_subclass_of( $class, Conditional::class ) ) {
$definition->setPublic( true );
}

if ( \is_subclass_of( $class, Initializer_Interface::class ) ) {
$loader_definition->addMethodCall( 'register_initializer', [ $class ] );
$definition->setPublic( true );
}

if ( \is_subclass_of( $class, Integration_Interface::class ) ) {
Expand All @@ -75,19 +100,65 @@ private function process_definition( Definition $definition, Definition $loader_

if ( \is_subclass_of( $class, Route_Interface::class ) ) {
$loader_definition->addMethodCall( 'register_route', [ $class ] );
$definition->setPublic( true );
}

if ( \is_subclass_of( $class, Command_Interface::class ) ) {
$loader_definition->addMethodCall( 'register_command', [ $class ] );
$definition->setPublic( true );
}

if ( \is_subclass_of( $class, Migration::class ) ) {
$reflect = new ReflectionClass( $class );
$reflect = new \ReflectionClass( $class );
$path = $reflect->getFileName();
$file = \basename( $path, '.php' );
$version = \explode( '_', $file )[0];
$plugin = $class::$plugin;
$loader_definition->addMethodCall( 'register_migration', [ $plugin, $version, $class ] );
$definition->setPublic( true );
}
}

/**
* Checks if a class should be public. A class can be made public in the dependency injection by adding the
* `@makePublic` annotation in the doc block.
*
* @param Definition $definition The definition to make public.
* @return bool
*/
private function should_make_public( Definition $definition ): bool {
$doc_comment = $this->get_method_doc_block( $definition );

if ( empty( $doc_comment ) ) {
// If there is no doc comment, assume we should autowire.
return false;
}

return strpos( $doc_comment, '* @makePublic' ) !== false;
}

/**
* Retrieves the doc block comment for the given definition.
*
* @param Definition $definition The definition to parse.
*
* @return string The doc block.
*/
private function get_method_doc_block( Definition $definition ) {
$classname = $definition->getClass();
try {
$reflection_class = new \ReflectionClass( $classname );
} catch ( \ReflectionException $exception ) {
return '';
}

/**
* The DocComment for the class we're reflecting.
*
* @var string|false $doc_comment
*/
$doc_comment = $reflection_class->getDocComment();

return ( $doc_comment === false ) ? '' : $doc_comment;
}
}
2 changes: 1 addition & 1 deletion config/dependency-injection/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
$yoast_seo_base_definition
->setAutowired( true )
->setAutoconfigured( true )
->setPublic( true );
->setPublic( false );

/**
* Holds the dependency injection loader.
Expand Down
2 changes: 2 additions & 0 deletions src/analytics/application/missing-indexables-collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

/**
* Manages the collection of the missing indexable data.
*
* @makePublic
*/
class Missing_Indexables_Collector implements WPSEO_Collection {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

/**
* Collects data about to-be-cleaned indexables.
*
* @makePublic
*/
class To_Be_Cleaned_Indexables_Collector implements WPSEO_Collection {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Yoast\WP\SEO\Schema\Application;

use Yoast\WP\SEO\Schema\Domain\Search_Result_Schema_Piece;

/**
* Handles the Generate_Search_Result_Schema_Piece action
*
* @phpcs:disable Yoast.NamingConventions.ObjectNameDepth.MaxExceeded
*/
class Generate_Search_Result_Schema_Piece_Handler {

/**
* Invokes the generation of the Schema Piece
*
* @param Generate_Search_Result_Schema_Piece $command The command.
*
* @return Search_Result_Schema_Piece
*/
public function handle( Generate_Search_Result_Schema_Piece $command ) {
return new Search_Result_Schema_Piece( $command->get_search_term() );
}
}
35 changes: 35 additions & 0 deletions src/schema/application/generate-search-result-schema-piece.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
namespace Yoast\WP\SEO\Schema\Application;

use Yoast\WP\SEO\Schema\Domain\Search_Term;

/**
* The action for search result schema
*/
class Generate_Search_Result_Schema_Piece {

/**
* The search term domain object.
*
* @var Search_Term $search_term The search term domain object.
*/
private $search_term;

/**
* The search term.
*
* @param string $search_term The search term.
*/
public function __construct( $search_term ) {
$this->search_term = new Search_Term( $search_term );
}

/**
* Gets the search term domain object.
*
* @return Search_Term
*/
public function get_search_term() {
return $this->search_term;
}
}
52 changes: 52 additions & 0 deletions src/schema/domain/search-result-schema-piece.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
namespace Yoast\WP\SEO\Schema\Domain;

use Yoast\WP\SEO\Generators\Schema\Abstract_Schema_Piece;
use Yoast\WP\SEO\Schema\Domain\Search_Term;

/**
* Generates the SearchAction schema Piece
*/
class Search_Result_Schema_Piece extends Abstract_Schema_Piece {

/**
* The search term domain object.
*
* @var Search_Term $search_term
*/
private $search_term;

/**
* Search_Result_Schema_Piece constructor.
*
* @param Search_Term $search_term The search term domain object.
*/
public function __construct( Search_Term $search_term ) {
$this->search_term = $search_term;
}

/**
* Generates the data to be added to the schema graph.
*
* @return array The data to be added to the schema graph
*/
public function generate() {
$data = [
'@type' => 'SearchAction',
'actionStatus' => 'https://schema.org/CompletedActionStatus',
'query' => $this->search_term->get_query(),
'result' => [ '@id' => $this->context->main_schema_id ],
];

return $data;
}

/**
* Returns if the schema graph is needed.
*
* @return bool
*/
public function is_needed() {
return true;
}
}
33 changes: 33 additions & 0 deletions src/schema/domain/search-term.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
namespace Yoast\WP\SEO\Schema\Domain;

/**
* The search term domain object.
*/
class Search_Term {

/**
* The search query.
*
* @var string $query
*/
private $query;

/**
* Search Term constructor.
*
* @param string $query The query.
*/
public function __construct( $query ) {
$this->query = $query;
}

/**
* Return the search query.
*
* @return string The search query.
*/
public function get_query() {
return $this->query;
}
}
71 changes: 71 additions & 0 deletions src/schema/user-interface/search-result-integration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Yoast\WP\SEO\Schema\User_Interface;

use Yoast\WP\SEO\Conditionals\Front_End_Conditional;
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
use Yoast\WP\SEO\Integrations\Integration_Interface;
use Yoast\WP\SEO\Schema\Application\Generate_Search_Result_Schema_Piece;
use Yoast\WP\SEO\Schema\Application\Generate_Search_Result_Schema_Piece_Handler;

/**
* Integrates the search action graph piece into the schema graph.
*/
class Search_Result_Integration implements Integration_Interface {

/**
* The current page helper.
*
* @var Current_Page_Helper
*/
private $current_page_helper;

/**
* The Generate_Search_Result_Schema handler.
*
* @var Generate_Search_Result_Schema_Piece_Handler
*/
private $handler;

/**
* {@inheritDoc}
*/
public static function get_conditionals() {
return [ Front_End_Conditional::class ];
}

/**
* Search_Result_Integration constructor.
*
* @param Current_Page_Helper $current_page_helper The current page helper class.
* @param Generate_Search_Result_Schema_Piece_Handler $handler The generate command handler.
*/
public function __construct( Current_Page_Helper $current_page_helper, Generate_Search_Result_Schema_Piece_Handler $handler ) {
$this->current_page_helper = $current_page_helper;
$this->handler = $handler;
}

/**
* {@inheritDoc}
*/
public function register_hooks() {
\add_filter( 'wpseo_schema_graph_pieces', [ $this, 'add_search_result_schema_piece' ], 10, 2 );
}

/**
* Integrates a new Schema piece into the graph if we are on a search page.
*
* @param array $graph The current schema graph.
* @param array $context The schema context.
*
* @return mixed Returns the schema graph
*/
public function add_search_result_schema_piece( $graph, $context ) {
if ( $this->current_page_helper->is_search_result() ) {
$graph[] = $this->handler->handle( new Generate_Search_Result_Schema_Piece( \get_search_query() ) );
}

return $graph;
}
}

Loading

0 comments on commit 4e9f987

Please sign in to comment.