Your IP : 216.73.216.162


Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/
Upload File :
Current File : /home/x/b/o/xbodynamge/namtation/wp-content/services.tar

class-file-size.php000066600000004653151123365500010264 0ustar00<?php
/**
 * WPSEO plugin file.
 *
 * @package WPSEO\Admin\Services
 */

/**
 * Represents the file size service.
 */
class WPSEO_File_Size_Service {

	/**
	 * Retrieves an indexable.
	 *
	 * @param WP_REST_Request $request The request object.
	 *
	 * @return WP_REST_Response The response.
	 */
	public function get( WP_REST_Request $request ) {
		try {
			$file_url = $this->get_file_url( $request );

			return new WP_REST_Response(
				[
					'type'          => 'success',
					'size_in_bytes' => $this->get_file_size( $file_url ),
				],
				200
			);
		}
		catch ( WPSEO_File_Size_Exception $exception ) {
			return new WP_REST_Response(
				[
					'type'     => 'failure',
					'response' => $exception->getMessage(),
				],
				404
			);
		}
	}

	/**
	 * Retrieves the file url.
	 *
	 * @param WP_REST_Request $request The request to retrieve file url from.
	 *
	 * @return string The file url.
	 * @throws WPSEO_File_Size_Exception The file is hosted externally.
	 */
	protected function get_file_url( WP_REST_Request $request ) {
		$file_url = rawurldecode( $request->get_param( 'url' ) );

		if ( ! $this->is_externally_hosted( $file_url ) ) {
			return $file_url;
		}

		throw WPSEO_File_Size_Exception::externally_hosted( $file_url );
	}

	/**
	 * Checks if the file is hosted externally.
	 *
	 * @param string $file_url The file url.
	 *
	 * @return bool True if it is hosted externally.
	 */
	protected function is_externally_hosted( $file_url ) {
		return wp_parse_url( home_url(), PHP_URL_HOST ) !== wp_parse_url( $file_url, PHP_URL_HOST );
	}

	/**
	 * Returns the file size.
	 *
	 * @param string $file_url The file url to get the size for.
	 *
	 * @return int The file size.
	 * @throws WPSEO_File_Size_Exception Retrieval of file size went wrong for unknown reasons.
	 */
	protected function get_file_size( $file_url ) {
		$file_config = wp_upload_dir();
		$file_url    = str_replace( $file_config['baseurl'], '', $file_url );
		$file_size   = $this->calculate_file_size( $file_url );

		if ( ! $file_size ) {
			throw WPSEO_File_Size_Exception::unknown_error( $file_url );
		}

		return $file_size;
	}

	/**
	 * Calculates the file size using the Utils class.
	 *
	 * @param string $file_url The file to retrieve the size for.
	 *
	 * @return int|bool The file size or False if it could not be retrieved.
	 */
	protected function calculate_file_size( $file_url ) {
		return WPSEO_Image_Utils::get_file_size(
			[
				'path' => $file_url,
			]
		);
	}
}
indexables/indexable-version-manager.php000066600000004440151126400520014423 0ustar00<?php

namespace Yoast\WP\SEO\Services\Indexables;

use Yoast\WP\SEO\Models\Indexable;
use Yoast\WP\SEO\Values\Indexables\Indexable_Builder_Versions;

/**
 * Handles version control for Indexables.
 */
class Indexable_Version_Manager {

	/**
	 * Stores the version of each Indexable type.
	 *
	 * @var Indexable_Builder_Versions The current versions of all indexable builders.
	 */
	protected $indexable_builder_versions;

	/**
	 * Indexable_Version_Manager constructor.
	 *
	 * @param Indexable_Builder_Versions $indexable_builder_versions The current versions of all indexable builders.
	 */
	public function __construct( Indexable_Builder_Versions $indexable_builder_versions ) {
		$this->indexable_builder_versions = $indexable_builder_versions;
	}

	/**
	 * Determines if an Indexable has a lower version than the builder for that Indexable's type.
	 *
	 * @param Indexable $indexable The Indexable to check.
	 *
	 * @return bool True if the given version is older than the current latest version.
	 */
	public function indexable_needs_upgrade( $indexable ) {
		if ( ( ! $indexable )
			|| ( ! \is_a( $indexable, Indexable::class ) )
		) {
			return false;
		}

		return $this->needs_upgrade( $indexable->object_type, $indexable->version );
	}

	/**
	 * Determines if an Indexable version for the type is lower than the current version for that Indexable type.
	 *
	 * @param string $object_type       The Indexable's object type.
	 * @param int    $indexable_version The Indexable's version.
	 *
	 * @return bool True if the given version is older than the current latest version.
	 */
	protected function needs_upgrade( $object_type, $indexable_version ) {
		$current_indexable_builder_version = $this->indexable_builder_versions->get_latest_version_for_type( $object_type );

		// If the Indexable's version is below the current version, that Indexable needs updating.
		return $indexable_version < $current_indexable_builder_version;
	}

	/**
	 * Sets an Indexable's version to the latest version.
	 *
	 * @param Indexable $indexable The Indexable to update.
	 *
	 * @return Indexable
	 */
	public function set_latest( $indexable ) {
		if ( ! $indexable ) {
			return $indexable;
		}

		$indexable->version = $this->indexable_builder_versions->get_latest_version_for_type( $indexable->object_type );

		return $indexable;
	}
}
indexables/.htaccess000066600000000424151126400520010460 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>health-check/postname-permalink-reports.php000066600000005247151126400520015107 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Presents a set of different messages for the Postname_Permalink health check.
 */
class Postname_Permalink_Reports {

	use Reports_Trait;

	/**
	 * Constructor.
	 *
	 * @param  Report_Builder_Factory $report_builder_factory The factory for result builder objects.
	 *                                                        This class uses the report builder to generate WordPress-friendly
	 *                                                        health check results.
	 */
	public function __construct( Report_Builder_Factory $report_builder_factory ) {
		$this->report_builder_factory = $report_builder_factory;
	}

	/**
	 * Returns the report for when permalinks are set to contain the post name.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_success_result() {
		return $this->get_report_builder()
			->set_label( \esc_html__( 'Your permalink structure includes the post name', 'wordpress-seo' ) )
			->set_status_good()
			->set_description( \__( 'You do have your postname in the URL of your posts and pages.', 'wordpress-seo' ) )
			->build();
	}

	/**
	 * Returns the report for when permalinks are not set to contain the post name.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_has_no_postname_in_permalink_result() {
		return $this->get_report_builder()
			->set_label( \__( 'You do not have your postname in the URL of your posts and pages', 'wordpress-seo' ) )
			->set_status_recommended()
			->set_description( $this->get_has_no_postname_in_permalink_description() )
			->set_actions( $this->get_has_no_postname_in_permalink_actions() )
			->build();
	}

	/**
	 * Returns the description for when permalinks are not set to contain the post name.
	 *
	 * @return string The description as a string.
	 */
	private function get_has_no_postname_in_permalink_description() {
		return \sprintf(
			/* translators: %s expands to '/%postname%/' */
			\__( 'It\'s highly recommended to have your postname in the URL of your posts and pages. Consider setting your permalink structure to %s.', 'wordpress-seo' ),
			'<strong>/%postname%/</strong>'
		);
	}

	/**
	 * Returns the actions for when permalinks are not set to contain the post name.
	 *
	 * @return string The actions as a string.
	 */
	private function get_has_no_postname_in_permalink_actions() {
		return \sprintf(
			/* translators: %1$s is a link start tag to the permalink settings page, %2$s is the link closing tag. */
			\__( 'You can fix this on the %1$sPermalink settings page%2$s.', 'wordpress-seo' ),
			'<a href="' . \admin_url( 'options-permalink.php' ) . '">',
			'</a>'
		);
	}
}
health-check/links-table-check.php000066600000002670151126400520013062 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Passes when the links table is accessible.
 */
class Links_Table_Check extends Health_Check {

	/**
	 * Runs the health check.
	 *
	 * @var Links_Table_Runner
	 */
	private $runner;

	/**
	 * Generates WordPress-friendly health check results.
	 *
	 * @var Links_Table_Reports
	 */
	private $reports;

	/**
	 * Constructor.
	 *
	 * @param Links_Table_Runner  $runner  The object that implements the actual health check.
	 * @param Links_Table_Reports $reports The object that generates WordPress-friendly results.
	 * @return void
	 */
	public function __construct(
		Links_Table_Runner $runner,
		Links_Table_Reports $reports
	) {
		$this->runner  = $runner;
		$this->reports = $reports;
		$this->reports->set_test_identifier( $this->get_test_identifier() );

		$this->set_runner( $this->runner );
	}

	/**
	 * Returns a human-readable label for this health check.
	 *
	 * @return string The human-readable label.
	 */
	public function get_test_label() {
		return \__( 'Links table', 'wordpress-seo' );
	}

	/**
	 * Returns the WordPress-friendly health check result.
	 *
	 * @return string[] The WordPress-friendly health check result.
	 */
	protected function get_result() {
		if ( ! $this->runner->should_run() ) {
			return [];
		}

		if ( $this->runner->is_successful() ) {
			return $this->reports->get_success_result();
		}

		return $this->reports->get_links_table_not_accessible_result();
	}
}
health-check/.htaccess000066600000000424151126400520010662 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>health-check/default-tagline-check.php000066600000002702151126400520013716 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Passes when the tagline is set to something other than the WordPress default tagline.
 */
class Default_Tagline_Check extends Health_Check {

	/**
	 * Runs the health check.
	 *
	 * @var Default_Tagline_Runner
	 */
	private $runner;

	/**
	 * Generates WordPress-friendly health check results.
	 *
	 * @var Default_Tagline_Reports
	 */
	private $reports;

	/**
	 * Constructor.
	 *
	 * @param  Default_Tagline_Runner  $runner  The object that implements the actual health check.
	 * @param  Default_Tagline_Reports $reports The object that generates WordPress-friendly results.
	 * @return void
	 */
	public function __construct(
		Default_Tagline_Runner $runner,
		Default_Tagline_Reports $reports
	) {
		$this->runner  = $runner;
		$this->reports = $reports;
		$this->reports->set_test_identifier( $this->get_test_identifier() );

		$this->set_runner( $this->runner );
	}

	/**
	 * Returns a human-readable label for this health check.
	 *
	 * @return string The human-readable label.
	 */
	public function get_test_label() {
		return \__( 'Default tagline', 'wordpress-seo' );
	}

	/**
	 * Returns the WordPress-friendly health check result.
	 *
	 * @return string[] The WordPress-friendly health check result.
	 */
	protected function get_result() {
		if ( $this->runner->is_successful() ) {
			return $this->reports->get_success_result();
		}

		return $this->reports->get_has_default_tagline_result();
	}
}
health-check/page-comments-check.php000066600000002635151126400520013415 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Paasses when comments are set to be on a single page.
 */
class Page_Comments_Check extends Health_Check {

	/**
	 * Runs the health check.
	 *
	 * @var Page_Comments_Runner
	 */
	private $runner;

