• File: woocommerce.php
  • Full Path: /home/matthif/www/wp-content/plugins/wordpress-seo/src/integrations/third-party/woocommerce.php
  • Date Modified: 02/24/2024 11:29 PM
  • File size: 9.44 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace Yoast\WP\SEO\Integrations\Third_Party;

use 
WPSEO_Replace_Vars;
use 
Yoast\WP\SEO\Conditionals\Front_End_Conditional;
use 
Yoast\WP\SEO\Conditionals\WooCommerce_Conditional;
use 
Yoast\WP\SEO\Helpers\Options_Helper;
use 
Yoast\WP\SEO\Helpers\Pagination_Helper;
use 
Yoast\WP\SEO\Helpers\Woocommerce_Helper;
use 
Yoast\WP\SEO\Integrations\Integration_Interface;
use 
Yoast\WP\SEO\Memoizers\Meta_Tags_Context_Memoizer;
use 
Yoast\WP\SEO\Models\Indexable;
use 
Yoast\WP\SEO\Presentations\Indexable_Presentation;
use 
Yoast\WP\SEO\Repositories\Indexable_Repository;

/**
 * WooCommerce integration.
 */
class WooCommerce implements Integration_Interface {

    
/**
     * The options helper.
     *
     * @var Options_Helper
     */
    
private $options;

    
/**
     * The WPSEO Replace Vars object.
     *
     * @var WPSEO_Replace_Vars
     */
    
private $replace_vars;

    
/**
     * The memoizer for the meta tags context.
     *
     * @var Meta_Tags_Context_Memoizer
     */
    
protected $context_memoizer;

    
/**
     * The indexable repository.
     *
     * @var Indexable_Repository
     */
    
private $repository;

    
/**
     * The pagination helper.
     *
     * @var Pagination_Helper
     */
    
protected $pagination_helper;

    
/**
     * The WooCommerce helper.
     *
     * @var Woocommerce_Helper
     */
    
private $woocommerce_helper;

    
/**
     * Returns the conditionals based in which this loadable should be active.
     *
     * @return array
     */
    
public static function get_conditionals() {
        return [ 
WooCommerce_Conditional::class, Front_End_Conditional::class ];
    }

    
/**
     * WooCommerce constructor.
     *
     * @param Options_Helper             $options            The options helper.
     * @param WPSEO_Replace_Vars         $replace_vars       The replace vars helper.
     * @param Meta_Tags_Context_Memoizer $context_memoizer   The meta tags context memoizer.
     * @param Indexable_Repository       $repository         The indexable repository.
     * @param Pagination_Helper          $pagination_helper  The paginataion helper.
     * @param Woocommerce_Helper         $woocommerce_helper The WooCommerce helper.
     */
    
public function __construct(
        
Options_Helper $options,
        
WPSEO_Replace_Vars $replace_vars,
        
Meta_Tags_Context_Memoizer $context_memoizer,
        
Indexable_Repository $repository,
        
Pagination_Helper $pagination_helper,
        
Woocommerce_Helper $woocommerce_helper
    
) {
        
$this->options            $options;
        
$this->replace_vars       $replace_vars;
        
$this->context_memoizer   $context_memoizer;
        
$this->repository         $repository;
        
$this->pagination_helper  $pagination_helper;
        
$this->woocommerce_helper $woocommerce_helper;
    }

    
/**
     * Initializes the integration.
     *
     * This is the place to register hooks and filters.
     *
     * @return void
     */
    
public function register_hooks() {
        
\add_filter'wpseo_frontend_page_type_simple_page_id', [ $this'get_page_id' ] );
        
\add_filter'wpseo_breadcrumb_indexables', [ $this'add_shop_to_breadcrumbs' ] );

        
\add_filter'wpseo_title', [ $this'title' ], 10);
        
\add_filter'wpseo_metadesc', [ $this'description' ], 10);
        
\add_filter'wpseo_canonical', [ $this'canonical' ], 10);
        
\add_filter'wpseo_adjacent_rel_url', [ $this'adjacent_rel_url' ], 10);
    }

    
/**
     * Returns the correct canonical when WooCommerce is enabled.
     *
     * @param string                      $canonical    The current canonical.
     * @param Indexable_Presentation|null $presentation The indexable presentation.
     *
     * @return string The correct canonical.
     */
    
public function canonical$canonical$presentation null ) {
        if ( ! 
$this->woocommerce_helper->is_shop_page() ) {
            return 
$canonical;
        }

        
$url $this->get_shop_paginated_link'curr'$presentation );

        if ( 
$url ) {
            return 
$url;
        }

        return 
$canonical;
    }

    
/**
     * Returns correct adjacent pages when WooCommerce is enabled.
     *
     * @param string                      $link         The current link.
     * @param string                      $rel          Link relationship, prev or next.
     * @param Indexable_Presentation|null $presentation The indexable presentation.
     *
     * @return string The correct link.
     */
    
public function adjacent_rel_url$link$rel$presentation null ) {
        if ( ! 
$this->woocommerce_helper->is_shop_page() ) {
            return 
$link;
        }

        if ( 
$rel !== 'next' && $rel !== 'prev' ) {
            return 
$link;
        }

        
$url $this->get_shop_paginated_link$rel$presentation );

        if ( 
$url ) {
            return 
$url;
        }

        return 
