plugins/wordpress-seo-extended/src/config/schema-ids.php                                            0000644                 00000002103 15122266560 0017422 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';
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                             plugins/wordpress-seo-extended/src/config/schema-types.php                                          0000644                 00000010002 15122266560 0020004 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',
				],
			]
		);
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              plugins/wordpress-seo-extended/src/config/semrush-client.php                                        0000644                 00000005172 15122266560 0020360 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 );
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                      plugins/wordpress-seo-extended/src/config/wincher-client.php                                        0000644                 00000007531 15122266560 0020332 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 );
	}
}
                                                                                                                                                                       plugins/wordpress-seo-extended/src/config/wincher-pkce-provider.php                                 0000644                 00000016020 15122266560 0021617 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;
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                plugins/wordpress-seo-extended/src/config/wordproof-app-config.php                                  0000644                 00000001015 15122266560 0021450 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Yoast\WP\SEO\Config;

use YoastSEO_Vendor\WordProof\SDK\Config\DefaultAppConfig;

/**
 * Class WordProof_App_Config.
 *
 * @package Yoast\WP\SEO\Config
 */
class Wordproof_App_Config extends DefaultAppConfig {

	/**
	 * Returns the partner.
	 *
	 * @return string The partner.
	 */
	public function getPartner() {
		return 'yoast';
	}