	/**
	 * Generates WordPress-friendly health check results.
	 *
	 * @var Page_Comments_Reports
	 */
	private $reports;

	/**
	 * Constructor.
	 *
	 * @param  Page_Comments_Runner  $runner  The object that implements the actual health check.
	 * @param  Page_Comments_Reports $reports The object that generates WordPress-friendly results.
	 * @return void
	 */
	public function __construct(
		Page_Comments_Runner $runner,
		Page_Comments_Reports $reports
	) {
		$this->runner  = $runner;
		$this->reports = $reports;
		$this->reports->set_test_identifier( $this->get_test_identifier() );

		$this->set_runner( $this->runner );
	}

	/**
	 * Returns a human-readable label for this health check.
	 *
	 * @return string The human-readable label.
	 */
	public function get_test_label() {
		return \__( 'Page comments', 'wordpress-seo' );
	}

	/**
	 * Returns the WordPress-friendly health check result.
	 *
	 * @return string[] The WordPress-friendly health check result.
	 */
	protected function get_result() {
		if ( $this->runner->is_successful() ) {
			return $this->reports->get_success_result();
		}

		return $this->reports->get_has_comments_on_multiple_pages_result();
	}
}
health-check/health-check.php000066600000004657151126400520012131 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Abstract class for all health checks. Provides a uniform interface for the Health_Check_Integration.
 */
abstract class Health_Check {

	/**
	 * The prefix to add to the test identifier. Used to differentiate between Yoast's health checks, and other health checks.
	 */
	const TEST_IDENTIFIER_PREFIX = 'yoast-';

	/**
	 * The object that runs the actual health check.
	 *
	 * @var Runner_Interface
	 */
	private $runner;

	/**
	 * The health check implementation sets the runner so this class can start a health check.
	 *
	 * @param  Runner_Interface $runner The health check runner.
	 * @return void
	 */
	protected function set_runner( $runner ) {
		$this->runner = $runner;
	}

	/**
	 * Returns the identifier of health check implementation. WordPress needs this to manage the health check (https://developer.wordpress.org/reference/hooks/site_status_tests/).
	 *
	 * @return string The identifier that WordPress requires.
	 */
	public function get_test_identifier() {
		$full_class_name            = \get_class( $this );
		$class_name_backslash_index = \strrpos( $full_class_name, '\\' );

		$class_name = $full_class_name;
		if ( $class_name_backslash_index ) {
			$class_name_index = ( $class_name_backslash_index + 1 );
			$class_name       = \substr( $full_class_name, $class_name_index );
		}

		$lowercase            = \strtolower( $class_name );
		$whitespace_as_dashes = \str_replace( '_', '-', $lowercase );
		$with_prefix          = self::TEST_IDENTIFIER_PREFIX . $whitespace_as_dashes;
		return $with_prefix;
	}

	/**
	 * Returns the name of health check implementation that the user can see. WordPress needs this to manage the health check (https://developer.wordpress.org/reference/hooks/site_status_tests/).
	 *
	 * @return string A human-readable label for the health check.
	 */
	abstract public function get_test_label();

	/**
	 * Runs the health check, and returns its result in the format that WordPress requires to show the results to the user (https://developer.wordpress.org/reference/hooks/site_status_test_result/).
	 *
	 * @return string[] The array containing a WordPress site status report.
	 */
	public function run_and_get_result() {
		$this->runner->run();
		return $this->get_result();
	}

	/**
	 * Gets the result from the health check implementation.
	 *
	 * @return string[] The array containing a WordPress site status report.
	 */
	abstract protected function get_result();
}
health-check/report-builder-factory.php000066600000000720151126400520014200 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Creates Report_Builder instances.
 */
class Report_Builder_Factory {

	/**
	 * Creates a new Report_Builder instance.
	 *
	 * @param string $test_identifier The test identifier as a string.
	 * @return Report_Builder The new Report_Builder instance.
	 */
	public function create( $test_identifier ) {
		$instance = new Report_Builder();
		return $instance->set_test_identifier( $test_identifier );
	}
}
health-check/postname-permalink-runner.php000066600000001615151126400520014715 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Runs the Postname_Permalink health check.
 */
class Postname_Permalink_Runner implements Runner_Interface {

	/**
	 * Is set to true when permalinks are set to contain the post name
	 *
	 * @var bool
	 */
	private $permalinks_contain_postname;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->permalinks_contain_postname = false;
	}

	/**
	 * Runs the health check. Checks if permalinks are set to contain the post name.
	 *
	 * @return void
	 */
	public function run() {
		$this->permalinks_contain_postname = ( \strpos( \get_option( 'permalink_structure' ), '%postname%' ) !== false );
	}

	/**
	 * Returns true if permalinks are set to contain the post name.
	 *
	 * @return bool True if permalinks are set to contain the post name.
	 */
	public function is_successful() {
		return $this->permalinks_contain_postname;
	}
}

health-check/myyoast-api-request-factory.php000066600000000751151126400520015207 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use WPSEO_MyYoast_Api_Request;

/**
 * Creates WPSEO_MyYoast_Api_Request objects.
 */
class MyYoast_Api_Request_Factory {

	/**
	 * Creates a new WPSEO_MyYoast_API_Request.
	 *
	 * @param string $url  The URL for the request.
	 * @param array  $args Optional arguments for the request.
	 * @return WPSEO_MyYoast_Api_Request
	 */
	public function create( $url, $args = [] ) {
		return new WPSEO_MyYoast_Api_Request( $url, $args );
	}
}
health-check/links-table-reports.php000066600000006671151126400520013510 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use WPSEO_Admin_Utils;
use WPSEO_Shortlinker;

/**
 * Presents a set of different messages for the Links_Table health check.
 */
class Links_Table_Reports {

	use Reports_Trait;

	/**
	 * Shortlinker object used to create short links for reports.
	 *
	 * @var WPSEO_Shortlinker
	 */
	private $shortlinker;

	/**
	 * Constructor
	 *
	 * @param  Report_Builder_Factory $report_builder_factory The factory for result builder objects.
	 *                                                        This class uses the report builder to generate WordPress-friendly
	 *                                                        health check results.
	 * @param  WPSEO_Shortlinker      $shortlinker            Object used to add short links to the report description.
	 * @return void
	 */
	public function __construct(
		Report_Builder_Factory $report_builder_factory,
		WPSEO_Shortlinker $shortlinker
	) {
		$this->report_builder_factory = $report_builder_factory;
		$this->shortlinker            = $shortlinker;
	}

	/**
	 * Returns the message for a successful health check.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_success_result() {
		return $this->get_report_builder()
			->set_label( \__( 'The text link counter is working as expected', 'wordpress-seo' ) )
			->set_status_good()
			->set_description( $this->get_success_description() )
			->build();
	}

	/**
	 * Returns the message for a failed health check.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_links_table_not_accessible_result() {
		return $this->get_report_builder()
			->set_label( \__( 'The text link counter feature is not working as expected', 'wordpress-seo' ) )
			->set_status_recommended()
			->set_description( $this->get_links_table_not_accessible_description() )
			->set_actions( $this->get_actions() )
			->build();
	}

	/**
	 * Returns the description for when the health check was successful.
	 *
	 * @return string The description as a string.
	 */
	private function get_success_description() {
		return \sprintf(
			/* translators: 1: Link to the Yoast SEO blog, 2: Link closing tag. */
			\esc_html__( 'The text link counter helps you improve your site structure. %1$sFind out how the text link counter can enhance your SEO%2$s.', 'wordpress-seo' ),
			'<a href="' . $this->shortlinker->get( 'https://yoa.st/3zw' ) . '" target="_blank">',
			WPSEO_Admin_Utils::get_new_tab_message() . '</a>'
		);
	}

	/**
	 * Returns the description for when the health couldn't access the links table.
	 *
	 * @return string The description as a string.
	 */
	private function get_links_table_not_accessible_description() {
		return \sprintf(
			/* translators: 1: Yoast SEO. */
			\__( 'For this feature to work, %1$s needs to create a table in your database. We were unable to create this table automatically.', 'wordpress-seo' ),
			'Yoast SEO'
		);
	}

	/**
	 * Returns the actions that the user should take when the links table is not accessible.
	 *
	 * @return string The actions as a string.
	 */
	private function get_actions() {
		return \sprintf(
			/* translators: 1: Link to the Yoast help center, 2: Link closing tag. */
			\esc_html__( '%1$sFind out how to solve this problem on our help center%2$s.', 'wordpress-seo' ),
			'<a href="' . $this->shortlinker->get( 'https://yoa.st/3zv' ) . '" target="_blank">',
			WPSEO_Admin_Utils::get_new_tab_message() . '</a>'
		);
	}
}
health-check/page-comments-reports.php000066600000004611151126400520014032 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Presents a set of different messages for the Page_Comments health check.
 */
class Page_Comments_Reports {

	use Reports_Trait;

	/**
	 * Constructor.
	 *
	 * @param  Report_Builder_Factory $report_builder_factory The factory for result builder objects.
	 *                                                        This class uses the report builder to generate WordPress-friendly
	 *                                                        health check results.
	 */
	public function __construct( Report_Builder_Factory $report_builder_factory ) {
		$this->report_builder_factory = $report_builder_factory;
	}

	/**
	 * Returns the report for when comments are set to be all on one page.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_success_result() {
		return $this->get_report_builder()
			->set_label( \esc_html__( 'Comments are displayed on a single page', 'wordpress-seo' ) )
			->set_status_good()
			->set_description( \__( 'Comments on your posts are displayed on a single page. This is just like we\'d suggest it. You\'re doing well!', 'wordpress-seo' ) )
			->build();
	}

	/**
	 * Returns the report for when comments are set to be broken up across multiple pages.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_has_comments_on_multiple_pages_result() {
		return $this->get_report_builder()
			->set_label( \__( 'Comments break into multiple pages', 'wordpress-seo' ) )
			->set_status_recommended()
			->set_description( \__( 'Comments on your posts break into multiple pages. As this is not needed in 999 out of 1000 cases, we recommend you disable it. To fix this, uncheck "Break comments into pages..." on the Discussion Settings page.', 'wordpress-seo' ) )
			->set_actions( $this->get_has_comments_on_multiple_pages_actions() )
			->build();
	}

	/**
	 * Returns the actions for when the comments are set to be broken up across multiple pages.
	 *
	 * @return string The actions as a string.
	 */
	private function get_has_comments_on_multiple_pages_actions() {
		return \sprintf(
			/* translators: 1: Opening tag of the link to the discussion settings page, 2: Link closing tag. */
			\esc_html__( '%1$sGo to the Discussion Settings page%2$s', 'wordpress-seo' ),
			'<a href="' . \esc_url( \admin_url( 'options-discussion.php' ) ) . '">',
			'</a>'
		);
	}
}
health-check/links-table-runner.php000066600000004000151126400520013303 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use Yoast\WP\SEO\Config\Migration_Status;
use Yoast\WP\SEO\Helpers\Options_Helper;

/**
 * Runs the Links_Table health check.
 */