$link;
    }

    
/**
     * Adds a breadcrumb for the shop page.
     *
     * @param Indexable[] $indexables The array with indexables.
     *
     * @return Indexable[] The indexables to be shown in the breadcrumbs, with the shop page added.
     */
    
public function add_shop_to_breadcrumbs$indexables ) {
        
$shop_page_id $this->woocommerce_helper->get_shop_page_id();

        if ( ! 
\is_int$shop_page_id ) || $shop_page_id ) {
            return 
$indexables;
        }

        foreach ( 
$indexables as $index => $indexable ) {
            if ( 
$indexable->object_type === 'post-type-archive' && $indexable->object_sub_type === 'product' ) {
                
$shop_page_indexable $this->repository->find_by_id_and_type$shop_page_id'post' );
                if ( 
\is_a$shop_page_indexableIndexable::class ) ) {
                    
$indexables$index ] = $shop_page_indexable;
                }
            }
        }

        return 
$indexables;
    }

    
/**
     * Returns the ID of the WooCommerce shop page when the currently opened page is the shop page.
     *
     * @param int $page_id The page id.
     *
     * @return int The Page ID of the shop.
     */
    
public function get_page_id$page_id ) {
        if ( ! 
$this->woocommerce_helper->is_shop_page() ) {
            return 
$page_id;
        }

        return 
$this->woocommerce_helper->get_shop_page_id();
    }

    
/**
     * Handles the title.
     *
     * @param string                      $title        The title.
     * @param Indexable_Presentation|null $presentation The indexable presentation.
     *
     * @return string The title to use.
     */
    
public function title$title$presentation null ) {
        
$presentation $this->ensure_presentation$presentation );

        if ( 
$presentation->model->title ) {
            return 
$title;
        }

        if ( ! 
$this->woocommerce_helper->is_shop_page() ) {
            return 
$title;
        }

        if ( ! 
\is_archive() ) {
            return 
$title;
        }

        
$shop_page_id $this->woocommerce_helper->get_shop_page_id();
        if ( 
$shop_page_id ) {
            return 
$title;
        }

        
$product_template_title $this->get_product_template'title-product'$shop_page_id );
        if ( 
$product_template_title ) {
            return 
$product_template_title;
        }

        return 
$title;
    }

    
/**
     * Handles the meta description.
     *
     * @param string                      $description  The title.
     * @param Indexable_Presentation|null $presentation The indexable presentation.
     *
     * @return string The description to use.
     */
    
public function description$description$presentation null ) {
        
$presentation $this->ensure_presentation$presentation );

        if ( 
$presentation->model->description ) {
            return 
$description;
        }

        if ( ! 
$this->woocommerce_helper->is_shop_page() ) {
            return 
$description;
        }

        if ( ! 
\is_archive() ) {
            return 
$description;
        }

        
$shop_page_id $this->woocommerce_helper->get_shop_page_id();
        if ( 
$shop_page_id ) {
            return 
$description;
        }

        
$product_template_description $this->get_product_template'metadesc-product'$shop_page_id );
        if ( 
$product_template_description ) {
            return 
$product_template_description;
        }

        return 
$description;
    }

    
/**
     * Uses template for the given option name and replace the replacement variables on it.
     *
     * @param string $option_name  The option name to get the template for.
     * @param string $shop_page_id The page id to retrieve template for.
     *
     * @return string The rendered value.
     */
    
protected function get_product_template$option_name$shop_page_id ) {
        
$template $this->options->get$option_name );
        
$page     \get_post$shop_page_id );

        return 
$this->replace_vars->replace$template$page );
    }

    
/**
     * Get paginated link for shop page.
     *
     * @param string                      $rel          Link relationship, prev or next or curr.
     * @param Indexable_Presentation|null $presentation The indexable presentation.
     *
     * @return string|null The link.
     */
    
protected function get_shop_paginated_link$rel$presentation null ) {
        
$presentation $this->ensure_presentation$presentation );

        
$permalink $presentation->permalink;
        if ( ! 
$permalink ) {
            return 
null;
        }

        
$current_page \max1$this->pagination_helper->get_current_archive_page_number() );

        if ( 
$rel === 'curr' && $current_page === ) {
            return 
$permalink;
        }

        if ( 
$rel === 'curr' && $current_page ) {
            return 
$this->pagination_helper->get_paginated_url$permalink$current_page );
        }

        if ( 
$rel === 'prev' && $current_page === ) {
            return 
$permalink;
        }

        if ( 
$rel === 'prev' && $current_page ) {
            return 
$this->pagination_helper->get_paginated_url$permalink, ( $current_page ) );
        }

        if ( 
$rel === 'next' && $current_page $this->pagination_helper->get_number_of_archive_pages() ) {
            return 
$this->pagination_helper->get_paginated_url$permalink, ( $current_page ) );
        }

        return 
null;
    }

    
/**
     * Ensures a presentation is available.
     *
     * @param Indexable_Presentation $presentation The indexable presentation.
     *
     * @return Indexable_Presentation The presentation, taken from the current page if the input was invalid.
     */
    
protected function ensure_presentation$presentation ) {
        if ( 
\is_a$presentationIndexable_Presentation::class ) ) {
            return 
$presentation;
        }

        
$context $this->context_memoizer->for_current_page();

        return 
$context->presentation;
    }
}