This commit is contained in:
Tony Volpe
2024-06-17 14:41:24 -04:00
parent f885e93ca8
commit a00f379f7f
11158 changed files with 0 additions and 1781316 deletions

View File

@@ -1,123 +0,0 @@
<?php
namespace Yoast\WP\SEO\Premium\Initializers;
use Yoast\WP\SEO\Conditionals\No_Conditionals;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Initializers\Initializer_Interface;
/**
* Index_Now_Key class
*/
class Index_Now_Key implements Initializer_Interface {
use No_Conditionals;
/**
* The options helper.
*
* @var Options_Helper
*/
private $options_helper;
/**
* Holds the IndexNow key.
*
* @var string
*/
private $key;
/**
* Index_Now_Key initializer constructor.
*
* @param Options_Helper $options_helper The option helper.
*/
public function __construct( Options_Helper $options_helper ) {
$this->options_helper = $options_helper;
}
/**
* Initializes the integration.
*
* This is the place to register hooks and filters.
*
* @return void
*/
public function initialize() {
\add_action( 'init', [ $this, 'add_rewrite_rule' ], 1 );
\add_action( 'plugins_loaded', [ $this, 'load' ], 15 );
}
/**
* Loads the integration.
*
* @return void
*/
public function load() {
if ( $this->options_helper->get( 'enable_index_now' ) === false ) {
return;
}
$this->key = $this->options_helper->get( 'index_now_key' );
if ( $this->key === '' ) {
$this->generate_key();
}
\add_action( 'wp', [ $this, 'output_key' ], 0 );
}
/**
* Adds the rewrite rule for the IndexNow key txt file.
*
* @return void
*/
public function add_rewrite_rule() {
if ( $this->options_helper->get( 'enable_index_now' ) !== true ) {
return;
}
global $wp;
$wp->add_query_var( 'yoast_index_now_key' );
\add_rewrite_rule( '^yoast-index-now-([a-zA-Z0-9-]+)\.txt$', 'index.php?yoast_index_now_key=$matches[1]', 'top' );
}
/**
* Outputs the key when it matches the key in the database.
*
* @return void
*/
public function output_key() {
$key_in_url = \get_query_var( 'yoast_index_now_key' );
if ( empty( $key_in_url ) ) {
return;
}
if ( $key_in_url === $this->key ) {
// Remove all headers.
\header_remove();
// Only send plain text header.
\header( 'Content-Type: text/plain;charset=UTF-8' );
echo \esc_html( $this->key );
die;
}
// Trying keys? Good luck.
global $wp_query;
$wp_query->set_404();
}
/**
* Generates an IndexNow key.
*
* Adapted from wp_generate_password to include dash (-) and not be filtered.
*
* @return void
*/
private function generate_key() {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-';
for ( $i = 0; $i < 100; $i++ ) {
$this->key .= \substr( $chars, \wp_rand( 0, ( \strlen( $chars ) - 1 ) ), 1 );
}
$this->options_helper->set( 'index_now_key', $this->key );
}
}

View File

@@ -1,96 +0,0 @@
<?php
namespace Yoast\WP\SEO\Premium\Initializers;
use Yoast\WP\SEO\Conditionals\Admin\Yoast_Admin_Conditional;
use Yoast\WP\SEO\Helpers\Current_Page_Helper;
use Yoast\WP\SEO\Initializers\Initializer_Interface;
use Yoast\WP\SEO\Introductions\Application\Current_Page_Trait;
use Yoast\WP\SEO\Introductions\Domain\Introduction_Interface;
/**
* Initializes Premium introductions.
*/
class Introductions_Initializer implements Initializer_Interface {
const SCRIPT_HANDLE = 'wp-seo-premium-introductions';
use Current_Page_Trait;
/**
* Holds the current page helper.
*
* @var Current_Page_Helper
*/
private $current_page_helper;
/**
* Holds the introductions.
*
* @var Introduction_Interface
*/
private $introductions;
/**
* Constructs the new features integration.
*
* @param Current_Page_Helper $current_page_helper The current page helper.
* @param Introduction_Interface ...$introductions The introductions.
*/
public function __construct( Current_Page_Helper $current_page_helper, Introduction_Interface ...$introductions ) {
$this->current_page_helper = $current_page_helper;
$this->introductions = $introductions;
}
/**
* Returns the conditionals based in which this loadable should be active.
*
* In this case: when on an admin page.
*/
public static function get_conditionals() {
return [ Yoast_Admin_Conditional::class ];
}
/**
* Registers the action to enqueue the needed script(s).
*
* @return void
*/
public function initialize() {
if ( $this->is_on_installation_page() ) {
return;
}
\add_filter( 'wpseo_introductions', [ $this, 'add_introductions' ] );
\add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
}
/**
* Adds the Premium introductions.
*
* @param Introduction_Interface[] $introductions The introductions.
*
* @return array The merged introductions.
*/
public function add_introductions( $introductions ) {
// Safety check and bail.
if ( ! \is_array( $introductions ) ) {
return $introductions;
}
return \array_merge( $introductions, $this->introductions );
}
/**
* Enqueue the workouts app.
*/
public function enqueue_assets() {
\wp_enqueue_script( self::SCRIPT_HANDLE );
\wp_localize_script(
self::SCRIPT_HANDLE,
'wpseoPremiumIntroductions',
[
'pluginUrl' => \plugins_url( '', \WPSEO_PREMIUM_FILE ),
]
);
}
}