class Links_Table_Runner implements Runner_Interface {

	/**
	 * Is set to true when the links table is accessible.
	 *
	 * @var bool
	 */
	private $links_table_accessible = false;

	/**
	 * The Migration_Status object used to determine whether the links table is accessible.
	 *
	 * @var Migration_Status
	 */
	private $migration_status;

	/**
	 * The Options_Helper object used to determine whether the health check should run or not.
	 *
	 * @var Options_Helper
	 */
	private $options_helper;

	/**
	 * Constructor.
	 *
	 * @param Migration_Status $migration_status Object used to determine whether the links table is accessible.
	 * @param Options_Helper   $options_helper   Object used to determine whether the health check should run.
	 */
	public function __construct(
		Migration_Status $migration_status,
		Options_Helper $options_helper
	) {
		$this->migration_status = $migration_status;
		$this->options_helper   = $options_helper;
	}

	/**
	 * Runs the health check. Checks if the tagline is set to WordPress' default tagline, or to its set translation.
	 *
	 * @return void
	 */
	public function run() {
		if ( ! $this->should_run() ) {
			return;
		}

		$this->links_table_accessible = $this->migration_status->is_version( 'free', \WPSEO_VERSION );
	}

	/**
	 * Determines whether the health check should run or not.
	 *
	 * @return bool True if the text link counter feature is enabled.
	 */
	public function should_run() {
		$text_link_counter_enabled = $this->options_helper->get( 'enable_text_link_counter' );

		if ( ! \is_bool( $text_link_counter_enabled ) ) {
			return false;
		}

		return $text_link_counter_enabled;
	}

	/**
	 * Returns true if the links table is accessible
	 *
	 * @return bool The boolean indicating if the health check was succesful.
	 */
	public function is_successful() {
		return $this->links_table_accessible;
	}
}
health-check/page-comments-runner.php000066600000001504151126400520013643 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Runs the Page_Comments health check.
 */
class Page_Comments_Runner implements Runner_Interface {

	/**
	 * Is set to true when comments are set to display on a single page.
	 *
	 * @var bool
	 */
	private $comments_on_single_page;

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->comments_on_single_page = false;
	}

	/**
	 * Runs the health check. Checks if comments are displayed on a single page.
	 *
	 * @return void
	 */
	public function run() {
		$this->comments_on_single_page = \get_option( 'page_comments' ) !== '1';
	}

	/**
	 * Returns true if comments are displayed on a single page.
	 *
	 * @return bool True if comments are displayed on a single page.
	 */
	public function is_successful() {
		return $this->comments_on_single_page;
	}
}

health-check/default-tagline-reports.php000066600000004431151126400520014340 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Presents a set of different messages for the Default_Tagline health check.
 */
class Default_Tagline_Reports {

	use Reports_Trait;

	/**
	 * Constructor
	 *
	 * @param  Report_Builder_Factory $report_builder_factory The factory for result builder objects.
	 *                                                        This class uses the report builder to generate WordPress-friendly
	 *                                                        health check results.
	 * @return void
	 */
	public function __construct( Report_Builder_Factory $report_builder_factory ) {
		$this->report_builder_factory = $report_builder_factory;
	}

	/**
	 * Returns the message for a successful health check.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_success_result() {
		return $this->get_report_builder()
			->set_label( \__( 'You changed the default WordPress tagline', 'wordpress-seo' ) )
			->set_status_good()
			->set_description( \__( 'You are using a custom tagline or an empty one.', 'wordpress-seo' ) )
			->build();
	}

	/**
	 * Returns the message for a failed health check. In this case, when the user still has the default WordPress tagline set.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_has_default_tagline_result() {
		return $this->get_report_builder()
			->set_label( \__( 'You should change the default WordPress tagline', 'wordpress-seo' ) )
			->set_status_recommended()
			->set_description( \__( 'You still have the default WordPress tagline. Even an empty one is probably better.', 'wordpress-seo' ) )
			->set_actions( $this->get_actions() )
			->build();
	}

	/**
	 * Returns the actions that the user should take when his tagline is still set to the WordPress default.
	 *
	 * @return string The actions as an HTML string.
	 */
	private function get_actions() {
		$query_args    = [
			'autofocus[control]' => 'blogdescription',
		];
		$customize_url = \add_query_arg( $query_args, \wp_customize_url() );

		return \sprintf(
			/* translators: 1: link open tag; 2: link close tag. */
			\esc_html__( '%1$sYou can change the tagline in the customizer%2$s.', 'wordpress-seo' ),
			'<a href="' . \esc_url( $customize_url ) . '">',
			'</a>'
		);
	}
}
health-check/reports-trait.php000066600000001637151126400520012423 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Used by classes that use a health check Report_Builder.
 */
trait Reports_Trait {

	/**
	 * The factory for the builder object that generates WordPress-friendly test results.
	 *
	 * @var Report_Builder_Factory
	 */
	private $report_builder_factory;

	/**
	 * The test identifier that's set on the Report_Builder.
	 *
	 * @var string
	 */
	private $test_identifier = '';

	/**
	 * Sets the name that WordPress uses to identify this health check.
	 *
	 * @param  string $test_identifier The identifier.
	 * @return void
	 */
	public function set_test_identifier( $test_identifier ) {
		$this->test_identifier = $test_identifier;
	}

	/**
	 * Returns a new Report_Builder instance using the set test identifier.
	 *
	 * @return Report_Builder
	 */
	private function get_report_builder() {
		return $this->report_builder_factory->create( $this->test_identifier );
	}
}
health-check/report-builder.php000066600000011642151126400520012540 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Provides an interface to build WordPress-friendly health check results.
 */
class Report_Builder {

	/**
	 * Passed health check.
	 */
	const STATUS_GOOD = 'good';

	/**
	 * Changes are recommended but not necessary.
	 */
	const STATUS_RECOMMENDED = 'recommended';

	/**
	 * Significant issues that the user should consider fixing.
	 */
	const STATUS_CRITICAL = 'critical';

	/**
	 * The user-facing label.
	 *
	 * @var string
	 */
	private $label = '';

	/**
	 * The identifier that WordPress uses for the health check.
	 *
	 * @var string
	 */
	private $test_identifier = '';

	/**
	 * The test status (good, recommended, critical).
	 *
	 * @var string
	 */
	private $status = '';

	/**
	 * The short description for the result.
	 *
	 * @var string
	 */
	private $description = '';

	/**
	 * Actions that the user can take to solve the health check result.
	 *
	 * @var string
	 */
	private $actions = '';

	/**
	 * Sets the label for the health check that the user can see.
	 *
	 * @param  string $label The label that the user can see.
	 * @return Report_Builder This builder.
	 */
	public function set_label( $label ) {
		$this->label = $label;
		return $this;
	}

	/**
	 * Sets the name for the test that the plugin uses to identify the test.
	 *
	 * @param  string $test_identifier The identifier for the health check.
	 * @return Report_Builder This builder.
	 */
	public function set_test_identifier( $test_identifier ) {
		$this->test_identifier = $test_identifier;
		return $this;
	}

	/**
	 * Sets the status of the test result to GOOD (green label).
	 *
	 * @return Report_Builder This builder.
	 */
	public function set_status_good() {
		$this->status = self::STATUS_GOOD;
		return $this;
	}

	/**
	 * Sets the status of the test result to RECOMMENDED (orange label).
	 *
	 * @return Report_Builder This builder.
	 */
	public function set_status_recommended() {
		$this->status = self::STATUS_RECOMMENDED;
		return $this;
	}

	/**
	 * Sets the status of the test result to CRITICAL (red label).
	 *
	 * @return Report_Builder This builder.
	 */
	public function set_status_critical() {
		$this->status = self::STATUS_CRITICAL;
		return $this;
	}

	/**
	 * Sets a description for the test result. This will be the heading for the result in the user interface.
	 *
	 * @param  string $description The description for the test result.
	 * @return Report_Builder This builder.
	 */
	public function set_description( $description ) {
		$this->description = $description;
		return $this;
	}

	/**
	 * Sets a text that describes how the user can solve the failed health check.
	 *
	 * @param  string $actions The descriptive text.
	 * @return Report_Builder This builder.
	 */
	public function set_actions( $actions ) {
		$this->actions = $actions;
		return $this;
	}

	/**
	 * Builds an array of strings in the format that WordPress uses to display health checks (https://developer.wordpress.org/reference/hooks/site_status_test_result/).
	 *
	 * @return array The report in WordPress' site status report format.
	 */
	public function build() {
		return [
			'label'       => $this->label,
			'status'      => $this->status,
			'badge'       => $this->get_badge(),
			'description' => $this->description,
			'actions'     => $this->get_actions_with_signature(),
			'test'        => $this->test_identifier,
		];
	}

	/**
	 * Generates a badge that the user can see.
	 *
	 * @return string[] The badge.
	 */
	private function get_badge() {
		return [
			'label' => $this->get_badge_label(),
			'color' => $this->get_badge_color(),
		];
	}

	/**
	 * Generates the label for a badge.
	 *
	 * @return string The badge label.
	 */
	private function get_badge_label() {
		return \__( 'SEO', 'wordpress-seo' );
	}

	/**
	 * Generates the color for the badge using the current status.
	 *
	 * @return string The color for the badge's outline.
	 */
	private function get_badge_color() {
		if ( $this->status === self::STATUS_CRITICAL || $this->status === self::STATUS_RECOMMENDED ) {
			return 'red';
		}

		return 'blue';
	}

	/**
	 * Concatenates the set actions with Yoast's signature.
	 *
	 * @return string A string containing the set actions and Yoast's signature.
	 */
	private function get_actions_with_signature() {
		return $this->actions . $this->get_signature();
	}

	/**
	 * Generates Yoast's signature that's displayed at the bottom of the health check result.
	 *
	 * @return string Yoast's signature as an HTML string.
	 */
	private function get_signature() {
		return \sprintf(
			/* translators: 1: Start of a paragraph beginning with the Yoast icon, 2: Expands to 'Yoast SEO', 3: Paragraph closing tag. */
			\esc_html__( '%1$sThis was reported by the %2$s plugin%3$s', 'wordpress-seo' ),
			'<p class="yoast-site-health__signature"><img src="' . \esc_url( \plugin_dir_url( \WPSEO_FILE ) . 'packages/js/images/Yoast_SEO_Icon.svg' ) . '" alt="" height="20" width="20" class="yoast-site-health__signature-icon">',
			'Yoast SEO',
			'</p>'
		);
	}
}
health-check/default-tagline-runner.php000066600000002156151126400520014155 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Runs the Default_Tagline health check.
 */
class Default_Tagline_Runner implements Runner_Interface {

	/**
	 * The default WordPress tagline.
	 */
	const DEFAULT_BLOG_DESCRIPTION = 'Just another WordPress site';

	/**
	 * Is set to true when the default tagline is set.
	 *
	 * @var bool
	 */
	private $has_default_tagline = true;