	/**
	 * Returns if the WordProof Uikit should be loaded from a cdn.
	 *
	 * @return bool True or false.
	 */
	public function getLoadUikitFromCdn() {
		return false;
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   plugins/wordpress-seo-extended/src/config/wordproof-translations.php                                0000644                 00000005003 15122266560 0022147 0                                                                                                    ustar 00                                                                                                                                                                                                                                                       <?php

namespace Yoast\WP\SEO\Config;

use YoastSEO_Vendor\WordProof\SDK\Translations\TranslationsInterface;

/**
 * Class WordProof_Translations
 *
 * @package Yoast\WP\SEO\Config
 */
class Wordproof_Translations implements TranslationsInterface {

	/**
	 * Returns no balance notice translation.
	 *
	 * @return string The translation.
	 */
	public function getNoBalanceNotice() {
		/* translators: %s expands to WordProof. */
		return \sprintf( \__( 'You are out of timestamps. Please upgrade your account by opening the %s settings.', 'wordpress-seo' ), 'WordProof' );
	}

	/**
	 * Returns no balance notice translation.
	 *
	 * @return string The translation.
	 */
	public function getTimestampSuccessNotice() {
		/* translators: %s expands to WordProof. */
		return \sprintf( \__( '%s has successfully timestamped this page.', 'wordpress-seo' ), 'WordProof' );
	}

	/**
	 * Returns timestamp failed notice translation.
	 *
	 * @return string The translation.
	 */
	public function getTimestampFailedNotice() {
		/* translators: %s expands to WordProof. */
		return \sprintf( \__( '%1$s failed to timestamp this page. Please check if you\'re correctly authenticated with %1$s and try to save this page again.', 'wordpress-seo' ), 'WordProof' );
	}

	/**
	 * Returns webhook failed notice translation.
	 *
	 * @return string The translation.
	 */
	public function getWebhookFailedNotice() {
		/* translators: %s expands to WordProof. */
		return \sprintf( \__( 'The timestamp is not retrieved by your site. Please try again or contact %1$s support.', 'wordpress-seo' ), 'WordProof' );
	}

	/**
	 * Returns no authentication notice translation.
	 *
	 * @return string The translation.
	 */
	public function getNotAuthenticatedNotice() {
		/* translators: %s expands to WordProof. */
		return \sprintf( \__( 'The timestamp is not created because you need to authenticate with %s first.', 'wordpress-seo' ), 'WordProof' );
	}

	/**
	 * Returns authenticate button text.
	 *
	 * @return string The translation.
	 */
	public function getOpenAuthenticationButtonText() {
		return \__( 'Open authentication', 'wordpress-seo' );
	}

	/**
	 * Returns open settings button translation.
	 *
	 * @return string The translation.
	 */
	public function getOpenSettingsButtonText() {
		return \__( 'Open settings', 'wordpress-seo' );
	}

	/**
	 * Returns get contact WordProof Support button translation.
	 *
	 * @return string The translation.
	 */
	public function getContactWordProofSupportButtonText() {
		return \__( 'Contact WordProof support', 'wordpress-seo' );
	}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             src/content-type-visibility/application/content-type-visibility-dismiss-notifications.php           0000644                 00000010522 15122266560 0034344 0                                                                                                    ustar 00                                                                                plugins/wordpress-seo-extended                                                                                                                                         <?php

namespace Yoast\WP\SEO\Content_Type_Visibility\Application;

use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast_Notification_Center;

/**
 * Handles dismissing notifications and "New" badges for new content types.
 */
class Content_Type_Visibility_Dismiss_Notifications {

	/**
	 * Holds the Options_Helper instance.
	 *
	 * @var Options_Helper
	 */
	private $options;

	/**
	 * Constructs Content_Type_Visibility_Dismiss_New_Route.
	 *
	 * @param Options_Helper $options The options helper.
	 */
	public function __construct( Options_Helper $options ) {
		$this->options = $options;
	}

	/**
	 * Removes New badge from a post type in the Settings, remove notifications if needed.
	 *
	 * @param string $post_type_name The post type name from the request.
	 * @return array The response.
	 */
	public function post_type_dismiss( $post_type_name ) {
		$success                 = true;
		$message                 = \__( 'Post type is not new.', 'wordpress-seo' );
		$post_types_needs_review = $this->options->get( 'new_post_types', [] );

		if ( $post_types_needs_review && \in_array( $post_type_name, $post_types_needs_review, true ) ) {
			$new_needs_review = \array_diff( $post_types_needs_review, [ $post_type_name ] );
			$success          = $this->options->set( 'new_post_types', $new_needs_review );
			$message          = ( $success ) ? \__( 'Post type is no longer new.', 'wordpress-seo' ) : \__( 'Error: Post type was not removed from new_post_types list.', 'wordpress-seo' );
			if ( $success ) {
				$this->maybe_dismiss_notifications( [ 'new_post_types' => $new_needs_review ] );
			}
		}

		$status = ( $success ) ? 200 : 400;

		return [
			'message' => $message,
			'success' => $success,
			'status'  => $status,
		];
	}

	/**
	 * Removes New badge from a taxonomy in the Settings, remove notifications if needed.
	 *
	 * @param string $taxonomy_name The taxonomy name from the request.
	 * @return array The response.
	 */
	public function taxonomy_dismiss( $taxonomy_name ) {
		$success                 = true;
		$message                 = \__( 'Taxonomy is not new.', 'wordpress-seo' );
		$taxonomies_needs_review = $this->options->get( 'new_taxonomies', [] );

		if ( \in_array( $taxonomy_name, $taxonomies_needs_review, true ) ) {

			$new_needs_review = \array_diff( $taxonomies_needs_review, [ $taxonomy_name ] );
			$success          = $this->options->set( 'new_taxonomies', $new_needs_review );
			$message          = ( $success ) ? \__( 'Taxonomy is no longer new.', 'wordpress-seo' ) : \__( 'Error: Taxonomy was not removed from new_taxonomies list.', 'wordpress-seo' );
			if ( $success ) {
				$this->maybe_dismiss_notifications( [ 'new_taxonomies' => $new_needs_review ] );
			}
		}

		$status = ( $success ) ? 200 : 400;

		return [
			'message' => $message,
			'success' => $success,
			'status'  => $status,
		];
	}

	/**
	 * Checks if there are new content types or taxonomies.
	 *
	 * @param array $new_content_types The new content types.
	 * @return void
	 */
	public function maybe_dismiss_notifications( $new_content_types = [] ) {

		$post_types_needs_review = ( \array_key_exists( 'new_post_types', $new_content_types ) ) ? $new_content_types['new_post_types'] : $this->options->get( 'new_post_types', [] );
		$taxonomies_needs_review = ( \array_key_exists( 'new_taxonomies', $new_content_types ) ) ? $new_content_types['new_taxonomies'] : $this->options->get( 'new_taxonomies', [] );

		if ( $post_types_needs_review || $taxonomies_needs_review ) {
			return;
		}
		$this->dismiss_notifications();
	}

	/**
	 * Dismisses the notification in the notification center when there are no more new content types.
	 *
	 * @return bool
	 */
	public function dismiss_notifications() {
		$notification_center = Yoast_Notification_Center::get();
		$notification_center->remove_notification_by_id( 'content-types-made-public' );
		return $this->options->set( 'show_new_content_type_notification', false );
	}

	/**
	 * Check if there is a new content type to show notification only once in the settings.
	 *
	 * @return bool Should the notification be shown.
	 */
	public function maybe_add_settings