class-configuration-options-adapter.php 4.92 KB
Newer Older
imac's avatar
imac committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
<?php
/**
 * @package WPSEO\Admin\ConfigurationUI
 */

/**
 * Class WPSEO_Configuration_Options_Adapter
 *
 * Convert Configuration settings to WPSEO Options
 *
 * @since 3.6
 */
class WPSEO_Configuration_Options_Adapter {

	const OPTION_TYPE_WORDPRESS = 'wordpress';
	const OPTION_TYPE_YOAST = 'yoast';
	const OPTION_TYPE_CUSTOM = 'custom';

	/** @var array List of registered lookups */
	protected $lookup = array();

	/**
	 * Add a lookup for a WordPress native option
	 *
	 * @param string $class_name Class to bind to an option.
	 * @param string $option     Option name to use.
	 *
	 * @throws InvalidArgumentException Thrown when invalid input is provided.
	 */
	public function add_wordpress_lookup( $class_name, $option ) {

		if ( ! is_string( $option ) ) {
			throw new InvalidArgumentException( 'WordPress option must be a string.' );
		}

		$this->add_lookup( $class_name, self::OPTION_TYPE_WORDPRESS, $option );
	}

	/**
	 * Add a lookup for a Yoast option
	 *
	 * @param string $class_name Class to bind to the lookup.
	 * @param string $option     Option group to use.
	 * @param string $key        Key in the option group to bind to.
	 *
	 * @throws InvalidArgumentException Thrown when invalid input is provided.
	 */
	public function add_yoast_lookup( $class_name, $option, $key ) {

		$test = WPSEO_Options::get_option( $option );
		if ( is_null( $test ) ) {
			/* translators: %1$s resolves to the option name passed to the lookup registration */
			throw new InvalidArgumentException( sprintf( __( 'Yoast option %1$s not found.', 'wordpress-seo' ), $option ) );
		}

		$this->add_lookup( $class_name, self::OPTION_TYPE_YOAST, array(
			$option,
			$key,
		) );
	}

	/**
	 * Add a lookup for a custom implementation
	 *
	 * @param string   $class_name   Class to bind to the lookup.
	 * @param callable $callback_get Callback to retrieve data.
	 * @param callable $callback_set Callback to save data.
	 *
	 * @throws InvalidArgumentException Thrown when invalid input is provided.
	 */
	public function add_custom_lookup( $class_name, $callback_get, $callback_set ) {

		if ( ! is_callable( $callback_get ) || ! is_callable( $callback_set ) ) {
			throw new InvalidArgumentException( 'Custom option must be callable.' );
		}

		$this->add_lookup( $class_name, self::OPTION_TYPE_CUSTOM, array(
			$callback_get,
			$callback_set,
		) );
	}

	/**
	 * Add a field lookup.
	 *
	 * @param string       $class_name Class to add lookup for.
	 * @param string       $type       Type of lookup.
	 * @param string|array $option     Implementation of the lookup.
	 *
	 * @throws Exception Thrown when invalid input is provided.
	 */
	protected function add_lookup( $class_name, $type, $option ) {
		$this->lookup[ $class_name ] = array(
			'type'   => $type,
			'option' => $option,
		);
	}

	/**
	 * Get the data for the provided field
	 *
	 * @param WPSEO_Config_Field $field Field to get data for.
	 *
	 * @return mixed
	 */
	public function get( WPSEO_Config_Field $field ) {
		$identifier = $field->get_identifier();

		// Lookup option and retrieve value.
		$type   = $this->get_option_type( $identifier );
		$option = $this->get_option( $identifier );

		switch ( $type ) {
			case self::OPTION_TYPE_WORDPRESS:
				return get_option( $option );

			case self::OPTION_TYPE_YOAST:
				$group = WPSEO_Options::get_option( $option[0] );

				return $group[ $option[1] ];

			case self::OPTION_TYPE_CUSTOM:
				return call_user_func( $option[0] );
		}

		return null;
	}

	/**
	 * Save data from a field
	 *
	 * @param WPSEO_Config_Field $field Field to use for lookup.
	 * @param mixed              $value Value to save to the lookup of the field.
	 *
	 * @return bool
	 */
	public function set( WPSEO_Config_Field $field, $value ) {
		$identifier = $field->get_identifier();

		// Lookup option and retrieve value.
		$type   = $this->get_option_type( $identifier );
		$option = $this->get_option( $identifier );

		switch ( $type ) {
			case self::OPTION_TYPE_WORDPRESS:
				return update_option( $option, $value );

			case self::OPTION_TYPE_YOAST:
				$group = WPSEO_Options::get_option( $option[0] );

				$group[ $option[1] ] = $value;
				update_option( $option[0], $group );

				$saved = WPSEO_Options::get_option( $option[0] );

				return $saved[ $option[1] ] === $value;

			case self::OPTION_TYPE_CUSTOM:
				return call_user_func( $option[1], $value );
		}

		return false;
	}

	/**
	 * Get the lookup type for a specific class
	 *
	 * @param string $class_name Class to get the type of.
	 *
	 * @return null|string
	 */
	protected function get_option_type( $class_name ) {
		if ( ! isset( $this->lookup[ $class_name ] ) ) {
			return null;
		}

		return $this->lookup[ $class_name ]['type'];
	}

	/**
	 * Get the option for a specific class
	 *
	 * @param string $class_name Class to get the option of.
	 *
	 * @return null|string|array
	 */
	protected function get_option( $class_name ) {
		if ( ! isset( $this->lookup[ $class_name ] ) ) {
			return null;
		}

		return $this->lookup[ $class_name ]['option'];
	}
}