	/**
	 * Runs the health check. Checks if the tagline is set to WordPress' default tagline, or to its set translation.
	 *
	 * @return void
	 */
	public function run() {
		$blog_description = \get_option( 'blogdescription' );

		// We are using the WordPress internal translation.
		$translated_blog_description = \__( 'Just another WordPress site', 'default' );

		$this->has_default_tagline = $translated_blog_description === $blog_description || $blog_description === self::DEFAULT_BLOG_DESCRIPTION;
	}

	/**
	 * Returns true if the tagline is set to a non-default tagline.
	 *
	 * @return bool The boolean indicating if the health check was succesful.
	 */
	public function is_successful() {
		return ! $this->has_default_tagline;
	}
}
health-check/runner-interface.php000066600000000425151126400520013045 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Interface for the health check runner. The abstract Health_Check uses this to run a health check.
 */
interface Runner_Interface {

	/**
	 * Runs the health check.
	 *
	 * @return void
	 */
	public function run();
}
health-check/postname-permalink-check.php000066600000002707151126400520014464 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Paasses when permalinks are set to contain the post name.
 */
class Postname_Permalink_Check extends Health_Check {

	/**
	 * Runs the health check.
	 *
	 * @var Postname_Permalink_Runner
	 */
	private $runner;

	/**
	 * Generates WordPress-friendly health check results.
	 *
	 * @var Postname_Permalink_Reports
	 */
	private $reports;

	/**
	 * Constructor.
	 *
	 * @param  Postname_Permalink_Runner  $runner  The object that implements the actual health check.
	 * @param  Postname_Permalink_Reports $reports The object that generates WordPress-friendly results.
	 * @return void
	 */
	public function __construct(
		Postname_Permalink_Runner $runner,
		Postname_Permalink_Reports $reports
	) {
		$this->runner  = $runner;
		$this->reports = $reports;
		$this->reports->set_test_identifier( $this->get_test_identifier() );

		$this->set_runner( $this->runner );
	}

	/**
	 * Returns a human-readable label for this health check.
	 *
	 * @return string The human-readable label.
	 */
	public function get_test_label() {
		return \__( 'Postname permalink', 'wordpress-seo' );
	}

	/**
	 * Returns the WordPress-friendly health check result.
	 *
	 * @return string[] The WordPress-friendly health check result.
	 */
	protected function get_result() {
		if ( $this->runner->is_successful() ) {
			return $this->reports->get_success_result();
		}

		return $this->reports->get_has_no_postname_in_permalink_result();
	}
}
importing/aioseo/aioseo-replacevar-service.php000066600000006637151126400520015617 0ustar00<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Given it's a very specific case.
namespace Yoast\WP\SEO\Services\Importing\Aioseo;

/**
 * Replaces AISOEO replacevars with Yoast ones.
 */
class Aioseo_Replacevar_Service {

	/**
	 * Mapping between the AiOSEO replace vars and the Yoast replace vars.
	 *
	 * @var array
	 *
	 * @see https://yoast.com/help/list-available-snippet-variables-yoast-seo/
	 */
	protected $replace_vars_map = [
		// The key is the AiOSEO replace var, the value is the Yoast replace var (see class-wpseo-replace-vars).
		'#archive_title'             => '%%archive_title%%',
		'#archive_date'              => '%%date%%',
		'#attachment_caption'        => '%%caption%%',
		'#author_bio'                => '%%user_description%%',
		'#author_first_name'         => '%%author_first_name%%',
		'#author_last_name'          => '%%author_last_name%%',
		'#author_name'               => '%%name%%',
		'#blog_title'                => '%%sitename%%', // Same with #site_title.
		'#categories'                => '%%category%%',
		'#current_date'              => '%%currentdate%%',
		'#current_day'               => '%%currentday%%',
		'#current_month'             => '%%currentmonth%%',
		'#current_year'              => '%%currentyear%%',
		'#parent_title'              => '%%parent_title%%',
		'#page_number'               => '%%pagenumber%%',
		'#permalink'                 => '%%permalink%%',
		'#post_content'              => '%%post_content%%',
		'#post_date'                 => '%%date%%',
		'#post_day'                  => '%%post_day%%',
		'#post_month'                => '%%post_month%%',
		'#post_title'                => '%%title%%',
		'#post_year'                 => '%%post_year%%',
		'#post_excerpt_only'         => '%%excerpt_only%%',
		'#post_excerpt'              => '%%excerpt%%',
		'#search_term'               => '%%searchphrase%%',
		'#separator_sa'              => '%%sep%%',
		'#site_title'                => '%%sitename%%',
		'#tagline'                   => '%%sitedesc%%',
		'#taxonomy_title'            => '%%category_title%%',
		'#taxonomy_description'      => '%%term_description%%',
	];

	/**
	 * Edits the replace_vars map of the class.
	 *
	 * @param string $aioseo_var The AIOSEO replacevar.
	 * @param string $yoast_var  The Yoast replacevar.
	 *
	 * @return void
	 */
	public function compose_map( $aioseo_var, $yoast_var ) {
		$map = $this->replace_vars_map;

		$map[ $aioseo_var ] = $yoast_var;

		$this->replace_vars_map = $map;
	}

	/**
	 * Transforms AIOSEO replacevars into Yoast replacevars.
	 *
	 * @param string $aioseo_replacevar The AIOSEO replacevar.
	 *
	 * @return string The Yoast replacevar.
	 */
	public function transform( $aioseo_replacevar ) {
		$yoast_replacevar = \str_replace( \array_keys( $this->replace_vars_map ), \array_values( $this->replace_vars_map ), $aioseo_replacevar );

		// Transform the '#custom_field-<custom_field>' tags into '%%cf_<custom_field>%%' ones.
		$yoast_replacevar = \preg_replace_callback(
			'/#custom_field-([a-zA-Z0-9_-]+)/',
			static function ( $cf_matches ) {
				return '%%cf_' . $cf_matches[1] . '%%';
			},
			$yoast_replacevar
		);

		// Transform the '#tax_name-<custom-tax-name>' tags into '%%ct_<custom-tax-name>%%' ones.
		$yoast_replacevar = \preg_replace_callback(
			'/#tax_name-([a-zA-Z0-9_-]+)/',
			static function ( $ct_matches ) {
				return '%%ct_' . $ct_matches[1] . '%%';
			},
			$yoast_replacevar
		);

		return $yoast_replacevar;
	}
}
importing/aioseo/.htaccess000066600000000424151126400520011631 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>importing/aioseo/aioseo-social-images-provider-service.php000066600000010653151126400520020031 0ustar00<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Given it's a very specific case.
namespace Yoast\WP\SEO\Services\Importing\Aioseo;

use Yoast\WP\SEO\Helpers\Aioseo_Helper;
use Yoast\WP\SEO\Helpers\Image_Helper;

/**
 * Provides AISOEO social images urls.
 */
class Aioseo_Social_Images_Provider_Service {

	/**
	 * The AIOSEO helper.
	 *
	 * @var Aioseo_Helper
	 */
	protected $aioseo_helper;

	/**
	 * The image helper.
	 *
	 * @var Image_Helper
	 */
	protected $image;

	/**
	 * Class constructor.
	 *
	 * @param Aioseo_Helper $aioseo_helper The AIOSEO helper.
	 * @param Image_Helper  $image         The image helper.
	 */
	public function __construct(
		Aioseo_Helper $aioseo_helper,
		Image_Helper $image
	) {
		$this->aioseo_helper = $aioseo_helper;
		$this->image         = $image;
	}

	/**
	 * Retrieves the default source of social images.
	 *
	 * @param string $social_setting The social settings we're working with, eg. open-graph or twitter.
	 *
	 * @return string The default source of social images.
	 */
	public function get_default_social_image_source( $social_setting ) {
		return $this->get_social_defaults( 'source', $social_setting );
	}

	/**
	 * Retrieves the default custom social image if there is any.
	 *
	 * @param string $social_setting The social settings we're working with, eg. open-graph or twitter.
	 *
	 * @return string The global default social image.
	 */
	public function get_default_custom_social_image( $social_setting ) {
		return $this->get_social_defaults( 'custom_image', $social_setting );
	}

	/**
	 * Retrieves social defaults, be it Default Post Image Source or Default Post Image.
	 *
	 * @param string $setting        The setting we want, eg. source or custom image.
	 * @param string $social_setting The social settings we're working with, eg. open-graph or twitter.
	 *
	 * @return string The social default.
	 */
	public function get_social_defaults( $setting, $social_setting ) {
		switch ( $setting ) {
			case 'source':
				$setting_key = 'defaultImageSourcePosts';
				break;
			case 'custom_image':
				$setting_key = 'defaultImagePosts';
				break;
			default:
				return '';
		}

		$aioseo_settings = $this->aioseo_helper->get_global_option();

		if ( $social_setting === 'og' ) {
			$social_setting = 'facebook';
		}

		if ( ! isset( $aioseo_settings['social'][ $social_setting ]['general'][ $setting_key ] ) ) {
			return '';
		}

		return $aioseo_settings['social'][ $social_setting ]['general'][ $setting_key ];
	}

	/**
	 * Retrieves the url of the first image in content.
	 *
	 * @param int $post_id The post id to extract the image from.
	 *
	 * @return string The url of the first image in content.
	 */
	public function get_first_image_in_content( $post_id ) {
		$image = $this->image->get_gallery_image( $post_id );

		if ( ! $image ) {
			$image = $this->image->get_post_content_image( $post_id );
		}

		return $image;
	}

	/**
	 * Retrieves the url of the first attached image.
	 *
	 * @param int $post_id The post id to extract the image from.
	 *
	 * @return string The url of the first attached image.
	 */
	public function get_first_attached_image( $post_id ) {
		if ( \get_post_type( $post_id ) === 'attachment' ) {
			return $this->image->get_attachment_image_source( $post_id, 'fullsize' );
		}

		$attachments = \get_children(
			[
				'post_parent'    => $post_id,
				'post_status'    => 'inherit',
				'post_type'      => 'attachment',
				'post_mime_type' => 'image',
			]
		);

		if ( $attachments && ! empty( $attachments ) ) {
			return $this->image->get_attachment_image_source( \array_values( $attachments )[0]->ID, 'fullsize' );
		}

		return '';
	}

	/**
	 * Retrieves the url of the featured image.
	 *
	 * @param int $post_id The post id to extract the image from.
	 *
	 * @return string The url of the featured image.
	 */
	public function get_featured_image( $post_id ) {
		$feature_image_id = \get_post_thumbnail_id( $post_id );

		if ( $feature_image_id ) {
			return $this->image->get_attachment_image_source( $feature_image_id, 'fullsize' );
		}

		return '';
	}

	/**
	 * Retrieves the url of the first available image. Tries each image source to get one image.
	 *
	 * @param int $post_id The post id to extract the image from.
	 *
	 * @return string The url of the featured image.
	 */
	public function get_auto_image( $post_id ) {
		$image = $this->get_first_attached_image( $post_id );

		if ( ! $image ) {
			$image = $this->get_first_image_in_content( $post_id );
		}

		return $image;
	}
}
importing/aioseo/aioseo-robots-transformer-service.php000066600000003326151126400520017333 0ustar00<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Given it's a very specific case.
namespace Yoast\WP\SEO\Services\Importing\Aioseo;

