|
Server : LiteSpeed System : Linux server51.dnsbootclub.com 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64 User : nandedex ( 1060) PHP Version : 8.1.33 Disable Function : NONE Directory : /home/nandedex/public_html/s.nandedexpress.com/ |
wincher-client.php 0000644 00000007531 15121603254 0010175 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
use WPSEO_Utils;
use Yoast\WP\SEO\Exceptions\OAuth\Authentication_Failed_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Property_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Token_Exception;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Values\OAuth\OAuth_Token;
use Yoast\WP\SEO\Wrappers\WP_Remote_Handler;
use YoastSEO_Vendor\GuzzleHttp\Client;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\Exception\IdentityProviderException;
/**
* Class Wincher_Client
*/
class Wincher_Client extends OAuth_Client {
/**
* The option's key.
*/
public const TOKEN_OPTION = 'wincher_tokens';
/**
* Name of the temporary PKCE cookie.
*/
public const PKCE_TRANSIENT_NAME = 'yoast_wincher_pkce';
/**
* The WP_Remote_Handler instance.
*
* @var WP_Remote_Handler
*/
protected $wp_remote_handler;
/**
* Wincher_Client constructor.
*
* @param Options_Helper $options_helper The Options_Helper instance.
* @param WP_Remote_Handler $wp_remote_handler The request handler.
*
* @throws Empty_Property_Exception Exception thrown if a token property is empty.
*/
public function __construct(
Options_Helper $options_helper,
WP_Remote_Handler $wp_remote_handler
) {
$provider = new Wincher_PKCE_Provider(
[
'clientId' => 'yoast',
'redirectUri' => 'https://auth.wincher.com/yoast/setup',
'urlAuthorize' => 'https://auth.wincher.com/connect/authorize',
'urlAccessToken' => 'https://auth.wincher.com/connect/token',
'urlResourceOwnerDetails' => 'https://api.wincher.com/beta/user',
'scopes' => [ 'profile', 'account', 'websites:read', 'websites:write', 'offline_access' ],
'scopeSeparator' => ' ',
'pkceMethod' => 'S256',
],
[
'httpClient' => new Client( [ 'handler' => $wp_remote_handler ] ),
]
);
parent::__construct(
self::TOKEN_OPTION,
$provider,
$options_helper
);
}
/**
* Return the authorization URL.
*
* @return string The authentication URL.
*/
public function get_authorization_url() {
$parsed_site_url = \wp_parse_url( \get_site_url() );
$url = $this->provider->getAuthorizationUrl(
[
'state' => WPSEO_Utils::format_json_encode( [ 'domain' => $parsed_site_url['host'] ] ),
]
);
$pkce_code = $this->provider->getPkceCode();
// Store a transient value with the PKCE code that we need in order to
// exchange the returned code for a token after authorization.
\set_transient( self::PKCE_TRANSIENT_NAME, $pkce_code, \DAY_IN_SECONDS );
return $url;
}
/**
* Requests the access token and refresh token based on the passed code.
*
* @param string $code The code to send.
*
* @return OAuth_Token The requested tokens.
*
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
*/
public function request_tokens( $code ) {
$pkce_code = \get_transient( self::PKCE_TRANSIENT_NAME );
if ( $pkce_code ) {
$this->provider->setPkceCode( $pkce_code );
}
return parent::request_tokens( $code );
}
/**
* Performs the specified request.
*
* @codeCoverageIgnore
*
* @param string $method The HTTP method to use.
* @param string $url The URL to send the request to.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
protected function do_request( $method, $url, array $options ) {
$options['headers'] = [ 'Content-Type' => 'application/json' ];
return parent::do_request( $method, $url, $options );
}
}
oauth-client.php 0000644 00000021617 15121603254 0007657 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
use Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Authentication_Failed_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Property_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Token_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Failed_Storage_Exception;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Values\OAuth\OAuth_Token;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\GenericProvider;
/**
* Class OAuth_Client
*/
abstract class OAuth_Client {
/**
* The option's key.
*
* @var string
*/
protected $token_option = null;
/**
* The provider.
*
* @var Wincher_PKCE_Provider|GenericProvider
*/
protected $provider;
/**
* The options helper.
*
* @var Options_Helper
*/
protected $options_helper;
/**
* The token.
*
* @var OAuth_Token|null
*/
protected $token = null;
/**
* OAuth_Client constructor.
*
* @param string $token_option The option's name to save the token as.
* @param Wincher_PKCE_Provider|GenericProvider $provider The provider.
* @param Options_Helper $options_helper The Options_Helper instance.
*
* @throws Empty_Property_Exception Exception thrown if a token property is empty.
*/
public function __construct(
$token_option,
$provider,
Options_Helper $options_helper
) {
$this->provider = $provider;
$this->token_option = $token_option;
$this->options_helper = $options_helper;
$tokens = $this->options_helper->get( $this->token_option );
if ( ! empty( $tokens ) ) {
$this->token = new OAuth_Token(
$tokens['access_token'],
$tokens['refresh_token'],
$tokens['expires'],
$tokens['has_expired'],
$tokens['created_at'],
( $tokens['error_count'] ?? 0 )
);
}
}
/**
* Requests the access token and refresh token based on the passed code.
*
* @param string $code The code to send.
*
* @return OAuth_Token The requested tokens.
*
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
*/
public function request_tokens( $code ) {
try {
$response = $this->provider
->getAccessToken(
'authorization_code',
[
'code' => $code,
]
);
$token = OAuth_Token::from_response( $response );
return $this->store_token( $token );
} catch ( Exception $exception ) {
throw new Authentication_Failed_Exception( $exception );
}
}
/**
* Performs an authenticated GET request to the desired URL.
*
* @param string $url The URL to send the request to.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function get( $url, $options = [] ) {
return $this->do_request( 'GET', $url, $options );
}
/**
* Performs an authenticated POST request to the desired URL.
*
* @param string $url The URL to send the request to.
* @param mixed $body The data to send along in the request's body.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function post( $url, $body, $options = [] ) {
$options['body'] = $body;
return $this->do_request( 'POST', $url, $options );
}
/**
* Performs an authenticated DELETE request to the desired URL.
*
* @param string $url The URL to send the request to.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function delete( $url, $options = [] ) {
return $this->do_request( 'DELETE', $url, $options );
}
/**
* Determines whether there are valid tokens available.
*
* @return bool Whether there are valid tokens.
*/
public function has_valid_tokens() {
return ! empty( $this->token ) && $this->token->has_expired() === false;
}
/**
* Gets the stored tokens and refreshes them if they've expired.
*
* @return OAuth_Token The stored tokens.
*
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function get_tokens() {
if ( empty( $this->token ) ) {
throw new Empty_Token_Exception();
}
if ( $this->token->has_expired() ) {
$this->token = $this->refresh_tokens( $this->token );
}
return $this->token;
}
/**
* Stores the passed token.
*
* @param OAuth_Token $token The token to store.
*
* @return OAuth_Token The stored token.
*
* @throws Failed_Storage_Exception Exception thrown if storing of the token fails.
*/
public function store_token( OAuth_Token $token ) {
$saved = $this->options_helper->set( $this->token_option, $token->to_array() );
if ( $saved === false ) {
throw new Failed_Storage_Exception();
}
return $token;
}
/**
* Clears the stored token from storage.
*
* @return bool The stored token.
*
* @throws Failed_Storage_Exception Exception thrown if clearing of the token fails.
*/
public function clear_token() {
$saved = $this->options_helper->set( $this->token_option, [] );
if ( $saved === false ) {
throw new Failed_Storage_Exception();
}
return true;
}
/**
* Performs the specified request.
*
* @param string $method The HTTP method to use.
* @param string $url The URL to send the request to.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
protected function do_request( $method, $url, array $options ) {
$defaults = [
'headers' => $this->provider->getHeaders( $this->get_tokens()->access_token ),
];
$options = \array_merge_recursive( $defaults, $options );
if ( \array_key_exists( 'params', $options ) ) {
$url .= '?' . \http_build_query( $options['params'] );
unset( $options['params'] );
}
$request = $this->provider
->getAuthenticatedRequest( $method, $url, null, $options );
return $this->provider->getParsedResponse( $request );
}
/**
* Refreshes the outdated tokens.
*
* @param OAuth_Token $tokens The outdated tokens.
*
* @return OAuth_Token The refreshed tokens.
*
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
*/
protected function refresh_tokens( OAuth_Token $tokens ) {
// We do this dance with transients since we need to make sure we don't
// delete valid tokens because of a race condition when two calls are
// made simultaneously to this function and refresh token rotation is
// turned on in the OAuth server. This is not 100% safe, but should at
// least be much better than not having any lock at all.
$lock_name = \sprintf( 'lock:%s', $this->token_option );
$can_lock = \get_transient( $lock_name ) === false;
$has_lock = $can_lock && \set_transient( $lock_name, true, 30 );
try {
$new_tokens = $this->provider->getAccessToken(
'refresh_token',
[
'refresh_token' => $tokens->refresh_token,
]
);
$token_obj = OAuth_Token::from_response( $new_tokens );
return $this->store_token( $token_obj );
} catch ( Exception $exception ) {
// If we tried to refresh but the refresh token is invalid, delete
// the tokens so that we don't try again. Only do this if we got the
// lock at the beginning of the call.
if ( $has_lock && $exception->getMessage() === 'invalid_grant' ) {
try {
// To protect from race conditions, only do this if we've
// seen an error before with the same token.
if ( $tokens->error_count >= 1 ) {
$this->clear_token();
}
else {
$tokens->error_count += 1;
$this->store_token( $tokens );
}
} catch ( Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
// Pass through.
}
}
throw new Authentication_Failed_Exception( $exception );
} finally {
\delete_transient( $lock_name );
}
}
}
indexing-reasons.php 0000644 00000002443 15121603254 0010534 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Class Indexing_Reasons. Contains constants that aren't context specific.
*/
class Indexing_Reasons {
/**
* Represents the reason that the indexing process failed and should be tried again.
*/
public const REASON_INDEXING_FAILED = 'indexing_failed';
/**
* Represents the reason that the permalink settings are changed.
*/
public const REASON_PERMALINK_SETTINGS = 'permalink_settings_changed';
/**
* Represents the reason that the category base is changed.
*/
public const REASON_CATEGORY_BASE_PREFIX = 'category_base_changed';
/**
* Represents the reason that the tag base is changed.
*/
public const REASON_TAG_BASE_PREFIX = 'tag_base_changed';
/**
* Represents the reason that the home url option is changed.
*/
public const REASON_HOME_URL_OPTION = 'home_url_option_changed';
/**
* Represents the reason that a post type has been made public.
*/
public const REASON_POST_TYPE_MADE_PUBLIC = 'post_type_made_public';
/**
* Represents the reason that a post type has been made viewable.
*/
public const REASON_TAXONOMY_MADE_PUBLIC = 'taxonomy_made_public';
/**
* Represents the reason that attachments have stopped being redirected.
*/
public const REASON_ATTACHMENTS_MADE_ENABLED = 'attachments_made_enabled';
}
schema-types.php 0000644 00000010002 15121603254 0007647 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Class Schema_Types.
*/
class Schema_Types {
/**
* Holds the possible schema page types.
*
* Capitalized in this way so the value can be directly used in the schema output.
*
* @var string[]
*/
public const PAGE_TYPES = [
'WebPage' => '',
'ItemPage' => '',
'AboutPage' => '',
'FAQPage' => '',
'QAPage' => '',
'ProfilePage' => '',
'ContactPage' => '',
'MedicalWebPage' => '',
'CollectionPage' => '',
'CheckoutPage' => '',
'RealEstateListing' => '',
'SearchResultsPage' => '',
];
/**
* Holds the possible schema article types.
*
* Capitalized in this way so the value can be directly used in the schema output.
*
* @var string[]
*/
public const ARTICLE_TYPES = [
'Article' => '',
'BlogPosting' => '',
'SocialMediaPosting' => '',
'NewsArticle' => '',
'AdvertiserContentArticle' => '',
'SatiricalArticle' => '',
'ScholarlyArticle' => '',
'TechArticle' => '',
'Report' => '',
'None' => '',
];
/**
* Gets the page type options.
*
* @return array[] The schema page type options.
*/
public function get_page_type_options() {
return [
[
'name' => \__( 'Web Page', 'wordpress-seo' ),
'value' => 'WebPage',
],
[
'name' => \__( 'Item Page', 'wordpress-seo' ),
'value' => 'ItemPage',
],
[
'name' => \__( 'About Page', 'wordpress-seo' ),
'value' => 'AboutPage',
],
[
'name' => \__( 'FAQ Page', 'wordpress-seo' ),
'value' => 'FAQPage',
],
[
'name' => \__( 'QA Page', 'wordpress-seo' ),
'value' => 'QAPage',
],
[
'name' => \__( 'Profile Page', 'wordpress-seo' ),
'value' => 'ProfilePage',
],
[
'name' => \__( 'Contact Page', 'wordpress-seo' ),
'value' => 'ContactPage',
],
[
'name' => \__( 'Medical Web Page', 'wordpress-seo' ),
'value' => 'MedicalWebPage',
],
[
'name' => \__( 'Collection Page', 'wordpress-seo' ),
'value' => 'CollectionPage',
],
[
'name' => \__( 'Checkout Page', 'wordpress-seo' ),
'value' => 'CheckoutPage',
],
[
'name' => \__( 'Real Estate Listing', 'wordpress-seo' ),
'value' => 'RealEstateListing',
],
[
'name' => \__( 'Search Results Page', 'wordpress-seo' ),
'value' => 'SearchResultsPage',
],
];
}
/**
* Gets the article type options.
*
* @return array[] The schema article type options.
*/
public function get_article_type_options() {
/**
* Filter: 'wpseo_schema_article_types_labels' - Allow developers to filter the available article types and their labels.
*
* Make sure when you filter this to also filter `wpseo_schema_article_types`.
*
* @param array $schema_article_types_labels The available schema article types and their labels.
*/
return \apply_filters(
'wpseo_schema_article_types_labels',
[
[
'name' => \__( 'Article', 'wordpress-seo' ),
'value' => 'Article',
],
[
'name' => \__( 'Blog Post', 'wordpress-seo' ),
'value' => 'BlogPosting',
],
[
'name' => \__( 'Social Media Posting', 'wordpress-seo' ),
'value' => 'SocialMediaPosting',
],
[
'name' => \__( 'News Article', 'wordpress-seo' ),
'value' => 'NewsArticle',
],
[
'name' => \__( 'Advertiser Content Article', 'wordpress-seo' ),
'value' => 'AdvertiserContentArticle',
],
[
'name' => \__( 'Satirical Article', 'wordpress-seo' ),
'value' => 'SatiricalArticle',
],
[
'name' => \__( 'Scholarly Article', 'wordpress-seo' ),
'value' => 'ScholarlyArticle',
],
[
'name' => \__( 'Tech Article', 'wordpress-seo' ),
'value' => 'TechArticle',
],
[
'name' => \__( 'Report', 'wordpress-seo' ),
'value' => 'Report',
],
[
'name' => \__( 'None', 'wordpress-seo' ),
'value' => 'None',
],
]
);
}
}
migration-status.php 0000644 00000012227 15121603254 0010572 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Migration_Status class.
*
* Used to validate whether or not migrations have been run and whether or not they should be run again.
*/
class Migration_Status {
/**
* The migration option key.
*
* @var string
*/
public const MIGRATION_OPTION_KEY = 'yoast_migrations_';
/**
* The migration options.
*
* @var array
*/
protected $migration_options = [];
/**
* Checks if a given migration should be run.
*
* @param string $name The name of the migration.
* @param string $version The current version.
*
* @return bool Whether or not the migration should be run.
*/
public function should_run_migration( $name, $version = \WPSEO_VERSION ) {
$migration_status = $this->get_migration_status( $name );
// Check if we've attempted to run this migration in the past 10 minutes. If so, it may still be running.
if ( \array_key_exists( 'lock', $migration_status ) ) {
$timestamp = \strtotime( '-10 minutes' );
return $timestamp > $migration_status['lock'];
}
// Is the migration version less than the current version.
return \version_compare( $migration_status['version'], $version, '<' );
}
/**
* Checks whether or not the given migration is at least the given version, defaults to checking for the latest version.
*
* @param string $name The name of the migration.
* @param string $version The version to check, defaults to the latest version.
*
* @return bool Whether or not the requested migration is at least the requested version.
*/
public function is_version( $name, $version = \WPSEO_VERSION ) {
$migration_status = $this->get_migration_status( $name );
return \version_compare( $version, $migration_status['version'], '<=' );
}
/**
* Gets the error of a given migration if it exists.
*
* @param string $name The name of the migration.
*
* @return bool|array False if there is no error, otherwise the error.
*/
public function get_error( $name ) {
$migration_status = $this->get_migration_status( $name );
if ( ! isset( $migration_status['error'] ) ) {
return false;
}
return $migration_status['error'];
}
/**
* Sets an error for the migration.
*
* @param string $name The name of the migration.
* @param string $message Message explaining the reason for the error.
* @param string $version The current version.
*
* @return void
*/
public function set_error( $name, $message, $version = \WPSEO_VERSION ) {
$migration_status = $this->get_migration_status( $name );
$migration_status['error'] = [
'time' => \strtotime( 'now' ),
'version' => $version,
'message' => $message,
];
$this->set_migration_status( $name, $migration_status );
}
/**
* Updates the migration version to the latest version.
*
* @param string $name The name of the migration.
* @param string $version The current version.
*
* @return void
*/
public function set_success( $name, $version = \WPSEO_VERSION ) {
$migration_status = $this->get_migration_status( $name );
unset( $migration_status['lock'] );
unset( $migration_status['error'] );
$migration_status['version'] = $version;
$this->set_migration_status( $name, $migration_status );
}
/**
* Locks the migration status.
*
* @param string $name The name of the migration.
*
* @return bool Whether or not the migration was succesfully locked.
*/
public function lock_migration( $name ) {
$migration_status = $this->get_migration_status( $name );
$migration_status['lock'] = \strtotime( 'now' );
return $this->set_migration_status( $name, $migration_status );
}
/**
* Retrieves the migration option.
*
* @param string $name The name of the migration.
*
* @return bool|array The status of the migration, false if no status exists.
*/
protected function get_migration_status( $name ) {
$current_blog_id = \get_current_blog_id();
if ( ! isset( $this->migration_options[ $current_blog_id ][ $name ] ) ) {
$migration_status = \get_option( self::MIGRATION_OPTION_KEY . $name );
if ( ! \is_array( $migration_status ) || ! isset( $migration_status['version'] ) ) {
$migration_status = [ 'version' => '0.0' ];
}
if ( ! isset( $this->migration_options[ $current_blog_id ] ) ) {
$this->migration_options[ $current_blog_id ] = [];
}
$this->migration_options[ $current_blog_id ][ $name ] = $migration_status;
}
return $this->migration_options[ $current_blog_id ][ $name ];
}
/**
* Retrieves the migration option.
*
* @param string $name The name of the migration.
* @param array $migration_status The migration status.
*
* @return bool True if the status was succesfully updated, false otherwise.
*/
protected function set_migration_status( $name, $migration_status ) {
if ( ! \is_array( $migration_status ) || ! isset( $migration_status['version'] ) ) {
return false;
}
$current_blog_id = \get_current_blog_id();
if ( ! isset( $this->migration_options[ $current_blog_id ] ) ) {
$this->migration_options[ $current_blog_id ] = [];
}
$this->migration_options[ $current_blog_id ][ $name ] = $migration_status;
return \update_option( self::MIGRATION_OPTION_KEY . $name, $migration_status );
}
}
migrations/20200420073606_AddColumnsToIndexables.php 0000644 00000004124 15121603254 0015423 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class AddColumnsToIndexables.
*/
class AddColumnsToIndexables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$tables = $this->get_tables();
$blog_id = \get_current_blog_id();
foreach ( $tables as $table ) {
$this->add_column(
$table,
'blog_id',
'biginteger',
[
'null' => false,
'limit' => 20,
'default' => $blog_id,
]
);
}
$attr_limit_32 = [
'null' => true,
'limit' => 32,
];
$attr_limit_64 = [
'null' => true,
'limit' => 64,
];
$indexable_table = $this->get_indexable_table();
$this->add_column( $indexable_table, 'language', 'string', $attr_limit_32 );
$this->add_column( $indexable_table, 'region', 'string', $attr_limit_32 );
$this->add_column( $indexable_table, 'schema_page_type', 'string', $attr_limit_64 );
$this->add_column( $indexable_table, 'schema_article_type', 'string', $attr_limit_64 );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$tables = $this->get_tables();
foreach ( $tables as $table ) {
$this->remove_column( $table, 'blog_id' );
}
$indexable_table = $this->get_indexable_table();
$this->remove_column( $indexable_table, 'language' );
$this->remove_column( $indexable_table, 'region' );
$this->remove_column( $indexable_table, 'schema_page_type' );
$this->remove_column( $indexable_table, 'schema_article_type' );
}
/**
* Retrieves the Indexable table.
*
* @return string The Indexable table name.
*/
protected function get_indexable_table() {
return Model::get_table_name( 'Indexable' );
}
/**
* Retrieves the table names to use.
*
* @return string[] The table names to use.
*/
protected function get_tables() {
return [
$this->get_indexable_table(),
Model::get_table_name( 'Indexable_Hierarchy' ),
Model::get_table_name( 'Primary_Term' ),
];
}
}
migrations/20230417083836_AddInclusiveLanguageScore.php 0000644 00000001662 15121603254 0016125 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* AddInclusiveLanguageScore class.
*/
class AddInclusiveLanguageScore extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$this->add_column(
$table_name,
'inclusive_language_score',
'integer',
[
'null' => true,
'limit' => 3,
]
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$table_name = $this->get_table_name();
$this->remove_column( $table_name, 'inclusive_language_score' );
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20191011111109_WpYoastIndexableHierarchy.php 0000644 00000003072 15121603254 0016146 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class WpYoastIndexableHierarchy.
*/
class WpYoastIndexableHierarchy extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$indexable_table = $this->create_table( $table_name, [ 'id' => false ] );
$indexable_table->column(
'indexable_id',
'integer',
[
'primary_key' => true,
'unsigned' => true,
'null' => true,
'limit' => 11,
]
);
$indexable_table->column(
'ancestor_id',
'integer',
[
'primary_key' => true,
'unsigned' => true,
'null' => true,
'limit' => 11,
]
);
$indexable_table->column(
'depth',
'integer',
[
'unsigned' => true,
'null' => true,
'limit' => 11,
]
);
$indexable_table->finish();
$this->add_index( $table_name, 'indexable_id', [ 'name' => 'indexable_id' ] );
$this->add_index( $table_name, 'ancestor_id', [ 'name' => 'ancestor_id' ] );
$this->add_index( $table_name, 'depth', [ 'name' => 'depth' ] );
}
/**
* Migration up.
*
* @return void
*/
public function down() {
$this->drop_table( $this->get_table_name() );
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable_Hierarchy' );
}
}
migrations/20210817092415_AddVersionColumnToIndexables.php 0000644 00000001547 15121603254 0016626 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* AddVersionColumnToIndexables class.
*/
class AddVersionColumnToIndexables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->add_column(
$this->get_table_name(),
'version',
'integer',
[
'default' => 1,
]
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->remove_column(
$this->get_table_name(),
'version'
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200408101900_AddCollationToTables.php 0000644 00000001676 15121603254 0015067 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class AddCollationToTables.
*/
class AddCollationToTables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
if ( empty( $charset_collate ) ) {
return;
}
$tables = [
Model::get_table_name( 'migrations' ),
Model::get_table_name( 'Indexable' ),
Model::get_table_name( 'Indexable_Hierarchy' ),
Model::get_table_name( 'Primary_Term' ),
];
foreach ( $tables as $table ) {
$this->query( 'ALTER TABLE ' . $table . ' CONVERT TO ' . \str_replace( 'DEFAULT ', '', $charset_collate ) );
}
}
/**
* Migration down.
*
* @return void
*/
public function down() {
// No down required.
}
}
migrations/20200429105310_TruncateIndexableTables.php 0000644 00000002065 15121603254 0015623 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class TruncateIndexableTables.
*/
class TruncateIndexableTables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->query( 'TRUNCATE TABLE ' . $this->get_indexable_table_name() );
$this->query( 'TRUNCATE TABLE ' . $this->get_indexable_hierarchy_table_name() );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
// Nothing to do.
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_indexable_table_name() {
return Model::get_table_name( 'Indexable' );
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_indexable_hierarchy_table_name() {
return Model::get_table_name( 'Indexable_Hierarchy' );
}
}
migrations/20200430075614_AddIndexableObjectIdAndTypeIndex.php 0000644 00000001737 15121603254 0017266 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class AddIndexableObjectIdAndTypeIndex.
*/
class AddIndexableObjectIdAndTypeIndex extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->add_index(
$this->get_table_name(),
[
'object_id',
'object_type',
],
[
'name' => 'object_id_and_type',
]
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->remove_index(
$this->get_table_name(),
[
'object_id',
'object_type',
],
[
'name' => 'object_id_and_type',
]
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200507054848_DeleteDuplicateIndexables.php 0000644 00000002113 15121603254 0016135 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class DeleteDuplicateIndexables.
*/
class DeleteDuplicateIndexables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
/*
* Deletes duplicate indexables that have the same object_id and object_type.
* The rows with a higher ID are deleted as those should be unused and could be outdated.
*/
$this->query( 'DELETE wyi FROM ' . $table_name . ' wyi INNER JOIN ' . $table_name . ' wyi2 WHERE wyi2.object_id = wyi.object_id AND wyi2.object_type = wyi.object_type AND wyi2.id < wyi.id;' );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
// Nothing to do.
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200616130143_ReplacePermalinkHashIndex.php 0000644 00000004365 15121603254 0016106 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* ReplacePermalinkHashIndex class.
*/
class ReplacePermalinkHashIndex extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$adapter = $this->get_adapter();
if ( ! $adapter->has_table( $table_name ) ) {
return;
}
$this->change_column(
$table_name,
'permalink_hash',
'string',
[
'null' => true,
'limit' => 40,
]
);
if ( $adapter->has_index( $table_name, [ 'permalink_hash' ], [ 'name' => 'permalink_hash' ] ) ) {
$this->remove_index(
$table_name,
[
'permalink_hash',
],
[
'name' => 'permalink_hash',
]
);
}
if ( ! $adapter->has_index( $table_name, [ 'permalink_hash', 'object_type' ], [ 'name' => 'permalink_hash_and_object_type' ] ) ) {
$this->add_index(
$table_name,
[
'permalink_hash',
'object_type',
],
[
'name' => 'permalink_hash_and_object_type',
]
);
}
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$table_name = $this->get_table_name();
$adapter = $this->get_adapter();
if ( ! $adapter->has_table( $table_name ) ) {
return;
}
if ( $adapter->has_index( $table_name, [ 'permalink_hash', 'object_type' ], [ 'name' => 'permalink_hash_and_object_type' ] ) ) {
$this->remove_index(
$table_name,
[
'permalink_hash',
'object_type',
],
[
'name' => 'permalink_hash_and_object_type',
]
);
}
$this->change_column(
$table_name,
'permalink_hash',
'string',
[
'null' => true,
'limit' => 191,
]
);
if ( ! $adapter->has_index( $table_name, [ 'permalink_hash' ], [ 'name' => 'permalink_hash' ] ) ) {
$this->add_index(
$table_name,
[
'permalink_hash',
],
[
'name' => 'permalink_hash',
]
);
}
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200513133401_ResetIndexableHierarchyTable.php 0000644 00000001366 15121603254 0016573 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class ResetIndexableHierarchyTable.
*/
class ResetIndexableHierarchyTable extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->query( 'TRUNCATE TABLE ' . $this->get_table_name() );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
// Nothing to do.
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable_Hierarchy' );
}
}
migrations/20200617122511_CreateSEOLinksTable.php 0000644 00000004735 15121603254 0014621 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* CreateSEOLinksTable class.
*/
class CreateSEOLinksTable extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$adapter = $this->get_adapter();
// The table may already have been created by legacy code.
// If not, create it exactly as it was.
if ( ! $adapter->table_exists( $table_name ) ) {
$table = $this->create_table( $table_name, [ 'id' => false ] );
$table->column(
'id',
'biginteger',
[
'primary_key' => true,
'limit' => 20,
'unsigned' => true,
'auto_increment' => true,
]
);
$table->column( 'url', 'string', [ 'limit' => 255 ] );
$table->column(
'post_id',
'biginteger',
[
'limit' => 20,
'unsigned' => true,
]
);
$table->column(
'target_post_id',
'biginteger',
[
'limit' => 20,
'unsigned' => true,
]
);
$table->column( 'type', 'string', [ 'limit' => 8 ] );
$table->finish();
}
if ( ! $adapter->has_index( $table_name, [ 'post_id', 'type' ], [ 'name' => 'link_direction' ] ) ) {
$this->add_index( $table_name, [ 'post_id', 'type' ], [ 'name' => 'link_direction' ] );
}
// Add these columns outside of the initial table creation as these did not exist on the legacy table.
$this->add_column( $table_name, 'indexable_id', 'integer', [ 'unsigned' => true ] );
$this->add_column( $table_name, 'target_indexable_id', 'integer', [ 'unsigned' => true ] );
$this->add_column( $table_name, 'height', 'integer', [ 'unsigned' => true ] );
$this->add_column( $table_name, 'width', 'integer', [ 'unsigned' => true ] );
$this->add_column( $table_name, 'size', 'integer', [ 'unsigned' => true ] );
$this->add_column( $table_name, 'language', 'string', [ 'limit' => 32 ] );
$this->add_column( $table_name, 'region', 'string', [ 'limit' => 32 ] );
$this->add_index( $table_name, [ 'indexable_id', 'type' ], [ 'name' => 'indexable_link_direction' ] );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->drop_table( $this->get_table_name() );
}
/**
* Returns the SEO Links table name.
*
* @return string
*/
private function get_table_name() {
return Model::get_table_name( 'SEO_Links' );
}
}
migrations/20171228151841_WpYoastPrimaryTerm.php 0000644 00000003022 15121603254 0014701 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Migration for the Primary Term.
*/
class WpYoastPrimaryTerm extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$indexable_table = $this->create_table( $table_name );
$indexable_table->column(
'post_id',
'integer',
[
'unsigned' => true,
'null' => false,
'limit' => 11,
]
);
$indexable_table->column(
'term_id',
'integer',
[
'unsigned' => true,
'null' => false,
'limit' => 11,
]
);
$indexable_table->column(
'taxonomy',
'string',
[
'null' => false,
'limit' => 32,
]
);
// Executes the SQL to create the table.
$indexable_table->finish();
$this->add_index(
$table_name,
[
'post_id',
'taxonomy',
],
[
'name' => 'post_taxonomy',
]
);
$this->add_index(
$table_name,
[
'post_id',
'term_id',
],
[
'name' => 'post_term',
]
);
$this->add_timestamps( $table_name );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->drop_table( $this->get_table_name() );
}
/**
* Retrieves the table name to use.
*
* @return string Table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Primary_Term' );
}
}
migrations/20200430150130_ClearIndexableTables.php 0000644 00000002057 15121603254 0015055 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class ClearIndexableTables.
*/
class ClearIndexableTables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->query( 'TRUNCATE TABLE ' . $this->get_indexable_table_name() );
$this->query( 'TRUNCATE TABLE ' . $this->get_indexable_hierarchy_table_name() );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
// Nothing to do.
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_indexable_table_name() {
return Model::get_table_name( 'Indexable' );
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_indexable_hierarchy_table_name() {
return Model::get_table_name( 'Indexable_Hierarchy' );
}
}
migrations/20211020091404_AddObjectTimestamps.php 0000644 00000003007 15121603254 0014747 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* AddObjectTimestamps class.
*/
class AddObjectTimestamps extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->add_column(
$this->get_table_name(),
'object_last_modified',
'datetime',
[
'null' => true,
'default' => null,
]
);
$this->add_column(
$this->get_table_name(),
'object_published_at',
'datetime',
[
'null' => true,
'default' => null,
]
);
$this->add_index(
$this->get_table_name(),
[
'object_published_at',
'is_robots_noindex',
'object_type',
'object_sub_type',
],
[
'name' => 'published_sitemap_index',
]
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->remove_column( $this->get_table_name(), 'object_last_modified' );
$this->remove_column( $this->get_table_name(), 'object_published_at' );
$this->remove_index(
$this->get_table_name(),
[
'object_published_at',
'is_robots_noindex',
'object_type',
'object_sub_type',
],
[
'name' => 'published_sitemap_index',
]
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20201216124002_ExpandIndexableIDColumnLengths.php 0000644 00000002023 15121603254 0017026 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* ExpandIndexableIDColumnLengths class.
*/
class ExpandIndexableIDColumnLengths extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* The columns to change the column type and length of.
*
* @var string[]
*/
protected static $columns_to_change = [
'object_id',
'author_id',
'post_parent',
];
/**
* Migration up.
*
* @return void
*/
public function up() {
foreach ( self::$columns_to_change as $column ) {
$this->change_column(
$this->get_table_name(),
$column,
'biginteger',
[ 'limit' => 20 ]
);
}
}
/**
* Migration down.
*
* @return void
*/
public function down() {
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200428123747_BreadcrumbTitleAndHierarchyReset.php 0000644 00000002356 15121603254 0017444 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class BreadcrumbTitleAndHierarchyReset.
*/
class BreadcrumbTitleAndHierarchyReset extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->change_column( $this->get_indexable_table_name(), 'breadcrumb_title', 'text', [ 'null' => true ] );
$this->query( 'DELETE FROM ' . $this->get_indexable_hierarchy_table_name() );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->change_column(
$this->get_indexable_table_name(),
'breadcrumb_title',
'string',
[
'null' => true,
'limit' => 191,
]
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_indexable_table_name() {
return Model::get_table_name( 'Indexable' );
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_indexable_hierarchy_table_name() {
return Model::get_table_name( 'Indexable_Hierarchy' );
}
}
migrations/20190529075038_WpYoastDropIndexableMetaTableIfExists.php 0000644 00000001573 15121603254 0020425 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class WpYoastDropIndexableMetaTableIfExists.
*/
class WpYoastDropIndexableMetaTableIfExists extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
// This can be done safely as it executes a DROP IF EXISTS.
$this->drop_table( $table_name );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
// No down required. This specific table should never exist.
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable_Meta' );
}
}
migrations/20200428194858_ExpandIndexableColumnLengths.php 0000644 00000003413 15121603254 0016653 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Class ExpandIndexableColumnLengths.
*/
class ExpandIndexableColumnLengths extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->change_column( $this->get_table_name(), 'title', 'text', [ 'null' => true ] );
$this->change_column( $this->get_table_name(), 'open_graph_title', 'text', [ 'null' => true ] );
$this->change_column( $this->get_table_name(), 'twitter_title', 'text', [ 'null' => true ] );
$this->change_column( $this->get_table_name(), 'open_graph_image_source', 'text', [ 'null' => true ] );
$this->change_column( $this->get_table_name(), 'twitter_image_source', 'text', [ 'null' => true ] );
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$attr_limit_191 = [
'null' => true,
'limit' => 191,
];
$this->change_column(
$this->get_table_name(),
'title',
'string',
$attr_limit_191
);
$this->change_column(
$this->get_table_name(),
'opengraph_title',
'string',
$attr_limit_191
);
$this->change_column(
$this->get_table_name(),
'twitter_title',
'string',
$attr_limit_191
);
$this->change_column(
$this->get_table_name(),
'open_graph_image_source',
'string',
$attr_limit_191
);
$this->change_column(
$this->get_table_name(),
'twitter_image_source',
'string',
$attr_limit_191
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20171228151840_WpYoastIndexable.php 0000644 00000014256 15121603254 0014333 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* Indexable migration.
*/
class WpYoastIndexable extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->add_table();
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->drop_table( $this->get_table_name() );
}
/**
* Creates the indexable table.
*
* @return void
*/
private function add_table() {
$table_name = $this->get_table_name();
$indexable_table = $this->create_table( $table_name );
// Permalink.
$indexable_table->column( 'permalink', 'mediumtext', [ 'null' => true ] );
$indexable_table->column(
'permalink_hash',
'string',
[
'null' => true,
'limit' => 191,
]
);
// Object information.
$indexable_table->column(
'object_id',
'integer',
[
'unsigned' => true,
'null' => true,
'limit' => 11,
]
);
$indexable_table->column(
'object_type',
'string',
[
'null' => false,
'limit' => 32,
]
);
$indexable_table->column(
'object_sub_type',
'string',
[
'null' => true,
'limit' => 32,
]
);
// Ownership.
$indexable_table->column(
'author_id',
'integer',
[
'unsigned' => true,
'null' => true,
'limit' => 11,
]
);
$indexable_table->column(
'post_parent',
'integer',
[
'unsigned' => true,
'null' => true,
'limit' => 11,
]
);
// Title and description.
$indexable_table->column(
'title',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column( 'description', 'text', [ 'null' => true ] );
$indexable_table->column(
'breadcrumb_title',
'string',
[
'null' => true,
'limit' => 191,
]
);
// Post metadata: status, public, protected.
$indexable_table->column(
'post_status',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column(
'is_public',
'boolean',
[
'null' => true,
'default' => null,
]
);
$indexable_table->column( 'is_protected', 'boolean', [ 'default' => false ] );
$indexable_table->column(
'has_public_posts',
'boolean',
[
'null' => true,
'default' => null,
]
);
$indexable_table->column(
'number_of_pages',
'integer',
[
'unsigned' => true,
'null' => true,
'default' => null,
'limit' => 11,
]
);
$indexable_table->column( 'canonical', 'mediumtext', [ 'null' => true ] );
// SEO and readability analysis.
$indexable_table->column(
'primary_focus_keyword',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column(
'primary_focus_keyword_score',
'integer',
[
'null' => true,
'limit' => 3,
]
);
$indexable_table->column(
'readability_score',
'integer',
[
'null' => true,
'limit' => 3,
]
);
$indexable_table->column( 'is_cornerstone', 'boolean', [ 'default' => false ] );
// Robots.
$indexable_table->column(
'is_robots_noindex',
'boolean',
[
'null' => true,
'default' => false,
]
);
$indexable_table->column(
'is_robots_nofollow',
'boolean',
[
'null' => true,
'default' => false,
]
);
$indexable_table->column(
'is_robots_noarchive',
'boolean',
[
'null' => true,
'default' => false,
]
);
$indexable_table->column(
'is_robots_noimageindex',
'boolean',
[
'null' => true,
'default' => false,
]
);
$indexable_table->column(
'is_robots_nosnippet',
'boolean',
[
'null' => true,
'default' => false,
]
);
// Twitter.
$indexable_table->column(
'twitter_title',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column( 'twitter_image', 'mediumtext', [ 'null' => true ] );
$indexable_table->column( 'twitter_description', 'mediumtext', [ 'null' => true ] );
$indexable_table->column(
'twitter_image_id',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column(
'twitter_image_source',
'string',
[
'null' => true,
'limit' => 191,
]
);
// Open-Graph.
$indexable_table->column(
'open_graph_title',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column( 'open_graph_description', 'mediumtext', [ 'null' => true ] );
$indexable_table->column( 'open_graph_image', 'mediumtext', [ 'null' => true ] );
$indexable_table->column(
'open_graph_image_id',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column(
'open_graph_image_source',
'string',
[
'null' => true,
'limit' => 191,
]
);
$indexable_table->column( 'open_graph_image_meta', 'text', [ 'null' => true ] );
// Link count.
$indexable_table->column(
'link_count',
'integer',
[
'null' => true,
'limit' => 11,
]
);
$indexable_table->column(
'incoming_link_count',
'integer',
[
'null' => true,
'limit' => 11,
]
);
// Prominent words.
$indexable_table->column(
'prominent_words_version',
'integer',
[
'null' => true,
'limit' => 11,
'unsigned' => true,
'default' => null,
]
);
$indexable_table->finish();
$this->add_indexes( $table_name );
$this->add_timestamps( $table_name );
}
/**
* Adds indexes to the indexable table.
*
* @param string $indexable_table_name The name of the indexable table.
*
* @return void
*/
private function add_indexes( $indexable_table_name ) {
$this->add_index(
$indexable_table_name,
[
'object_type',
'object_sub_type',
],
[
'name' => 'object_type_and_sub_type',
]
);
$this->add_index(
$indexable_table_name,
'permalink_hash',
[
'name' => 'permalink_hash',
]
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200728095334_AddIndexesForProminentWordsOnIndexables.php 0000644 00000002265 15121603254 0020777 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* AddIndexesForProminentWordsOnIndexables class.
*/
class AddIndexesForProminentWordsOnIndexables extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* The columns on which an index should be added.
*
* @var string[]
*/
private $columns_with_index = [
'prominent_words_version',
'object_type',
'object_sub_type',
'post_status',
];
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$adapter = $this->get_adapter();
if ( ! $adapter->has_index( $table_name, $this->columns_with_index, [ 'name' => 'prominent_words' ] ) ) {
$this->add_index(
$table_name,
$this->columns_with_index,
[
'name' => 'prominent_words',
]
);
}
}
/**
* Migration down.
*
* @return void
*/
public function down() {
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200702141921_CreateIndexableSubpagesIndex.php 0000644 00000002354 15121603254 0016573 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* CreateIndexableSubpagesIndex class.
*/
class CreateIndexableSubpagesIndex extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->change_column(
$this->get_table_name(),
'post_status',
'string',
[
'null' => true,
'limit' => 20,
]
);
$this->add_index(
$this->get_table_name(),
[ 'post_parent', 'object_type', 'post_status', 'object_id' ],
[ 'name' => 'subpages' ]
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->change_column(
$this->get_table_name(),
'post_status',
'string',
[
'null' => true,
'limit' => 191,
]
);
$this->remove_index(
$this->get_table_name(),
[ 'post_parent', 'object_type', 'post_status', 'object_id' ],
[ 'name' => 'subpages' ]
);
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20201202144329_AddEstimatedReadingTime.php 0000644 00000001703 15121603254 0015531 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* AddEstimatedReadingTime class.
*/
class AddEstimatedReadingTime extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$table_name = $this->get_table_name();
$this->add_column(
$table_name,
'estimated_reading_time_minutes',
'integer',
[
'null' => true,
'default' => null,
]
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$table_name = $this->get_table_name();
$this->remove_column( $table_name, 'estimated_reading_time_minutes' );
}
/**
* Retrieves the table name to use.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Indexable' );
}
}
migrations/20200609154515_AddHasAncestorsColumn.php 0000644 00000001661 15121603254 0015267 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
use Yoast\WP\SEO\WordPress\Wrapper;
/**
* Class AddHasAncestorsColumn.
*/
class AddHasAncestorsColumn extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* Migration up.
*
* @return void
*/
public function up() {
$this->add_column(
Model::get_table_name( 'Indexable' ),
'has_ancestors',
'boolean',
[
'default' => false,
]
);
Wrapper::get_wpdb()->query(
'
UPDATE ' . Model::get_table_name( 'Indexable' ) . '
SET has_ancestors = 1
WHERE id IN ( SELECT indexable_id FROM ' . Model::get_table_name( 'Indexable_Hierarchy' ) . ' )
'
);
}
/**
* Migration down.
*
* @return void
*/
public function down() {
$this->remove_column( Model::get_table_name( 'Indexable' ), 'has_ancestors' );
}
}
migrations/20201216141134_ExpandPrimaryTermIDColumnLengths.php 0000644 00000002005 15121603254 0017413 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config\Migrations;
use Yoast\WP\Lib\Migrations\Migration;
use Yoast\WP\Lib\Model;
/**
* ExpandPrimaryTermIDColumnLengths class.
*/
class ExpandPrimaryTermIDColumnLengths extends Migration {
/**
* The plugin this migration belongs to.
*
* @var string
*/
public static $plugin = 'free';
/**
* The columns to change the column type and length of.
*
* @var string[]
*/
protected static $columns_to_change = [
'post_id',
'term_id',
];
/**
* Migration up.
*
* @return void
*/
public function up() {
foreach ( self::$columns_to_change as $column ) {
$this->change_column(
$this->get_table_name(),
$column,
'biginteger',
[ 'limit' => 20 ]
);
}
}
/**
* Migration down.
*
* @return void
*/
public function down() {
}
/**
* Retrieves the table name to use for storing indexables.
*
* @return string The table name to use.
*/
protected function get_table_name() {
return Model::get_table_name( 'Primary_Term' );
}
}
researcher-languages.php 0000644 00000000523 15121603254 0011343 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Holds all languages supported with specific researches for our readability analysis.
*/
class Researcher_Languages {
public const SUPPORTED_LANGUAGES = [ 'ar', 'ca', 'de', 'en', 'es', 'fa', 'fr', 'he', 'hu', 'id', 'it', 'nb', 'nl', 'pl', 'pt', 'ru', 'sv', 'tr', 'cs', 'sk', 'el', 'ja' ];
}
badge-group-names.php 0000644 00000002771 15121603254 0010560 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Class Badge_Group_Names.
*
* This class defines groups for "new" badges, with the version in which those groups are no longer considered
* to be "new".
*/
class Badge_Group_Names {
public const GROUP_GLOBAL_TEMPLATES = 'global-templates';
/**
* Constant describing when certain groups of new badges will no longer be shown.
*/
public const GROUP_NAMES = [
self::GROUP_GLOBAL_TEMPLATES => '16.7-beta0',
];
/**
* The current plugin version.
*
* @var string
*/
protected $version;
/**
* Badge_Group_Names constructor.
*
* @param string|null $version Optional: the current plugin version.
*/
public function __construct( $version = null ) {
if ( ! $version ) {
$version = \WPSEO_VERSION;
}
$this->version = $version;
}
/**
* Check whether a group of badges is still eligible for a "new" badge.
*
* @param string $group One of the GROUP_* constants.
* @param string|null $current_version The current version of the plugin that's being checked.
*
* @return bool Whether a group of badges is still eligible for a "new" badge.
*/
public function is_still_eligible_for_new_badge( $group, $current_version = null ) {
if ( ! \array_key_exists( $group, $this::GROUP_NAMES ) ) {
return false;
}
$group_version = $this::GROUP_NAMES[ $group ];
if ( \is_null( $current_version ) ) {
$current_version = $this->version;
}
return (bool) \version_compare( $group_version, $current_version, '>' );
}
}
wincher-pkce-provider.php 0000644 00000016020 15121603254 0011462 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
use Exception;
use UnexpectedValueException;
use YoastSEO_Vendor\GuzzleHttp\Exception\BadResponseException;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\GenericProvider;
use YoastSEO_Vendor\League\OAuth2\Client\Token\AccessToken;
use YoastSEO_Vendor\League\OAuth2\Client\Token\AccessTokenInterface;
use YoastSEO_Vendor\League\OAuth2\Client\Tool\BearerAuthorizationTrait;
use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
use YoastSEO_Vendor\Psr\Log\InvalidArgumentException;
/**
* Class Wincher_PKCE_Provider
*
* @codeCoverageIgnore Ignoring as this class is purely a temporary wrapper until https://github.com/thephpleague/oauth2-client/pull/901 is merged.
*
* @phpcs:disable WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase -- This class extends an external class.
* @phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- This class extends an external class.
*/
class Wincher_PKCE_Provider extends GenericProvider {
use BearerAuthorizationTrait;
/**
* The method to use.
*
* @var string
*/
protected $pkceMethod = null;
/**
* The PKCE code.
*
* @var string
*/
protected $pkceCode;
/**
* Set the value of the pkceCode parameter.
*
* When using PKCE this should be set before requesting an access token.
*
* @param string $pkce_code The value for the pkceCode.
* @return self
*/
public function setPkceCode( $pkce_code ) {
$this->pkceCode = $pkce_code;
return $this;
}
/**
* Returns the current value of the pkceCode parameter.
*
* This can be accessed by the redirect handler during authorization.
*
* @return string
*/
public function getPkceCode() {
return $this->pkceCode;
}
/**
* Returns a new random string to use as PKCE code_verifier and
* hashed as code_challenge parameters in an authorization flow.
* Must be between 43 and 128 characters long.
*
* @param int $length Length of the random string to be generated.
*
* @return string
*
* @throws Exception Throws exception if an invalid value is passed to random_bytes.
*/
protected function getRandomPkceCode( $length = 64 ) {
return \substr(
\strtr(
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
\base64_encode( \random_bytes( $length ) ),
'+/',
'-_'
),
0,
$length
);
}
/**
* Returns the current value of the pkceMethod parameter.
*
* @return string|null
*/
protected function getPkceMethod() {
return $this->pkceMethod;
}
/**
* Returns authorization parameters based on provided options.
*
* @param array $options The options to use in the authorization parameters.
*
* @return array The authorization parameters
*
* @throws InvalidArgumentException Throws exception if an invalid PCKE method is passed in the options.
* @throws Exception When something goes wrong with generating the PKCE code.
*/
protected function getAuthorizationParameters( array $options ) {
if ( empty( $options['state'] ) ) {
$options['state'] = $this->getRandomState();
}
if ( empty( $options['scope'] ) ) {
$options['scope'] = $this->getDefaultScopes();
}
$options += [
'response_type' => 'code',
];
if ( \is_array( $options['scope'] ) ) {
$separator = $this->getScopeSeparator();
$options['scope'] = \implode( $separator, $options['scope'] );
}
// Store the state as it may need to be accessed later on.
$this->state = $options['state'];
$pkce_method = $this->getPkceMethod();
if ( ! empty( $pkce_method ) ) {
$this->pkceCode = $this->getRandomPkceCode();
if ( $pkce_method === 'S256' ) {
$options['code_challenge'] = \trim(
\strtr(
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
\base64_encode( \hash( 'sha256', $this->pkceCode, true ) ),
'+/',
'-_'
),
'='
);
}
elseif ( $pkce_method === 'plain' ) {
$options['code_challenge'] = $this->pkceCode;
}
else {
throw new InvalidArgumentException( 'Unknown PKCE method "' . $pkce_method . '".' );
}
$options['code_challenge_method'] = $pkce_method;
}
// Business code layer might set a different redirect_uri parameter.
// Depending on the context, leave it as-is.
if ( ! isset( $options['redirect_uri'] ) ) {
$options['redirect_uri'] = $this->redirectUri;
}
$options['client_id'] = $this->clientId;
return $options;
}
/**
* Requests an access token using a specified grant and option set.
*
* @param mixed $grant The grant to request access for.
* @param array $options The options to use with the current request.
*
* @return AccessToken|AccessTokenInterface The access token.
*
* @throws UnexpectedValueException Exception thrown if the provider response contains errors.
*/
public function getAccessToken( $grant, array $options = [] ) {
$grant = $this->verifyGrant( $grant );
$params = [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectUri,
];
if ( ! empty( $this->pkceCode ) ) {
$params['code_verifier'] = $this->pkceCode;
}
$params = $grant->prepareRequestParameters( $params, $options );
$request = $this->getAccessTokenRequest( $params );
$response = $this->getParsedResponse( $request );
if ( \is_array( $response ) === false ) {
throw new UnexpectedValueException(
'Invalid response received from Authorization Server. Expected JSON.'
);
}
$prepared = $this->prepareAccessTokenResponse( $response );
$token = $this->createAccessToken( $prepared, $grant );
return $token;
}
/**
* Returns all options that can be configured.
*
* @return array The configurable options.
*/
protected function getConfigurableOptions() {
return \array_merge(
$this->getRequiredOptions(),
[
'accessTokenMethod',
'accessTokenResourceOwnerId',
'scopeSeparator',
'responseError',
'responseCode',
'responseResourceOwnerId',
'scopes',
'pkceMethod',
]
);
}
/**
* Parses the request response.
*
* @param RequestInterface $request The request interface.
*
* @return array The parsed response.
*
* @throws IdentityProviderException Exception thrown if there is no proper identity provider.
*/
public function getParsedResponse( RequestInterface $request ) {
try {
$response = $this->getResponse( $request );
} catch ( BadResponseException $e ) {
$response = $e->getResponse();
}
$parsed = $this->parseResponse( $response );
$this->checkResponse( $response, $parsed );
// We always expect an array from the API except for on DELETE requests.
// We convert to an array here to prevent problems with array_key_exists on PHP8.
if ( ! \is_array( $parsed ) ) {
$parsed = [ 'data' => [] ];
}
// Add the response code as this is omitted from Winchers API.
if ( ! \array_key_exists( 'status', $parsed ) ) {
$parsed['status'] = $response->getStatusCode();
}
return $parsed;
}
}
conflicting-plugins.php 0000644 00000012443 15121603254 0011236 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Conflicting_Plugins class that holds all known conflicting plugins.
*/
class Conflicting_Plugins {
public const OPEN_GRAPH_PLUGINS = [
'2-click-socialmedia-buttons/2-click-socialmedia-buttons.php',
// 2 Click Social Media Buttons.
'add-link-to-facebook/add-link-to-facebook.php', // Add Link to Facebook.
'add-meta-tags/add-meta-tags.php', // Add Meta Tags.
'easy-facebook-share-thumbnails/esft.php', // Easy Facebook Share Thumbnail.
'facebook/facebook.php', // Facebook (official plugin).
'facebook-awd/AWD_facebook.php', // Facebook AWD All in one.
'facebook-featured-image-and-open-graph-meta-tags/fb-featured-image.php',
// Facebook Featured Image & OG Meta Tags.
'facebook-meta-tags/facebook-metatags.php', // Facebook Meta Tags.
'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
// Facebook Open Graph Meta Tags for WordPress.
'facebook-revised-open-graph-meta-tag/index.php', // Facebook Revised Open Graph Meta Tag.
'facebook-thumb-fixer/_facebook-thumb-fixer.php', // Facebook Thumb Fixer.
'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
// Fedmich's Facebook Open Graph Meta.
'network-publisher/networkpub.php', // Network Publisher.
'nextgen-facebook/nextgen-facebook.php', // NextGEN Facebook OG.
'opengraph/opengraph.php', // Open Graph.
'open-graph-protocol-framework/open-graph-protocol-framework.php',
// Open Graph Protocol Framework.
'seo-facebook-comments/seofacebook.php', // SEO Facebook Comments.
'sexybookmarks/sexy-bookmarks.php', // Shareaholic.
'shareaholic/sexy-bookmarks.php', // Shareaholic.
'sharepress/sharepress.php', // SharePress.
'simple-facebook-connect/sfc.php', // Simple Facebook Connect.
'social-discussions/social-discussions.php', // Social Discussions.
'social-sharing-toolkit/social_sharing_toolkit.php', // Social Sharing Toolkit.
'socialize/socialize.php', // Socialize.
'only-tweet-like-share-and-google-1/tweet-like-plusone.php',
// Tweet, Like, Google +1 and Share.
'wordbooker/wordbooker.php', // Wordbooker.
'wpsso/wpsso.php', // WordPress Social Sharing Optimization.
'wp-caregiver/wp-caregiver.php', // WP Caregiver.
'wp-facebook-like-send-open-graph-meta/wp-facebook-like-send-open-graph-meta.php',
// WP Facebook Like Send & Open Graph Meta.
'wp-facebook-open-graph-protocol/wp-facebook-ogp.php', // WP Facebook Open Graph protocol.
'wp-ogp/wp-ogp.php', // WP-OGP.
'zoltonorg-social-plugin/zosp.php', // Zolton.org Social Plugin.
];
public const XML_SITEMAPS_PLUGINS = [
'google-sitemap-plugin/google-sitemap-plugin.php',
// Google Sitemap (BestWebSoft).
'xml-sitemaps/xml-sitemaps.php',
// XML Sitemaps (Denis de Bernardy and Mike Koepke).
'bwp-google-xml-sitemaps/bwp-simple-gxs.php',
// Better WordPress Google XML Sitemaps (Khang Minh).
'google-sitemap-generator/sitemap.php',
// Google XML Sitemaps (Arne Brachhold).
'xml-sitemap-feed/xml-sitemap.php',
// XML Sitemap & Google News feeds (RavanH).
'google-monthly-xml-sitemap/monthly-xml-sitemap.php',
// Google Monthly XML Sitemap (Andrea Pernici).
'simple-google-sitemap-xml/simple-google-sitemap-xml.php',
// Simple Google Sitemap XML (iTx Technologies).
'another-simple-xml-sitemap/another-simple-xml-sitemap.php',
// Another Simple XML Sitemap.
'xml-maps/google-sitemap.php',
// Xml Sitemap (Jason Martens).
'google-xml-sitemap-generator-by-anton-dachauer/adachauer-google-xml-sitemap.php',
// Google XML Sitemap Generator by Anton Dachauer (Anton Dachauer).
'wp-xml-sitemap/wp-xml-sitemap.php',
// WP XML Sitemap (Team Vivacity).
'sitemap-generator-for-webmasters/sitemap.php',
// Sitemap Generator for Webmasters (iwebslogtech).
'xml-sitemap-xml-sitemapcouk/xmls.php',
// XML Sitemap - XML-Sitemap.co.uk (Simon Hancox).
'sewn-in-xml-sitemap/sewn-xml-sitemap.php',
// Sewn In XML Sitemap (jcow).
'rps-sitemap-generator/rps-sitemap-generator.php',
// RPS Sitemap Generator (redpixelstudios).
];
public const CLOAKING_PLUGINS = [
'rs-head-cleaner/rs-head-cleaner.php',
// RS Head Cleaner Plus https://wordpress.org/plugins/rs-head-cleaner/.
'rs-head-cleaner-lite/rs-head-cleaner-lite.php',
// RS Head Cleaner Lite https://wordpress.org/plugins/rs-head-cleaner-lite/.
];
public const SEO_PLUGINS = [
'all-in-one-seo-pack/all_in_one_seo_pack.php', // All in One SEO Pack.
'seo-ultimate/seo-ultimate.php', // SEO Ultimate.
'seo-by-rank-math/rank-math.php', // Rank Math.
];
/**
* Returns the list of all conflicting plugins.
*
* @return array The list of all conflicting plugins.
*/
public static function all_plugins() {
return \array_merge(
self::OPEN_GRAPH_PLUGINS,
self::XML_SITEMAPS_PLUGINS,
self::CLOAKING_PLUGINS,
self::SEO_PLUGINS
);
}
}
semrush-client.php 0000644 00000005172 15121603254 0010223 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
use Yoast\WP\SEO\Exceptions\OAuth\Authentication_Failed_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Property_Exception;
use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Token_Exception;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Wrappers\WP_Remote_Handler;
use YoastSEO_Vendor\GuzzleHttp\Client;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use YoastSEO_Vendor\League\OAuth2\Client\Provider\GenericProvider;
/**
* Class SEMrush_Client
*/
class SEMrush_Client extends OAuth_Client {
/**
* The option's key.
*/
public const TOKEN_OPTION = 'semrush_tokens';
/**
* SEMrush_Client constructor.
*
* @param Options_Helper $options_helper The Options_Helper instance.
* @param WP_Remote_Handler $wp_remote_handler The request handler.
*
* @throws Empty_Property_Exception Throws when one of the required properties is empty.
*/
public function __construct(
Options_Helper $options_helper,
WP_Remote_Handler $wp_remote_handler
) {
$provider = new GenericProvider(
[
'clientId' => 'yoast',
'clientSecret' => 'YdqNsWwnP4vE54WO1ugThKEjGMxMAHJt',
'redirectUri' => 'https://oauth.semrush.com/oauth2/yoast/success',
'urlAuthorize' => 'https://oauth.semrush.com/oauth2/authorize',
'urlAccessToken' => 'https://oauth.semrush.com/oauth2/access_token',
'urlResourceOwnerDetails' => 'https://oauth.semrush.com/oauth2/resource',
],
[
'httpClient' => new Client( [ 'handler' => $wp_remote_handler ] ),
]
);
parent::__construct(
self::TOKEN_OPTION,
$provider,
$options_helper
);
}
/**
* Performs the specified request.
*
* @codeCoverageIgnore
*
* @param string $method The HTTP method to use.
* @param string $url The URL to send the request to.
* @param array $options The options to pass along to the request.
*
* @return mixed The parsed API response.
*
* @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
* @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
* @throws Empty_Token_Exception Exception thrown if the token is empty.
*/
public function do_request( $method, $url, array $options ) {
// Add the access token to the GET parameters as well since this is what
// the SEMRush API expects.
$options = \array_merge_recursive(
$options,
[
'params' => [
'access_token' => $this->get_tokens()->access_token,
],
]
);
return parent::do_request( $method, $url, $options );
}
}
schema-ids.php 0000644 00000002103 15121603254 0007265 0 ustar 00 <?php
namespace Yoast\WP\SEO\Config;
/**
* Class Schema_IDs.
*/
class Schema_IDs {
/**
* Hash used for the Author `@id`.
*/
public const AUTHOR_HASH = '#author';
/**
* Hash used for the Author Logo's `@id`.
*/
public const AUTHOR_LOGO_HASH = '#authorlogo';
/**
* Hash used for the Breadcrumb's `@id`.
*/
public const BREADCRUMB_HASH = '#breadcrumb';
/**
* Hash used for the Person `@id`.
*/
public const PERSON_HASH = '#/schema/person/';
/**
* Hash used for the Article `@id`.
*/
public const ARTICLE_HASH = '#article';
/**
* Hash used for the Organization `@id`.
*/
public const ORGANIZATION_HASH = '#organization';
/**
* Hash used for the Organization `@id`.
*/
public const ORGANIZATION_LOGO_HASH = '#/schema/logo/image/';
/**
* Hash used for the logo `@id`.
*/
public const PERSON_LOGO_HASH = '#/schema/person/image/';
/**
* Hash used for an Article's primary image `@id`.
*/
public const PRIMARY_IMAGE_HASH = '#primaryimage';
/**
* Hash used for the Website's `@id`.
*/
public const WEBSITE_HASH = '#website';
}