- WordPress core y plugins - Tema Twenty Twenty-Four configurado - Plugin allow-unfiltered-html.php simplificado - .gitignore configurado para excluir wp-config.php y uploads 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
441 lines
8.9 KiB
PHP
Executable File
441 lines
8.9 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* This class is serving as the base for metadata service.
|
|
*
|
|
* @package AdvancedAds
|
|
* @author Advanced Ads <info@wpadvancedads.com>
|
|
* @since 1.48.0
|
|
*/
|
|
|
|
namespace AdvancedAds\Abstracts;
|
|
|
|
use WP_Error;
|
|
use Exception;
|
|
use AdvancedAds\Framework\Utilities\Arr;
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* Data.
|
|
*/
|
|
abstract class Data implements \ArrayAccess {
|
|
|
|
/**
|
|
* ID for this object.
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $id = 0;
|
|
|
|
/**
|
|
* Core data for this object. Name value pairs (name + default value).
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $data = [];
|
|
|
|
/**
|
|
* Core data changes for this object.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $changes = [];
|
|
|
|
/**
|
|
* Set to _data on construct so we can track and reset data if needed.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $default_data = [];
|
|
|
|
/**
|
|
* This is false until the object is read from the DB.
|
|
*
|
|
* @var bool
|
|
*/
|
|
protected $object_read = false;
|
|
|
|
/**
|
|
* This is the object type.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $object_type = 'post';
|
|
|
|
/**
|
|
* Contains a reference to the data store for this class.
|
|
*
|
|
* @var object
|
|
*/
|
|
protected $data_store;
|
|
|
|
/**
|
|
* Stores temp data.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $temp_data = [];
|
|
|
|
/**
|
|
* Change data to JSON format.
|
|
*
|
|
* @return string Data in JSON format.
|
|
*/
|
|
public function __toString() {
|
|
return wp_json_encode( $this->get_data() );
|
|
}
|
|
|
|
/**
|
|
* Default constructor.
|
|
*
|
|
* @param int|object|array $read ID to load from the DB (optional) or already queried data.
|
|
*/
|
|
public function __construct( $read = 0 ) { // phpcs:ignore
|
|
$this->default_data = $this->data;
|
|
}
|
|
|
|
/**
|
|
* Save should create or update based on object existence.
|
|
*
|
|
* @return int ID.
|
|
*/
|
|
public function save(): int {
|
|
// Early bail!!
|
|
if ( ! $this->data_store ) {
|
|
return $this->get_id();
|
|
}
|
|
|
|
if ( $this->get_id() ) {
|
|
$this->data_store->update( $this );
|
|
} else {
|
|
$this->data_store->create( $this );
|
|
}
|
|
|
|
return $this->get_id();
|
|
}
|
|
|
|
/**
|
|
* Delete an object, set the ID to 0, and return result.
|
|
*
|
|
* @param bool $force_delete Should the date be deleted permanently.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function delete( $force_delete = false ): bool {
|
|
if ( $this->data_store ) {
|
|
$this->data_store->delete( $this, $force_delete );
|
|
$this->set_id( 0 );
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Merge changes with data and clear.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function apply_changes(): void {
|
|
$this->data = array_replace_recursive( $this->data, $this->changes );
|
|
$this->changes = [];
|
|
}
|
|
|
|
/* Getter ------------------- */
|
|
|
|
/**
|
|
* Returns the unique ID for this object.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function get_id(): int {
|
|
return $this->id;
|
|
}
|
|
|
|
/**
|
|
* Get the data store.
|
|
*
|
|
* @return object
|
|
*/
|
|
public function get_data_store() {
|
|
return $this->data_store;
|
|
}
|
|
|
|
/**
|
|
* Get object read property.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function get_object_read(): bool {
|
|
return (bool) $this->object_read;
|
|
}
|
|
|
|
/**
|
|
* Returns all data for this object.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_data(): array {
|
|
return array_merge(
|
|
[ 'id' => $this->get_id() ],
|
|
$this->data
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns array of expected data keys for this object.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_data_keys() {
|
|
$keys = array_keys( $this->data );
|
|
$keys = array_diff( $keys, [ 'title', 'content', 'status' ] );
|
|
|
|
return array_merge( $keys );
|
|
}
|
|
|
|
/**
|
|
* Return data changes only.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_changes(): array {
|
|
return $this->changes;
|
|
}
|
|
|
|
/**
|
|
* Prefix for action and filter hooks on data.
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function get_hook_prefix(): string {
|
|
return 'advanced-ads-' . $this->object_type . '-get-';
|
|
}
|
|
|
|
/**
|
|
* Gets a prop for a getter method.
|
|
*
|
|
* Gets the value from either current pending changes, or the data itself.
|
|
* Context controls what happens to the value before it's returned.
|
|
*
|
|
* @param string $prop Name of prop to get.
|
|
* @param string $context What the value is for. Valid values are view and edit.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function get_prop( $prop, $context = 'view' ) {
|
|
$value = null;
|
|
|
|
if ( Arr::has( $this->temp_data, $prop ) ) {
|
|
$value = Arr::get( $this->temp_data, $prop );
|
|
} elseif ( Arr::has( $this->data, $prop ) ) {
|
|
$value = Arr::has( $this->changes, $prop )
|
|
? Arr::get( $this->changes, $prop )
|
|
: Arr::get( $this->data, $prop );
|
|
}
|
|
|
|
if ( 'view' === $context ) {
|
|
/**
|
|
* Filter the option value retrieved for $field.
|
|
* `$field` parameter makes dynamic hook portion.
|
|
*
|
|
* @var mixed $value The option value (may be set to default).
|
|
* @var Ad $this The current Ad instance.
|
|
*/
|
|
$value = apply_filters_deprecated(
|
|
"advanced-ads-ad-option-{$prop}",
|
|
[ $value, $this ],
|
|
'2.0.0',
|
|
$this->get_hook_prefix() . $prop,
|
|
'This filter is deprecated. Use ' . $this->get_hook_prefix() . $prop . ' instead.'
|
|
);
|
|
|
|
$value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/* Setter ------------------- */
|
|
|
|
/**
|
|
* Set ID.
|
|
*
|
|
* @param int $id ID.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function set_id( $id ): void {
|
|
$this->id = absint( $id );
|
|
}
|
|
|
|
/**
|
|
* Set object read property.
|
|
*
|
|
* @param bool $read Should read?.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function set_object_read( $read = true ): void {
|
|
$this->object_read = boolval( $read );
|
|
}
|
|
|
|
/**
|
|
* Set all props to default values.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function set_defaults(): void {
|
|
$this->data = $this->default_data;
|
|
$this->changes = [];
|
|
$this->set_object_read( false );
|
|
}
|
|
|
|
/**
|
|
* Set a collection of props in one go, collect any errors, and return the result.
|
|
* Only sets using public methods.
|
|
*
|
|
* @param array $props Key value pairs to set. Key is the prop and should map to a setter function name.
|
|
*
|
|
* @return bool|WP_Error
|
|
*/
|
|
public function set_props( $props ) {
|
|
$errors = false;
|
|
|
|
foreach ( $props as $prop => $value ) {
|
|
try {
|
|
/**
|
|
* Checks if the prop being set is allowed, and the value is not null.
|
|
*/
|
|
if ( is_null( $value ) ) {
|
|
continue;
|
|
}
|
|
|
|
$setter = 'set_' . str_replace( '-', '_', $prop );
|
|
|
|
if ( is_callable( [ $this, $setter ] ) ) {
|
|
$this->{$setter}( $value );
|
|
} else {
|
|
$this->set_prop( $prop, $value );
|
|
}
|
|
} catch ( Exception $e ) {
|
|
if ( ! $errors ) {
|
|
$errors = new WP_Error();
|
|
}
|
|
$errors->add( $e->getCode(), $e->getMessage(), [ 'property_name' => $prop ] );
|
|
}
|
|
}
|
|
|
|
return $errors && count( $errors->get_error_codes() ) ? $errors : true;
|
|
}
|
|
|
|
/**
|
|
* Sets a prop for a setter method.
|
|
*
|
|
* @param string $prop Name of prop to set.
|
|
* @param mixed $value Value of the prop.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function set_prop( $prop, $value ): void {
|
|
if ( Arr::has( $this->data, $prop ) && true === $this->object_read ) {
|
|
if ( Arr::get( $this->data, $prop ) !== $value ) {
|
|
Arr::set( $this->changes, $prop, $value );
|
|
}
|
|
} else {
|
|
Arr::set( $this->data, $prop, $value );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets a prop temporary.
|
|
*
|
|
* @param string $prop Name of prop to set.
|
|
* @param mixed $value Value of the prop.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function set_prop_temp( $prop, $value ): void {
|
|
$this->temp_data[ $prop ] = $value;
|
|
}
|
|
|
|
/**
|
|
* Unset a prop.
|
|
*
|
|
* @param string $prop Name of prop to unset.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function unset_prop( $prop ): void {
|
|
if ( array_key_exists( $prop, $this->changes ) ) {
|
|
unset( $this->changes );
|
|
return;
|
|
}
|
|
|
|
$this->data[ $prop ] = null;
|
|
}
|
|
|
|
// ArrayAccess API -------------------.
|
|
|
|
/**
|
|
* Sets the value at the specified offset.
|
|
*
|
|
* @param mixed $offset The offset to set the value at.
|
|
* @param mixed $value The value to set.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function offsetSet( $offset, $value ): void {
|
|
$this->set_prop( $offset, $value );
|
|
}
|
|
|
|
/**
|
|
* Checks if the given offset exists.
|
|
*
|
|
* @param mixed $offset The offset to check for existence.
|
|
*
|
|
* @return bool True if the offset exists, false otherwise.
|
|
*/
|
|
public function offsetExists( $offset ): bool {
|
|
$func = 'get_' . $offset;
|
|
if ( method_exists( $this, $func ) ) {
|
|
return null !== $this->$func();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Unsets the property at the specified offset.
|
|
*
|
|
* @param mixed $offset The offset to unset.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function offsetUnset( $offset ): void {
|
|
$this->unset_prop( $offset );
|
|
}
|
|
|
|
/**
|
|
* Retrieve the value at the specified offset.
|
|
*
|
|
* This method attempts to call a getter method based on the offset name.
|
|
* If a method named 'get_{offset}' exists, it will be called and its return value will be returned.
|
|
* If no such method exists, null will be returned.
|
|
*
|
|
* @param string $offset The offset to retrieve.
|
|
*
|
|
* @return mixed The value at the specified offset, or null if the method does not exist.
|
|
*/
|
|
#[\ReturnTypeWillChange]
|
|
public function offsetGet( $offset ) {
|
|
$func = 'get_' . $offset;
|
|
if ( method_exists( $this, $func ) ) {
|
|
return $this->$func();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|