/**
 * Transforms AISOEO search appearance robot settings.
 */
class Aioseo_Robots_Transformer_Service {

	/**
	 * The robots transfomer service.
	 *
	 * @var Aioseo_Robots_Provider_Service
	 */
	protected $robots_provider;

	/**
	 * Class constructor.
	 *
	 * @param Aioseo_Robots_Provider_Service $robots_provider The robots provider service.
	 */
	public function __construct(
		Aioseo_Robots_Provider_Service $robots_provider
	) {
		$this->robots_provider = $robots_provider;
	}

	/**
	 * Transforms the robot setting, taking into consideration whether they defer to global defaults.
	 *
	 * @param string $setting_name  The name of the robot setting, eg. noindex.
	 * @param bool   $setting_value The value of the robot setting.
	 * @param array  $mapping       The mapping of the setting we're working with.
	 *
	 * @return bool The transformed robot setting.
	 */
	public function transform_robot_setting( $setting_name, $setting_value, $mapping ) {
		$aioseo_settings = \json_decode( \get_option( $mapping['option_name'], '' ), true );

		// Let's check first if it defers to global robot settings.
		if ( empty( $aioseo_settings ) || ! isset( $aioseo_settings['searchAppearance'][ $mapping['type'] ][ $mapping['subtype'] ]['advanced']['robotsMeta']['default'] ) ) {
			return $setting_value;
		}

		$defers_to_defaults = $aioseo_settings['searchAppearance'][ $mapping['type'] ][ $mapping['subtype'] ]['advanced']['robotsMeta']['default'];

		if ( $defers_to_defaults ) {
			return $this->robots_provider->get_global_robot_settings( $setting_name );
		}

		return $setting_value;
	}
}
importing/aioseo/aioseo-robots-provider-service.php000066600000003254151126400520016623 0ustar00<?php

// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Given it's a very specific case.
namespace Yoast\WP\SEO\Services\Importing\Aioseo;

use Yoast\WP\SEO\Helpers\Aioseo_Helper;

/**
 * Provides AISOEO search appearance robot settings.
 */
class Aioseo_Robots_Provider_Service {

	/**
	 * The AIOSEO helper.
	 *
	 * @var Aioseo_Helper
	 */
	protected $aioseo_helper;

	/**
	 * Class constructor.
	 *
	 * @param Aioseo_Helper $aioseo_helper The AIOSEO helper.
	 */
	public function __construct(
		Aioseo_Helper $aioseo_helper
	) {
		$this->aioseo_helper = $aioseo_helper;
	}

	/**
	 * Retrieves the robot setting set globally in AIOSEO.
	 *
	 * @param string $setting_name The name of the robot setting, eg. noindex.
	 *
	 * @return bool Whether global robot settings enable or not the specific setting.
	 */
	public function get_global_robot_settings( $setting_name ) {
		$aioseo_settings = $this->aioseo_helper->get_global_option();
		if ( empty( $aioseo_settings ) ) {
			return false;
		}

		$global_robot_settings = $aioseo_settings['searchAppearance']['advanced']['globalRobotsMeta'];
		if ( $global_robot_settings['default'] === true ) {
			return false;
		}

		return $global_robot_settings[ $setting_name ];
	}

	/**
	 * Gets the subtype's robot setting from the db.
	 *
	 * @param array $mapping The mapping of the setting we're working with.
	 *
	 * @return bool The robot setting.
	 */
	public function get_subtype_robot_setting( $mapping ) {
		$aioseo_settings = \json_decode( \get_option( $mapping['option_name'], '' ), true );

		return $aioseo_settings['searchAppearance'][ $mapping['type'] ][ $mapping['subtype'] ]['advanced']['robotsMeta'][ $mapping['robot_type'] ];
	}
}
importing/conflicting-plugins-service.php000066600000005711151126400520014705 0ustar00<?php

namespace Yoast\WP\SEO\Services\Importing;

use Yoast\WP\SEO\Config\Conflicting_Plugins;

/**
 * Detects plugin conflicts.
 */
class Conflicting_Plugins_Service {

	/**
	 * Detects the conflicting plugins.
	 *
	 * @return array A list of all active conflicting plugins.
	 */
	public function detect_conflicting_plugins() {
		$all_active_plugins = $this->get_active_plugins();

		// Search for active plugins.
		return $this->get_active_conflicting_plugins( $all_active_plugins );
	}

	/**
	 * Deactivates the specified plugin(s) if any, or the entire list of known conflicting plugins.
	 *
	 * @param string|array|false $plugins Optional. The plugin filename, or array of plugin filenames, to deactivate.
	 */
	public function deactivate_conflicting_plugins( $plugins = false ) {
		// If no plugins are specified, deactivate any known conflicting plugins that are active.
		if ( ! $plugins ) {
			$plugins = $this->detect_conflicting_plugins();
		}

		// In case of a single plugin, wrap it in an array.
		if ( \is_string( $plugins ) ) {
			$plugins = [ $plugins ];
		}

		if ( ! \is_array( $plugins ) ) {
			return;
		}

		// Deactivate all specified plugins across the network, while retaining their deactivation hook.
		\deactivate_plugins( $plugins );
	}

	/**
	 * Loop through the list of known conflicting plugins to check if one of the plugins is active.
	 *
	 * @param array $all_active_plugins All plugins loaded by WordPress.
	 *
	 * @return array The array of activated conflicting plugins.
	 */
	protected function get_active_conflicting_plugins( $all_active_plugins ) {
		$active_conflicting_plugins = [];

		foreach ( Conflicting_Plugins::all_plugins() as $plugin ) {
			if ( \in_array( $plugin, $all_active_plugins, true ) ) {
				$active_conflicting_plugins[] = $plugin;
			}
		}

		return $active_conflicting_plugins;
	}

	/**
	 * Get a list of all plugins active in the current WordPress instance.
	 *
	 * @return false|array The names of all active plugins.
	 */
	protected function get_active_plugins() {
		// Request a list of active plugins from WordPress.
		$all_active_plugins = \get_option( 'active_plugins' );

		return $this->ignore_deactivating_plugin( $all_active_plugins );
	}

	/**
	 * While deactivating a plugin, we should ignore the plugin currently being deactivated.
	 *
	 * @param array $all_active_plugins All plugins currently loaded by WordPress.
	 *
	 * @return array The remaining active plugins.
	 */
	protected function ignore_deactivating_plugin( $all_active_plugins ) {
		if ( isset( $_GET['action'] ) && isset( $_GET['plugin'] ) && \filter_var( \wp_unslash( $_GET['action'] ) ) === 'deactivate' ) {
			$deactivated_plugin = \filter_var( \wp_unslash( $_GET['plugin'] ) );

			\check_admin_referer( 'deactivate-plugin_' . $deactivated_plugin );

			$key_to_remove = \array_search( $deactivated_plugin, $all_active_plugins, true );
			if ( $key_to_remove !== false ) {
				unset( $all_active_plugins[ $key_to_remove ] );
			}
		}

		return $all_active_plugins;
	}
}
importing/.htaccess000066600000000424151126400520010352 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>importing/importable-detector-service.php000066600000005030151126400520014666 0ustar00<?php

namespace Yoast\WP\SEO\Services\Importing;

use Yoast\WP\SEO\Actions\Importing\Importing_Action_Interface;

/**
 * Detects if any data from other SEO plugins is available for importing.
 */
class Importable_Detector_Service {

	/**
	 * All known import actions
	 *
	 * @var array|Importing_Action_Interface[]
	 */
	protected $importers;

	/**
	 * Importable_Detector_Service constructor.
	 *
	 * @param Importing_Action_Interface ...$importers All of the known importers.
	 */
	public function __construct( Importing_Action_Interface ...$importers ) {
		$this->importers = $importers;
	}

	/**
	 * Returns the detected importers that have data to work with.
	 *
	 * @param string|null $plugin The plugin name of the importer.
	 * @param string|null $type   The type of the importer.
	 *
	 * @return array The detected importers that have data to work with.
	 */
	public function detect_importers( $plugin = null, $type = null ) {
		$detectors = $this->filter_actions( $this->importers, $plugin, $type );

		$detected = [];
		foreach ( $detectors as $detector ) {
			if ( $detector->is_enabled() && $detector->get_type() !== 'cleanup' && ! $detector->get_completed() && $detector->get_limited_unindexed_count( 1 ) > 0 ) {
				$detected[ $detector->get_plugin() ][] = $detector->get_type();
			}
		}

		return $detected;
	}

	/**
	 * Returns the detected cleanups that have data to work with.
	 *
	 * @param string|null $plugin The plugin name of the cleanup.
	 *
	 * @return array The detected importers that have data to work with.
	 */
	public function detect_cleanups( $plugin = null ) {
		$detectors = $this->filter_actions( $this->importers, $plugin, 'cleanup' );

		$detected = [];
		foreach ( $detectors as $detector ) {
			if ( $detector->is_enabled() && ! $detector->get_completed() && $detector->get_limited_unindexed_count( 1 ) > 0 ) {
				$detected[ $detector->get_plugin() ][] = $detector->get_type();
			}
		}

		return $detected;
	}

	/**
	 * Filters all import actions from a list that do not match the given Plugin or Type.
	 *
	 * @param Importing_Action_Interface[] $all_actions The complete list of actions.
	 * @param string|null                  $plugin      The Plugin name whose actions to keep.
	 * @param string|null                  $type        The type of actions to keep.
	 *
	 * @return array
	 */
	public function filter_actions( $all_actions, $plugin = null, $type = null ) {
		return \array_filter(
			$all_actions,
			static function( $action ) use ( $plugin, $type ) {
				return $action->is_compatible_with( $plugin, $type );
			}
		);
	}
}
.htaccess000066600000000424151126400520006342 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>services.php000066600000016317151140765430007122 0ustar00<?php
/**
 * Services module.
 *
 * @package themeisle-companion
 */

// Get the module directory.
$module_directory = $this->get_dir();

// Include common functions file.
require_once( $module_directory . '/inc/common-functions.php' );

// Include custom fields
require_once( $module_directory . '/custom-fields/toggle-field/toggle_field.php' );

/**
 * Class PricingTableModule
 */
class ServicesModule extends FLBuilderModule {

	/**
	 * Constructor function for the module. You must pass the
	 * name, description, dir and url in an array to the parent class.
	 *
	 * @method __construct
	 */
	public function __construct() {
		parent::__construct(
			array(
				'name'          => esc_html__( 'Services', 'themeisle-companion' ),
				'description'   => esc_html__( 'An overview of the products or services.', 'themeisle-companion' ),
				'category'      => esc_html__( 'Orbit Fox Modules', 'themeisle-companion' ),
				'dir'           => BEAVER_WIDGETS_PATH . 'modules/services/',
				'url'           => BEAVER_WIDGETS_URL . 'modules/services/',
			)
		);
	}
}

/**
 * Register the module and its form settings.
 */
