first
This commit is contained in:
171
wp-content/plugins/wordpress-seo/lib/abstract-main.php
Normal file
171
wp-content/plugins/wordpress-seo/lib/abstract-main.php
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib;
|
||||
|
||||
use Exception;
|
||||
use Yoast\WP\Lib\Dependency_Injection\Container_Registry;
|
||||
use Yoast\WP\SEO\Exceptions\Forbidden_Property_Mutation_Exception;
|
||||
use Yoast\WP\SEO\Loader;
|
||||
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Abstract class to extend for the main class in a plugin.
|
||||
*/
|
||||
abstract class Abstract_Main {
|
||||
|
||||
/**
|
||||
* The DI container.
|
||||
*
|
||||
* @var ContainerInterface|null
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* A cache for previously requested and constructed surfaces.
|
||||
*
|
||||
* @var mixed[]
|
||||
*/
|
||||
private $cached_surfaces = [];
|
||||
|
||||
/**
|
||||
* Loads the plugin.
|
||||
*
|
||||
* @throws Exception If loading fails and YOAST_ENVIRONMENT is development.
|
||||
*/
|
||||
public function load() {
|
||||
if ( $this->container ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->container = $this->get_container();
|
||||
Container_Registry::register( $this->get_name(), $this->container );
|
||||
|
||||
if ( ! $this->container ) {
|
||||
return;
|
||||
}
|
||||
if ( ! $this->container->has( Loader::class ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->container->get( Loader::class )->load();
|
||||
} catch ( Exception $e ) {
|
||||
if ( $this->is_development() ) {
|
||||
throw $e;
|
||||
}
|
||||
// Don't crash the entire site, simply don't load.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter for retrieving a property from a surface.
|
||||
*
|
||||
* @param string $property The property to retrieve.
|
||||
*
|
||||
* @return mixed The value of the property.
|
||||
*
|
||||
* @throws Exception When the property doesn't exist.
|
||||
*/
|
||||
public function __get( $property ) {
|
||||
if ( \array_key_exists( $property, $this->cached_surfaces ) ) {
|
||||
return $this->cached_surfaces[ $property ];
|
||||
}
|
||||
|
||||
$surfaces = $this->get_surfaces();
|
||||
|
||||
if ( isset( $surfaces[ $property ] ) ) {
|
||||
$this->cached_surfaces[ $property ] = $this->container->get( $surfaces[ $property ] );
|
||||
|
||||
return $this->cached_surfaces[ $property ];
|
||||
}
|
||||
throw new Exception( sprintf( 'Property $%s does not exist.', $property ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given property exists as a surface.
|
||||
*
|
||||
* @param string $property The property to retrieve.
|
||||
*
|
||||
* @return bool True when property is set.
|
||||
*/
|
||||
public function __isset( $property ) {
|
||||
if ( \array_key_exists( $property, $this->cached_surfaces ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$surfaces = $this->get_surfaces();
|
||||
|
||||
if ( ! isset( $surfaces[ $property ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->container->has( $surfaces[ $property ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents setting dynamic properties and unsetting declared properties
|
||||
* from an inaccessible context.
|
||||
*
|
||||
* @param string $name The property name.
|
||||
* @param mixed $value The property value.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws Forbidden_Property_Mutation_Exception Set is never meant to be called.
|
||||
*/
|
||||
public function __set( $name, $value ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- __set must have a name and value - PHPCS #3715.
|
||||
throw Forbidden_Property_Mutation_Exception::cannot_set_because_property_is_immutable( $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents unsetting dynamic properties and unsetting declared properties
|
||||
* from an inaccessible context.
|
||||
*
|
||||
* @param string $name The property name.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws Forbidden_Property_Mutation_Exception Unset is never meant to be called.
|
||||
*/
|
||||
public function __unset( $name ) {
|
||||
throw Forbidden_Property_Mutation_Exception::cannot_unset_because_property_is_immutable( $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the DI container.
|
||||
*
|
||||
* @return ContainerInterface|null The DI container.
|
||||
*
|
||||
* @throws Exception If something goes wrong generating the DI container.
|
||||
*/
|
||||
abstract protected function get_container();
|
||||
|
||||
/**
|
||||
* Gets the name of the plugin.
|
||||
*
|
||||
* @return string The name.
|
||||
*/
|
||||
abstract protected function get_name();
|
||||
|
||||
/**
|
||||
* Gets the surfaces of this plugin.
|
||||
*
|
||||
* @return array A mapping of surface name to the responsible class.
|
||||
*/
|
||||
abstract protected function get_surfaces();
|
||||
|
||||
/**
|
||||
* Returns whether or not we're in an environment for Yoast development.
|
||||
*
|
||||
* @return bool Whether or not to load in development mode.
|
||||
*/
|
||||
protected function is_development() {
|
||||
try {
|
||||
return \WPSEO_Utils::is_development_mode();
|
||||
}
|
||||
catch ( Exception $exception ) {
|
||||
// E.g. when WordPress and/or WordPress SEO are not loaded.
|
||||
return \defined( 'YOAST_ENVIRONMENT' ) && \YOAST_ENVIRONMENT === 'development';
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib\Dependency_Injection;
|
||||
|
||||
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use YoastSEO_Vendor\Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
/**
|
||||
* Container_Registry class.
|
||||
*/
|
||||
class Container_Registry {
|
||||
|
||||
/**
|
||||
* The registered containers.
|
||||
*
|
||||
* @var ContainerInterface[]
|
||||
*/
|
||||
private static $containers = [];
|
||||
|
||||
/**
|
||||
* Register a container.
|
||||
*
|
||||
* @param string $name The name of the container.
|
||||
* @param ContainerInterface $container The container.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register( $name, ContainerInterface $container ) {
|
||||
self::$containers[ $name ] = $container;
|
||||
}
|
||||
|
||||
// phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber -- PHPCS doesn't take into account exceptions thrown in called methods.
|
||||
|
||||
/**
|
||||
* Get an instance from a specific container.
|
||||
*
|
||||
* @param string $name The name of the container.
|
||||
* @param string $id The ID of the service.
|
||||
* @param int $invalid_behaviour The behaviour when the service could not be found.
|
||||
*
|
||||
* @return object|null The service.
|
||||
*
|
||||
* @throws ServiceCircularReferenceException When a circular reference is detected.
|
||||
* @throws ServiceNotFoundException When the service is not defined.
|
||||
*/
|
||||
public static function get( $name, $id, $invalid_behaviour = 1 ) {
|
||||
if ( ! \array_key_exists( $name, self::$containers ) ) {
|
||||
if ( $invalid_behaviour === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE ) {
|
||||
throw new ServiceNotFoundException( $id );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return self::$containers[ $name ]->get( $id, $invalid_behaviour );
|
||||
}
|
||||
|
||||
// phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
|
||||
/**
|
||||
* Attempts to find a given service ID in all registered containers.
|
||||
*
|
||||
* @param string $id The service ID.
|
||||
*
|
||||
* @return string|null The name of the container if the service was found.
|
||||
*/
|
||||
public static function find( $id ) {
|
||||
foreach ( self::$containers as $name => $container ) {
|
||||
if ( $container->has( $id ) ) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1072
wp-content/plugins/wordpress-seo/lib/migrations/adapter.php
Normal file
1072
wp-content/plugins/wordpress-seo/lib/migrations/adapter.php
Normal file
File diff suppressed because it is too large
Load Diff
101
wp-content/plugins/wordpress-seo/lib/migrations/column.php
Normal file
101
wp-content/plugins/wordpress-seo/lib/migrations/column.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib\Migrations;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Yoast migrations column class.
|
||||
*/
|
||||
class Column {
|
||||
|
||||
/**
|
||||
* The adapter.
|
||||
*
|
||||
* @var Adapter
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* The name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* The type.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* The properties.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $properties;
|
||||
|
||||
/**
|
||||
* The options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $options = [];
|
||||
|
||||
/**
|
||||
* Creates an instance of a column.
|
||||
*
|
||||
* @param Adapter $adapter The current adapter.
|
||||
* @param string $name The name of the column.
|
||||
* @param string $type The type of the column.
|
||||
* @param array $options The column options.
|
||||
*
|
||||
* @throws Exception If invalid arguments provided.
|
||||
*/
|
||||
public function __construct( $adapter, $name, $type, $options = [] ) {
|
||||
if ( ! $adapter instanceof Adapter ) {
|
||||
throw new Exception( 'Invalid Adapter instance.' );
|
||||
}
|
||||
if ( empty( $name ) || ! \is_string( $name ) ) {
|
||||
throw new Exception( "Invalid 'name' parameter" );
|
||||
}
|
||||
if ( empty( $type ) || ! \is_string( $type ) ) {
|
||||
throw new Exception( "Invalid 'type' parameter" );
|
||||
}
|
||||
$this->adapter = $adapter;
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SQL of this column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function to_sql() {
|
||||
$column_sql = \sprintf( '%s %s', $this->adapter->identifier( $this->name ), $this->sql_type() );
|
||||
$column_sql .= $this->adapter->add_column_options( $this->type, $this->options );
|
||||
return $column_sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SQL string version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->to_sql();
|
||||
}
|
||||
|
||||
/**
|
||||
* The SQL type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function sql_type() {
|
||||
return $this->adapter->type_to_sql( $this->type, $this->options );
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib\Migrations;
|
||||
|
||||
/**
|
||||
* Yoast migrations constants class.
|
||||
*/
|
||||
class Constants {
|
||||
|
||||
const MYSQL_MAX_IDENTIFIER_LENGTH = 64;
|
||||
const SQL_UNKNOWN_QUERY_TYPE = 1;
|
||||
const SQL_SELECT = 2;
|
||||
const SQL_INSERT = 4;
|
||||
const SQL_UPDATE = 8;
|
||||
const SQL_DELETE = 16;
|
||||
const SQL_ALTER = 32;
|
||||
const SQL_DROP = 64;
|
||||
const SQL_CREATE = 128;
|
||||
const SQL_SHOW = 256;
|
||||
const SQL_RENAME = 512;
|
||||
const SQL_SET = 1024;
|
||||
}
|
277
wp-content/plugins/wordpress-seo/lib/migrations/migration.php
Normal file
277
wp-content/plugins/wordpress-seo/lib/migrations/migration.php
Normal file
@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib\Migrations;
|
||||
|
||||
/**
|
||||
* Base migration class.
|
||||
*/
|
||||
abstract class Migration {
|
||||
|
||||
/**
|
||||
* The plugin this migration belongs to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $plugin = 'unknown';
|
||||
|
||||
/**
|
||||
* The adapter.
|
||||
*
|
||||
* @var Adapter
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* Performs the migration.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function up();
|
||||
|
||||
/**
|
||||
* Reverts the migration.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function down();
|
||||
|
||||
/**
|
||||
* Creates a new migration.
|
||||
*
|
||||
* @param Adapter $adapter The current adapter.
|
||||
*/
|
||||
public function __construct( Adapter $adapter ) {
|
||||
$this->set_adapter( $adapter );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an adapter.
|
||||
*
|
||||
* @param Adapter $adapter The adapter to set.
|
||||
*
|
||||
* @return $this|null
|
||||
*/
|
||||
public function set_adapter( $adapter ) {
|
||||
if ( ! $adapter instanceof Adapter ) {
|
||||
return;
|
||||
}
|
||||
$this->adapter = $adapter;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current adapter.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function get_adapter() {
|
||||
return $this->adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a database.
|
||||
*
|
||||
* @param string $name The name of the database.
|
||||
* @param array|null $options The options.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function create_database( $name, $options = null ) {
|
||||
return $this->adapter->create_database( $name, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a database.
|
||||
*
|
||||
* @param string $name The name of the database.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function drop_database( $name ) {
|
||||
return $this->adapter->drop_database( $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function drop_table( $table_name ) {
|
||||
return $this->adapter->drop_table( $table_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a table.
|
||||
*
|
||||
* @param string $name The name of the table.
|
||||
* @param string $new_name The new name of the table.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rename_table( $name, $new_name ) {
|
||||
return $this->adapter->rename_table( $name, $new_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a column.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param string $column_name The column name.
|
||||
* @param string $new_column_name The new column name.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function rename_column( $table_name, $column_name, $new_column_name ) {
|
||||
return $this->adapter->rename_column( $table_name, $column_name, $new_column_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a column.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param string $column_name The column name.
|
||||
* @param string $type The column type.
|
||||
* @param array|string $options The options.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function add_column( $table_name, $column_name, $type, $options = [] ) {
|
||||
return $this->adapter->add_column( $table_name, $column_name, $type, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a column.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param string $column_name The column name.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function remove_column( $table_name, $column_name ) {
|
||||
return $this->adapter->remove_column( $table_name, $column_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes a column.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param string $column_name The column name.
|
||||
* @param string $type The column type.
|
||||
* @param array|string $options The options.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function change_column( $table_name, $column_name, $type, $options = [] ) {
|
||||
return $this->adapter->change_column( $table_name, $column_name, $type, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an index.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param array|string $column_name The column name.
|
||||
* @param array|string $options The options.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function add_index( $table_name, $column_name, $options = [] ) {
|
||||
return $this->adapter->add_index( $table_name, $column_name, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an index.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param array|string $column_name The column name.
|
||||
* @param array|string $options The options.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function remove_index( $table_name, $column_name, $options = [] ) {
|
||||
return $this->adapter->remove_index( $table_name, $column_name, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds timestamps.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param string $created_column_name Created at column name.
|
||||
* @param string $updated_column_name Updated at column name.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function add_timestamps( $table_name, $created_column_name = 'created_at', $updated_column_name = 'updated_at' ) {
|
||||
return $this->adapter->add_timestamps( $table_name, $created_column_name, $updated_column_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes timestamps.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param string $created_column_name Created at column name.
|
||||
* @param string $updated_column_name Updated at column name.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function remove_timestamps( $table_name, $created_column_name = 'created_at', $updated_column_name = 'updated_at' ) {
|
||||
return $this->adapter->remove_timestamps( $table_name, $created_column_name, $updated_column_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table.
|
||||
*
|
||||
* @param string $table_name The name of the table.
|
||||
* @param array|string $options The options.
|
||||
*
|
||||
* @return bool|Table
|
||||
*/
|
||||
public function create_table( $table_name, $options = [] ) {
|
||||
return $this->adapter->create_table( $table_name, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query and return the first result.
|
||||
*
|
||||
* @param string $sql The query to run.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function select_one( $sql ) {
|
||||
return $this->adapter->select_one( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query and return all results.
|
||||
*
|
||||
* @param string $sql The query to run.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function select_all( $sql ) {
|
||||
return $this->adapter->select_all( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a query.
|
||||
*
|
||||
* @param string $sql The query to run.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function query( $sql ) {
|
||||
return $this->adapter->query( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a quoted string.
|
||||
*
|
||||
* @param string $str The string to quote.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function quote_string( $str ) {
|
||||
return $this->adapter->quote_string( $str );
|
||||
}
|
||||
}
|
256
wp-content/plugins/wordpress-seo/lib/migrations/table.php
Normal file
256
wp-content/plugins/wordpress-seo/lib/migrations/table.php
Normal file
@ -0,0 +1,256 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib\Migrations;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Yoast migrations table class.
|
||||
*/
|
||||
class Table {
|
||||
|
||||
/**
|
||||
* The adapter.
|
||||
*
|
||||
* @var Adapter
|
||||
*/
|
||||
private $adapter;
|
||||
|
||||
/**
|
||||
* The name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* The options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* The SQL representation of this table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $sql = '';
|
||||
|
||||
/**
|
||||
* Whether or not the table has been initialized.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $initialized = false;
|
||||
|
||||
/**
|
||||
* The columns
|
||||
*
|
||||
* @var Column[]
|
||||
*/
|
||||
private $columns = [];
|
||||
|
||||
/**
|
||||
* The primary keys.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $primary_keys = [];
|
||||
|
||||
/**
|
||||
* Whether or not to auto generate the id.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $auto_generate_id = true;
|
||||
|
||||
/**
|
||||
* Creates an instance of the Adapter.
|
||||
*
|
||||
* @param Adapter $adapter The current adapter.
|
||||
* @param string $name The table name.
|
||||
* @param array $options The options.
|
||||
*
|
||||
* @throws Exception If invalid arguments are passed.
|
||||
*/
|
||||
public function __construct( $adapter, $name, $options = [] ) {
|
||||
// Sanity checks.
|
||||
if ( ! $adapter instanceof Adapter ) {
|
||||
throw new Exception( 'Invalid MySQL Adapter instance.' );
|
||||
}
|
||||
if ( ! $name ) {
|
||||
throw new Exception( "Invalid 'name' parameter" );
|
||||
}
|
||||
$this->adapter = $adapter;
|
||||
$this->name = $name;
|
||||
$this->options = $options;
|
||||
$this->init_sql( $name, $options );
|
||||
if ( \array_key_exists( 'id', $options ) ) {
|
||||
if ( \is_bool( $options['id'] ) && $options['id'] === false ) {
|
||||
$this->auto_generate_id = false;
|
||||
}
|
||||
|
||||
// If its a string then we want to auto-generate an integer-based
|
||||
// primary key with this name.
|
||||
if ( \is_string( $options['id'] ) ) {
|
||||
$this->auto_generate_id = true;
|
||||
$this->primary_keys[] = $options['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a column
|
||||
*
|
||||
* @param string $column_name The column name.
|
||||
* @param string $type The column type.
|
||||
* @param array $options The options.
|
||||
*/
|
||||
public function column( $column_name, $type, $options = [] ) {
|
||||
// If there is already a column by the same name then silently fail and continue.
|
||||
foreach ( $this->columns as $column ) {
|
||||
if ( $column->name === $column_name ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$column_options = [];
|
||||
if ( \array_key_exists( 'primary_key', $options ) ) {
|
||||
if ( $options['primary_key'] ) {
|
||||
$this->primary_keys[] = $column_name;
|
||||
}
|
||||
}
|
||||
if ( \array_key_exists( 'auto_increment', $options ) ) {
|
||||
if ( $options['auto_increment'] ) {
|
||||
$column_options['auto_increment'] = true;
|
||||
}
|
||||
}
|
||||
$column_options = \array_merge( $column_options, $options );
|
||||
$column = new Column( $this->adapter, $column_name, $type, $column_options );
|
||||
$this->columns[] = $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut to create timestamps columns (default created_at, updated_at)
|
||||
*
|
||||
* @param string $created_column_name Created at column name.
|
||||
* @param string $updated_column_name Updated at column name.
|
||||
*/
|
||||
public function timestamps( $created_column_name = 'created_at', $updated_column_name = 'updated_at' ) {
|
||||
$this->column( $created_column_name, 'datetime' );
|
||||
$this->column(
|
||||
$updated_column_name,
|
||||
'timestamp',
|
||||
[
|
||||
'null' => false,
|
||||
'default' => 'CURRENT_TIMESTAMP',
|
||||
'extra' => 'ON UPDATE CURRENT_TIMESTAMP',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all primary keys
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function keys() {
|
||||
if ( \count( $this->primary_keys ) > 0 ) {
|
||||
$lead = ' PRIMARY KEY (';
|
||||
$quoted = [];
|
||||
foreach ( $this->primary_keys as $key ) {
|
||||
$quoted[] = \sprintf( '%s', $this->adapter->identifier( $key ) );
|
||||
}
|
||||
$primary_key_sql = ",\n" . $lead . \implode( ',', $quoted ) . ')';
|
||||
return $primary_key_sql;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Table definition
|
||||
*
|
||||
* @param bool $wants_sql Whether or not to return SQL or execute the query. Defaults to false.
|
||||
*
|
||||
* @return bool|string
|
||||
*
|
||||
* @throws Exception If the table definition has not been intialized.
|
||||
*/
|
||||
public function finish( $wants_sql = false ) {
|
||||
if ( ! $this->initialized ) {
|
||||
throw new Exception( \sprintf( "Table Definition: '%s' has not been initialized", $this->name ) );
|
||||
}
|
||||
$opt_str = '';
|
||||
if ( \is_array( $this->options ) && \array_key_exists( 'options', $this->options ) ) {
|
||||
$opt_str = $this->options['options'];
|
||||
}
|
||||
else {
|
||||
if ( isset( $this->adapter->db_info['charset'] ) ) {
|
||||
$opt_str = ' DEFAULT CHARSET=' . $this->adapter->db_info['charset'];
|
||||
}
|
||||
else {
|
||||
$opt_str = ' DEFAULT CHARSET=utf8';
|
||||
}
|
||||
}
|
||||
$close_sql = \sprintf( ') %s;', $opt_str );
|
||||
$create_table_sql = $this->sql;
|
||||
if ( $this->auto_generate_id === true ) {
|
||||
$this->primary_keys[] = 'id';
|
||||
$primary_id = new Column(
|
||||
$this->adapter,
|
||||
'id',
|
||||
'integer',
|
||||
[
|
||||
'unsigned' => true,
|
||||
'null' => false,
|
||||
'auto_increment' => true,
|
||||
]
|
||||
);
|
||||
$create_table_sql .= $primary_id->to_sql() . ",\n";
|
||||
}
|
||||
$create_table_sql .= $this->columns_to_str();
|
||||
$create_table_sql .= $this->keys() . $close_sql;
|
||||
if ( $wants_sql ) {
|
||||
return $create_table_sql;
|
||||
}
|
||||
return $this->adapter->execute_ddl( $create_table_sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SQL for all columns.
|
||||
*
|
||||
* @return string The SQL.
|
||||
*/
|
||||
private function columns_to_str() {
|
||||
$fields = [];
|
||||
$len = \count( $this->columns );
|
||||
for ( $i = 0; $i < $len; $i++ ) {
|
||||
$c = $this->columns[ $i ];
|
||||
$fields[] = $c->__toString();
|
||||
}
|
||||
return \implode( ",\n", $fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init create sql statement.
|
||||
*
|
||||
* @param string $name The name.
|
||||
* @param array $options The options.
|
||||
*/
|
||||
private function init_sql( $name, $options ) {
|
||||
// Are we forcing table creation? If so, drop it first.
|
||||
if ( \array_key_exists( 'force', $options ) && $options['force'] === true ) {
|
||||
$this->adapter->drop_table( $name );
|
||||
}
|
||||
$temp = '';
|
||||
if ( \array_key_exists( 'temporary', $options ) ) {
|
||||
$temp = ' TEMPORARY';
|
||||
}
|
||||
$create_sql = \sprintf( 'CREATE%s TABLE ', $temp );
|
||||
$create_sql .= \sprintf( "%s (\n", $this->adapter->identifier( $name ) );
|
||||
$this->sql .= $create_sql;
|
||||
$this->initialized = true;
|
||||
}
|
||||
}
|
729
wp-content/plugins/wordpress-seo/lib/model.php
Normal file
729
wp-content/plugins/wordpress-seo/lib/model.php
Normal file
@ -0,0 +1,729 @@
|
||||
<?php
|
||||
|
||||
namespace Yoast\WP\Lib;
|
||||
|
||||
use JsonSerializable;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Make Model compatible with WordPress.
|
||||
*
|
||||
* Model base class. Your model objects should extend
|
||||
* this class. A minimal subclass would look like:
|
||||
*
|
||||
* class Widget extends Model {
|
||||
* }
|
||||
*/
|
||||
class Model implements JsonSerializable {
|
||||
|
||||
/**
|
||||
* Default ID column for all models. Can be overridden by adding
|
||||
* a public static $id_column property to your model classes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DEFAULT_ID_COLUMN = 'id';
|
||||
|
||||
/**
|
||||
* Default foreign key suffix used by relationship methods.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DEFAULT_FOREIGN_KEY_SUFFIX = '_id';
|
||||
|
||||
/**
|
||||
* Set a prefix for model names. This can be a namespace or any other
|
||||
* abitrary prefix such as the PEAR naming convention.
|
||||
*
|
||||
* @example Model::$auto_prefix_models = 'MyProject_MyModels_'; //PEAR
|
||||
* @example Model::$auto_prefix_models = '\MyProject\MyModels\'; //Namespaces
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $auto_prefix_models = '\Yoast\WP\SEO\Models\\';
|
||||
|
||||
/**
|
||||
* Set true to to ignore namespace information when computing table names
|
||||
* from class names.
|
||||
*
|
||||
* @example Model::$short_table_names = true;
|
||||
* @example Model::$short_table_names = false; // default
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $short_table_names = false;
|
||||
|
||||
/**
|
||||
* The ORM instance used by this model instance to communicate with the database.
|
||||
*
|
||||
* @var ORM
|
||||
*/
|
||||
public $orm;
|
||||
|
||||
/**
|
||||
* The table name for the implemented Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $table;
|
||||
|
||||
/**
|
||||
* Whether or not this model uses timestamps.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $uses_timestamps = false;
|
||||
|
||||
/**
|
||||
* Which columns contain boolean values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $boolean_columns = [];
|
||||
|
||||
/**
|
||||
* Which columns contain int values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $int_columns = [];
|
||||
|
||||
/**
|
||||
* Which columns contain float values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $float_columns = [];
|
||||
|
||||
/**
|
||||
* Hacks around the Model to provide WordPress prefix to tables.
|
||||
*
|
||||
* @param string $class_name Type of Model to load.
|
||||
* @param bool $yoast_prefix Optional. True to prefix the table name with the Yoast prefix.
|
||||
*
|
||||
* @return ORM Wrapper to use.
|
||||
*/
|
||||
public static function of_type( $class_name, $yoast_prefix = true ) {
|
||||
// Prepend namespace to the class name.
|
||||
$class = static::$auto_prefix_models . $class_name;
|
||||
|
||||
// Set the class variable to the custom value based on the WPDB prefix.
|
||||
$class::$table = static::get_table_name( $class_name, $yoast_prefix );
|
||||
|
||||
return static::factory( $class_name, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a model without the Yoast prefix.
|
||||
*
|
||||
* @param string $class_name Type of Model to load.
|
||||
*
|
||||
* @return ORM
|
||||
*/
|
||||
public static function of_wp_type( $class_name ) {
|
||||
return static::of_type( $class_name, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes method to get the table name to use.
|
||||
*
|
||||
* @param string $table_name Simple table name.
|
||||
* @param bool $yoast_prefix Optional. True to prefix the table name with the Yoast prefix.
|
||||
*
|
||||
* @return string Prepared full table name.
|
||||
*/
|
||||
public static function get_table_name( $table_name, $yoast_prefix = true ) {
|
||||
global $wpdb;
|
||||
|
||||
// Allow the use of WordPress internal tables.
|
||||
if ( $yoast_prefix ) {
|
||||
$table_name = 'yoast_' . $table_name;
|
||||
}
|
||||
|
||||
return $wpdb->prefix . \strtolower( $table_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the table name for the given class name.
|
||||
*
|
||||
* @param string $class_name The class to set the table name for.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function set_table_name( $class_name ) {
|
||||
// Prepend namespace to the class name.
|
||||
$class = static::$auto_prefix_models . $class_name;
|
||||
|
||||
$class::$table = static::get_table_name( $class_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value of a static property on a class. If the
|
||||
* class or the property does not exist, returns the default
|
||||
* value supplied as the third argument (which defaults to null).
|
||||
*
|
||||
* @param string $class_name The target class name.
|
||||
* @param string $property The property to get the value for.
|
||||
* @param mixed|null $default_value Default value when property does not exist.
|
||||
*
|
||||
* @return mixed|null The value of the property.
|
||||
*/
|
||||
protected static function get_static_property( $class_name, $property, $default_value = null ) {
|
||||
if ( ! \class_exists( $class_name ) || ! \property_exists( $class_name, $property ) ) {
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
if ( ! isset( $class_name::${$property} ) ) {
|
||||
return $default_value;
|
||||
}
|
||||
|
||||
return $class_name::${$property};
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to get a table name given a class name.
|
||||
* If the supplied class has a public static property
|
||||
* named $table, the value of this property will be
|
||||
* returned.
|
||||
*
|
||||
* If not, the class name will be converted using
|
||||
* the class_name_to_table_name() method.
|
||||
*
|
||||
* If Model::$short_table_names == true or public static
|
||||
* property $table_use_short_name == true then $class_name passed
|
||||
* to class_name_to_table_name() is stripped of namespace information.
|
||||
*
|
||||
* @param string $class_name The class name to get the table name for.
|
||||
*
|
||||
* @return string The table name.
|
||||
*/
|
||||
protected static function get_table_name_for_class( $class_name ) {
|
||||
$specified_table_name = static::get_static_property( $class_name, 'table' );
|
||||
$use_short_class_name = static::use_short_table_name( $class_name );
|
||||
if ( $use_short_class_name ) {
|
||||
$exploded_class_name = \explode( '\\', $class_name );
|
||||
$class_name = \end( $exploded_class_name );
|
||||
}
|
||||
|
||||
if ( $specified_table_name === null ) {
|
||||
return static::class_name_to_table_name( $class_name );
|
||||
}
|
||||
|
||||
return $specified_table_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should short table names, disregarding class namespaces, be computed?
|
||||
*
|
||||
* $class_property overrides $global_option, unless $class_property is null.
|
||||
*
|
||||
* @param string $class_name The class name to get short name for.
|
||||
*
|
||||
* @return bool True when short table name should be used.
|
||||
*/
|
||||
protected static function use_short_table_name( $class_name ) {
|
||||
$class_property = static::get_static_property( $class_name, 'table_use_short_name' );
|
||||
|
||||
if ( $class_property === null ) {
|
||||
return static::$short_table_names;
|
||||
}
|
||||
|
||||
return $class_property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a namespace to the standard PEAR underscore format.
|
||||
*
|
||||
* Then convert a class name in CapWords to a table name in
|
||||
* lowercase_with_underscores.
|
||||
*
|
||||
* Finally strip doubled up underscores.
|
||||
*
|
||||
* For example, CarTyre would be converted to car_tyre. And
|
||||
* Project\Models\CarTyre would be project_models_car_tyre.
|
||||
*
|
||||
* @param string $class_name The class name to get the table name for.
|
||||
*
|
||||
* @return string The table name.
|
||||
*/
|
||||
protected static function class_name_to_table_name( $class_name ) {
|
||||
$find = [
|
||||
'/\\\\/',
|
||||
'/(?<=[a-z])([A-Z])/',
|
||||
'/__/',
|
||||
];
|
||||
$replacements = [
|
||||
'_',
|
||||
'_$1',
|
||||
'_',
|
||||
];
|
||||
|
||||
$class_name = \ltrim( $class_name, '\\' );
|
||||
$class_name = \preg_replace( $find, $replacements, $class_name );
|
||||
|
||||
return \strtolower( $class_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ID column name to use for this class. If it is
|
||||
* not set on the class, returns null.
|
||||
*
|
||||
* @param string $class_name The class name to get the ID column for.
|
||||
*
|
||||
* @return string|null The ID column name.
|
||||
*/
|
||||
protected static function get_id_column_name( $class_name ) {
|
||||
return static::get_static_property( $class_name, 'id_column', static::DEFAULT_ID_COLUMN );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a foreign key based on a table name. If the first argument
|
||||
* (the specified foreign key column name) is null, returns the second
|
||||
* argument (the name of the table) with the default foreign key column
|
||||
* suffix appended.
|
||||
*
|
||||
* @param string $specified_foreign_key_name The keyname to build.
|
||||
* @param string $table_name The table name to build the key name for.
|
||||
*
|
||||
* @return string The built foreign key name.
|
||||
*/
|
||||
protected static function build_foreign_key_name( $specified_foreign_key_name, $table_name ) {
|
||||
if ( $specified_foreign_key_name !== null ) {
|
||||
return $specified_foreign_key_name;
|
||||
}
|
||||
|
||||
return $table_name . static::DEFAULT_FOREIGN_KEY_SUFFIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method used to acquire instances of the given class.
|
||||
* The class name should be supplied as a string, and the class
|
||||
* should already have been loaded by PHP (or a suitable autoloader
|
||||
* should exist). This method actually returns a wrapped ORM object
|
||||
* which allows a database query to be built. The wrapped ORM object is
|
||||
* responsible for returning instances of the correct class when
|
||||
* its find_one or find_many methods are called.
|
||||
*
|
||||
* @param string $class_name The target class name.
|
||||
*
|
||||
* @return ORM Instance of the ORM wrapper.
|
||||
*/
|
||||
public static function factory( $class_name ) {
|
||||
$class_name = static::$auto_prefix_models . $class_name;
|
||||
$table_name = static::get_table_name_for_class( $class_name );
|
||||
$wrapper = ORM::for_table( $table_name );
|
||||
$wrapper->set_class_name( $class_name );
|
||||
$wrapper->use_id_column( static::get_id_column_name( $class_name ) );
|
||||
|
||||
return $wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to construct the queries for both the has_one and
|
||||
* has_many methods. These two types of association are identical; the
|
||||
* only difference is whether find_one or find_many is used to complete
|
||||
* the method chain.
|
||||
*
|
||||
* @param string $associated_class_name The associated class name.
|
||||
* @param string|null $foreign_key_name The foreign key name in the associated table.
|
||||
* @param string|null $foreign_key_name_in_current_models_table The foreign key in the current models table.
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*
|
||||
* @throws \Exception When ID of current model has a null value.
|
||||
*/
|
||||
protected function has_one_or_many( $associated_class_name, $foreign_key_name = null, $foreign_key_name_in_current_models_table = null ) {
|
||||
$base_table_name = static::get_table_name_for_class( \get_class( $this ) );
|
||||
$foreign_key_name = static::build_foreign_key_name( $foreign_key_name, $base_table_name );
|
||||
|
||||
/*
|
||||
* Value of foreign_table.{$foreign_key_name} we're looking for. Where foreign_table is the actual
|
||||
* database table in the associated model.
|
||||
*/
|
||||
if ( $foreign_key_name_in_current_models_table === null ) {
|
||||
// Matches foreign_table.{$foreign_key_name} with the value of "{$this->table}.{$this->id()}".
|
||||
$where_value = $this->id();
|
||||
}
|
||||
else {
|
||||
// Matches foreign_table.{$foreign_key_name} with "{$this->table}.{$foreign_key_name_in_current_models_table}".
|
||||
$where_value = $this->{$foreign_key_name_in_current_models_table};
|
||||
}
|
||||
|
||||
return static::factory( $associated_class_name )->where( $foreign_key_name, $where_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to manage one-to-one relations where the foreign
|
||||
* key is on the associated table.
|
||||
*
|
||||
* @param string $associated_class_name The associated class name.
|
||||
* @param string|null $foreign_key_name The foreign key name in the associated table.
|
||||
* @param string|null $foreign_key_name_in_current_models_table The foreign key in the current models table.
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*
|
||||
* @throws \Exception When ID of current model has a null value.
|
||||
*/
|
||||
protected function has_one( $associated_class_name, $foreign_key_name = null, $foreign_key_name_in_current_models_table = null ) {
|
||||
return $this->has_one_or_many( $associated_class_name, $foreign_key_name, $foreign_key_name_in_current_models_table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to manage one-to-many relations where the foreign
|
||||
* key is on the associated table.
|
||||
*
|
||||
* @param string $associated_class_name The associated class name.
|
||||
* @param string|null $foreign_key_name The foreign key name in the associated table.
|
||||
* @param string|null $foreign_key_name_in_current_models_table The foreign key in the current models table.
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*
|
||||
* @throws \Exception When ID has a null value.
|
||||
*/
|
||||
protected function has_many( $associated_class_name, $foreign_key_name = null, $foreign_key_name_in_current_models_table = null ) {
|
||||
$this->set_table_name( $associated_class_name );
|
||||
|
||||
return $this->has_one_or_many( $associated_class_name, $foreign_key_name, $foreign_key_name_in_current_models_table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to manage one-to-one and one-to-many relations where
|
||||
* the foreign key is on the base table.
|
||||
*
|
||||
* @param string $associated_class_name The associated class name.
|
||||
* @param string|null $foreign_key_name The foreign key in the current models table.
|
||||
* @param string|null $foreign_key_name_in_associated_models_table The foreign key in the associated table.
|
||||
*
|
||||
* @return $this|null Instance of the foreign model.
|
||||
*/
|
||||
protected function belongs_to( $associated_class_name, $foreign_key_name = null, $foreign_key_name_in_associated_models_table = null ) {
|
||||
$this->set_table_name( $associated_class_name );
|
||||
|
||||
$associated_table_name = static::get_table_name_for_class( static::$auto_prefix_models . $associated_class_name );
|
||||
$foreign_key_name = static::build_foreign_key_name( $foreign_key_name, $associated_table_name );
|
||||
$associated_object_id = $this->{$foreign_key_name};
|
||||
|
||||
if ( $foreign_key_name_in_associated_models_table === null ) {
|
||||
/*
|
||||
* Comparison: "{$associated_table_name}.primary_key = {$associated_object_id}".
|
||||
*
|
||||
* NOTE: primary_key is a placeholder for the actual primary key column's name in $associated_table_name.
|
||||
*/
|
||||
return static::factory( $associated_class_name )->where_id_is( $associated_object_id );
|
||||
}
|
||||
|
||||
// Comparison: "{$associated_table_name}.{$foreign_key_name_in_associated_models_table} = {$associated_object_id}".
|
||||
return static::factory( $associated_class_name )
|
||||
->where( $foreign_key_name_in_associated_models_table, $associated_object_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to manage many-to-many relationships via an intermediate model. See
|
||||
* README for a full explanation of the parameters.
|
||||
*
|
||||
* @param string $associated_class_name The associated class name.
|
||||
* @param string|null $join_class_name The class name to join.
|
||||
* @param string|null $key_to_base_table The key to the the current models table.
|
||||
* @param string|null $key_to_associated_table The key to the associated table.
|
||||
* @param string|null $key_in_base_table The key in the current models table.
|
||||
* @param string|null $key_in_associated_table The key in the associated table.
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*/
|
||||
protected function has_many_through( $associated_class_name, $join_class_name = null, $key_to_base_table = null, $key_to_associated_table = null, $key_in_base_table = null, $key_in_associated_table = null ) {
|
||||
$base_class_name = \get_class( $this );
|
||||
|
||||
/*
|
||||
* The class name of the join model, if not supplied, is formed by
|
||||
* concatenating the names of the base class and the associated class,
|
||||
* in alphabetical order.
|
||||
*/
|
||||
if ( $join_class_name === null ) {
|
||||
$base_model = \explode( '\\', $base_class_name );
|
||||
$base_model_name = \end( $base_model );
|
||||
if ( \strpos( $base_model_name, static::$auto_prefix_models ) === 0 ) {
|
||||
$base_model_name = \substr( $base_model_name, \strlen( static::$auto_prefix_models ), \strlen( $base_model_name ) );
|
||||
}
|
||||
// Paris wasn't checking the name settings for the associated class.
|
||||
$associated_model = \explode( '\\', $associated_class_name );
|
||||
$associated_model_name = \end( $associated_model );
|
||||
if ( \strpos( $associated_model_name, static::$auto_prefix_models ) === 0 ) {
|
||||
$associated_model_name = \substr( $associated_model_name, \strlen( static::$auto_prefix_models ), \strlen( $associated_model_name ) );
|
||||
}
|
||||
$class_names = [ $base_model_name, $associated_model_name ];
|
||||
\sort( $class_names, \SORT_STRING );
|
||||
$join_class_name = \implode( '', $class_names );
|
||||
}
|
||||
|
||||
// Get table names for each class.
|
||||
$base_table_name = static::get_table_name_for_class( $base_class_name );
|
||||
$associated_table_name = static::get_table_name_for_class( static::$auto_prefix_models . $associated_class_name );
|
||||
$join_table_name = static::get_table_name_for_class( static::$auto_prefix_models . $join_class_name );
|
||||
|
||||
// Get ID column names.
|
||||
$base_table_id_column = ( $key_in_base_table === null ) ? static::get_id_column_name( $base_class_name ) : $key_in_base_table;
|
||||
$associated_table_id_column = ( $key_in_associated_table === null ) ? static::get_id_column_name( static::$auto_prefix_models . $associated_class_name ) : $key_in_associated_table;
|
||||
|
||||
// Get the column names for each side of the join table.
|
||||
$key_to_base_table = static::build_foreign_key_name( $key_to_base_table, $base_table_name );
|
||||
$key_to_associated_table = static::build_foreign_key_name( $key_to_associated_table, $associated_table_name );
|
||||
|
||||
/* phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- Reason: This is commented out code.
|
||||
" SELECT {$associated_table_name}.*
|
||||
FROM {$associated_table_name} JOIN {$join_table_name}
|
||||
ON {$associated_table_name}.{$associated_table_id_column} = {$join_table_name}.{$key_to_associated_table}
|
||||
WHERE {$join_table_name}.{$key_to_base_table} = {$this->$base_table_id_column} ;"
|
||||
*/
|
||||
|
||||
return static::factory( $associated_class_name )
|
||||
->select( "{$associated_table_name}.*" )
|
||||
->join(
|
||||
$join_table_name,
|
||||
[
|
||||
"{$associated_table_name}.{$associated_table_id_column}",
|
||||
'=',
|
||||
"{$join_table_name}.{$key_to_associated_table}",
|
||||
]
|
||||
)
|
||||
->where( "{$join_table_name}.{$key_to_base_table}", $this->{$base_table_id_column} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the wrapped ORM instance associated with this Model instance.
|
||||
*
|
||||
* @param ORM $orm The ORM instance to set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_orm( $orm ) {
|
||||
$this->orm = $orm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter method, allows $model->property access to data.
|
||||
*
|
||||
* @param string $property The property to get.
|
||||
*
|
||||
* @return mixed The value of the property
|
||||
*/
|
||||
public function __get( $property ) {
|
||||
$value = $this->orm->get( $property );
|
||||
|
||||
if ( $value !== null && \in_array( $property, $this->boolean_columns, true ) ) {
|
||||
return (bool) $value;
|
||||
}
|
||||
if ( $value !== null && \in_array( $property, $this->int_columns, true ) ) {
|
||||
return (int) $value;
|
||||
}
|
||||
if ( $value !== null && \in_array( $property, $this->float_columns, true ) ) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic setter method, allows $model->property = 'value' access to data.
|
||||
*
|
||||
* @param string $property The property to set.
|
||||
* @param string $value The value to set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __set( $property, $value ) {
|
||||
if ( $value !== null && \in_array( $property, $this->boolean_columns, true ) ) {
|
||||
$value = ( $value ) ? '1' : '0';
|
||||
}
|
||||
if ( $value !== null && \in_array( $property, $this->int_columns, true ) ) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
if ( $value !== null && \in_array( $property, $this->float_columns, true ) ) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
$this->orm->set( $property, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic unset method, allows unset($model->property)
|
||||
*
|
||||
* @param string $property The property to unset.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __unset( $property ) {
|
||||
$this->orm->__unset( $property );
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON serializer.
|
||||
*
|
||||
* @return array The data of this object.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize() {
|
||||
return $this->orm->as_array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips all nested dependencies from the debug info.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo() {
|
||||
if ( $this->orm ) {
|
||||
return $this->orm->as_array();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic isset method, allows isset($model->property) to work correctly.
|
||||
*
|
||||
* @param string $property The property to check.
|
||||
*
|
||||
* @return bool True when value is set.
|
||||
*/
|
||||
public function __isset( $property ) {
|
||||
return $this->orm->__isset( $property );
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method, allows $model->get('property') access to data
|
||||
*
|
||||
* @param string $property The property to get.
|
||||
*
|
||||
* @return string The value of a property.
|
||||
*/
|
||||
public function get( $property ) {
|
||||
return $this->orm->get( $property );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter method, allows $model->set('property', 'value') access to data.
|
||||
*
|
||||
* @param string|array $property The property to set.
|
||||
* @param string|null $value The value to give.
|
||||
*
|
||||
* @return static Current object.
|
||||
*/
|
||||
public function set( $property, $value = null ) {
|
||||
$this->orm->set( $property, $value );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter method, allows $model->set_expr('property', 'value') access to data.
|
||||
*
|
||||
* @param string|array $property The property to set.
|
||||
* @param string|null $value The value to give.
|
||||
*
|
||||
* @return static Current object.
|
||||
*/
|
||||
public function set_expr( $property, $value = null ) {
|
||||
$this->orm->set_expr( $property, $value );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given property has changed since the object was created or saved.
|
||||
*
|
||||
* @param string $property The property to check.
|
||||
*
|
||||
* @return bool True when field is changed.
|
||||
*/
|
||||
public function is_dirty( $property ) {
|
||||
return $this->orm->is_dirty( $property );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the model was the result of a call to create() or not.
|
||||
*
|
||||
* @return bool True when is new.
|
||||
*/
|
||||
public function is_new() {
|
||||
return $this->orm->is_new();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for Idiorm's as_array method.
|
||||
*
|
||||
* @return array The models data as array.
|
||||
*/
|
||||
public function as_array() {
|
||||
$args = \func_get_args();
|
||||
|
||||
return \call_user_func_array( [ $this->orm, 'as_array' ], $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the data associated with this model instance to the database.
|
||||
*
|
||||
* @return bool True on success.
|
||||
*/
|
||||
public function save() {
|
||||
if ( $this->uses_timestamps ) {
|
||||
if ( ! $this->created_at ) {
|
||||
$this->created_at = \gmdate( 'Y-m-d H:i:s' );
|
||||
}
|
||||
$this->updated_at = \gmdate( 'Y-m-d H:i:s' );
|
||||
}
|
||||
|
||||
return $this->orm->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the database row associated with this model instance.
|
||||
*
|
||||
* @return bool|int Response of wpdb::query.
|
||||
*/
|
||||
public function delete() {
|
||||
return $this->orm->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database ID of this model instance.
|
||||
*
|
||||
* @return int The database ID of the models instance.
|
||||
*
|
||||
* @throws \Exception When the ID is a null value.
|
||||
*/
|
||||
public function id() {
|
||||
return $this->orm->id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hydrate this model instance with an associative array of data.
|
||||
* WARNING: The keys in the array MUST match with columns in the
|
||||
* corresponding database table. If any keys are supplied which
|
||||
* do not match up with columns, the database will throw an error.
|
||||
*
|
||||
* @param array $data The data to pass to the ORM.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hydrate( $data ) {
|
||||
$this->orm->hydrate( $data )->force_all_dirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls static methods directly on the ORM
|
||||
*
|
||||
* @param string $method The method to call.
|
||||
* @param array $arguments The arguments to use.
|
||||
*
|
||||
* @return array Result of the static call.
|
||||
*/
|
||||
public static function __callStatic( $method, $arguments ) {
|
||||
if ( ! \function_exists( 'get_called_class' ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$model = static::factory( \get_called_class() );
|
||||
|
||||
return \call_user_func_array( [ $model, $method ], $arguments );
|
||||
}
|
||||
}
|
2544
wp-content/plugins/wordpress-seo/lib/orm.php
Normal file
2544
wp-content/plugins/wordpress-seo/lib/orm.php
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user