/home/techb158/public_html/wp-content/plugins/kirki/libraries/framework/Database/Query
Edit: /home/techb158/public_html/wp-content/plugins/kirki/libraries/framework/Database/Query/Model.php (33642B)
boot_if_not_booted();
$this->fill($attributes);
$this->sync_original();
}
/**
* Boot the model if it has not been booted yet.
*
* @return void
*
* @since 1.0.0
*/
protected function boot_if_not_booted()
{
if (!isset(static::$booted[static::class])) {
static::$booted[static::class] = \true;
static::booting();
static::boot();
static::booted();
}
}
/**
* The booting event.
*
* @return void
*
* @since 1.0.0
*/
protected function booting()
{
//
}
/**
* The boot event.
*
* @return void
*
* @since 1.0.0
*/
protected function boot()
{
//
}
/**
* The booted event.
*
* @return void
*
* @since 1.0.0
*/
protected function booted()
{
//
}
/**
* Prevent silently discarding attributes.
*
* @return bool
*
* @since 1.0.0
*/
public static function is_attribute_silently_discarding_enabled()
{
return static::$prevent_silently_discarding_attributes;
}
/**
* Prevent silently discarding attributes.
*
* @param bool $state The state.
*
* @return void
*
* @since 1.0.0
*/
public static function prevent_silently_discarding_attributes($state = \true)
{
static::$prevent_silently_discarding_attributes = $state;
}
/**
* Set the callback to be invoked when an attribute is silently discarded.
*
* @param callable|null $callback The callback to set.
*
* @return void
*
* @since 1.0.0
*/
public static function discarded_attribute_callback(?callable $callback = null)
{
static::$discarded_attribute_callback = $callback;
}
/**
* Set the model to be strict.
*
* @param bool $state The state.
*
* @return void
*
* @since 1.0.0
*/
public static function should_be_strict(bool $state = \true)
{
static::prevent_silently_discarding_attributes($state);
}
/**
* Set the shared database connection used by all models.
*
* Allows applications and tests to inject a specific connection instance
* for use when building and executing queries across model operations.
*
* @param Connection $connection The connection to assign
*
* @return void
*
* @since 1.0.0
*/
public static function set_connection(Connection $connection)
{
static::$connection = $connection;
}
/**
* Retrieve the active connection, creating it on first use.
*
* Lazily resolves the singleton connection from the Connection manager
* when a model requires database access. Ensures a single shared instance
* is used throughout the application lifecycle.
*
* @return Connection The active database connection
*
* @since 1.0.0
*/
protected static function get_connection()
{
return app()->make(Connection::class);
}
/**
* Determine the database table name for the model.
*
* Returns the explicitly set table when provided; otherwise infers the
* table by lowercasing the class base name and appending an "s" suffix.
*
* @return string The table name associated with the model
*
* @since 1.0.0
*/
public function get_table()
{
if (isset($this->table)) {
return $this->table;
}
$class_name = (new ReflectionClass($this))->getShortName();
$table_name = \strtolower($class_name) . 's';
return $table_name;
}
/**
* Get the table name for the model class.
*
* @return string The table name for the model class
*
* @since 1.0.0
*/
public static function get_table_name()
{
return (new static())->get_table();
}
/**
* Set the database table name for the model.
*
* @param string $table The table name to assign
*
* @return static The model instance for method chaining
*
* @since 1.0.0
*/
public function set_table($table)
{
$this->table = $table;
return $this;
}
/**
* Get the route key name for the model.
*
* @return string The route key name
*
* @since 1.0.0
*/
public function get_route_key()
{
return $this->primary_key;
}
/**
* Get the primary key name for the model.
*
* @return string The primary key name
*
* @since 1.0.0
*/
public function get_primary_key()
{
return $this->primary_key;
}
/**
* Get the type of the primary key.
*
* @return string The type of the primary key
*
* @since 1.0.0
*/
public function get_key_type()
{
return $this->key_type;
}
/**
* Get the fillable attributes for the model.
*
* @return array The fillable attributes
*
* @since 1.0.0
*/
public function get_fillable()
{
return $this->fillable;
}
/**
* Prepare the column name for the query.
*
* @param string $column The column name to prepare
*
* @return string The prepared column name
*
* @since 1.0.0
*/
public function prepare_column($column)
{
if (str_contains($column, '.')) {
return $column;
}
return $this->get_table() . '.' . $column;
}
/**
* Get the prepared primary key name for the query.
*
* @return string The prepared primary key name
*
* @since 1.0.0
*/
public function get_prepared_key_name()
{
return $this->prepare_column($this->get_primary_key());
}
/**
* Prepare the columns for the query.
*
* @param array $columns The columns to prepare
*
* @return array The prepared columns
*
* @since 1.0.0
*/
public function prepare_columns($columns)
{
$columns = Arr::wrap($columns);
return $this->new_collection($columns)->map(function ($column) {
return $this->prepare_column($column);
})->all();
}
/**
* Create a new instance of the model.
*
* @param array $attributes The attributes to set
* @param mixed $exists The exists.
*
* @return static The new instance
*
* @since 1.0.0
*/
public function new_instance($attributes = [], $exists = \false)
{
$model = new static();
$model->exists = $exists;
$model->set_table($this->get_table());
$model->merge_casts($this->casts);
$model->fill($attributes);
return $model;
}
/**
* Create a new instance of the model with fillable attributes.
*
* @param array $attributes The attributes to set
*
* @return static The new instance
*
* @since 1.0.0
*/
public function new_fillable_instance($attributes = [])
{
$model = new static();
$model->set_table($this->get_table());
$model->merge_casts($this->casts);
$model->fill($attributes);
return $model;
}
/**
* Create a new query builder instance for the model's table.
*
* Instantiates a fresh model to determine the table and returns a
* configured query builder bound to this model class for fluent query
* construction and result hydration.
*
* @return QueryBuilder The query builder targeting this model's table
*
* @since 1.0.0
*/
public static function query()
{
return new QueryBuilder(static::get_connection(), static::get_connection()->get_query_compiler(), new static());
}
/**
* Create a new query builder instance for the model's table.
*
* Instantiates a fresh model to determine the table and returns a
* configured query builder bound to this model class for fluent query
* construction and result hydration.
*
* @return QueryBuilder The query builder targeting this model's table
*
* @since 1.0.0
*/
public function new_query()
{
return new QueryBuilder($this->get_connection(), $this->get_connection()->get_query_compiler(), $this);
}
/**
* Retrieve all records for the model.
*
* Builds a basic select query and returns a collection of hydrated model
* instances representing all rows in the corresponding table.
*
* @param mixed $columns The columns.
*
* @return Collection A collection of model instances
*
* @since 1.0.0
*/
public static function all($columns = ['*'])
{
return static::query()->get(\is_array($columns) ? $columns : \func_get_args());
}
/**
* Specify relationships to eager load with the query results.
*
* @param mixed $relations The relations to eager load
*
* @return static The query builder instance for method chaining
*
* @since 1.0.0
*/
public static function with($relations)
{
return static::query()->with(\is_string($relations) ? \func_get_args() : $relations);
}
/**
* Retrieve a model instance by its primary key.
*
* @param mixed $id The primary key of the record to find
*
* @return Model The hydrated model instance
*
* @since 1.0.0
*/
public static function find($id)
{
return static::query()->find($id, (new static())->primary_key);
}
/**
* Create and persist a new model instance.
*
* Mass assigns the provided attributes, saves the model, and returns the
* fresh instance. Fillable and guarded rules apply during assignment.
*
* @param array $attributes The attributes to assign and persist
*
* @return static The newly created, persisted model instance
*
* @since 1.0.0
*/
public static function create(array $attributes)
{
$instance = new static($attributes);
$instance->save();
return $instance;
}
/**
* Persist the model to the database.
*
* Updates timestamps when enabled, then performs an insert or update
* depending on whether the model already exists. Returns a boolean to
* indicate success.
*
* @return bool True when the operation succeeds; false otherwise
*
* @since 1.0.0
*/
public function save()
{
$this->merge_attributes_from_cached_class_casts();
if ($this->exists) {
$saved = $this->is_dirty() ? $this->perform_update() : \true;
} else {
$saved = $this->perform_insert();
}
if ($saved) {
$this->sync_original();
}
return $saved;
}
/**
* Insert the model as a new record in the database.
*
* Uses the query builder to insert attributes and capture the generated
* primary key, then updates the original snapshot. Returns true on
* completion to mirror successful persistence semantics.
*
* @return bool True when the insert completes successfully
*
* @since 1.0.0
*/
protected function perform_insert()
{
if ($this->uses_timestamps()) {
$this->update_timestamps();
}
$query = static::query();
$attributes = $this->get_attributes_for_insert();
if (empty($attributes)) {
return \true;
}
$newly_created_key_value = $query->insert_get_id($attributes);
$this->set_attribute($this->get_primary_key(), $newly_created_key_value);
$this->exists = \true;
$this->was_recently_created = \true;
return \true;
}
/**
* Update the existing database record with dirty attributes.
*
* Computes the set of changed attributes and issues an update statement
* scoped to the primary key. When no changes are detected, returns true to
* indicate no action was required.
*
* @return bool True on success or when no changes are present
*
* @since 1.0.0
*/
protected function perform_update()
{
if ($this->uses_timestamps()) {
$this->update_timestamps();
}
$dirty = $this->get_dirty();
if (empty($dirty)) {
return \true;
}
static::query()->where($this->get_primary_key(), '=', $this->get_key_for_save_query())->update($dirty);
$this->sync_changes();
return \true;
}
/**
* Get the key for save query.
*
* @return mixed
*
* @since 1.0.0
*/
protected function get_key_for_save_query()
{
return $this->original[$this->get_primary_key()] ?? $this->get_primary_key_value();
}
/**
* Update attributes on the model and persist the changes.
*
* Merges the provided attributes using fill rules and then calls save to
* perform the appropriate persistence action. Returns the boolean result
* of the save operation.
*
* @param array $attributes The attributes to assign prior to saving
*
* @return bool True when the model is saved successfully
*
* @since 1.0.0
*/
public function update(array $attributes = [])
{
if (!$this->exists) {
return \false;
}
return $this->fill($attributes)->save();
}
/**
* Delete the model's record from the database.
*
* When the model does not yet exist, returns false. Otherwise performs a
* delete query constrained by the primary key and returns its result.
*
* @return bool True when deletion succeeds; false if not persisted
*
* @throws Exception
*
* @since 1.0.0
*/
public function delete()
{
$this->merge_attributes_from_cached_class_casts();
if (\is_null($this->get_primary_key())) {
throw new Exception('No primary key defined on model.');
}
if (!$this->exists) {
return \false;
}
$this->perform_delete_on_model();
return \true;
}
/**
* Delete the model's record from the database.
*
* @return void
*
* @since 1.0.0
*/
protected function perform_delete_on_model()
{
static::query()->where($this->get_primary_key(), '=', $this->get_primary_key_value())->delete();
$this->exists = \false;
}
/**
* Delete one or many models by primary key.
*
* Accepts a single id or multiple, finds each, and deletes them when
* present. Returns the count of successfully deleted records.
*
* @param mixed $ids One id, array of ids, or variadic list of ids
*
* @return int The number of records deleted
*
* @since 1.0.0
*/
public static function destroy($ids)
{
if ($ids instanceof Collection) {
$ids = $ids->model_keys();
}
if ($ids instanceof BaseCollection) {
$ids = $ids->all();
}
$ids = \is_array($ids) ? $ids : \func_get_args();
if (empty($ids)) {
return 0;
}
$key = ($instance = new static())->get_primary_key();
$count = 0;
foreach ($instance->where_in($key, $ids)->get() as $model) {
if ($model->delete()) {
$count++;
}
}
return $count;
}
/**
* Mass assign attributes allowed by fillable/guarded rules.
*
* Iterates through provided attributes, only setting those permitted by the
* model's configuration. Returns the model instance for chaining.
*
* @param array $attributes The attributes to attempt to assign
*
* @return $this The model instance for method chaining
*
* @since 1.0.0
*/
public function fill(array $attributes)
{
$totally_guarded = $this->totally_guarded();
$fillable = $this->fillable_from_array($attributes);
foreach ($attributes as $key => $value) {
if ($this->is_fillable($key)) {
$this->set_attribute($key, $value);
} elseif ($totally_guarded || static::is_attribute_silently_discarding_enabled()) {
if (isset(static::$discarded_attribute_callback)) {
\call_user_func(static::$discarded_attribute_callback, $this, [$key]);
} else {
throw new MassAssignmentException(\sprintf('Add [%s] to fillable array to allow mass assignment on [%s].', $key, \get_class($this)));
}
}
}
if (\count($attributes) !== \count($fillable) && static::is_attribute_silently_discarding_enabled()) {
$keys = \array_diff(\array_keys($attributes), \array_keys($fillable));
if (isset(static::$discarded_attribute_callback)) {
\call_user_func(static::$discarded_attribute_callback, $this, $keys);
} else {
throw new MassAssignmentException(\sprintf('Add [%s] to fillable array to allow mass assignment on [%s].', \implode(', ', $keys), \get_class($this)));
}
}
return $this;
}
/**
* Update timestamp attributes when enabled.
*
* Sets updated_at on every save and created_at on initial inserts when the
* model is configured to manage timestamps automatically.
*
* @return void
*
* @since 1.0.0
*/
protected function update_timestamps()
{
$time = Date::now();
if (!$this->exists()) {
$this->set_attribute('created_at', $time);
}
$this->set_attribute('updated_at', $time);
}
/**
* Hydrate a new model instance from raw data.
*
* Accepts an object or array of attributes, normalizes to an array, and
* sets both current and original states. Used by query results to produce
* model instances.
*
* @param array $items The source attributes as object or array
*
* @return Collection The hydrated model instance
*
* @since 1.0.0
*/
public function hydrate(array $items)
{
$instance = $this->new_instance();
return $instance->new_collection(\array_map(function ($item) use($instance) {
return $instance->new_for_hydration($item);
}, $items));
}
/**
* Create a new collection instance.
*
* @param array $items The items to seed the collection
*
* @return Collection The new collection instance
*
* @since 1.0.0
*/
public function new_collection(array $items = [])
{
return new Collection($items);
}
/**
* Create a new model instance from a builder.
*
* @param array $attributes The item to create the model from
*
* @return Model The new model instance
*
* @since 1.0.0
*/
public function new_for_hydration($attributes = [])
{
$model = $this->new_instance([], \true);
$model->set_raw_attributes((array) $attributes, \true);
return $model;
}
/**
* Eager load one or more relations onto the model.
*
* Accepts a single relation or multiple and assigns the retrieved results
* to the model's relations array for later access and serialization.
*
* @param mixed $relations The relation name(s) to load
*
* @return static The model instance for method chaining
*
* @since 1.0.0
*/
public function load($relations)
{
$query = $this->new_query_without_relations()->with(\is_string($relations) ? \func_get_args() : $relations);
$query->eager_load_relations(new Collection([$this]));
return $this;
}
/**
* Eager load the missing relationships for the model.
*
* @param mixed $relations The relations to eager load
*
* @return $this The model instance
*
* @since 1.0.0
*/
public function load_missing($relations)
{
if (\is_string($relations)) {
$relations = \func_get_args();
}
$this->new_collection([$this])->load_missing($relations);
return $this;
}
/**
* Create a new query builder instance for the model's table.
*
* Instantiates a fresh model to determine the table and returns a
* configured query builder bound to this model class for fluent query
* construction and result hydration.
*
* @return QueryBuilder The query builder targeting this model's table
*
* @since 1.0.0
*/
public function new_query_without_relations()
{
return $this->new_query();
}
/**
* Infer the foreign key name for the model.
*
* Uses the lowercase short class name with an _id suffix to determine the
* conventional foreign key column name used on related tables.
*
* @return string The inferred foreign key column name
*
* @since 1.0.0
*/
protected function get_foreign_key()
{
return \strtolower((new ReflectionClass($this))->getShortName()) . '_id';
}
/**
* Compute a conventional pivot table name for two tables.
*
* Sorts the provided table names alphabetically and joins them with an
* underscore to produce a deterministic pivot table name.
*
* @param string $table1 The first table name
* @param string $table2 The second table name
*
* @return string The generated pivot table name
*
* @since 1.0.0
*/
protected function get_pivot_table_name($table1, $table2)
{
$tables = [$table1, $table2];
\sort($tables);
return \implode('_', $tables);
}
/**
* Get a fresh model instance from the database.
*
* @param array|string $with The relations to load
*
* @return static|null The fresh model instance
*
* @since 1.0.0
*/
public function fresh($with = [])
{
if (!$this->exists) {
return;
}
return $this->set_where_for_fresh_query($this->new_query())->with(\is_string($with) ? \func_get_args() : $with)->first();
}
/**
* Refresh the model instance from the database.
*
* @return static The refreshed model instance
*
* @since 1.0.0
*/
public function refresh()
{
if (!$this->exists) {
return $this;
}
$this->set_raw_attributes($this->set_where_for_fresh_query($this->new_query())->first_or_fail()->attributes);
$this->load((new BaseCollection($this->relations))->keys()->all());
$this->sync_original();
return $this;
}
/**
* Set the where clause for a fresh query.
*
* @param QueryBuilder $query The query builder instance
*
* @return QueryBuilder The query builder instance
*
* @since 1.0.0
*/
protected function set_where_for_fresh_query(QueryBuilder $query)
{
$query->where($this->get_primary_key(), '=', $this->get_primary_key_value());
return $query;
}
/**
* Get the primary key value.
*
* @return mixed The primary key value
*
* @since 1.0.0
*/
public function get_primary_key_value()
{
return $this->get_attribute($this->get_primary_key());
}
/**
* Convert the model and loaded relations to an array.
*
* Serializes attributes and recursively converts relation values to arrays
* to produce a structure suitable for JSON encoding or API responses.
*
* @return array The array representation of the model
*
* @since 1.0.0
*/
public function to_array()
{
return \array_merge($this->attributes_to_array(), $this->relations_to_array());
}
/**
* Determine if the model has a named scope.
*
* @param string $scope The scope name to check
*
* @return bool True when the scope exists; false otherwise
*
* @since 1.0.0
*/
public function has_named_scope(string $scope)
{
return \method_exists($this, 'scope_' . $scope);
}
/**
* Call a named scope on the model.
*
* @param string $scope The scope name to call
* @param array $parameters The parameters to pass to the scope
*
* @return mixed The result of the scope call
*
* @since 1.0.0
*/
public function call_named_scope(string $scope, ...$parameters)
{
$method = 'scope_' . $scope;
return $this->{$method}(...$parameters);
}
/**
* Convert the model and relations to a JSON string.
*
* Utilizes json_encode on the array form of the model. Useful for logging
* and simple serialization needs without a dedicated resource layer.
*
* @param mixed $options The options array.
*
* @return string The JSON-encoded representation of the model
*
* @since 1.0.0
*/
public function to_json($options = 0)
{
return Arr::json_encode($this->to_array(), $options);
}
/**
* Get an attribute or relation.
*
* @param string $offset The attribute or relation key to get
* @return mixed The value of the attribute or relation
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->get_attribute($offset);
}
/**
* Set an attribute or relation.
*
* @param string $offset The attribute or relation key to set
* @param mixed $value The value to assign to the attribute or relation
*
* @return void No return value
*
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value) : void
{
$this->set_attribute($offset, $value);
}
/**
* Check if an attribute or relation is set.
*
* @param string $offset The attribute or relation key to check
*
* @return bool True when a value is present; false otherwise
*
* @since 1.0.0
*/
public function offsetExists($offset) : bool
{
return isset($this->attributes[$offset]) || isset($this->relations[$offset]);
}
/**
* Unset an attribute or relation.
*
* @param string $offset The attribute or relation key to unset
*
* @return void
*
* @since 1.0.0
*/
public function offsetUnset($offset) : void
{
unset($this->attributes[$offset], $this->relations[$offset]);
}
/**
* Convert the model to a JSON serializable array.
*
* @return mixed The model's attributes and relations
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->to_array();
}
/**
* Dynamically retrieve attributes or relations via property access.
*
* Forwards to get_attribute to keep behavior consistent with explicit
* accessor calls while supporting PHP's magic access pattern.
*
* @param string $key The attribute or relation name
* @return mixed The resolved value or null when absent
* @since 1.0.0
*/
#[\ReturnTypeWillChange]
public function __get($key)
{
return $this->get_attribute($key);
}
/**
* Dynamically set attribute values via property access.
*
* Forwards to set_attribute to ensure consistent mutation behavior and
* chaining semantics when used programmatically.
*
* @param string $key The attribute name
* @param mixed $value The value to assign
*
* @return void
*
* @since 1.0.0
*/
public function __set($key, $value)
{
$this->set_attribute($key, $value);
}
/**
* Determine if an attribute or relation is set.
*
* Checks both the attributes and relations arrays to report whether the
* given key currently resolves to a non-null value.
*
* @param string $key The attribute or relation key to test
*
* @return bool True when a value is present; false otherwise
*
* @since 1.0.0
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset an attribute or relation.
*
* @param string $key The attribute or relation key to unset
*
* @return void
*
* @since 1.0.0
*/
public function __unset($key)
{
$this->offsetUnset($key);
}
/**
* Dynamically call a method on the query builder.
*
* @param string $method The method name to call
* @param array $arguments The arguments to pass to the method
*
* @return mixed The result of the method call
*
* @since 1.0.0
*/
public function __call($method, $arguments)
{
return $this->query()->{$method}(...$arguments);
}
/**
* Dynamically call a static method on the model.
*
* @param string $method The method name to call
* @param array $arguments The arguments to pass to the method
*
* @return mixed The result of the method call
*
* @since 1.0.0
*/
public static function __callStatic($method, $arguments)
{
return (new static())->{$method}(...$arguments);
}
}