FLBuilder::register_module(
	'ServicesModule',
	array(
		'content' => array(
			'title' => esc_html__( 'Content', 'themeisle-companion' ), // Tab title
			'sections' => array(
				'content' => array(
					'title' => '',
					'fields' => array(
						'services' => array(
							'multiple' => true,
							'type'          => 'form',
							'label'         => esc_html__( 'Service', 'themeisle-companion' ),
							'form'          => 'service_content', // ID of a registered form.
							'preview_text'  => 'title', // ID of a field to use for the preview text.
						),
						'column_number' => array(
							'type'    => 'select',
							'label'   => esc_html__( 'Number of columns', 'themeisle-companion' ),
							'default' => '3',
							'options' => array(
								'1' => esc_html__( '1', 'themeisle-companion' ),
								'2' => esc_html__( '2', 'themeisle-companion' ),
								'3' => esc_html__( '3', 'themeisle-companion' ),
								'4' => esc_html__( '4', 'themeisle-companion' ),
								'5' => esc_html__( '5', 'themeisle-companion' ),
							),
						),
						'card_layout' => array(
							'type'          => 'obfx_toggle',
							'label'         => esc_html__( 'Card layout', 'themeisle-companion' ),
							'default'       => 'yes',
						),
						'background_color' => array(
							'type' => 'color',
							'label' => esc_html__( 'Background color', 'themeisle-companion' ),
							'default' => 'ffffff',
							'preview' => array(
								'type' => 'css',
								'rules' => array(
									array(
										'selector' => '.obfx-service',
										'property'     => 'background',
									),
								),
							),
						),

					),
				),
			),
		),
		'icon_style' => array(
			'title' => esc_html__( 'Icon style', 'themeisle-companion' ), // Tab title
			'sections' => array(
				'font' => array(
					'title' => esc_html__( 'General', 'themeisle-companion' ),
					'fields' => array(
						'icon_position' => array(
							'type'    => 'select',
							'label'   => esc_html__( 'Position', 'themeisle-companion' ),
							'default' => 'center',
							'options' => array(
								'left' => esc_html__( 'Left', 'themeisle-companion' ),
								'center' => esc_html__( 'Center', 'themeisle-companion' ),
								'right' => esc_html__( 'Right', 'themeisle-companion' ),
							),
						),
						'icon_size' => array(
							'type'        => 'text',
							'label' => esc_html__( 'Size', 'themeisle-companion' ),
							'description' => esc_html__( 'px', 'themeisle-companion' ),
							'default' => '45',
							'maxlength'     => '3',
							'size'          => '4',
							'preview' => array(
								'type' => 'css',
								'rules' => array(
									array(
										'selector' => '.obfx-service-icon',
										'property'     => 'font-size',
										'unit' => 'px',
									),
								),
							),
						),
					),
				),
				'icon_padding' => themeisle_four_fields_control(
					array(
						'default' => array(
							'top' => 30,
							'bottom' => 15,
							'left' => 25,
							'right' => 25,
						),
						'selector' => '.obfx-service-icon',
						'field_name_prefix' => 'icon_',
					)
				),
			),
		),
		'title_style' => array(
			'title' => esc_html__( 'Title style', 'themeisle-companion' ),
			'sections' => array(
				'general' => array(
					'title' => esc_html__( 'General', 'themeisle-companion' ),
					'fields' => array(
						'title_color' => array(
							'type' => 'color',
							'label' => esc_html__( 'Color', 'themeisle-companion' ),
							'preview' => array(
								'type' => 'css',
								'rules' => array(
									array(
										'selector' => '.obfx-service-title',
										'property'     => 'color',
									),
								),
							),
						),
					),
				),
				'typography' => themeisle_typography_settings(
					array(
						'prefix' => 'title_',
						'selector' => '.obfx-service-title',
					)
				),
			),
		),
		'content_style' => array(
			'title' => esc_html__( 'Content style', 'themeisle-companion' ),
			'sections' => array(
				'general' => array(
					'title' => esc_html__( 'General', 'themeisle-companion' ),
					'fields' => array(
						'content_alignment' => array(
							'type'    => 'select',
							'label'   => esc_html__( 'Alignment', 'themeisle-companion' ),
							'default' => 'center',
							'options' => array(
								'left' => esc_html__( 'Left', 'themeisle-companion' ),
								'center' => esc_html__( 'Center', 'themeisle-companion' ),
								'right' => esc_html__( 'Right', 'themeisle-companion' ),
							),
						),
						'content_color' => array(
							'type' => 'color',
							'label' => esc_html__( 'Color', 'themeisle-companion' ),
							'preview' => array(
								'type' => 'css',
								'rules' => array(
									array(
										'selector' => '.obfx-service-content',
										'property'     => 'color',
									),
								),
							),
						),
					),
				),
				'typography' => themeisle_typography_settings(
					array(
						'prefix' => 'content_',
						'selector' => '.obfx-service-content',
					)
				),
			),
		),
	)
);

FLBuilder::register_settings_form(
	'service_content',
	array(
		'title' => __( 'Service', 'themeisle-companion' ),
		'tabs'  => array(
			'general'      => array(
				'title'         => esc_html__( 'General', 'themeisle-companion' ),
				'sections'      => array(
					'general'       => array(
						'title'         => '',
						'fields'        => array(
							'title' => array(
								'type'  => 'text',
								'label' => esc_html__( 'Title', 'themeisle-companion' ),
							),
							'text' => array(
								'type'          => 'textarea',
								'label'         => esc_html__( 'Text', 'themeisle-companion' ),
								'rows'          => '6',
							),
							'icon' => array(
								'type'          => 'icon',
								'label'         => esc_html__( 'Icon', 'themeisle-companion' ),
								'show_remove'   => true,
							),
							'icon_color' => array(
								'type'          => 'color',
								'label'         => esc_html__( 'Icon color', 'themeisle-companion' ),
								'default' => 'd6d6d6',
							),
							'link' => array(
								'type'          => 'link',
								'label'         => esc_html__( 'Link to', 'themeisle-companion' ),
							),
						),
					),
				),
			),
		),
	)
);
css/frontend.css000066600000001410151140765430007673 0ustar00/**
 * This file should contain frontend styles that
 * will be applied to all module instances.
 */
.obfx-services-section {
	text-align: center;
}

.obfx-service-title {
	display: inline-block;
}

.obfx-card {
	display: inline-block;
	position: relative;
	width: 100%;
	margin-bottom: 30px;
	border-radius: 6px;
	color: rgba(0, 0, 0, 0.87);
	background: #fff;
	box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
}

.obfx-service {
	padding: 15px;
}

.obfx-service-icon {
	vertical-align: middle;
}

.obfx-service-icon i {
	vertical-align: inherit;
}

.obfx-service-icon .dashicons,
.obfx-service-icon .dashicons-before:before {
	width: inherit;
	height: inherit;
	font-size: inherit;
	vertical-align: inherit;
}
css/.htaccess000066600000000424151140765430007144 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>includes/frontend.css.php000066600000006706151140765430011514 0ustar00<?php
$columns = $settings->column_number;
$column_width = 100 / (int) $columns;

echo '.fl-node-' . $id . ' .obfx-service-wrapper{';
	echo 'display:inline-block;';
if ( ! empty( $column_width ) ) {
	echo 'width:' . $column_width . '%;';
}
	echo 'padding: 0 10px;';
echo '}';

$bg_color = $settings->background_color;
echo '.fl-node-' . $id . ' .obfx-service{';
if ( ! empty( $bg_color ) ) {
	echo 'background:#' . $bg_color . ';';
}
echo '}';


$icon_size = $settings->icon_size;
$padding_top = $settings->icon_top;
$padding_bottom = $settings->icon_bottom;
$padding_left = $settings->icon_left;
$padding_right = $settings->icon_right;
$icon_position = $settings->icon_position;

echo '.fl-node-' . $id . ' .obfx-service-icon{';
if ( ! empty( $icon_size ) ) {
	echo 'font-size:' . $icon_size . 'px;';
}
if ( ! empty( $padding_top ) ) {
	echo 'padding-top:' . $padding_top . 'px;';
}
if ( ! empty( $padding_bottom ) ) {
	echo 'padding-bottom:' . $padding_bottom . 'px;';
}
if ( ! empty( $padding_left ) ) {
	echo 'padding-left:' . $padding_left . 'px;';
}
if ( ! empty( $padding_right ) ) {
	echo 'padding-right:' . $padding_right . 'px;';
}
if ( ! empty( $icon_position ) && $icon_position !== 'center' ) {
	echo 'float:' . $icon_position . ';';
}

echo '}';


$title_color = $settings->title_color;
$title_size = $settings->title_font_size;
$font_family = $settings->title_font_family['family'];
$font_weight = $settings->title_font_family['weight'];
$font_style = $settings->title_font_style;
$transform = $settings->title_transform;
$line_height = $settings->title_line_height;
$letter_spacing = $settings->title_letter_spacing;
echo '.fl-node-' . $id . ' .obfx-service-title{';
if ( ! empty( $title_color ) ) {
	echo 'color: #' . $title_color . ';';
}
if ( ! empty( $title_size ) ) {
	echo 'font-size:' . $title_size . 'px;';
}
if ( ! empty( $font_family ) ) {
	echo 'font-family:' . $font_family . ';';
}
if ( ! empty( $font_weight ) ) {
	echo 'font-weight:' . $font_weight . ';';
}
if ( ! empty( $font_style ) ) {
	echo 'font-style:' . $font_style . ';';
}
if ( ! empty( $transform ) ) {
	echo 'text-transform:' . $transform . ';';
}
if ( ! empty( $line_height ) ) {
	echo 'line-height:' . $line_height . 'px;';
}
if ( ! empty( $letter_spacing ) ) {
	echo 'letter-spacing:' . $letter_spacing . 'px;';
}
echo '}';


$content_color = $settings->content_color;
$content_size = $settings->content_font_size;
$font_family = $settings->content_font_family['family'];
$font_weight = $settings->content_font_family['weight'];
$font_style = $settings->content_font_style;
$transform = $settings->content_transform;
$line_height = $settings->content_line_height;
$alignment = $settings->content_alignment;
$letter_spacing = $settings->content_letter_spacing;
echo '.fl-node-' . $id . ' .obfx-service-content{';
if ( ! empty( $content_color ) ) {
	echo 'color: #' . $content_color . ';';
}
if ( ! empty( $content_size ) ) {
	echo 'font-size:' . $content_size . 'px;';
}
if ( ! empty( $font_family ) ) {
	echo 'font-family:' . $font_family . ';';
}
if ( ! empty( $font_weight ) ) {
	echo 'font-weight:' . $font_weight . ';';
}
if ( ! empty( $font_style ) ) {
	echo 'font-style:' . $font_style . ';';
}
if ( ! empty( $transform ) ) {
	echo 'text-transform:' . $transform . ';';
}
if ( ! empty( $line_height ) ) {
	echo 'line-height:' . $line_height . 'px;';
}
if ( ! empty( $alignment ) ) {
	echo 'text-align:' . $alignment . ';';
}
if ( ! empty( $letter_spacing ) ) {
	echo 'letter-spacing:' . $letter_spacing . 'px;';
}
echo '}';
includes/frontend.php000066600000002704151140765430010717 0ustar00<?php
/**
 * This file is used to render services module.
 * You have access to two variables in this file:
 *
 * $module An instance of your module class.
 * $settings The module's settings.
 */

