Merged in feature/314-dev-dev01 (pull request #24)
auto-patch 314-dev-dev01-2024-01-25T04_09_02 * auto-patch 314-dev-dev01-2024-01-25T04_09_02
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
namespace Yoast\WP\Lib;
|
||||
|
||||
use Exception;
|
||||
use WPSEO_Utils;
|
||||
use Yoast\WP\Lib\Dependency_Injection\Container_Registry;
|
||||
use Yoast\WP\SEO\Exceptions\Forbidden_Property_Mutation_Exception;
|
||||
use Yoast\WP\SEO\Loader;
|
||||
@@ -30,6 +31,8 @@ abstract class Abstract_Main {
|
||||
/**
|
||||
* Loads the plugin.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws Exception If loading fails and YOAST_ENVIRONMENT is development.
|
||||
*/
|
||||
public function load() {
|
||||
@@ -78,7 +81,7 @@ abstract class Abstract_Main {
|
||||
|
||||
return $this->cached_surfaces[ $property ];
|
||||
}
|
||||
throw new Exception( sprintf( 'Property $%s does not exist.', $property ) );
|
||||
throw new Exception( \sprintf( 'Property $%s does not exist.', $property ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +164,7 @@ abstract class Abstract_Main {
|
||||
*/
|
||||
protected function is_development() {
|
||||
try {
|
||||
return \WPSEO_Utils::is_development_mode();
|
||||
return WPSEO_Utils::is_development_mode();
|
||||
}
|
||||
catch ( Exception $exception ) {
|
||||
// E.g. when WordPress and/or WordPress SEO are not loaded.
|
||||
|
||||
@@ -29,7 +29,7 @@ class Container_Registry {
|
||||
self::$containers[ $name ] = $container;
|
||||
}
|
||||
|
||||
// phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber -- PHPCS doesn't take into account exceptions thrown in called methods.
|
||||
// phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber -- PHPCS doesn't take into account exceptions thrown in called methods.
|
||||
|
||||
/**
|
||||
* Get an instance from a specific container.
|
||||
@@ -53,7 +53,7 @@ class Container_Registry {
|
||||
return self::$containers[ $name ]->get( $id, $invalid_behaviour );
|
||||
}
|
||||
|
||||
// phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
// phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
|
||||
/**
|
||||
* Attempts to find a given service ID in all registered containers.
|
||||
|
||||
@@ -125,6 +125,8 @@ class Adapter {
|
||||
|
||||
/**
|
||||
* Create the schema table, if necessary.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function create_schema_version_table() {
|
||||
if ( ! $this->has_table( $this->get_schema_version_table_name() ) ) {
|
||||
@@ -137,6 +139,8 @@ class Adapter {
|
||||
|
||||
/**
|
||||
* Starts a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function start_transaction() {
|
||||
if ( $this->in_transaction() === false ) {
|
||||
@@ -146,6 +150,8 @@ class Adapter {
|
||||
|
||||
/**
|
||||
* Commits a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function commit_transaction() {
|
||||
if ( $this->in_transaction() ) {
|
||||
@@ -155,6 +161,8 @@ class Adapter {
|
||||
|
||||
/**
|
||||
* Rollbacks a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rollback_transaction() {
|
||||
if ( $this->in_transaction() ) {
|
||||
@@ -293,7 +301,7 @@ class Adapter {
|
||||
$query_type = $this->determine_query_type( $query );
|
||||
$data = [];
|
||||
if ( $query_type === Constants::SQL_SELECT || $query_type === Constants::SQL_SHOW ) {
|
||||
$data = $wpdb->get_results( $query, ARRAY_A );
|
||||
$data = $wpdb->get_results( $query, \ARRAY_A );
|
||||
if ( $data === false ) {
|
||||
return false;
|
||||
}
|
||||
@@ -794,10 +802,8 @@ class Adapter {
|
||||
$column_type_sql .= \sprintf( '(%d)', $precision );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( $scale ) {
|
||||
throw new Exception( "Error adding $type column: precision cannot be empty if scale is specified" );
|
||||
}
|
||||
elseif ( $scale ) {
|
||||
throw new Exception( "Error adding $type column: precision cannot be empty if scale is specified" );
|
||||
}
|
||||
}
|
||||
elseif ( $type === 'enum' ) {
|
||||
|
||||
@@ -7,16 +7,16 @@ namespace Yoast\WP\Lib\Migrations;
|
||||
*/
|
||||
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;
|
||||
public const MYSQL_MAX_IDENTIFIER_LENGTH = 64;
|
||||
public const SQL_UNKNOWN_QUERY_TYPE = 1;
|
||||
public const SQL_SELECT = 2;
|
||||
public const SQL_INSERT = 4;
|
||||
public const SQL_UPDATE = 8;
|
||||
public const SQL_DELETE = 16;
|
||||
public const SQL_ALTER = 32;
|
||||
public const SQL_DROP = 64;
|
||||
public const SQL_CREATE = 128;
|
||||
public const SQL_SHOW = 256;
|
||||
public const SQL_RENAME = 512;
|
||||
public const SQL_SET = 1024;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ class Table {
|
||||
* @param string $column_name The column name.
|
||||
* @param string $type The column type.
|
||||
* @param array $options The options.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function column( $column_name, $type, $options = [] ) {
|
||||
// If there is already a column by the same name then silently fail and continue.
|
||||
@@ -136,6 +138,8 @@ class Table {
|
||||
*
|
||||
* @param string $created_column_name Created at column name.
|
||||
* @param string $updated_column_name Updated at column name.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function timestamps( $created_column_name = 'created_at', $updated_column_name = 'updated_at' ) {
|
||||
$this->column( $created_column_name, 'datetime' );
|
||||
@@ -186,13 +190,11 @@ class Table {
|
||||
if ( \is_array( $this->options ) && \array_key_exists( 'options', $this->options ) ) {
|
||||
$opt_str = $this->options['options'];
|
||||
}
|
||||
elseif ( isset( $this->adapter->db_info['charset'] ) ) {
|
||||
$opt_str = ' DEFAULT CHARSET=' . $this->adapter->db_info['charset'];
|
||||
}
|
||||
else {
|
||||
if ( isset( $this->adapter->db_info['charset'] ) ) {
|
||||
$opt_str = ' DEFAULT CHARSET=' . $this->adapter->db_info['charset'];
|
||||
}
|
||||
else {
|
||||
$opt_str = ' DEFAULT CHARSET=utf8';
|
||||
}
|
||||
$opt_str = ' DEFAULT CHARSET=utf8';
|
||||
}
|
||||
$close_sql = \sprintf( ') %s;', $opt_str );
|
||||
$create_table_sql = $this->sql;
|
||||
@@ -238,6 +240,8 @@ class Table {
|
||||
*
|
||||
* @param string $name The name.
|
||||
* @param array $options The options.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function init_sql( $name, $options ) {
|
||||
// Are we forcing table creation? If so, drop it first.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Yoast\WP\Lib;
|
||||
|
||||
use Exception;
|
||||
use JsonSerializable;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
@@ -22,14 +23,14 @@ class Model implements JsonSerializable {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DEFAULT_ID_COLUMN = 'id';
|
||||
public const DEFAULT_ID_COLUMN = 'id';
|
||||
|
||||
/**
|
||||
* Default foreign key suffix used by relationship methods.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const DEFAULT_FOREIGN_KEY_SUFFIX = '_id';
|
||||
public const DEFAULT_FOREIGN_KEY_SUFFIX = '_id';
|
||||
|
||||
/**
|
||||
* Set a prefix for model names. This can be a namespace or any other
|
||||
@@ -330,10 +331,10 @@ class Model implements JsonSerializable {
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*
|
||||
* @throws \Exception When ID of current model has a null value.
|
||||
* @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 ) );
|
||||
$base_table_name = static::get_table_name_for_class( static::class );
|
||||
$foreign_key_name = static::build_foreign_key_name( $foreign_key_name, $base_table_name );
|
||||
|
||||
/*
|
||||
@@ -362,7 +363,7 @@ class Model implements JsonSerializable {
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*
|
||||
* @throws \Exception When ID of current model has a null value.
|
||||
* @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 );
|
||||
@@ -378,7 +379,7 @@ class Model implements JsonSerializable {
|
||||
*
|
||||
* @return ORM Instance of the ORM.
|
||||
*
|
||||
* @throws \Exception When ID has a null value.
|
||||
* @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 );
|
||||
@@ -431,7 +432,7 @@ class Model implements JsonSerializable {
|
||||
* @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 );
|
||||
$base_class_name = static::class;
|
||||
|
||||
/*
|
||||
* The class name of the join model, if not supplied, is formed by
|
||||
@@ -689,7 +690,7 @@ class Model implements JsonSerializable {
|
||||
*
|
||||
* @return int The database ID of the models instance.
|
||||
*
|
||||
* @throws \Exception When the ID is a null value.
|
||||
* @throws Exception When the ID is a null value.
|
||||
*/
|
||||
public function id() {
|
||||
return $this->orm->id();
|
||||
@@ -722,7 +723,7 @@ class Model implements JsonSerializable {
|
||||
return [];
|
||||
}
|
||||
|
||||
$model = static::factory( \get_called_class() );
|
||||
$model = static::factory( static::class );
|
||||
|
||||
return \call_user_func_array( [ $model, $method ], $arguments );
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Yoast\WP\Lib;
|
||||
|
||||
use ArrayAccess;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use ReturnTypeWillChange;
|
||||
use wpdb;
|
||||
use Yoast\WP\SEO\Config\Migration_Status;
|
||||
@@ -48,15 +51,15 @@ use Yoast\WP\SEO\Config\Migration_Status;
|
||||
*
|
||||
* @see http://www.php-fig.org/psr/psr-1/
|
||||
*/
|
||||
class ORM implements \ArrayAccess {
|
||||
class ORM implements ArrayAccess {
|
||||
|
||||
/*
|
||||
* --- CLASS CONSTANTS ---
|
||||
*/
|
||||
|
||||
const CONDITION_FRAGMENT = 0;
|
||||
public const CONDITION_FRAGMENT = 0;
|
||||
|
||||
const CONDITION_VALUES = 1;
|
||||
public const CONDITION_VALUES = 1;
|
||||
|
||||
/*
|
||||
* --- INSTANCE PROPERTIES ---
|
||||
@@ -270,13 +273,13 @@ class ORM implements \ArrayAccess {
|
||||
|
||||
$show_errors = $wpdb->show_errors;
|
||||
|
||||
if ( YoastSEO()->classes->get( Migration_Status::class )->get_error( 'free' ) ) {
|
||||
if ( \YoastSEO()->classes->get( Migration_Status::class )->get_error( 'free' ) ) {
|
||||
$wpdb->show_errors = false;
|
||||
}
|
||||
|
||||
$parameters = \array_filter(
|
||||
$parameters,
|
||||
static function( $parameter ) {
|
||||
static function ( $parameter ) {
|
||||
return $parameter !== null;
|
||||
}
|
||||
);
|
||||
@@ -537,7 +540,7 @@ class ORM implements \ArrayAccess {
|
||||
if ( ! \is_numeric( $result->{$alias} ) ) {
|
||||
$return_value = $result->{$alias};
|
||||
}
|
||||
// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison -- Reason: This loose comparison seems intended.
|
||||
// phpcs:ignore Universal.Operators.StrictComparisons -- Reason: This loose comparison seems intentional.
|
||||
elseif ( (int) $result->{$alias} == (float) $result->{$alias} ) {
|
||||
$return_value = (int) $result->{$alias};
|
||||
}
|
||||
@@ -634,8 +637,8 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @return int The amount of null columns.
|
||||
*
|
||||
* @throws \Exception Primary key ID contains null value(s).
|
||||
* @throws \Exception Primary key ID missing from row or is null.
|
||||
* @throws Exception Primary key ID contains null value(s).
|
||||
* @throws Exception Primary key ID missing from row or is null.
|
||||
*/
|
||||
public function count_null_id_columns() {
|
||||
if ( \is_array( $this->get_id_column_name() ) ) {
|
||||
@@ -1155,7 +1158,7 @@ class ORM implements \ArrayAccess {
|
||||
protected function get_compound_id_column_values( $value ) {
|
||||
$filtered = [];
|
||||
foreach ( $this->get_id_column_name() as $key ) {
|
||||
$filtered[ $key ] = isset( $value[ $key ] ) ? $value[ $key ] : null;
|
||||
$filtered[ $key ] = ( $value[ $key ] ?? null );
|
||||
}
|
||||
|
||||
return $filtered;
|
||||
@@ -1257,7 +1260,7 @@ class ORM implements \ArrayAccess {
|
||||
}
|
||||
$firstsub = true;
|
||||
foreach ( $value as $key => $item ) {
|
||||
$op = \is_string( $operator ) ? $operator : ( isset( $operator[ $key ] ) ? $operator[ $key ] : '=' );
|
||||
$op = \is_string( $operator ) ? $operator : ( $operator[ $key ] ?? '=' );
|
||||
if ( $op === '=' && $item === null ) {
|
||||
$op = 'IS';
|
||||
}
|
||||
@@ -1976,6 +1979,8 @@ class ORM implements \ArrayAccess {
|
||||
|
||||
/**
|
||||
* Resets the Idiorm instance state.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reset_idiorm_state() {
|
||||
$this->values = [];
|
||||
@@ -2012,13 +2017,13 @@ class ORM implements \ArrayAccess {
|
||||
if ( \is_array( $key ) ) {
|
||||
$result = [];
|
||||
foreach ( $key as $column ) {
|
||||
$result[ $column ] = isset( $this->data[ $column ] ) ? $this->data[ $column ] : null;
|
||||
$result[ $column ] = ( $this->data[ $column ] ?? null );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
else {
|
||||
return isset( $this->data[ $key ] ) ? $this->data[ $key ] : null;
|
||||
return ( $this->data[ $key ] ?? null );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2042,8 +2047,8 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @return array|mixed|null
|
||||
*
|
||||
* @throws \Exception Primary key ID contains null value(s).
|
||||
* @throws \Exception Primary key ID missing from row or is null.
|
||||
* @throws Exception Primary key ID contains null value(s).
|
||||
* @throws Exception Primary key ID missing from row or is null.
|
||||
*/
|
||||
public function id( $disallow_null = false ) {
|
||||
$id = $this->get( $this->get_id_column_name() );
|
||||
@@ -2051,14 +2056,12 @@ class ORM implements \ArrayAccess {
|
||||
if ( \is_array( $id ) ) {
|
||||
foreach ( $id as $id_part ) {
|
||||
if ( $id_part === null ) {
|
||||
throw new \Exception( 'Primary key ID contains null value(s)' );
|
||||
throw new Exception( 'Primary key ID contains null value(s)' );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( $id === null ) {
|
||||
throw new \Exception( 'Primary key ID missing from row or is null' );
|
||||
}
|
||||
elseif ( $id === null ) {
|
||||
throw new Exception( 'Primary key ID missing from row or is null' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2114,10 +2117,8 @@ class ORM implements \ArrayAccess {
|
||||
if ( $expr === false && isset( $this->expr_fields[ $field ] ) ) {
|
||||
unset( $this->expr_fields[ $field ] );
|
||||
}
|
||||
else {
|
||||
if ( $expr === true ) {
|
||||
$this->expr_fields[ $field ] = true;
|
||||
}
|
||||
elseif ( $expr === true ) {
|
||||
$this->expr_fields[ $field ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2149,8 +2150,8 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @return bool True on success.
|
||||
*
|
||||
* @throws \Exception Primary key ID contains null value(s).
|
||||
* @throws \Exception Primary key ID missing from row or is null.
|
||||
* @throws Exception Primary key ID contains null value(s).
|
||||
* @throws Exception Primary key ID missing from row or is null.
|
||||
*/
|
||||
public function save() {
|
||||
global $wpdb;
|
||||
@@ -2204,14 +2205,14 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @return array The distinct set of columns that are dirty in at least one of the models.
|
||||
*
|
||||
* @throws \InvalidArgumentException Instance to be inserted is not a new one.
|
||||
* @throws InvalidArgumentException Instance to be inserted is not a new one.
|
||||
*/
|
||||
public function get_dirty_column_names( $models ) {
|
||||
$dirty_column_names = [];
|
||||
|
||||
foreach ( $models as $model ) {
|
||||
if ( ! $model->orm->is_new() ) {
|
||||
throw new \InvalidArgumentException( 'Instance to be inserted is not a new one' );
|
||||
throw new InvalidArgumentException( 'Instance to be inserted is not a new one' );
|
||||
}
|
||||
|
||||
// Remove any expression fields as they are already baked into the query.
|
||||
@@ -2233,13 +2234,13 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @return bool True for successful insert, false for failed.
|
||||
*
|
||||
* @throws \InvalidArgumentException Invalid instances to be inserted.
|
||||
* @throws \InvalidArgumentException Instance to be inserted is not a new one.
|
||||
* @throws InvalidArgumentException Invalid instances to be inserted.
|
||||
* @throws InvalidArgumentException Instance to be inserted is not a new one.
|
||||
*/
|
||||
public function insert_many( $models ) {
|
||||
// Validate the input first.
|
||||
if ( ! \is_array( $models ) ) {
|
||||
throw new \InvalidArgumentException( 'Invalid instances to be inserted' );
|
||||
throw new InvalidArgumentException( 'Invalid instances to be inserted' );
|
||||
}
|
||||
|
||||
if ( empty( $models ) ) {
|
||||
@@ -2251,7 +2252,7 @@ class ORM implements \ArrayAccess {
|
||||
/**
|
||||
* Filter: 'wpseo_chunk_bulked_insert_queries' - Allow filtering the chunk size of each bulked INSERT query.
|
||||
*
|
||||
* @api int The chunk size of the bulked INSERT queries.
|
||||
* @param int $chunk_size The chunk size of the bulked INSERT queries.
|
||||
*/
|
||||
$chunk = \apply_filters( 'wpseo_chunk_bulk_insert_queries', 100 );
|
||||
$chunk = ! \is_int( $chunk ) ? 100 : $chunk;
|
||||
@@ -2276,7 +2277,7 @@ class ORM implements \ArrayAccess {
|
||||
}
|
||||
|
||||
// Only register the value if it is not null.
|
||||
if ( ! is_null( $model->orm->dirty_fields[ $dirty_column ] ) ) {
|
||||
if ( ! \is_null( $model->orm->dirty_fields[ $dirty_column ] ) ) {
|
||||
$model_values[] = $model->orm->dirty_fields[ $dirty_column ];
|
||||
}
|
||||
}
|
||||
@@ -2415,8 +2416,8 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @return string The delete query.
|
||||
*
|
||||
* @throws \Exception Primary key ID contains null value(s).
|
||||
* @throws \Exception Primary key ID missing from row or is null.
|
||||
* @throws Exception Primary key ID contains null value(s).
|
||||
* @throws Exception Primary key ID missing from row or is null.
|
||||
*/
|
||||
public function delete() {
|
||||
$query = [ 'DELETE FROM', $this->quote_identifier( $this->table_name ), $this->add_id_column_conditions() ];
|
||||
@@ -2477,6 +2478,8 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @param string|int $offset Key.
|
||||
* @param mixed $value Value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetSet( $offset, $value ) {
|
||||
@@ -2490,6 +2493,8 @@ class ORM implements \ArrayAccess {
|
||||
* Removes the given key from the data.
|
||||
*
|
||||
* @param mixed $offset Key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function offsetUnset( $offset ) {
|
||||
@@ -2517,6 +2522,8 @@ class ORM implements \ArrayAccess {
|
||||
*
|
||||
* @param string|int $key Key.
|
||||
* @param mixed $value Value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __set( $key, $value ) {
|
||||
$this->offsetSet( $key, $value );
|
||||
@@ -2526,6 +2533,8 @@ class ORM implements \ArrayAccess {
|
||||
* Handles magic unset via offset.
|
||||
*
|
||||
* @param mixed $key Key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __unset( $key ) {
|
||||
$this->offsetUnset( $key );
|
||||
|
||||
Reference in New Issue
Block a user