Skip to content

Commit

Permalink
Merge pull request #21814 from Yoast/320-add-post-types-and-taxonomy-…
Browse files Browse the repository at this point in the history
…filters-in-the-script-data

Add post type and taxonomy filters in the script data
  • Loading branch information
thijsoo authored Nov 14, 2024
2 parents a775b85 + 2e37dcb commit 4fb9746
Show file tree
Hide file tree
Showing 12 changed files with 617 additions and 30 deletions.
72 changes: 72 additions & 0 deletions src/dash/application/content-types/content-types-repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dash\Application\Content_Types;

use Yoast\WP\SEO\Dash\Application\Taxonomies\Taxonomies_Repository;
use Yoast\WP\SEO\Dash\Domain\Content_Types\Content_Type;
use Yoast\WP\SEO\Dash\Domain\Content_Types\Content_Types_List;
use Yoast\WP\SEO\Helpers\Post_Type_Helper;

/**
* The repository to get content types.
*/
class Content_Types_Repository {

/**
* The post type helper.
*
* @var Post_Type_Helper
*/
protected $post_type_helper;

/**
* The content types list.
*
* @var Content_Types_List
*/
protected $content_types_list;

/**
* The taxonomies repository.
*
* @var Taxonomies_Repository
*/
private $taxonomies_repository;

/**
* The constructor.
*
* @param Post_Type_Helper $post_type_helper The post type helper.
* @param Content_Types_List $content_types_list The content types list.
* @param Taxonomies_Repository $taxonomies_repository The taxonomies repository.
*/
public function __construct(
Post_Type_Helper $post_type_helper,
Content_Types_List $content_types_list,
Taxonomies_Repository $taxonomies_repository
) {
$this->post_type_helper = $post_type_helper;
$this->content_types_list = $content_types_list;
$this->taxonomies_repository = $taxonomies_repository;
}

/**
* Returns the content types array.
*
* @return array<array<string,array<string, array<string, array<string, string|null>>>>> The content types array.
*/
public function get_content_types(): array {
$post_types = $this->post_type_helper->get_indexable_post_types();

foreach ( $post_types as $post_type ) {
$post_type_object = \get_post_type_object( $post_type ); // @TODO: Refactor `Post_Type_Helper::get_indexable_post_types()` to be able to return objects. That way, we can remove this line.
$content_type_taxonomy = $this->taxonomies_repository->get_content_type_taxonomy( $post_type_object->name );

$content_type = new Content_Type( $post_type_object->name, $post_type_object->label, $content_type_taxonomy );
$this->content_types_list->add( $content_type );
}

return $this->content_types_list->to_array();
}
}
59 changes: 59 additions & 0 deletions src/dash/application/filter-pairs/filter-pairs-repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dash\Application\Filter_Pairs;

use Yoast\WP\SEO\Dash\Domain\Filter_Pairs\Filter_Pairs_Interface;
use Yoast\WP\SEO\Dash\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dash\Infrastructure\Taxonomies\Taxonomies_Collector;

/**
* The repository to get hardcoded filter pairs.
*/
class Filter_Pairs_Repository {

/**
* The taxonomies collector.
*
* @var Taxonomies_Collector
*/
private $taxonomies_collector;

/**
* All filter pairs.
*
* @var Filter_Pairs_Interface[]
*/
private $filter_pairs;

/**
* The constructor.
*
* @param Taxonomies_Collector $taxonomies_collector The taxonomies collector.
* @param Filter_Pairs_Interface ...$filter_pairs All filter pairs.
*/
public function __construct(
Taxonomies_Collector $taxonomies_collector,
Filter_Pairs_Interface ...$filter_pairs
) {
$this->taxonomies_collector = $taxonomies_collector;
$this->filter_pairs = $filter_pairs;
}

/**
* Returns a taxonomy based on a content type, by looking into hardcoded filter pairs.
*
* @param string $content_type The content type.
*
* @return Taxonomy|null The taxonomy filter.
*/
public function get_taxonomy( string $content_type ): ?Taxonomy {
foreach ( $this->filter_pairs as $filter_pair ) {
if ( $filter_pair->get_filtered_content_type() === $content_type ) {
return $this->taxonomies_collector->get_taxonomy( $filter_pair->get_filtering_taxonomy(), $content_type );
}
}

return null;
}
}
66 changes: 66 additions & 0 deletions src/dash/application/taxonomies/taxonomies-repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong
namespace Yoast\WP\SEO\Dash\Application\Taxonomies;

use Yoast\WP\SEO\Dash\Application\Filter_Pairs\Filter_Pairs_Repository;
use Yoast\WP\SEO\Dash\Domain\Taxonomies\Taxonomy;
use Yoast\WP\SEO\Dash\Infrastructure\Taxonomies\Taxonomies_Collector;