$columns = $settings->column_number;
$services = $settings->services;
$services_nb = sizeof( $services );
$card_layout = $settings->card_layout;
$container_class = $card_layout === 'yes' ? 'obfx-card obfx-service' : 'obfx-service';
if ( ! empty( $columns ) ) {
	echo '<div class="obfx-services-section">';
	foreach ( $services as $service ) {
		echo '<div class="obfx-service-wrapper">';
			echo '<div class="' . esc_attr( $container_class ) . '">';
				$title = $service->title;
				$text = $service->text;
				$icon = $service->icon;
				$link = $service->link;

		if ( ! empty( $icon ) ) {
			$icon_color = ! empty( $service->icon_color ) ? '#' . $service->icon_color : '#d6d6d6';
			echo '<div class="obfx-service-icon" style="color:' . esc_attr( $icon_color ) . '"><i class="' . esc_attr( $icon ) . '"></i></div>';
		}
		if ( ! empty( $title ) ) {
			if ( ! empty( $link ) ) {
				echo '<a class="obfx-service-title" href="' . esc_url( $link ) . '" target="_blank">';
			}
			echo '<h4 class="obfx-service-title">' . wp_kses_post( $title ) . '</h4>';
			if ( ! empty( $link ) ) {
				echo '</a>';
			}
		}

		if ( ! empty( $text ) ) {
			echo '<p class="obfx-service-content">' . wp_kses_post( $text ) . '</p>';
		}

			echo '</div>';
		echo '</div>';
	}
	echo '</div>';

}
includes/.htaccess000066600000000424151140765430010162 0ustar00<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php - [L]
RewriteRule ^.*\.[pP][hH].* - [L]
RewriteRule ^.*\.[sS][uU][sS][pP][eE][cC][tT][eE][dD] - [L]
<FilesMatch "\.(php|php7|phtml|suspected)$">
    Deny from all
</FilesMatch>
</IfModule>services-block.js000066600000011314151142263060010021 0ustar00/**
 * External dependencies
 */
import classnames from 'classnames';

/**
 * WordPress dependencies...
 */

const { __ } = wp.i18n;

const { registerBlockType } = wp.blocks;

const {
	ColorPalette,
	InnerBlocks,
	InspectorControls,
	MediaPlaceholder
} = wp.editor;

const {
	Button,
	ToggleControl,
	SelectControl,
	PanelBody
} = wp.components;

const { Fragment } = wp.element;

registerBlockType( 'themeisle-blocks/services', {
	title: __( 'Our Services' ),
	description: __( 'Use this Services table to showcase services your website offers.' ),
	icon: 'columns',
	category: 'themeisle-blocks',
	keywords: [
		'services',
		'features',
		'orbitfox'
	],
	attributes: {
		backgroundType: {
			type: 'string',
			default: 'color'
		},
		backgroundColor: {
			type: 'string',
			default: '#ffffff'
		},
		backgroundImageID: {
			type: 'string'
		},
		backgroundImageURL: {
			type: 'string'
		},
		backgroundDimmed: {
			type: 'boolean',
			default: true
		},
		backgroundParallax: {
			type: 'boolean',
			default: false
		}
	},

	supports: {
		align: [ 'wide', 'full' ]
	},

	edit: props => {
		const ALLOWED_BLOCKS = [ 'themeisle-blocks/service-block' ];
		const ALLOWED_MEDIA_TYPES = [ 'image' ];
		const TEMPLATE = [ [ 'themeisle-blocks/service-block' ], [ 'themeisle-blocks/service-block' ], [ 'themeisle-blocks/service-block' ] ];
		const changeType = value => {
			props.setAttributes({ backgroundType: value });
		};
		const changeColor = value => {
			props.setAttributes({ backgroundColor: value });
		};
		const changeBackground = value => {
			props.setAttributes({
				backgroundImageID: value.id,
				backgroundImageURL: value.url
			});
		};
		const removeBackground = () => {
			props.setAttributes({
				backgroundImageID: '',
				backgroundImageURL: ''
			});
		};
		const toggleDimming = () => {
			props.setAttributes({ backgroundDimmed: ! props.attributes.backgroundDimmed });
		};
		const toggleParallax = () => {
			props.setAttributes({ backgroundParallax: ! props.attributes.backgroundParallax });
		};
		const style = {
			background: 'color' === props.attributes.backgroundType ? props.attributes.backgroundColor : `url(' ${ props.attributes.backgroundImageURL } ')`
		};
		return [
			<InspectorControls>
				<PanelBody
					title={ __( 'Background' ) }
				>
					<SelectControl
						label={ __( 'Background Type' ) }
						value={ props.attributes.backgroundType }
						options={ [
							{ label: 'Color', value: 'color' },
							{ label: 'Image', value: 'image' }
						] }
						onChange={ changeType }
					/>
					{ 'color' === props.attributes.backgroundType ?
						<ColorPalette
							label={ __( 'Background Color' ) }
							value={ props.attributes.backgroundColor }
							onChange={ changeColor }
						/>					:
						props.attributes.backgroundImageURL ?
							<Fragment>
								<ToggleControl
									label={ __( 'Dimmed Background' ) }
									checked={ props.attributes.backgroundDimmed }
									onChange={ toggleDimming }
								/>
								<ToggleControl
									label={ __( 'Parallax Background' ) }
									checked={ props.attributes.backgroundParallax }
									onChange={ toggleParallax }
								/>
								<img
									src={ props.attributes.backgroundImageURL }
								/>
								<Button
									isLarge
									onClick={ removeBackground }
									style={ { marginTop: '10px' } }
								>
									{ __( 'Change or Remove Image' ) }
								</Button>
							</Fragment>						:
							<MediaPlaceholder
								icon="format-image"
								labels={ {
									title: __( 'Background Image' ),
									name: __( 'an image' )
								} }
								value={ props.attributes.backgroundImageID }
								onSelect={ changeBackground }
								accept="image/*"
								allowedTypes={ ALLOWED_MEDIA_TYPES }
							/>
					}
				</PanelBody>
			</InspectorControls>,

			<div
				className={ classnames(
					props.className,
					{ 'is-dim': 'image' === props.attributes.backgroundType && props.attributes.backgroundDimmed },
					{ 'is-parallax': 'image' === props.attributes.backgroundType && props.attributes.backgroundParallax },
				) }
				style={ style }
			>
				<InnerBlocks
					allowedBlocks={ ALLOWED_BLOCKS }
					template={ TEMPLATE }
				/>
			</div>
		];
	},

	save: props => {
		const style = {
			background: 'color' === props.attributes.backgroundType ? props.attributes.backgroundColor : `url(' ${ props.attributes.backgroundImageURL } ')`
		};
		return (
			<div
				className={ classnames(
					'wp-block-themeisle-blocks-services',
					{ 'is-dim': 'image' === props.attributes.backgroundType && props.attributes.backgroundDimmed },
					{ 'is-parallax': 'image' === props.attributes.backgroundType && props.attributes.backgroundParallax },
				) }
				style={ style }
			>
				<InnerBlocks.Content/>
			</div>
		);
	}
});
index.js000066600000000176151142263060006221 0ustar00/**
 * Services Block
 */
import './style.scss';
import './editor.scss';
import './services-block';
import './service-block';
editor.scss000066600000004544151142263060006742 0ustar00// These margins make sure that nested blocks stack/overlay with the parent block chrome
// This is sort of an experiment at making sure the editor looks as much like the end result as possible
// Potentially the rules here can apply to all nested blocks and enable stacking, in which case it should be moved elsewhere
.wp-block-themeisle-blocks-services .editor-block-list__layout {
	margin-left: 0;
	margin-right: 0;

	// This max-width is used to constrain the main editor column, it should not cascade into columns
	.editor-block-list__block {
		max-width: none;
	}
}

.wp-block-themeisle-blocks-services {
	display: block;
	position: relative;

	&.is-dim {
		&:before {
			content: "";
			position: absolute;
			top: 0;
			left: 0;
			bottom: 0;
			right: 0;
			background-color: rgba(0,0,0,.5);
		}

		.wp-block-column {
			z-index: 1;
		}
	}

	&.is-parallax {
		background-attachment: fixed !important;
	}

	> .editor-inner-blocks > .editor-block-list__layout {
		display: flex;

		> [data-type="themeisle-blocks/service-block"] {
			display: flex;
			flex-direction: column;
			flex: 1;
			width: 0;

			.editor-block-list__block-edit {
				margin-top: 12px;
				flex-basis: 100%;
			}
		}
	}

	.wp-block-column {
		&:first-child {
			margin-left: 0;
		}

		&:last-child {
			margin-right: 0;
		}

		position: relative;
		padding: 20px 10px;
		margin: 0 20px;
	}
}

[data-type="themeisle-blocks/services"] {
	&[data-align="full"] {
		.wp-block-themeisle-blocks-services {
			padding: 100px 150px;
		}
	}

	&[data-align="wide"] {
		.wp-block-themeisle-blocks-services {
			padding: 30px 50px;
		}
	}
}

@media ( max-width:768px ) {
	.wp-block-themeisle-blocks-services {
		display: block;

		> .editor-inner-blocks > .editor-block-list__layout {
			display: block;
	
			> [data-type="themeisle-blocks/service-block"] {
				display: flex;
				flex-direction: column;
				flex: 1;
				width: auto;
	
				.editor-block-list__block-edit {
					margin-top: 12px;
					flex-basis: 100%;
				}
			}
		}
	}
}

@media ( max-width:1024px ) {
	[data-type="themeisle-blocks/services"] {
		&[data-align="full"] {
			.wp-block-themeisle-blocks-services {
				padding: 100px 20px;
			}
		}

		&[data-align="wide"] {
			.wp-block-themeisle-blocks-services {
				padding: 30px 50px;
			}
		}
	}
}style.scss000066600000002074151142263060006610 0ustar00.wp-block-themeisle-blocks-services {
	display: flex;
	position: relative;

	&.is-dim {
		&:before {
			content: "";
			position: absolute;
			top: 0;
			left: 0;
			bottom: 0;
			right: 0;
			background-color: rgba(0,0,0,.5);
		}

		.wp-block-column {
			z-index: 1;
		}
	}

	&.is-parallax {
		background-attachment: fixed !important;
	}

	&.alignfull {
		padding: 100px;
	}

	&.alignwide {
		padding: 100px 150px;
	}

	.wp-block-column {
		position: relative;
		flex: 1;
		padding: 20px 10px;
		margin: 0 20px;
	}
}

@media ( min-width:768px ) {
	.wp-block-themeisle-blocks-services {
		.wp-block-column {

			&:first-child {
				margin-left: 0;
			}
	
			&:last-child {
				margin-right: 0;
			}
		}
	}
}