View File

@@ -1,68 +0,0 @@
<?php
namespace Yoast\WP\SEO\Premium\Initializers;
use WPSEO_Capability_Manager_Factory;
use WPSEO_Premium;
use WPSEO_Premium_Register_Capabilities;
use Yoast\WP\SEO\Conditionals\No_Conditionals;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Initializers\Initializer_Interface;
/**
* Class Plugin.
*/
class Plugin implements Initializer_Interface {
use No_Conditionals;
/**
* The options helper.
*
* @var Options_Helper
*/
protected $options_helper;
/**
* Plugin constructor.
*
* @param Options_Helper $options_helper The options helper.
*/
public function __construct( Options_Helper $options_helper ) {
$this->options_helper = $options_helper;
}
/**
* Loads the redirect handler.
*
* @return void
*/
public function initialize() {
\add_action( 'plugins_loaded', [ $this, 'load' ], 15 );
$wpseo_premium_capabilities = new WPSEO_Premium_Register_Capabilities();
$wpseo_premium_capabilities->register_hooks();
\register_deactivation_hook( \WPSEO_PREMIUM_FILE, [ $this, 'wpseo_premium_deactivate' ] );
}
/**
* The premium setup
*/
public function load() {
new WPSEO_Premium();
}
/**
* Cleans up Premium on deactivation.
*
* @return void
*/
public function wpseo_premium_deactivate() {
\do_action( 'wpseo_register_capabilities_premium' );
WPSEO_Capability_Manager_Factory::get( 'premium' )->remove();
if ( $this->options_helper->get( 'toggled_tracking' ) !== true ) {
$this->options_helper->set( 'tracking', false );
}
}
}

View File