/**
* The repository to get taxonomies.
*/
class Taxonomies_Repository {

/**
* The taxonomies collector.
*
* @var Taxonomies_Collector
*/
private $taxonomies_collector;

/**
* The filter pairs repository.
*
* @var Filter_Pairs_Repository
*/
private $filter_pairs_repository;

/**
* The constructor.
*
* @param Taxonomies_Collector $taxonomies_collector The taxonomies collector.
* @param Filter_Pairs_Repository $filter_pairs_repository The filter pairs repository.
*/
public function __construct(
Taxonomies_Collector $taxonomies_collector,
Filter_Pairs_Repository $filter_pairs_repository
) {
$this->taxonomies_collector = $taxonomies_collector;
$this->filter_pairs_repository = $filter_pairs_repository;
}

/**
* Returns the object of the filtering taxonomy of a content type.
*
* @param string $content_type The content type that the taxonomy filters.
*
* @return Taxonomy|null The filtering taxonomy of the content type.
*/
public function get_content_type_taxonomy( string $content_type ) {
// First we check if there's a filter that overrides the filtering taxonomy for this content type.
$taxonomy = $this->taxonomies_collector->get_custom_filtering_taxonomy( $content_type );
if ( $taxonomy ) {
return $taxonomy;
}

// Then we check if there is a filter explicitly made for this content type.
$taxonomy = $this->filter_pairs_repository->get_taxonomy( $content_type );
if ( $taxonomy ) {
return $taxonomy;
}

// If everything else returned empty, we can always try the fallback taxonomy.
return $this->taxonomies_collector->get_fallback_taxonomy( $content_type );
}
}
72 changes: 72 additions & 0 deletions src/dash/domain/content-types/content-type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dash\Domain\Content_Types;

use Yoast\WP\SEO\Dash\Domain\Taxonomies\Taxonomy;

/**
* This class describes a Content Type.
*/
class Content_Type {

/**
* The name of the content type.
*
* @var string
*/
private $name;

/**
* The label of the content type.
*
* @var string
*/
private $label;

/**
* The taxonomy that filters the content type.
*
* @var Taxonomy
*/
private $taxonomy;

/**
* The constructor.
*
* @param string $name The name of the content type.
* @param string $label The label of the content type.
* @param Taxonomy|null $taxonomy The taxonomy that filters the content type.
*/
public function __construct( string $name, string $label, ?Taxonomy $taxonomy ) {
$this->name = $name;
$this->label = $label;
$this->taxonomy = $taxonomy;
}

/**
* Gets name of the content type.
*
* @return string The name of the content type.
*/
public function get_name(): string {
return $this->name;
}

/**
* Gets label of the content type.
*
* @return string The label of the content type.
*/
public function get_label(): string {
return $this->label;
}

/**
* Gets the taxonomy that filters the content type.
*
* @return Taxonomy|null The taxonomy that filters the content type.
*/
public function get_taxonomy(): ?Taxonomy {
return $this->taxonomy;
}
}
45 changes: 45 additions & 0 deletions src/dash/domain/content-types/content-types-list.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dash\Domain\Content_Types;

/**
* This class describes a list of content types.
*/
class Content_Types_List {

/**
* The content types.
*
* @var array<Content_Type>
*/
private $content_types = [];

/**
* Adds a content type to the list.
*
* @param Content_Type $content_type The content type to add.
*
* @return void
*/
public function add( Content_Type $content_type ): void {
$this->content_types[] = $content_type;
}

/**
* Parses the content type list to the expected key value representation.
*
* @return array<array<string,array<string, array<string, array<string, string|null>>>>> The content type list presented as the expected key value representation.
*/
public function to_array(): array {
$array = [];
foreach ( $this->content_types as $content_type ) {
$array[] = [
'name' => $content_type->get_name(),
'label' => $content_type->get_label(),
'taxonomy' => ( $content_type->get_taxonomy() ) ? $content_type->get_taxonomy()->to_array() : null,
];
}

return $array;
}
}
23 changes: 23 additions & 0 deletions src/dash/domain/filter-pairs/filter-pairs-interface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dash\Domain\Filter_Pairs;

/**
* This interface describes a Filter Pair implementation.
*/
interface Filter_Pairs_Interface {

/**
* Gets the filtering taxonomy.
*
* @return string
*/
public function get_filtering_taxonomy(): string;

/**
* Gets the filtered content type.
*
* @return string
*/
public function get_filtered_content_type(): string;
}
27 changes: 27 additions & 0 deletions src/dash/domain/filter-pairs/product-category-filter-pair.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
namespace Yoast\WP\SEO\Dash\Domain\Filter_Pairs;

/**
* This class describes the product category filter pair.
*/
class Product_Category_Filter_Pair implements Filter_Pairs_Interface {

/**
* Gets the filtering taxonomy.
*
* @return string The filtering taxonomy.
*/
public function get_filtering_taxonomy(): string {
return 'product_cat';
}

/**
* Gets the filtered content type.
*
* @return string The filtered content type.
*/
public function get_filtered_content_type(): string {
return 'product';
}
}
Loading

0 comments on commit 4fb9746

Please sign in to comment.