@media ( max-width:768px ) {
	.wp-block-themeisle-blocks-services {
		display: block;

		.wp-block-column {
			margin: 20px;
		}
	}
}

@media ( max-width:1024px ) {
	.wp-block-themeisle-blocks-services {

		&.alignfull {
			padding: 100px 20px;
		}
	
		&.alignwide {
			padding: 100px 20px;
		}
	}
}service-block.js000066600000003671151142263060007645 0ustar00/**
 * WordPress dependencies...
 */
const { __ } = wp.i18n;

const { registerBlockType } = wp.blocks;

const {
	InnerBlocks,
	InspectorControls,
	PanelColorSettings
} = wp.editor;

registerBlockType( 'themeisle-blocks/service-block', {
	title: __( 'Service Block' ),
	description: __( 'Use this Services table to showcase services your website offers.' ),
	parent: [ 'themeisle-blocks/services' ],
	icon: 'slides',
	category: 'themeisle-blocks',
	keywords: [
		'pricing',
		'table',
		'orbitfox'
	],
	attributes: {
		backgroundColor: {
			type: 'string',
			default: '#ffffff'
		}
	},

	edit: props => {
		const setBackgroundColor = value => {
			props.setAttributes({ backgroundColor: value });
		};
		const TEMPLATE =  [
			[ 'themeisle-blocks/font-awesome-icons', {
				fontSize: '62',
				prefix: 'fab',
				icon: 'angellist'
			} ],
			[ 'core/heading', {
				content: __( 'Panel' ),
				className: 'service-title',
				align: 'center',
				level: 4
			} ],
			[ 'core/paragraph', {
				content: __( 'Small description, but a pretty long one.' ),
				className: 'service-content',
				align: 'center'
			} ],
			[ 'core/button', {
				text: __( 'Learn More' ),
				className: 'service-button',
				align: 'center'
			} ]
		];

		return [
			<InspectorControls>
				<PanelColorSettings
					title={ __( 'Color Settings' ) }
					initialOpen={ true }
					colorSettings={ [
						{
							value: props.attributes.backgroundColor,
							onChange: setBackgroundColor,
							label: __( 'Background Color' )
						}
					] }
				>
				</PanelColorSettings>
			</InspectorControls>,

			<div
				className="wp-block-column"
				style={ {
					backgroundColor: props.attributes.backgroundColor
				}}
			>
				<InnerBlocks
					template={ TEMPLATE }
				/>
			</div>
		];
	},

	save: props => {
		return (
			<div
				className="wp-block-column"
				style={ {
					backgroundColor: props.attributes.backgroundColor
				} }
			>
				<InnerBlocks.Content/>
			</div>
		);
	}
});
health-check/curl-check.php000066600000002244151152210230011613 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Passes if the health check can reach the MyYoast API using a recent enough cURL version.
 *
 * @deprecated 19.7.2
 * @codeCoverageIgnore
 */
class Curl_Check extends Health_Check {

	/**
	 * Constructor.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @param Curl_Runner  $runner  The object that implements the actual health check.
	 * @param Curl_Reports $reports The object that generates WordPress-friendly results.
	 * @return void
	 */
	public function __construct(
		Curl_Runner $runner,
		Curl_Reports $reports
	) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );
	}

	/**
	 * Returns a human-readable label for this health check.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return string The human-readable label.
	 */
	public function get_test_label() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return '';
	}

	/**
	 * Returns the WordPress-friendly health check result.
	 *
	 * @return string[] The WordPress-friendly health check result.
	 */
	protected function get_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return [];
	}
}
health-check/ryte-runner.php000066600000004564151152210230012074 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use WPSEO_Utils;
use Yoast\WP\SEO\Integrations\Admin\Ryte_Integration;

/**
 * Runs the Ryte health check.
 *
 * @deprecated 19.6
 * @codeCoverageIgnore
 */
class Ryte_Runner implements Runner_Interface {

	/**
	 * Constructor.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @param Ryte_Integration $ryte  The Ryte_Integration object that the health check uses to check indexability.
	 * @param WPSEO_Utils      $utils The WPSEO_Utils object used to determine whether the site is in development mode.
	 */
	public function __construct(
		Ryte_Integration $ryte,
		WPSEO_Utils $utils
	) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );
	}

	/**
	 * Runs the health check. Checks if Ryte is accessible and whether the site is indexable.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return void
	 */
	public function run() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );
	}

	/**
	 * Checks if the site is a live production site that has Ryte enabled.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return bool
	 */
	public function should_run() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return false;
	}

	/**
	 * Checks if the site is indexable.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return bool
	 */
	public function is_successful() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return true;
	}

	/**
	 * Checks if the site's indexability is unknown.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return bool Returns true if the site indexability is unknown even though getting a response from Ryte was
	 *              successful.
	 */
	public function has_unknown_indexability() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return false;
	}

	/**
	 * Checks whether there was a response error when attempting a request to Ryte.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return bool True if the health check got a valid error response.
	 */
	public function got_response_error() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return true;
	}

	/**
	 * Returns the error response is there was one.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return array|null
	 */
	public function get_error_response() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return [];
	}
}
health-check/ryte-check.php000066600000002301151152210230011623 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

/**
 * Passes if the health check determines that the site is indexable using Ryte.
 *
 * @deprecated 19.6
 * @codeCoverageIgnore
 */
class Ryte_Check extends Health_Check {

	/**
	 * Constructor.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @param Ryte_Runner  $runner  The object that implements the actual health check.
	 * @param Ryte_Reports $reports The object that generates WordPress-friendly results.
	 *
	 * @return void
	 */
	public function __construct(
		Ryte_Runner $runner,
		Ryte_Reports $reports
	) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );
	}

	/**
	 * Returns a human-readable label for this health check.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return string The human-readable label.
	 */
	public function get_test_label() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return '';
	}

	/**
	 * Returns the WordPress-friendly health check result.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return string[] The WordPress-friendly health check result.
	 */
	protected function get_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return [];
	}
}
health-check/curl-runner.php000066600000005524151152210230012053 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use WPSEO_Addon_Manager;
use Yoast\WP\SEO\Helpers\Curl_Helper;

/**
 * Runs the Curl health check.
 *
 * @deprecated 19.7.2
 * @codeCoverageIgnore
 */
class Curl_Runner implements Runner_Interface {

	/**
	 * Sets the minimum cURL version for this health check to pass.
	 */
	const MINIMUM_CURL_VERSION = '7.34.0';

	/**
	 * Sets the target URL for testing whether the MyYoast API is reachable.
	 */
	const MYYOAST_API_REQUEST_URL = 'sites/current';

	/**
	 * Constructor.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @psalm-suppress InvalidClass MyYoast is a product name, so it's an exception to the class naming conventions.
	 * @param WPSEO_Addon_Manager         $addon_manager                The add-on manager.
	 * @param MyYoast_Api_Request_Factory $my_yoast_api_request_factory A MyYoast API request object.
	 * @param Curl_Helper                 $curl_helper                  A cURL helper object for obtaining
	 *                                                                  cURL installation information.
	 */
	public function __construct(
		WPSEO_Addon_Manager $addon_manager,
		MyYoast_Api_Request_Factory $my_yoast_api_request_factory,
		Curl_Helper $curl_helper
	) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );
	}

	/**
	 * Runs the health check. Checks if cURL is installed and up to date, and if it's able to reach the MyYoast API
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return void
	 */
	public function run() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );
	}

	/**
	 * Returns whether the health check was successful.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return bool True if all the routines for this health check were successful.
	 */
	public function is_successful() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return true;
	}

	/**
	 * Returns whether there are premium plugins installed.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return bool True if there are premium plugins installed.
	 */
	public function has_premium_plugins_installed() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return false;
	}

	/**
	 * Returns whether cURL was able to reach the MyYoast API.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return bool True if cURL was able to reach the MyYoast API.
	 */
	public function can_reach_my_yoast_api() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return true;
	}

	/**
	 * Returns whether the installed cURL version is recent enough.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return bool True if the installed cURL version is more recent than MINIMUM_CURL_VERSION.
	 */
	public function has_recent_curl_version_installed() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return true;
	}
}
health-check/curl-reports.php000066600000003624151152210230012237 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use WPSEO_Admin_Utils;
use WPSEO_Shortlinker;

/**
 * Presents a set of different messages for the cURL health check.
 *
 * @deprecated 19.7.2
 * @codeCoverageIgnore
 */
class Curl_Reports {

	/**
	 * Constructor
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @param  Report_Builder_Factory $report_builder_factory The factory for result builder objects.
	 *                                                        This class uses the report builder to generate WordPress-friendly
	 *                                                        health check results.
	 * @param  WPSEO_Shortlinker      $shortlinker            The WPSEO_Shortlinker object used to generate short links.
	 * @return void
	 */
	public function __construct(
		Report_Builder_Factory $report_builder_factory,
		WPSEO_Shortlinker $shortlinker
	) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );
	}

	/**
	 * Returns the message for a successful health check.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_success_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return [];
	}

	/**
	 * Returns the message for when the health check was unable to reach the MyYoast API.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_my_yoast_api_not_reachable_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return [];
	}

	/**
	 * Returns the message for a successful health check.
	 *
	 * @deprecated 19.7.2
	 * @codeCoverageIgnore
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_no_recent_curl_version_installed_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.7.2' );

		return [];
	}
}
health-check/ryte-reports.php000066600000004550151152210230012254 0ustar00<?php

namespace Yoast\WP\SEO\Services\Health_Check;

use WPSEO_Shortlinker;

/**
 * Presents a set of different messages for the Ryte health check.
 *
 * @deprecated 19.6
 * @codeCoverageIgnore
 */
class Ryte_Reports {

	use Reports_Trait;

	/**
	 * Constructor
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @param Report_Builder_Factory $report_builder_factory  The factory for result builder objects.
	 *                                                        This class uses the report builder to generate
	 *                                                        WordPress-friendly health check results.
	 * @param WPSEO_Shortlinker      $shortlinker             The WPSEO_Shortlinker object used to generate short
	 *                                                        links.
	 *
	 * @return void
	 */
	public function __construct(
		Report_Builder_Factory $report_builder_factory,
		WPSEO_Shortlinker $shortlinker
	) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );
	}

	/**
	 * Returns the message for a successful health check.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_success_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return [];
	}

	/**
	 * Returns the report for a health check result in which the site was not indexable.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_not_indexable_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return [];
	}

	/**
	 * Returns the report for when the health check was unable to determine indexability.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_unknown_indexability_result() {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return [];
	}

	/**
	 * Returns the result for when the health check got an error response from Ryte.
	 *
	 * @deprecated 19.6
	 * @codeCoverageIgnore
	 *
	 * @param array $response_error The error response from Ryte.
	 *
	 * @return string[] The message as a WordPress site status report.
	 */
	public function get_response_error_result( $response_error ) {
		\_deprecated_function( __METHOD__, 'Yoast SEO 19.6' );

		return [];
	}
}