@@ -1,673 +0,0 @@
<?php
namespace Yoast\WP\SEO\Premium\Initializers;
use WP_Query;
use WPSEO_Premium_Redirect_Option;
use WPSEO_Redirect_Option;
use WPSEO_Redirect_Util;
use Yoast\WP\SEO\Conditionals\Front_End_Conditional;
use Yoast\WP\SEO\Initializers\Initializer_Interface;
/**
* Class Redirect_Handler.
*/
class Redirect_Handler implements Initializer_Interface {
/**
* Array where the redirects will stored.
*
* @var array
*/
protected $redirects;
/**
* The matches parts of the URL in case of a matched regex redirect.
*
* @var array
*/
protected $url_matches = [];
/**
* Is the current page being redirected.
*
* @var bool
*/
protected $is_redirected = false;
/**
* The URL that is called at the moment.
*
* @var string
*/
private $request_url = '';
/**
* Sets the error template to include.
*
* @var string
*/
protected $template_file_path;
/**
* Returns the conditionals based on which this loadable should be active.
*
* @return array The conditionals.
*/
public static function get_conditionals() {
return [ Front_End_Conditional::class ];
}
/**
* Loads the redirect handler.
*
* @return void
*/
public function initialize() {
// Only handle the redirect when the option for php redirects is enabled.
if ( ! $this->load_php_redirects() ) {
return;
}
if ( ! \function_exists( 'is_plugin_active_for_network' ) ) {
require_once \ABSPATH . 'wp-admin/includes/plugin.php';
}
// If the plugin is network activated, we wait for the plugins to be loaded before initializing.
if ( \is_plugin_active_for_network( \WPSEO_PREMIUM_BASENAME ) ) {
\add_action( 'plugins_loaded', [ $this, 'handle_redirects' ], 16 );
}
else {
$this->handle_redirects();
}
}
/**
* Handles the 410 status code.
*
* @return void
*/
public function do_410() {
$is_include_hook_set = $this->set_template_include_hook( '410' );
if ( ! $is_include_hook_set ) {
$this->set_404();
}
$this->status_header( 410 );
}
/**
* Handles the 451 status code.
*
* @return void
*/
public function do_451() {
$is_include_hook_set = $this->set_template_include_hook( '451' );
if ( ! $is_include_hook_set ) {
$this->set_404();
}
$this->status_header( 451, 'Unavailable For Legal Reasons' );
}
/**
* Returns the template that should be included.
*
* @param string $template The template that will included before executing hook.
*
* @return string Returns the template that should be included.
*/
public function set_template_include( $template ) {
if ( ! empty( $this->template_file_path ) ) {
return $this->template_file_path;
}
return $template;
}
/**
* Replaces the $regex vars with URL matches.
*
* @param string[] $matches Array with the matches from the matching redirect.
*
* @return string The replaced URL.
*/
public function format_regex_redirect_url( $matches ) {
$arr_key = \substr( $matches[0], 1 );
if ( isset( $this->url_matches[ $arr_key ] ) ) {
return $this->url_matches[ $arr_key ];
}
return '';
}
/**
* Sets the wp_query to 404 when this is an object.
*
* @return void
*/
public function set_404() {
$wp_query = $this->get_wp_query();
$wp_query->is_404 = true;
}
/**
* Checks if the current URL matches a normal redirect.
*
* @param string $request_url The request url to look for.
*
* @return void
*/
protected function handle_normal_redirects( $request_url ) {
// Setting the redirects.
$redirects = $this->get_redirects( WPSEO_Redirect_Option::OPTION_PLAIN );
$this->redirects = $this->normalize_redirects( $redirects );
$request_url = $this->normalize_url( $request_url );
// Get the URL and doing the redirect.
$redirect_url = $this->find_url( $request_url );
if ( empty( $redirect_url ) ) {
return;
}
if ( $this->normalize_url( $redirect_url['url'] ) === $request_url ) {
return;
}
$this->is_redirected = true;
$this->do_redirect( $redirect_url['url'], $redirect_url['type'] );
}
/**
* Normalizes the url by trimming the slashes. If the given URL is a slash only,
* it will do nothing. By normalizing the URL there is a basis for matching multiple
* variants (Like: url, /url, /url/, url/).
*
* @param string $url The URL to normalize.
*
* @return string The modified url.
*/
protected function normalize_url( $url ) {
if ( $url === '/' ) {
return $url;
}
return \trim( $url, '/' );
}
/**
* Checks if the current URL matches a regex.
*
* @return void
*/
protected function handle_regex_redirects() {
// Setting the redirects.
$this->redirects = $this->get_redirects( WPSEO_Redirect_Option::OPTION_REGEX );
foreach ( $this->redirects as $regex => $redirect ) {
// Check if the URL matches the $regex.
$this->match_regex_redirect( $regex, $redirect );
}
}
/**
* Check if request URL matches one of the regex redirects.
*
* @param string $regex The reqular expression to match.
* @param array $redirect The URL that might be matched with the regex.
*
* @return void
*/
protected function match_regex_redirect( $regex, array $redirect ) {
/*
* Escape the ` because we use ` to delimit the regex to prevent faulty redirects.
*
* Explicitly chosen not to use `preg_quote` because we need to be able to parse
* user provided regular expression syntax.
*/
$regex = \str_replace( '`', '\\`', $regex );
// Suppress warning: a faulty redirect will give a warning and not an exception. So we can't catch it.
// See issue: https://github.com/Yoast/wordpress-seo-premium/issues/662.
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
if ( @\preg_match( "`{$regex}`", $this->request_url, $this->url_matches ) === 1 ) {
// Replace the $regex vars with URL matches.
$redirect_url = \preg_replace_callback(
'/\$[0-9]+/',
[ $this, 'format_regex_redirect_url' ],
$redirect['url']
);
$this->do_redirect( $redirect_url, $redirect['type'] );
}
// Reset url_matches.
$this->url_matches = [];
}
/**
* Gets the redirects from the options.
*
* @param string $option The option name that wil be fetched.
*
* @return array Returns the redirects for the given option.
*/
protected function get_redirects( $option ) {
static $redirects;
if ( ! isset( $redirects[ $option ] ) ) {
$redirects[ $option ] = \get_option( $option, false );
}
if ( ! empty( $redirects[ $option ] ) ) {
return $redirects[ $option ];
}
return [];
}
/**
* Performs the redirect.
*
* @param string $redirect_url The target URL.
* @param string $redirect_type The type of the redirect.
*
* @return void
*/
protected function do_redirect( $redirect_url, $redirect_type ) {
$redirect_url = $this->parse_target_url( $redirect_url );
// Prevents redirecting to itself.
if ( $this->home_url( $this->request_url ) === $redirect_url ) {
return;
}
$redirect_types_without_target = [ 410, 451 ];
if ( \in_array( $redirect_type, $redirect_types_without_target, true ) ) {
$this->handle_redirect_without_target( $redirect_type );
return;
}
$this->redirect( $redirect_url, $redirect_type );
}
/**
* Checks if a redirect has been executed.
*
* @return bool Whether a redirect has been executed.
*/
protected function is_redirected() {
return $this->is_redirected === true;
}
/**
* Checks if we should load the PHP redirects.
*
* If Apache or NginX configuration is selected, don't load PHP redirects.
*
* @return bool True if PHP redirects should be loaded and used.
*/
protected function load_php_redirects() {
if ( \defined( 'WPSEO_DISABLE_PHP_REDIRECTS' ) && \WPSEO_DISABLE_PHP_REDIRECTS === true ) {
return false;
}
if ( \defined( 'WP_CLI' ) && \WP_CLI === true ) {
return false;
}
$options = \get_option( 'wpseo_redirect', false );
if ( $options === false ) {
// If the option is not set, save it, to prevent a query for a non-existing option on every page load.
\add_action( 'wp_head', [ $this, 'save_default_redirect_options' ] );
return false;
}
// If the PHP redirects are disabled intentionally, return false.
if ( ! empty( $options['disable_php_redirect'] ) && $options['disable_php_redirect'] === 'on' ) {
return false;
}
// PHP redirects are the enabled method of redirecting.
return true;
}
/**
* Saves the default redirects options to the DB.
*/
public function save_default_redirect_options() {
$redirect_option = WPSEO_Premium_Redirect_Option::get_instance();
\update_option( 'wpseo_redirect', $redirect_option->get_defaults(), true );
}
/**
* Gets the request URI.
*
* @return string
*/
protected function get_request_uri() {
$request_uri = '';
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We sanitize after decoding.
$request_uri = \sanitize_text_field( \rawurldecode( \wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
}
return $this->strip_subdirectory( $request_uri );
}
/**
* Normalizes the redirects by raw url decoding the origin.
*
* @param array $redirects The redirects to normalize.
*
* @return array The normalized redirects.
*/
protected function normalize_redirects( $redirects ) {
$normalized_redirects = [];
foreach ( $redirects as $origin => $redirect ) {
$normalized_redirects[ \rawurldecode( $origin ) ] = $redirect;
}
return $normalized_redirects;
}
/**
* Sets the request URL and sanitize the slashes for it.
*
* @return void
*/
protected function set_request_url() {
$this->request_url = $this->get_request_uri();
}
/**
* Finds the URL in the redirects.
*
* @param string $url The needed URL.
*
* @return bool|string The found url or false if not found.
*/
protected function find_url( $url ) {
$redirect_url = $this->search( $url );
if ( ! empty( $redirect_url ) ) {
return $redirect_url;
}
return $this->find_url_fallback( $url );
}
/**
* Searches for the given URL in the redirects array.
*
* @param string $url The URL to search for.
*
* @return string|bool The found url or false if not found.
*/
protected function search( $url ) {
if ( ! empty( $this->redirects[ $url ] ) ) {
return $this->redirects[ $url ];
}
return false;
}
/**
* Searches for alternatives with slashes if requested URL isn't found.
*
* This will add a slash if there isn't a slash or it will remove a trailing slash when there isn't one.
*
* @todo Discuss: Maybe we should add slashes to all the values we handle instead of using a fallback.
*
* @param string $url The URL that have to be matched.
*
* @return bool|string The found url or false if not found.
*/
protected function find_url_fallback( $url ) {
$no_trailing_slash = \rtrim( $url, '/' );
$checks = [
'no_trailing_slash' => $no_trailing_slash,
'trailing_slash' => $no_trailing_slash . '/',
];
foreach ( $checks as $check ) {
$redirect_url = $this->search( $check );
if ( ! empty( $redirect_url ) ) {
return $redirect_url;
}
}
return false;
}
/**
* Parses the target URL.
*
* @param string $target_url The URL to parse. When there isn't found a scheme, just parse it based on the home URL.
*
* @return string The parsed url.
*/
protected function parse_target_url( $target_url ) {
if ( $this->has_url_scheme( $target_url ) ) {
return $target_url;
}
$target_url = $this->trailingslashit( $target_url );
$target_url = $this->format_for_multisite( $target_url );
return $this->home_url( $target_url );
}
/**
* Checks if given url has a scheme.
*
* @param string $url The url to check.
*
* @return bool True when url has scheme.
*/
protected function has_url_scheme( $url ) {
$scheme = \wp_parse_url( $url, \PHP_URL_SCHEME );
return ! empty( $scheme );
}
/**
* Determines whether the target URL ends with a slash and adds one if necessary.
*
* @param string $target_url The url to format.
*
* @return string The url with trailing slash.
*/
protected function trailingslashit( $target_url ) {
// Adds slash to target URL when permalink structure ends with a slash.
if ( $this->requires_trailing_slash( $target_url ) ) {
return \trailingslashit( $target_url );
}
return $target_url;
}
/**
* Formats the target url for the multisite if needed.
*
* @param string $target_url The url to format.
*
* @return string The formatted url.
*/
protected function format_for_multisite( $target_url ) {
if ( ! \is_multisite() ) {
return $target_url;
}
$blog_details = \get_blog_details();
if ( $blog_details && ! empty( $blog_details->path ) ) {
$blog_path = \ltrim( $blog_details->path, '/' );
if ( ! empty( $blog_path ) && \strpos( $target_url, $blog_path ) === 0 ) {
$target_url = \substr( $target_url, \strlen( $blog_path ) );
}
}
return $target_url;
}
/**
* Gets the redirect URL by given URL.
*
* @param string $redirect_url The URL that has to be redirected.
*
* @return string The redirect url.
*/
protected function home_url( $redirect_url ) {
$redirect_url = $this->strip_subdirectory( $redirect_url );
return \home_url( $redirect_url );
}
/**
* Strips the subdirectory from the given url.
*
* @param string $url The url to strip the subdirectory from.
*
* @return string The url with the stripped subdirectory.
*/
protected function strip_subdirectory( $url ) {
return WPSEO_Redirect_Util::strip_base_url_path_from_url( $this->get_home_url(), $url );
}
/**
* Returns the URL PATH from the home url.
*
* @return string|null The url path or null if there isn't one.
*/
protected function get_home_url() {
return \home_url();
}
/**
* Sets the hook for setting the template include. This is the file that we want to show.
*
* @param string $template_to_set The template to look for.
*
* @return bool True when template should be included.
*/
protected function set_template_include_hook( $template_to_set ) {
$this->template_file_path = $this->get_query_template( $template_to_set );
if ( ! empty( $this->template_file_path ) ) {
\add_filter( 'template_include', [ $this, 'set_template_include' ] );
return true;
}
return false;
}
/**
* Wraps the WordPress status_header function.
*
* @param int $code HTTP status code.
* @param string $description Optional. A custom description for the HTTP status.
*
* @return void
*/
protected function status_header( $code, $description = '' ) {
\status_header( $code, $description );
}
/**
* Returns instance of WP_Query.
*
* @return WP_Query Instance of WP_Query.
*/
protected function get_wp_query() {
global $wp_query;
if ( \is_object( $wp_query ) ) {
return $wp_query;
}
return new WP_Query();
}
/**
* Handles the redirects without a target by setting the needed hooks.
*
* @param string $redirect_type The type of the redirect.
*
* @return void
*/
protected function handle_redirect_without_target( $redirect_type ) {
if ( $redirect_type === 410 ) {
\add_action( 'wp', [ $this, 'do_410' ] );
}
if ( $redirect_type === 451 ) {
\add_action( 'wp', [ $this, 'do_451' ] );
}
}
/**
* Wrapper method for doing the actual redirect.
*
* @param string $location The path to redirect to.
* @param int $status Status code to use.
*
* @return void
*/
protected function redirect( $location, $status = 302 ) {
if ( ! \function_exists( 'wp_redirect' ) ) {
require_once \ABSPATH . 'wp-includes/pluggable.php';
}
\wp_redirect( $location, $status, 'Yoast SEO Premium' );
exit;
}
/**
* Returns whether or not a target URL requires a trailing slash.
*
* @param string $target_url The target URL to check.
*
* @return bool True when trailing slash is required.
*/
protected function requires_trailing_slash( $target_url ) {
return WPSEO_Redirect_Util::requires_trailing_slash( $target_url );
}
/**
* Returns the query template.
*
* @param string $filename Filename without extension.
*
* @return string Full path to template file.
*/
protected function get_query_template( $filename ) {
return \get_query_template( $filename );
}
/**
* Actually handles redirects.
*
* @return void
*/
public function handle_redirects() {
// Set the requested URL.
$this->set_request_url();
// Check the normal redirects.
$this->handle_normal_redirects( $this->request_url );
// Check the regex redirects.
if ( $this->is_redirected() === false ) {
$this->handle_regex_redirects();
}
}
}

View File

@@ -1,31 +0,0 @@
<?php
namespace Yoast\WP\SEO\Premium\Initializers;
use Automattic\WooCommerce\Utilities\FeaturesUtil;
use Yoast\WP\SEO\Conditionals\No_Conditionals;
use Yoast\WP\SEO\Initializers\Initializer_Interface;
/**
* Declares compatibility with the WooCommerce HPOS feature.
*/
class Woocommerce implements Initializer_Interface {
use No_Conditionals;
/**
* Hooks into WooCommerce.
*/
public function initialize() {
\add_action( 'before_woocommerce_init', [ $this, 'declare_custom_order_tables_compatibility' ] );
}
/**
* Declares compatibility with the WooCommerce HPOS feature.
*/
public function declare_custom_order_tables_compatibility() {
if ( \class_exists( FeaturesUtil::class ) ) {
FeaturesUtil::declare_compatibility( 'custom_order_tables', \WPSEO_PREMIUM_FILE, true );
}
}
}

View File

@@ -1,73 +0,0 @@
<?php
namespace Yoast\WP\SEO\Premium\Initializers;
use WP_CLI;
use Yoast\WP\SEO\Conditionals\No_Conditionals;
use Yoast\WP\SEO\Initializers\Initializer_Interface;
/**
* Wp_Cli_Initializer class
*/
class Wp_Cli_Initializer implements Initializer_Interface {
use No_Conditionals;
/**
* Initializes the integration.
*
* This is the place to register hooks and filters.
*
* @return void
*/
public function initialize() {
if ( \defined( 'WP_CLI' ) && \WP_CLI ) {
\add_action( 'plugins_loaded', [ $this, 'wpseo_cli_init' ], 20 );
}
}
/**
* Initialize the WP-CLI integration.
*
* The WP-CLI integration needs PHP 5.3 support, which should be automatically
* enforced by the check for the WP_CLI constant. As WP-CLI itself only runs
* on PHP 5.3+, the constant should only be set when requirements are met.
*/
public function wpseo_cli_init() {
WP_CLI::add_command(
'yoast redirect list',
'WPSEO_CLI_Redirect_List_Command',
[ 'before_invoke' => 'WPSEO_CLI_Premium_Requirement::enforce' ]
);
WP_CLI::add_command(
'yoast redirect create',
'WPSEO_CLI_Redirect_Create_Command',
[ 'before_invoke' => 'WPSEO_CLI_Premium_Requirement::enforce' ]
);
WP_CLI::add_command(
'yoast redirect update',
'WPSEO_CLI_Redirect_Update_Command',
[ 'before_invoke' => 'WPSEO_CLI_Premium_Requirement::enforce' ]
);
WP_CLI::add_command(
'yoast redirect delete',
'WPSEO_CLI_Redirect_Delete_Command',
[ 'before_invoke' => 'WPSEO_CLI_Premium_Requirement::enforce' ]
);
WP_CLI::add_command(
'yoast redirect has',
'WPSEO_CLI_Redirect_Has_Command',
[ 'before_invoke' => 'WPSEO_CLI_Premium_Requirement::enforce' ]
);
WP_CLI::add_command(
'yoast redirect follow',
'WPSEO_CLI_Redirect_Follow_Command',
[ 'before_invoke' => 'WPSEO_CLI_Premium_Requirement::enforce' ]
);
}
}