const regex = new RegExp('^\\s*[\\w\\s]+\\(.*\\)\\s*\\K({((?>"(?:[^"\\\\]*+|\\\\.)*"|\\'(?:[^\\'\\\\]*+|\\\\.)*\\'|//.*$|/\\*[\\s\\S]*?\\*/|#.*$|<<<\\s*["\\']?(\\w+)["\\']?[^;]+\\3;$|[^{}<\\'"/#]++|[^{}]++|(?1))*)})', 'gm')
const str = `<?php
namespace Illuminate\\Database\\Eloquent;
use Closure;
use DateTime;
use Exception;
use ArrayAccess;
use Carbon\\Carbon;
use LogicException;
use JsonSerializable;
use DateTimeInterface;
use Illuminate\\Support\\Arr;
use Illuminate\\Support\\Str;
use InvalidArgumentException;
use Illuminate\\Contracts\\Support\\Jsonable;
use Illuminate\\Contracts\\Events\\Dispatcher;
use Illuminate\\Contracts\\Support\\Arrayable;
use Illuminate\\Contracts\\Routing\\UrlRoutable;
use Illuminate\\Contracts\\Queue\\QueueableEntity;
use Illuminate\\Database\\Eloquent\\Relations\\Pivot;
use Illuminate\\Database\\Eloquent\\Relations\\HasOne;
use Illuminate\\Database\\Eloquent\\Relations\\HasMany;
use Illuminate\\Database\\Eloquent\\Relations\\MorphTo;
use Illuminate\\Database\\Eloquent\\Relations\\Relation;
use Illuminate\\Database\\Eloquent\\Relations\\MorphOne;
use Illuminate\\Support\\Collection as BaseCollection;
use Illuminate\\Database\\Eloquent\\Relations\\MorphMany;
use Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;
use Illuminate\\Database\\Query\\Builder as QueryBuilder;
use Illuminate\\Database\\Eloquent\\Relations\\MorphToMany;
use Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany;
use Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough;
use Illuminate\\Database\\ConnectionResolverInterface as Resolver;
abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
/**
* The connection name for the model.
*
* @var string
*/
protected \$connection;
/**
* The table associated with the model.
*
* @var string
*/
protected \$table;
/**
* The primary key for the model.
*
* @var string
*/
protected \$primaryKey = 'id';
/**
* The "type" of the auto-incrementing ID.
*
* @var string
*/
protected \$keyType = 'int';
/**
* The number of models to return for pagination.
*
* @var int
*/
protected \$perPage = 15;
/**
* Indicates if the IDs are auto-incrementing.
*
* @var bool
*/
public \$incrementing = true;
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public \$timestamps = true;
/**
* The model's attributes.
*
* @var array
*/
protected \$attributes = [];
/**
* The model attribute's original state.
*
* @var array
*/
protected \$original = [];
/**
* The loaded relationships for the model.
*
* @var array
*/
protected \$relations = [];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected \$hidden = [];
/**
* The attributes that should be visible in arrays.
*
* @var array
*/
protected \$visible = [];
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected \$appends = [];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected \$fillable = [];
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected \$guarded = ['*'];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected \$dates = [];
/**
* The storage format of the model's date columns.
*
* @var string
*/
protected \$dateFormat;
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected \$casts = [];
/**
* The relationships that should be touched on save.
*
* @var array
*/
protected \$touches = [];
/**
* User exposed observable events.
*
* @var array
*/
protected \$observables = [];
/**
* The relations to eager load on every query.
*
* @var array
*/
protected \$with = [];
/**
* The class name to be used in polymorphic relations.
*
* @var string
*/
protected \$morphClass;
/**
* Indicates if the model exists.
*
* @var bool
*/
public \$exists = false;
/**
* Indicates if the model was inserted during the current request lifecycle.
*
* @var bool
*/
public \$wasRecentlyCreated = false;
/**
* Indicates whether attributes are snake cased on arrays.
*
* @var bool
*/
public static \$snakeAttributes = true;
/**
* The connection resolver instance.
*
* @var \\Illuminate\\Database\\ConnectionResolverInterface
*/
protected static \$resolver;
/**
* The event dispatcher instance.
*
* @var \\Illuminate\\Contracts\\Events\\Dispatcher
*/
protected static \$dispatcher;
/**
* The array of booted models.
*
* @var array
*/
protected static \$booted = [];
/**
* The array of global scopes on the model.
*
* @var array
*/
protected static \$globalScopes = [];
/**
* Indicates if all mass assignment is enabled.
*
* @var bool
*/
protected static \$unguarded = false;
/**
* The cache of the mutated attributes for each class.
*
* @var array
*/
protected static \$mutatorCache = [];
/**
* The many to many relationship methods.
*
* @var array
*/
public static \$manyMethods = ['belongsToMany', 'morphToMany', 'morphedByMany'];
/**
* The name of the "created at" column.
*
* @var string
*/
const CREATED_AT = 'created_at';
/**
* The name of the "updated at" column.
*
* @var string
*/
const UPDATED_AT = 'updated_at';
/**
* Create a new Eloquent model instance.
*
* @param array \$attributes
* @return void
*/
public function __construct(array \$attributes = [])
{
\$str = "\\"";
\$this->bootIfNotBooted();
\$this->syncOriginal();
\$this->fill(\$attributes);
}
/**
* Check if the model needs to be booted and if so, do it.
*
* @return void
*/
protected function bootIfNotBooted()
{
if (! isset(static::\$booted[static::class])) {
static::\$booted[static::class] = true;
\$this->fireModelEvent('booting', false);
static::boot();
\$this->fireModelEvent('booted', false);
}
}
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
static::bootTraits();
}
/**
* Boot all of the bootable traits on the model.
*
* @return void
*/
protected static function bootTraits()
{
\$class = static::class;
foreach (class_uses_recursive(\$class) as \$trait) {
if (method_exists(\$class, \$method = 'boot'.class_basename(\$trait))) {
forward_static_call([\$class, \$method]);
}
}
}
/**
* Clear the list of booted models so they will be re-booted.
*
* @return void
*/
public static function clearBootedModels()
{
static::\$booted = [];
static::\$globalScopes = [];
}
/**
* Register a new global scope on the model.
*
* @param \\Illuminate\\Database\\Eloquent\\Scope|\\Closure|string \$scope
* @param \\Closure|null \$implementation
* @return mixed
*
* @throws \\InvalidArgumentException
*/
public static function addGlobalScope(\$scope, Closure \$implementation = null)
{
if (is_string(\$scope) && \$implementation !== null) {
return static::\$globalScopes[static::class][\$scope] = \$implementation;
}
if (\$scope instanceof Closure) {
return static::\$globalScopes[static::class][spl_object_hash(\$scope)] = \$scope;
}
if (\$scope instanceof Scope) {
return static::\$globalScopes[static::class][get_class(\$scope)] = \$scope;
}
throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.');
}
/**
* Determine if a model has a global scope.
*
* @param \\Illuminate\\Database\\Eloquent\\Scope|string \$scope
* @return bool
*/
public static function hasGlobalScope(\$scope)
{
return ! is_null(static::getGlobalScope(\$scope));
}
/**
* Get a global scope registered with the model.
*
* @param \\Illuminate\\Database\\Eloquent\\Scope|string \$scope
* @return \\Illuminate\\Database\\Eloquent\\Scope|\\Closure|null
*/
public static function getGlobalScope(\$scope)
{
if (! is_string(\$scope)) {
\$scope = get_class(\$scope);
}
return Arr::get(static::\$globalScopes, static::class.'.'.\$scope);
}
/**
* Get the global scopes for this class instance.
*
* @return array
*/
public function getGlobalScopes()
{
return Arr::get(static::\$globalScopes, static::class, []);
}
/**
* Register an observer with the Model.
*
* @param object|string \$class
* @param int \$priority
* @return void
*/
public static function observe(\$class, \$priority = 0)
{
\$instance = new static;
\$className = is_string(\$class) ? \$class : get_class(\$class);
// When registering a model observer, we will spin through the possible events
// and determine if this observer has that method. If it does, we will hook
// it into the model's event system, making it convenient to watch these.
foreach (\$instance->getObservableEvents() as \$event) {
if (method_exists(\$class, \$event)) {
static::registerModelEvent(\$event, \$className.'@'.\$event, \$priority);
}
}
}
/**
* Fill the model with an array of attributes.
*
* @param array \$attributes
* @return \$this
*
* @throws \\Illuminate\\Database\\Eloquent\\MassAssignmentException
*/
public function fill(array \$attributes)
{
\$totallyGuarded = \$this->totallyGuarded();
foreach (\$this->fillableFromArray(\$attributes) as \$key => \$value) {
\$key = \$this->removeTableFromKey(\$key);
// The developers may choose to place some attributes in the "fillable"
// array, which means only those attributes may be set through mass
// assignment to the model, and all others will just be ignored.
if (\$this->isFillable(\$key)) {
\$this->setAttribute(\$key, \$value);
} elseif (\$totallyGuarded) {
throw new MassAssignmentException(\$key);
}
}
return \$this;
}
/**
* Fill the model with an array of attributes. Force mass assignment.
*
* @param array \$attributes
* @return \$this
*/
public function forceFill(array \$attributes)
{
return static::unguarded(function () use (\$attributes) {
return \$this->fill(\$attributes);
});
}
/**
* Get the fillable attributes of a given array.
*
* @param array \$attributes
* @return array
*/
protected function fillableFromArray(array \$attributes)
{
if (count(\$this->getFillable()) > 0 && ! static::\$unguarded) {
return array_intersect_key(\$attributes, array_flip(\$this->getFillable()));
}
return \$attributes;
}
/**
* Create a new instance of the given model.
*
* @param array \$attributes
* @param bool \$exists
* @return static
*/
public function newInstance(\$attributes = [], \$exists = false)
{
// This method just provides a convenient way for us to generate fresh model
// instances of this current model. It is particularly useful during the
// hydration of new objects via the Eloquent query builder instances.
\$model = new static((array) \$attributes);
\$model->exists = \$exists;
return \$model;
}
/**
* Create a new model instance that is existing.
*
* @param array \$attributes
* @param string|null \$connection
* @return static
*/
public function newFromBuilder(\$attributes = [], \$connection = null)
{
\$model = \$this->newInstance([], true);
\$model->setRawAttributes((array) \$attributes, true);
\$model->setConnection(\$connection ?: \$this->connection);
return \$model;
}
/**
* Create a collection of models from plain arrays.
*
* @param array \$items
* @param string|null \$connection
* @return \\Illuminate\\Database\\Eloquent\\Collection
*/
public static function hydrate(array \$items, \$connection = null)
{
\$instance = (new static)->setConnection(\$connection);
\$items = array_map(function (\$item) use (\$instance) {
return \$instance->newFromBuilder(\$item);
}, \$items);
return \$instance->newCollection(\$items);
}
/**
* Create a collection of models from a raw query.
*
* @param string \$query
* @param array \$bindings
* @param string|null \$connection
* @return \\Illuminate\\Database\\Eloquent\\Collection
*/
public static function hydrateRaw(\$query, \$bindings = [], \$connection = null)
{
\$instance = (new static)->setConnection(\$connection);
\$items = \$instance->getConnection()->select(\$query, \$bindings);
return static::hydrate(\$items, \$connection);
}
/**
* Save a new model and return the instance.
*
* @param array \$attributes
* @return static
*/
public static function create(array \$attributes = [])
{
\$model = new static(\$attributes);
\$model->save();
return \$model;
}
/**
* Save a new model and return the instance. Allow mass-assignment.
*
* @param array \$attributes
* @return static
*/
public static function forceCreate(array \$attributes)
{
return static::unguarded(function () use (\$attributes) {
return (new static)->create(\$attributes);
});
}
/**
* Begin querying the model.
*
* @return \\Illuminate\\Database\\Eloquent\\Builder
*/
public static function query()
{
return (new static)->newQuery();
}
/**
* Begin querying the model on a given connection.
*
* @param string|null \$connection
* @return \\Illuminate\\Database\\Eloquent\\Builder
*/
public static function on(\$connection = null)
{
// First we will just create a fresh instance of this model, and then we can
// set the connection on the model so that it is be used for the queries
// we execute, as well as being set on each relationship we retrieve.
\$instance = new static;
\$instance->setConnection(\$connection);
return \$instance->newQuery();
}
/**
* Begin querying the model on the write connection.
*
* @return \\Illuminate\\Database\\Query\\Builder
*/
public static function onWriteConnection()
{
\$instance = new static;
return \$instance->newQuery()->useWritePdo();
}
/**
* Get all of the models from the database.
*
* @param array|mixed \$columns
* @return \\Illuminate\\Database\\Eloquent\\Collection|static[]
*/
public static function all(\$columns = ['*'])
{
\$columns = is_array(\$columns) ? \$columns : func_get_args();
\$instance = new static;
return \$instance->newQuery()->get(\$columns);
}
/**
* Reload a fresh model instance from the database.
*
* @param array|string \$with
* @return \$this|null
*/
public function fresh(\$with = [])
{
if (! \$this->exists) {
return;
}
if (is_string(\$with)) {
\$with = func_get_args();
}
\$key = \$this->getKeyName();
return static::with(\$with)->where(\$key, \$this->getKey())->first();
}
/**
* Eager load relations on the model.
*
* @param array|string \$relations
* @return \$this
*/
public function load(\$relations)
{
if (is_string(\$relations)) {
\$relations = func_get_args();
}
\$query = \$this->newQuery()->with(\$relations);
\$query->eagerLoadRelations([\$this]);
return \$this;
}
/**
* Begin querying a model with eager loading.
*
* @param array|string \$relations
* @return \\Illuminate\\Database\\Eloquent\\Builder|static
*/
public static function with(\$relations)
{
if (is_string(\$relations)) {
\$relations = func_get_args();
}
\$instance = new static;
return \$instance->newQuery()->with(\$relations);
}
/**
* Append attributes to query when building a query.
*
* @param array|string \$attributes
* @return \$this
*/
public function append(\$attributes)
{
if (is_string(\$attributes)) {
\$attributes = func_get_args();
}
\$this->appends = array_unique(
array_merge(\$this->appends, \$attributes)
);
return \$this;
}
/**
* Define a one-to-one relationship.
*
* @param string \$related
* @param string \$foreignKey
* @param string \$localKey
* @return \\Illuminate\\Database\\Eloquent\\Relations\\HasOne
*/
public function hasOne(\$related, \$foreignKey = null, \$localKey = null)
{
\$foreignKey = \$foreignKey ?: \$this->getForeignKey();
\$instance = new \$related;
\$localKey = \$localKey ?: \$this->getKeyName();
return new HasOne(\$instance->newQuery(), \$this, \$instance->getTable().'.'.\$foreignKey, \$localKey);
}
/**
* Define a polymorphic one-to-one relationship.
*
* @param string \$related
* @param string \$name
* @param string \$type
* @param string \$id
* @param string \$localKey
* @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphOne
*/
public function morphOne(\$related, \$name, \$type = null, \$id = null, \$localKey = null)
{
\$instance = new \$related;
list(\$type, \$id) = \$this->getMorphs(\$name, \$type, \$id);
\$table = \$instance->getTable();
\$localKey = \$localKey ?: \$this->getKeyName();
return new MorphOne(\$instance->newQuery(), \$this, \$table.'.'.\$type, \$table.'.'.\$id, \$localKey);
}
/**
* Define an inverse one-to-one or many relationship.
*
* @param string \$related
* @param string \$foreignKey
* @param string \$otherKey
* @param string \$relation
* @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsTo
*/
public function belongsTo(\$related, \$foreignKey = null, \$otherKey = null, \$relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relationships.
if (is_null(\$relation)) {
list(\$current, \$caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
\$relation = \$caller['function'];
}
// If no foreign key was supplied, we can use a backtrace to guess the proper
// foreign key name by using the name of the relationship function, which
// when combined with an "_id" should conventionally match the columns.
if (is_null(\$foreignKey)) {
\$foreignKey = Str::snake(\$relation).'_id';
}
\$instance = new \$related;
// Once we have the foreign key names, we'll just create a new Eloquent query
// for the related models and returns the relationship instance which will
// actually be responsible for retrieving and hydrating every relations.
\$query = \$instance->newQuery();
\$otherKey = \$otherKey ?: \$instance->getKeyName();
return new BelongsTo(\$query, \$this, \$foreignKey, \$otherKey, \$relation);
}
/**
* Define a polymorphic, inverse one-to-one or many relationship.
*
* @param string \$name
* @param string \$type
* @param string \$id
* @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphTo
*/
public function morphTo(\$name = null, \$type = null, \$id = null)
{
// If no name is provided, we will use the backtrace to get the function name
// since that is most likely the name of the polymorphic interface. We can
// use that to get both the class and foreign key that will be utilized.
if (is_null(\$name)) {
list(\$current, \$caller) = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
\$name = Str::snake(\$caller['function']);
}
list(\$type, \$id) = \$this->getMorphs(\$name, \$type, \$id);
// If the type value is null it is probably safe to assume we're eager loading
// the relationship. When that is the case we will pass in a dummy query as
// there are multiple types in the morph and we can't use single queries.
if (empty(\$class = \$this->\$type)) {
return new MorphTo(
\$this->newQuery(), \$this, \$id, null, \$type, \$name
);
}
// If we are not eager loading the relationship we will essentially treat this
// as a belongs-to style relationship since morph-to extends that class and
// we will pass in the appropriate values so that it behaves as expected.
else {
\$class = \$this->getActualClassNameForMorph(\$class);
\$instance = new \$class;
return new MorphTo(
\$instance->newQuery(), \$this, \$id, \$instance->getKeyName(), \$type, \$name
);
}
}
/**
* Retrieve the fully qualified class name from a slug.
*
* @param string \$class
* @return string
*/
public function getActualClassNameForMorph(\$class)
{
return Arr::get(Relation::morphMap(), \$class, \$class);
}
/**
* Define a one-to-many relationship.
*
* @param string \$related
* @param string \$foreignKey
* @param string \$localKey
* @return \\Illuminate\\Database\\Eloquent\\Relations\\HasMany
*/
public function hasMany(\$related, \$foreignKey = null, \$localKey = null)
{
\$foreignKey = \$foreignKey ?: \$this->getForeignKey();
\$instance = new \$related;
\$localKey = \$localKey ?: \$this->getKeyName();
return new HasMany(\$instance->newQuery(), \$this, \$instance->getTable().'.'.\$foreignKey, \$localKey);
}
/**
* Define a has-many-through relationship.
*
* @param string \$related
* @param string \$through
* @param string|null \$firstKey
* @param string|null \$secondKey
* @param string|null \$localKey
* @return \\Illuminate\\Database\\Eloquent\\Relations\\HasManyThrough
*/
public function hasManyThrough(\$related, \$through, \$firstKey = null, \$secondKey = null, \$localKey = null)
{
\$through = new \$through;
\$firstKey = \$firstKey ?: \$this->getForeignKey();
\$secondKey = \$secondKey ?: \$through->getForeignKey();
\$localKey = \$localKey ?: \$this->getKeyName();
return new HasManyThrough((new \$related)->newQuery(), \$this, \$through, \$firstKey, \$secondKey, \$localKey);
}
/**
* Define a polymorphic one-to-many relationship.
*
* @param string \$related
* @param string \$name
* @param string \$type
* @param string \$id
* @param string \$localKey
* @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphMany
*/
public function morphMany(\$related, \$name, \$type = null, \$id = null, \$localKey = null)
{
\$instance = new \$related;
// Here we will gather up the morph type and ID for the relationship so that we
// can properly query the intermediate table of a relation. Finally, we will
// get the table and create the relationship instances for the developers.
list(\$type, \$id) = \$this->getMorphs(\$name, \$type, \$id);
\$table = \$instance->getTable();
\$localKey = \$localKey ?: \$this->getKeyName();
return new MorphMany(\$instance->newQuery(), \$this, \$table.'.'.\$type, \$table.'.'.\$id, \$localKey);
}
/**
* Define a many-to-many relationship.
*
* @param string \$related
* @param string \$table
* @param string \$foreignKey
* @param string \$otherKey
* @param string \$relation
* @return \\Illuminate\\Database\\Eloquent\\Relations\\BelongsToMany
*/
public function belongsToMany(\$related, \$table = null, \$foreignKey = null, \$otherKey = null, \$relation = null)
{
// If no relationship name was passed, we will pull backtraces to get the
// name of the calling function. We will use that function name as the
// title of this relation since that is a great convention to apply.
if (is_null(\$relation)) {
\$relation = \$this->getBelongsToManyCaller();
}
// First, we'll need to determine the foreign key and "other key" for the
// relationship. Once we have determined the keys we'll make the query
// instances as well as the relationship instances we need for this.
\$foreignKey = \$foreignKey ?: \$this->getForeignKey();
\$instance = new \$related;
\$otherKey = \$otherKey ?: \$instance->getForeignKey();
// If no table name was provided, we can guess it by concatenating the two
// models using underscores in alphabetical order. The two model names
// are transformed to snake case from their default CamelCase also.
if (is_null(\$table)) {
\$table = \$this->joiningTable(\$related);
}
// Now we're ready to create a new query builder for the related model and
// the relationship instances for the relation. The relations will set
// appropriate query constraint and entirely manages the hydrations.
\$query = \$instance->newQuery();
return new BelongsToMany(\$query, \$this, \$table, \$foreignKey, \$otherKey, \$relation);
}
/**
* Define a polymorphic many-to-many relationship.
*
* @param string \$related
* @param string \$name
* @param string \$table
* @param string \$foreignKey
* @param string \$otherKey
* @param bool \$inverse
* @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphToMany
*/
public function morphToMany(\$related, \$name, \$table = null, \$foreignKey = null, \$otherKey = null, \$inverse = false)
{
\$caller = \$this->getBelongsToManyCaller();
// First, we will need to determine the foreign key and "other key" for the
// relationship. Once we have determined the keys we will make the query
// instances, as well as the relationship instances we need for these.
\$foreignKey = \$foreignKey ?: \$name.'_id';
\$instance = new \$related;
\$otherKey = \$otherKey ?: \$instance->getForeignKey();
// Now we're ready to create a new query builder for this related model and
// the relationship instances for this relation. This relations will set
// appropriate query constraints then entirely manages the hydrations.
\$query = \$instance->newQuery();
\$table = \$table ?: Str::plural(\$name);
return new MorphToMany(
\$query, \$this, \$name, \$table, \$foreignKey,
\$otherKey, \$caller, \$inverse
);
}
/**
* Define a polymorphic, inverse many-to-many relationship.
*
* @param string \$related
* @param string \$name
* @param string \$table
* @param string \$foreignKey
* @param string \$otherKey
* @return \\Illuminate\\Database\\Eloquent\\Relations\\MorphToMany
*/
public function morphedByMany(\$related, \$name, \$table = null, \$foreignKey = null, \$otherKey = null)
{
\$foreignKey = \$foreignKey ?: \$this->getForeignKey();
// For the inverse of the polymorphic many-to-many relations, we will change
// the way we determine the foreign and other keys, as it is the opposite
// of the morph-to-many method since we're figuring out these inverses.
\$otherKey = \$otherKey ?: \$name.'_id';
return \$this->morphToMany(\$related, \$name, \$table, \$foreignKey, \$otherKey, true);
}
/**
* Get the relationship name of the belongs to many.
*
* @return string
*/
protected function getBelongsToManyCaller()
{
\$self = __FUNCTION__;
\$caller = Arr::first(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), function (\$trace) use (\$self) {
\$caller = \$trace['function'];
return ! in_array(\$caller, Model::\$manyMethods) && \$caller != \$self;
});
return ! is_null(\$caller) ? \$caller['function'] : null;
}
/**
* Get the joining table name for a many-to-many relation.
*
* @param string \$related
* @return string
*/
public function joiningTable(\$related)
{
// The joining table name, by convention, is simply the snake cased models
// sorted alphabetically and concatenated with an underscore, so we can
// just sort the models and join them together to get the table name.
\$base = Str::snake(class_basename(\$this));
\$related = Str::snake(class_basename(\$related));
\$models = [\$related, \$base];
// Now that we have the model names in an array we can just sort them and
// use the implode function to join them together with an underscores,
// which is typically used by convention within the database system.
sort(\$models);
return strtolower(implode('_', \$models));
}
/**
* Destroy the models for the given IDs.
*
* @param array|int \$ids
* @return int
*/
public static function destroy(\$ids)
{
// We'll initialize a count here so we will return the total number of deletes
// for the operation. The developers can then check this number as a boolean
// type value or get this total count of records deleted for logging, etc.
\$count = 0;
\$ids = is_array(\$ids) ? \$ids : func_get_args();
\$instance = new static;
// We will actually pull the models from the database table and call delete on
// each of them individually so that their events get fired properly with a
// correct set of attributes in case the developers wants to check these.
\$key = \$instance->getKeyName();
foreach (\$instance->whereIn(\$key, \$ids)->get() as \$model) {
if (\$model->delete()) {
\$count++;
}
}
return \$count;
}
/**
* Delete the model from the database.
*
* @return bool|null
*
* @throws \\Exception
*/
public function delete()
{
if (is_null(\$this->getKeyName())) {
throw new Exception('No primary key defined on model.');
}
if (\$this->exists) {
if (\$this->fireModelEvent('deleting') === false) {
return false;
}
// Here, we'll touch the owning models, verifying these timestamps get updated
// for the models. This will allow any caching to get broken on the parents
// by the timestamp. Then we will go ahead and delete the model instance.
\$this->touchOwners();
\$this->performDeleteOnModel();
\$this->exists = false;
// Once the model has been deleted, we will fire off the deleted event so that
// the developers may hook into post-delete operations. We will then return
// a boolean true as the delete is presumably successful on the database.
\$this->fireModelEvent('deleted', false);
return true;
}
}
/**
* Force a hard delete on a soft deleted model.
*
* This method protects developers from running forceDelete when trait is missing.
*
* @return bool|null
*/
public function forceDelete()
{
return \$this->delete();
}
/**
* Perform the actual delete query on this model instance.
*
* @return void
*/
protected function performDeleteOnModel()
{
\$this->setKeysForSaveQuery(\$this->newQueryWithoutScopes())->delete();
}
/**
* Register a saving model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function saving(\$callback, \$priority = 0)
{
static::registerModelEvent('saving', \$callback, \$priority);
}
/**
* Register a saved model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function saved(\$callback, \$priority = 0)
{
static::registerModelEvent('saved', \$callback, \$priority);
}
/**
* Register an updating model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function updating(\$callback, \$priority = 0)
{
static::registerModelEvent('updating', \$callback, \$priority);
}
/**
* Register an updated model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function updated(\$callback, \$priority = 0)
{
static::registerModelEvent('updated', \$callback, \$priority);
}
/**
* Register a creating model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function creating(\$callback, \$priority = 0)
{
static::registerModelEvent('creating', \$callback, \$priority);
}
/**
* Register a created model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function created(\$callback, \$priority = 0)
{
static::registerModelEvent('created', \$callback, \$priority);
}
/**
* Register a deleting model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function deleting(\$callback, \$priority = 0)
{
static::registerModelEvent('deleting', \$callback, \$priority);
}
/**
* Register a deleted model event with the dispatcher.
*
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
public static function deleted(\$callback, \$priority = 0)
{
static::registerModelEvent('deleted', \$callback, \$priority);
}
/**
* Remove all of the event listeners for the model.
*
* @return void
*/
public static function flushEventListeners()
{
if (! isset(static::\$dispatcher)) {
return;
}
\$instance = new static;
foreach (\$instance->getObservableEvents() as \$event) {
static::\$dispatcher->forget("eloquent.{\$event}: ".static::class);
}
}
/**
* Register a model event with the dispatcher.
*
* @param string \$event
* @param \\Closure|string \$callback
* @param int \$priority
* @return void
*/
protected static function registerModelEvent(\$event, \$callback, \$priority = 0)
{
if (isset(static::\$dispatcher)) {
\$name = static::class;
static::\$dispatcher->listen("eloquent.{\$event}: {\$name}", \$callback, \$priority);
}
}
/**
* Get the observable event names.
*
* @return array
*/
public function getObservableEvents()
{
return array_merge(
[
'creating', 'created', 'updating', 'updated',
'deleting', 'deleted', 'saving', 'saved',
'restoring', 'restored',
],
\$this->observables
);
}
/**
* Set the observable event names.
*
* @param array \$observables
* @return \$this
*/
public function setObservableEvents(array \$observables)
{
\$this->observables = \$observables;
return \$this;
}
/**
* Add an observable event name.
*
* @param array|mixed \$observables
* @return void
*/
public function addObservableEvents(\$observables)
{
\$observables = is_array(\$observables) ? \$observables : func_get_args();
\$this->observables = array_unique(array_merge(\$this->observables, \$observables));
}
/**
* Remove an observable event name.
*
* @param array|mixed \$observables
* @return void
*/
public function removeObservableEvents(\$observables)
{
\$observables = is_array(\$observables) ? \$observables : func_get_args();
\$this->observables = array_diff(\$this->observables, \$observables);
}
/**
* Increment a column's value by a given amount.
*
* @param string \$column
* @param int \$amount
* @param array \$extra
* @return int
*/
protected function increment(\$column, \$amount = 1, array \$extra = [])
{
return \$this->incrementOrDecrement(\$column, \$amount, \$extra, 'increment');
}
/**
* Decrement a column's value by a given amount.
*
* @param string \$column
* @param int \$amount
* @param array \$extra
* @return int
*/
protected function decrement(\$column, \$amount = 1, array \$extra = [])
{
return \$this->incrementOrDecrement(\$column, \$amount, \$extra, 'decrement');
}
/**
* Run the increment or decrement method on the model.
*
* @param string \$column
* @param int \$amount
* @param array \$extra
* @param string \$method
* @return int
*/
protected function incrementOrDecrement(\$column, \$amount, \$extra, \$method)
{
\$query = \$this->newQuery();
if (! \$this->exists) {
return \$query->{\$method}(\$column, \$amount, \$extra);
}
\$this->incrementOrDecrementAttributeValue(\$column, \$amount, \$method);
return \$query->where(\$this->getKeyName(), \$this->getKey())->{\$method}(\$column, \$amount, \$extra);
}
/**
* Increment the underlying attribute value and sync with original.
*
* @param string \$column
* @param int \$amount
* @param string \$method
* @return void
*/
protected function incrementOrDecrementAttributeValue(\$column, \$amount, \$method)
{
\$this->{\$column} = \$this->{\$column} + (\$method == 'increment' ? \$amount : \$amount * -1);
\$this->syncOriginalAttribute(\$column);
}
/**
* Update the model in the database.
*
* @param array \$attributes
* @param array \$options
* @return bool|int
*/
public function update(array \$attributes = [], array \$options = [])
{
if (! \$this->exists) {
return false;
}
return \$this->fill(\$attributes)->save(\$options);
}
/**
* Save the model and all of its relationships.
*
* @return bool
*/
public function push()
{
if (! \$this->save()) {
return false;
}
// To sync all of the relationships to the database, we will simply spin through
// the relationships and save each model via this "push" method, which allows
// us to recurse into all of these nested relations for the model instance.
foreach (\$this->relations as \$models) {
\$models = \$models instanceof Collection
? \$models->all() : [\$models];
foreach (array_filter(\$models) as \$model) {
if (! \$model->push()) {
return false;
}
}
}
return true;
}
/**
* Save the model to the database.
*
* @param array \$options
* @return bool
*/
public function save(array \$options = [])
{
\$query = \$this->newQueryWithoutScopes();
// If the "saving" event returns false we'll bail out of the save and return
// false, indicating that the save failed. This provides a chance for any
// listeners to cancel save operations if validations fail or whatever.
if (\$this->fireModelEvent('saving') === false) {
return false;
}
// If the model already exists in the database we can just update our record
// that is already in this database using the current IDs in this "where"
// clause to only update this model. Otherwise, we'll just insert them.
if (\$this->exists) {
\$saved = \$this->performUpdate(\$query);
}
// If the model is brand new, we'll insert it into our database and set the
// ID attribute on the model to the value of the newly inserted row's ID
// which is typically an auto-increment value managed by the database.
else {
\$saved = \$this->performInsert(\$query);
}
if (\$saved) {
\$this->finishSave(\$options);
}
return \$saved;
}
/**
* Save the model to the database using transaction.
*
* @param array \$options
* @return bool
*
* @throws \\Throwable
*/
public function saveOrFail(array \$options = [])
{
return \$this->getConnection()->transaction(function () use (\$options) {
return \$this->save(\$options);
});
}
/**
* Finish processing on a successful save operation.
*
* @param array \$options
* @return void
*/
protected function finishSave(array \$options)
{
\$this->fireModelEvent('saved', false);
\$this->syncOriginal();
if (Arr::get(\$options, 'touch', true)) {
\$this->touchOwners();
}
}
/**
* Perform a model update operation.
*
* @param \\Illuminate\\Database\\Eloquent\\Builder \$query
* @return bool
*/
protected function performUpdate(Builder \$query)
{
\$dirty = \$this->getDirty();
if (count(\$dirty) > 0) {
// If the updating event returns false, we will cancel the update operation so
// developers can hook Validation systems into their models and cancel this
// operation if the model does not pass validation. Otherwise, we update.
if (\$this->fireModelEvent('updating') === false) {
return false;
}
// First we need to create a fresh query instance and touch the creation and
// update timestamp on the model which are maintained by us for developer
// convenience. Then we will just continue saving the model instances.
if (\$this->timestamps) {
\$this->updateTimestamps();
}
// Once we have run the update operation, we will fire the "updated" event for
// this model instance. This will allow developers to hook into these after
// models are updated, giving them a chance to do any special processing.
\$dirty = \$this->getDirty();
if (count(\$dirty) > 0) {
\$numRows = \$this->setKeysForSaveQuery(\$query)->update(\$dirty);
\$this->fireModelEvent('updated', false);
}
}
return true;
}
/**
* Perform a model insert operation.
*
* @param \\Illuminate\\Database\\Eloquent\\Builder \$query
* @return bool
*/
protected function performInsert(Builder \$query)
{
if (\$this->fireModelEvent('creating') === false) {
return false;
}
// First we'll need to create a fresh query instance and touch the creation and
// update timestamps on this model, which are maintained by us for developer
// convenience. After, we will just continue saving these model instances.
if (\$this->timestamps) {
\$this->updateTimestamps();
}
// If the model has an incrementing key, we can use the "insertGetId" method on
// the query builder, which will give us back the final inserted ID for this
// table from the database. Not all tables have to be incrementing though.
\$attributes = \$this->attributes;
if (\$this->getIncrementing()) {
\$this->insertAndSetId(\$query, \$attributes);
}
// If the table isn't incrementing we'll simply insert these attributes as they
// are. These attribute arrays must contain an "id" column previously placed
// there by the developer as the manually determined key for these models.
else {
\$query->insert(\$attributes);
}
// We will go ahead and set the exists property to true, so that it is set when
// the created event is fired, just in case the developer tries to update it
// during the event. This will allow them to do so and run an update here.
\$this->exists = true;
\$this->wasRecentlyCreated = true;
\$this->fireModelEvent('created', false);
return true;
}
/**
* Insert the given attributes and set the ID on the model.
*
* @param \\Illuminate\\Database\\Eloquent\\Builder \$query
* @param array \$attributes
* @return void
*/
protected function insertAndSetId(Builder \$query, \$attributes)
{
\$id = \$query->insertGetId(\$attributes, \$keyName = \$this->getKeyName());
\$this->setAttribute(\$keyName, \$id);
}
/**
* Touch the owning relations of the model.
*
* @return void
*/
public function touchOwners()
{
foreach (\$this->touches as \$relation) {
\$this->\$relation()->touch();
if (\$this->\$relation instanceof self) {
\$this->\$relation->fireModelEvent('saved', false);
\$this->\$relation->touchOwners();
} elseif (\$this->\$relation instanceof Collection) {
\$this->\$relation->each(function (Model \$relation) {
\$relation->touchOwners();
});
}
}
}
/**
* Determine if the model touches a given relation.
*
* @param string \$relation
* @return bool
*/
public function touches(\$relation)
{
return in_array(\$relation, \$this->touches);
}
/**
* Fire the given event for the model.
*
* @param string \$event
* @param bool \$halt
* @return mixed
*/
protected function fireModelEvent(\$event, \$halt = true)
{
if (! isset(static::\$dispatcher)) {
return true;
}
// We will append the names of the class to the event to distinguish it from
// other model events that are fired, allowing us to listen on each model
// event set individually instead of catching event for all the models.
\$event = "eloquent.{\$event}: ".static::class;
\$method = \$halt ? 'until' : 'fire';
return static::\$dispatcher->\$method(\$event, \$this);
}
/**
* Set the keys for a save update query.
*
* @param \\Illuminate\\Database\\Eloquent\\Builder \$query
* @return \\Illuminate\\Database\\Eloquent\\Builder
*/
protected function setKeysForSaveQuery(Builder \$query)
{
\$query->where(\$this->getKeyName(), '=', \$this->getKeyForSaveQuery());
return \$query;
}
/**
* Get the primary key value for a save query.
*
* @return mixed
*/
protected function getKeyForSaveQuery()
{
if (isset(\$this->original[\$this->getKeyName()])) {
return \$this->original[\$this->getKeyName()];
}
return \$this->getAttribute(\$this->getKeyName());
}
/**
* Update the model's update timestamp.
*
* @return bool
*/
public function touch()
{
if (! \$this->timestamps) {
return false;
}
\$this->updateTimestamps();
return \$this->save();
}
/**
* Update the creation and update timestamps.
*
* @return void
*/
protected function updateTimestamps()
{
\$time = \$this->freshTimestamp();
if (! \$this->isDirty(static::UPDATED_AT)) {
\$this->setUpdatedAt(\$time);
}
if (! \$this->exists && ! \$this->isDirty(static::CREATED_AT)) {
\$this->setCreatedAt(\$time);
}
}
/**
* Set the value of the "created at" attribute.
*
* @param mixed \$value
* @return \$this
*/
public function setCreatedAt(\$value)
{
\$this->{static::CREATED_AT} = \$value;
return \$this;
}
/**
* Set the value of the "updated at" attribute.
*
* @param mixed \$value
* @return \$this
*/
public function setUpdatedAt(\$value)
{
\$this->{static::UPDATED_AT} = \$value;
return \$this;
}
/**
* Get the name of the "created at" column.
*
* @return string
*/
public function getCreatedAtColumn()
{
return static::CREATED_AT;
}
/**
* Get the name of the "updated at" column.
*
* @return string
*/
public function getUpdatedAtColumn()
{
return static::UPDATED_AT;
}
/**
* Get a fresh timestamp for the model.
*
* @return \\Carbon\\Carbon
*/
public function freshTimestamp()
{
return new Carbon;
}
/**
* Get a fresh timestamp for the model.
*
* @return string
*/
public function freshTimestampString()
{
return \$this->fromDateTime(\$this->freshTimestamp());
}
/**
* Get a new query builder for the model's table.
*
* @return \\Illuminate\\Database\\Eloquent\\Builder
*/
public function newQuery()
{
\$builder = \$this->newQueryWithoutScopes();
foreach (\$this->getGlobalScopes() as \$identifier => \$scope) {
\$builder->withGlobalScope(\$identifier, \$scope);
}
return \$builder;
}
/**
* Get a new query instance without a given scope.
*
* @param \\Illuminate\\Database\\Eloquent\\Scope|string \$scope
* @return \\Illuminate\\Database\\Eloquent\\Builder
*/
public function newQueryWithoutScope(\$scope)
{
\$builder = \$this->newQuery();
return \$builder->withoutGlobalScope(\$scope);
}
/**
* Get a new query builder that doesn't have any global scopes.
*
* @return \\Illuminate\\Database\\Eloquent\\Builder|static
*/
public function newQueryWithoutScopes()
{
\$builder = \$this->newEloquentBuilder(
\$this->newBaseQueryBuilder()
);
// Once we have the query builders, we will set the model instances so the
// builder can easily access any information it may need from the model
// while it is constructing and executing various queries against it.
return \$builder->setModel(\$this)->with(\$this->with);
}
/**
* Create a new Eloquent query builder for the model.
*
* @param \\Illuminate\\Database\\Query\\Builder \$query
* @return \\Illuminate\\Database\\Eloquent\\Builder|static
*/
public function newEloquentBuilder(\$query)
{
return new Builder(\$query);
}
/**
* Get a new query builder instance for the connection.
*
* @return \\Illuminate\\Database\\Query\\Builder
*/
protected function newBaseQueryBuilder()
{
\$conn = \$this->getConnection();
\$grammar = \$conn->getQueryGrammar();
return new QueryBuilder(\$conn, \$grammar, \$conn->getPostProcessor());
}
/**
* Create a new Eloquent Collection instance.
*
* @param array \$models
* @return \\Illuminate\\Database\\Eloquent\\Collection
*/
public function newCollection(array \$models = [])
{
return new Collection(\$models);
}
/**
* Create a new pivot model instance.
*
* @param \\Illuminate\\Database\\Eloquent\\Model \$parent
* @param array \$attributes
* @param string \$table
* @param bool \$exists
* @return \\Illuminate\\Database\\Eloquent\\Relations\\Pivot
*/
public function newPivot(Model \$parent, array \$attributes, \$table, \$exists)
{
return new Pivot(\$parent, \$attributes, \$table, \$exists);
}
/**
* Get the table associated with the model.
*
* @return string
*/
public function getTable()
{
if (isset(\$this->table)) {
return \$this->table;
}
return str_replace('\\\\', '', Str::snake(Str::plural(class_basename(\$this))));
}
/**
* Set the table associated with the model.
*
* @param string \$table
* @return \$this
*/
public function setTable(\$table)
{
\$this->table = \$table;
return \$this;
}
/**
* Get the value of the model's primary key.
*
* @return mixed
*/
public function getKey()
{
return \$this->getAttribute(\$this->getKeyName());
}
/**
* Get the queueable identity for the entity.
*
* @return mixed
*/
public function getQueueableId()
{
return \$this->getKey();
}
/**
* Get the primary key for the model.
*
* @return string
*/
public function getKeyName()
{
return \$this->primaryKey;
}
/**
* Set the primary key for the model.
*
* @param string \$key
* @return \$this
*/
public function setKeyName(\$key)
{
\$this->primaryKey = \$key;
return \$this;
}
/**
* Get the table qualified key name.
*
* @return string
*/
public function getQualifiedKeyName()
{
return \$this->getTable().'.'.\$this->getKeyName();
}
/**
* Get the value of the model's route key.
*
* @return mixed
*/
public function getRouteKey()
{
return \$this->getAttribute(\$this->getRouteKeyName());
}
/**
* Get the route key for the model.
*
* @return string
*/
public function getRouteKeyName()
{
return \$this->getKeyName();
}
/**
* Determine if the model uses timestamps.
*
* @return bool
*/
public function usesTimestamps()
{
return \$this->timestamps;
}
/**
* Get the polymorphic relationship columns.
*
* @param string \$name
* @param string \$type
* @param string \$id
* @return array
*/
protected function getMorphs(\$name, \$type, \$id)
{
\$type = \$type ?: \$name.'_type';
\$id = \$id ?: \$name.'_id';
return [\$type, \$id];
}
/**
* Get the class name for polymorphic relations.
*
* @return string
*/
public function getMorphClass()
{
\$morphMap = Relation::morphMap();
\$class = static::class;
if (! empty(\$morphMap) && in_array(\$class, \$morphMap)) {
return array_search(\$class, \$morphMap, true);
}
return \$this->morphClass ?: \$class;
}
/**
* Get the number of models to return per page.
*
* @return int
*/
public function getPerPage()
{
return \$this->perPage;
}
/**
* Set the number of models to return per page.
*
* @param int \$perPage
* @return \$this
*/
public function setPerPage(\$perPage)
{
\$this->perPage = \$perPage;
return \$this;
}
/**
* Get the default foreign key name for the model.
*
* @return string
*/
public function getForeignKey()
{
return Str::snake(class_basename(\$this)).'_id';
}
/**
* Get the hidden attributes for the model.
*
* @return array
*/
public function getHidden()
{
return \$this->hidden;
}
/**
* Set the hidden attributes for the model.
*
* @param array \$hidden
* @return \$this
*/
public function setHidden(array \$hidden)
{
\$this->hidden = \$hidden;
return \$this;
}
/**
* Add hidden attributes for the model.
*
* @param array|string|null \$attributes
* @return void
*/
public function addHidden(\$attributes = null)
{
\$attributes = is_array(\$attributes) ? \$attributes : func_get_args();
\$this->hidden = array_merge(\$this->hidden, \$attributes);
}
/**
* Make the given, typically hidden, attributes visible.
*
* @param array|string \$attributes
* @return \$this
*/
public function makeVisible(\$attributes)
{
\$this->hidden = array_diff(\$this->hidden, (array) \$attributes);
if (! empty(\$this->visible)) {
\$this->addVisible(\$attributes);
}
return \$this;
}
/**
* Get the visible attributes for the model.
*
* @return array
*/
public function getVisible()
{
return \$this->visible;
}
/**
* Set the visible attributes for the model.
*
* @param array \$visible
* @return \$this
*/
public function setVisible(array \$visible)
{
\$this->visible = \$visible;
return \$this;
}
/**
* Add visible attributes for the model.
*
* @param array|string|null \$attributes
* @return void
*/
public function addVisible(\$attributes = null)
{
\$attributes = is_array(\$attributes) ? \$attributes : func_get_args();
\$this->visible = array_merge(\$this->visible, \$attributes);
}
/**
* Set the accessors to append to model arrays.
*
* @param array \$appends
* @return \$this
*/
public function setAppends(array \$appends)
{
\$this->appends = \$appends;
return \$this;
}
/**
* Get the fillable attributes for the model.
*
* @return array
*/
public function getFillable()
{
return \$this->fillable;
}
/**
* Set the fillable attributes for the model.
*
* @param array \$fillable
* @return \$this
*/
public function fillable(array \$fillable)
{
\$this->fillable = \$fillable;
return \$this;
}
/**
* Get the guarded attributes for the model.
*
* @return array
*/
public function getGuarded()
{
return \$this->guarded;
}
/**
* Set the guarded attributes for the model.
*
* @param array \$guarded
* @return \$this
*/
public function guard(array \$guarded)
{
\$this->guarded = \$guarded;
return \$this;
}
/**
* Disable all mass assignable restrictions.
*
* @param bool \$state
* @return void
*/
public static function unguard(\$state = true)
{
static::\$unguarded = \$state;
}
/**
* Enable the mass assignment restrictions.
*
* @return void
*/
public static function reguard()
{
static::\$unguarded = false;
}
/**
* Determine if current state is "unguarded".
*
* @return bool
*/
public static function isUnguarded()
{
return static::\$unguarded;
}
/**
* Run the given callable while being unguarded.
*
* @param callable \$callback
* @return mixed
*/
public static function unguarded(callable \$callback)
{
if (static::\$unguarded) {
return \$callback();
}
static::unguard();
try {
return \$callback();
} finally {
static::reguard();
}
}
/**
* Determine if the given attribute may be mass assigned.
*
* @param string \$key
* @return bool
*/
public function isFillable(\$key)
{
if (static::\$unguarded) {
return true;
}
// If the key is in the "fillable" array, we can of course assume that it's
// a fillable attribute. Otherwise, we will check the guarded array when
// we need to determine if the attribute is black-listed on the model.
if (in_array(\$key, \$this->getFillable())) {
return true;
}
if (\$this->isGuarded(\$key)) {
return false;
}
return empty(\$this->getFillable()) && ! Str::startsWith(\$key, '_');
}
/**
* Determine if the given key is guarded.
*
* @param string \$key
* @return bool
*/
public function isGuarded(\$key)
{
return in_array(\$key, \$this->getGuarded()) || \$this->getGuarded() == ['*'];
}
/**
* Determine if the model is totally guarded.
*
* @return bool
*/
public function totallyGuarded()
{
return count(\$this->getFillable()) == 0 && \$this->getGuarded() == ['*'];
}
/**
* Remove the table name from a given key.
*
* @param string \$key
* @return string
*/
protected function removeTableFromKey(\$key)
{
if (! Str::contains(\$key, '.')) {
return \$key;
}
return last(explode('.', \$key));
}
/**
* Get the relationships that are touched on save.
*
* @return array
*/
public function getTouchedRelations()
{
return \$this->touches;
}
/**
* Set the relationships that are touched on save.
*
* @param array \$touches
* @return \$this
*/
public function setTouchedRelations(array \$touches)
{
\$this->touches = \$touches;
return \$this;
}
/**
* Get the value indicating whether the IDs are incrementing.
*
* @return bool
*/
public function getIncrementing()
{
return \$this->incrementing;
}
/**
* Set whether IDs are incrementing.
*
* @param bool \$value
* @return \$this
*/
public function setIncrementing(\$value)
{
\$this->incrementing = \$value;
return \$this;
}
/**
* Convert the model instance to JSON.
*
* @param int \$options
* @return string
*/
public function toJson(\$options = 0)
{
return json_encode(\$this->jsonSerialize(), \$options);
}
/**
* Convert the object into something JSON serializable.
*
* @return array
*/
public function jsonSerialize()
{
return \$this->toArray();
}
/**
* Convert the model instance to an array.
*
* @return array
*/
public function toArray()
{
\$attributes = \$this->attributesToArray();
return array_merge(\$attributes, \$this->relationsToArray());
}
/**
* Convert the model's attributes to an array.
*
* @return array
*/
public function attributesToArray()
{
\$attributes = \$this->getArrayableAttributes();
// If an attribute is a date, we will cast it to a string after converting it
// to a DateTime / Carbon instance. This is so we will get some consistent
// formatting while accessing attributes vs. arraying / JSONing a model.
foreach (\$this->getDates() as \$key) {
if (! isset(\$attributes[\$key])) {
continue;
}
\$attributes[\$key] = \$this->serializeDate(
\$this->asDateTime(\$attributes[\$key])
);
}
\$mutatedAttributes = \$this->getMutatedAttributes();
// We want to spin through all the mutated attributes for this model and call
// the mutator for the attribute. We cache off every mutated attributes so
// we don't have to constantly check on attributes that actually change.
foreach (\$mutatedAttributes as \$key) {
if (! array_key_exists(\$key, \$attributes)) {
continue;
}
\$attributes[\$key] = \$this->mutateAttributeForArray(
\$key, \$attributes[\$key]
);
}
// Next we will handle any casts that have been setup for this model and cast
// the values to their appropriate type. If the attribute has a mutator we
// will not perform the cast on those attributes to avoid any confusion.
foreach (\$this->getCasts() as \$key => \$value) {
if (! array_key_exists(\$key, \$attributes) ||
in_array(\$key, \$mutatedAttributes)) {
continue;
}
\$attributes[\$key] = \$this->castAttribute(
\$key, \$attributes[\$key]
);
if (\$attributes[\$key] && (\$value === 'date' || \$value === 'datetime')) {
\$attributes[\$key] = \$this->serializeDate(\$attributes[\$key]);
}
}
// Here we will grab all of the appended, calculated attributes to this model
// as these attributes are not really in the attributes array, but are run
// when we need to array or JSON the model for convenience to the coder.
foreach (\$this->getArrayableAppends() as \$key) {
\$attributes[\$key] = \$this->mutateAttributeForArray(\$key, null);
}
return \$attributes;
}
/**
* Get an attribute array of all arrayable attributes.
*
* @return array
*/
protected function getArrayableAttributes()
{
return \$this->getArrayableItems(\$this->attributes);
}
/**
* Get all of the appendable values that are arrayable.
*
* @return array
*/
protected function getArrayableAppends()
{
if (! count(\$this->appends)) {
return [];
}
return \$this->getArrayableItems(
array_combine(\$this->appends, \$this->appends)
);
}
/**
* Get the model's relationships in array form.
*
* @return array
*/
public function relationsToArray()
{
\$attributes = [];
foreach (\$this->getArrayableRelations() as \$key => \$value) {
// If the values implements the Arrayable interface we can just call this
// toArray method on the instances which will convert both models and
// collections to their proper array form and we'll set the values.
if (\$value instanceof Arrayable) {
\$relation = \$value->toArray();
}
// If the value is null, we'll still go ahead and set it in this list of
// attributes since null is used to represent empty relationships if
// if it a has one or belongs to type relationships on the models.
elseif (is_null(\$value)) {
\$relation = \$value;
}
// If the relationships snake-casing is enabled, we will snake case this
// key so that the relation attribute is snake cased in this returned
// array to the developers, making this consistent with attributes.
if (static::\$snakeAttributes) {
\$key = Str::snake(\$key);
}
// If the relation value has been set, we will set it on this attributes
// list for returning. If it was not arrayable or null, we'll not set
// the value on the array because it is some type of invalid value.
if (isset(\$relation) || is_null(\$value)) {
\$attributes[\$key] = \$relation;
}
unset(\$relation);
}
return \$attributes;
}
/**
* Get an attribute array of all arrayable relations.
*
* @return array
*/
protected function getArrayableRelations()
{
return \$this->getArrayableItems(\$this->relations);
}
/**
* Get an attribute array of all arrayable values.
*
* @param array \$values
* @return array
*/
protected function getArrayableItems(array \$values)
{
if (count(\$this->getVisible()) > 0) {
return array_intersect_key(\$values, array_flip(\$this->getVisible()));
}
return array_diff_key(\$values, array_flip(\$this->getHidden()));
}
/**
* Get an attribute from the model.
*
* @param string \$key
* @return mixed
*/
public function getAttribute(\$key)
{
if (array_key_exists(\$key, \$this->attributes) || \$this->hasGetMutator(\$key)) {
return \$this->getAttributeValue(\$key);
}
return \$this->getRelationValue(\$key);
}
/**
* Get a plain attribute (not a relationship).
*
* @param string \$key
* @return mixed
*/
public function getAttributeValue(\$key)
{
\$value = \$this->getAttributeFromArray(\$key);
// If the attribute has a get mutator, we will call that then return what
// it returns as the value, which is useful for transforming values on
// retrieval from the model to a form that is more useful for usage.
if (\$this->hasGetMutator(\$key)) {
return \$this->mutateAttribute(\$key, \$value);
}
// If the attribute exists within the cast array, we will convert it to
// an appropriate native PHP type dependant upon the associated value
// given with the key in the pair. Dayle made this comment line up.
if (\$this->hasCast(\$key)) {
return \$this->castAttribute(\$key, \$value);
}
// If the attribute is listed as a date, we will convert it to a DateTime
// instance on retrieval, which makes it quite convenient to work with
// date fields without having to create a mutator for each property.
if (in_array(\$key, \$this->getDates()) && ! is_null(\$value)) {
return \$this->asDateTime(\$value);
}
return \$value;
}
/**
* Get a relationship.
*
* @param string \$key
* @return mixed
*/
public function getRelationValue(\$key)
{
// If the key already exists in the relationships array, it just means the
// relationship has already been loaded, so we'll just return it out of
// here because there is no need to query within the relations twice.
if (\$this->relationLoaded(\$key)) {
return \$this->relations[\$key];
}
// If the "attribute" exists as a method on the model, we will just assume
// it is a relationship and will load and return results from the query
// and hydrate the relationship's value on the "relationships" array.
if (method_exists(\$this, \$key)) {
return \$this->getRelationshipFromMethod(\$key);
}
}
/**
* Get an attribute from the \$attributes array.
*
* @param string \$key
* @return mixed
*/
protected function getAttributeFromArray(\$key)
{
if (array_key_exists(\$key, \$this->attributes)) {
return \$this->attributes[\$key];
}
}
/**
* Get a relationship value from a method.
*
* @param string \$method
* @return mixed
*
* @throws \\LogicException
*/
protected function getRelationshipFromMethod(\$method)
{
\$relations = \$this->\$method();
if (! \$relations instanceof Relation) {
throw new LogicException('Relationship method must return an object of type '
.'Illuminate\\Database\\Eloquent\\Relations\\Relation');
}
\$this->setRelation(\$method, \$results = \$relations->getResults());
return \$results;
}
/**
* Determine if a get mutator exists for an attribute.
*
* @param string \$key
* @return bool
*/
public function hasGetMutator(\$key)
{
return method_exists(\$this, 'get'.Str::studly(\$key).'Attribute');
}
/**
* Get the value of an attribute using its mutator.
*
* @param string \$key
* @param mixed \$value
* @return mixed
*/
protected function mutateAttribute(\$key, \$value)
{
return \$this->{'get'.Str::studly(\$key).'Attribute'}(\$value);
}
/**
* Get the value of an attribute using its mutator for array conversion.
*
* @param string \$key
* @param mixed \$value
* @return mixed
*/
protected function mutateAttributeForArray(\$key, \$value)
{
\$value = \$this->mutateAttribute(\$key, \$value);
return \$value instanceof Arrayable ? \$value->toArray() : \$value;
}
/**
* Determine whether an attribute should be cast to a native type.
*
* @param string \$key
* @param array|string|null \$types
* @return bool
*/
public function hasCast(\$key, \$types = null)
{
if (array_key_exists(\$key, \$this->getCasts())) {
return \$types ? in_array(\$this->getCastType(\$key), (array) \$types, true) : true;
}
return false;
}
/**
* Get the casts array.
*
* @return array
*/
public function getCasts()
{
if (\$this->getIncrementing()) {
return array_merge([
\$this->getKeyName() => \$this->keyType,
], \$this->casts);
}
return \$this->casts;
}
/**
* Determine whether a value is Date / DateTime castable for inbound manipulation.
*
* @param string \$key
* @return bool
*/
protected function isDateCastable(\$key)
{
return \$this->hasCast(\$key, ['date', 'datetime']);
}
/**
* Determine whether a value is JSON castable for inbound manipulation.
*
* @param string \$key
* @return bool
*/
protected function isJsonCastable(\$key)
{
return \$this->hasCast(\$key, ['array', 'json', 'object', 'collection']);
}
/**
* Get the type of cast for a model attribute.
*
* @param string \$key
* @return string
*/
protected function getCastType(\$key)
{
return trim(strtolower(\$this->getCasts()[\$key]));
}
/**
* Cast an attribute to a native PHP type.
*
* @param string \$key
* @param mixed \$value
* @return mixed
*/
protected function castAttribute(\$key, \$value)
{
if (is_null(\$value)) {
return \$value;
}
switch (\$this->getCastType(\$key)) {
case 'int':
case 'integer':
return (int) \$value;
case 'real':
case 'float':
case 'double':
return (float) \$value;
case 'string':
return (string) \$value;
case 'bool':
case 'boolean':
return (bool) \$value;
case 'object':
return \$this->fromJson(\$value, true);
case 'array':
case 'json':
return \$this->fromJson(\$value);
case 'collection':
return new BaseCollection(\$this->fromJson(\$value));
case 'date':
case 'datetime':
return \$this->asDateTime(\$value);
case 'timestamp':
return \$this->asTimeStamp(\$value);
default:
return \$value;
}
}
/**
* Set a given attribute on the model.
*
* @param string \$key
* @param mixed \$value
* @return \$this
*/
public function setAttribute(\$key, \$value)
{
// First we will check for the presence of a mutator for the set operation
// which simply lets the developers tweak the attribute as it is set on
// the model, such as "json_encoding" an listing of data for storage.
if (\$this->hasSetMutator(\$key)) {
\$method = 'set'.Str::studly(\$key).'Attribute';
return \$this->{\$method}(\$value);
}
// If an attribute is listed as a "date", we'll convert it from a DateTime
// instance into a form proper for storage on the database tables using
// the connection grammar's date format. We will auto set the values.
elseif (\$value && (in_array(\$key, \$this->getDates()) || \$this->isDateCastable(\$key))) {
\$value = \$this->fromDateTime(\$value);
}
if (\$this->isJsonCastable(\$key) && ! is_null(\$value)) {
\$value = \$this->asJson(\$value);
}
\$this->attributes[\$key] = \$value;
return \$this;
}
/**
* Determine if a set mutator exists for an attribute.
*
* @param string \$key
* @return bool
*/
public function hasSetMutator(\$key)
{
return method_exists(\$this, 'set'.Str::studly(\$key).'Attribute');
}
/**
* Get the attributes that should be converted to dates.
*
* @return array
*/
public function getDates()
{
\$defaults = [static::CREATED_AT, static::UPDATED_AT];
return \$this->timestamps ? array_merge(\$this->dates, \$defaults) : \$this->dates;
}
/**
* Convert a DateTime to a storable string.
*
* @param \\DateTime|int \$value
* @return string
*/
public function fromDateTime(\$value)
{
\$format = \$this->getDateFormat();
\$value = \$this->asDateTime(\$value);
return \$value->format(\$format);
}
/**
* Return a timestamp as DateTime object.
*
* @param mixed \$value
* @return \\Carbon\\Carbon
*/
protected function asDateTime(\$value)
{
// If this value is already a Carbon instance, we shall just return it as is.
// This prevents us having to re-instantiate a Carbon instance when we know
// it already is one, which wouldn't be fulfilled by the DateTime check.
if (\$value instanceof Carbon) {
return \$value;
}
// If the value is already a DateTime instance, we will just skip the rest of
// these checks since they will be a waste of time, and hinder performance
// when checking the field. We will just return the DateTime right away.
if (\$value instanceof DateTimeInterface) {
return new Carbon(
\$value->format('Y-m-d H:i:s.u'), \$value->getTimeZone()
);
}
// If this value is an integer, we will assume it is a UNIX timestamp's value
// and format a Carbon object from this timestamp. This allows flexibility
// when defining your date fields as they might be UNIX timestamps here.
if (is_numeric(\$value)) {
return Carbon::createFromTimestamp(\$value);
}
// If the value is in simply year, month, day format, we will instantiate the
// Carbon instances from that format. Again, this provides for simple date
// fields on the database, while still supporting Carbonized conversion.
if (preg_match('/^(\\d{4})-(\\d{1,2})-(\\d{1,2})\$/', \$value)) {
return Carbon::createFromFormat('Y-m-d', \$value)->startOfDay();
}
// Finally, we will just assume this date is in the format used by default on
// the database connection and use that format to create the Carbon object
// that is returned back out to the developers after we convert it here.
return Carbon::createFromFormat(\$this->getDateFormat(), \$value);
}
/**
* Return a timestamp as unix timestamp.
*
* @param mixed \$value
* @return int
*/
protected function asTimeStamp(\$value)
{
return \$this->asDateTime(\$value)->getTimestamp();
}
/**
* Prepare a date for array / JSON serialization.
*
* @param \\DateTimeInterface \$date
* @return string
*/
protected function serializeDate(DateTimeInterface \$date)
{
return \$date->format(\$this->getDateFormat());
}
/**
* Get the format for database stored dates.
*
* @return string
*/
protected function getDateFormat()
{
return \$this->dateFormat ?: \$this->getConnection()->getQueryGrammar()->getDateFormat();
}
/**
* Set the date format used by the model.
*
* @param string \$format
* @return \$this
*/
public function setDateFormat(\$format)
{
\$this->dateFormat = \$format;
return \$this;
}
/**
* Encode the given value as JSON.
*
* @param mixed \$value
* @return string
*/
protected function asJson(\$value)
{
return json_encode(\$value);
}
/**
* Decode the given JSON back into an array or object.
*
* @param string \$value
* @param bool \$asObject
* @return mixed
*/
public function fromJson(\$value, \$asObject = false)
{
return json_decode(\$value, ! \$asObject);
}
/**
* Clone the model into a new, non-existing instance.
*
* @param array|null \$except
* @return \\Illuminate\\Database\\Eloquent\\Model
*/
public function replicate(array \$except = null)
{
\$defaults = [
\$this->getKeyName(),
\$this->getCreatedAtColumn(),
\$this->getUpdatedAtColumn(),
];
\$except = \$except ? array_unique(array_merge(\$except, \$defaults)) : \$defaults;
\$attributes = Arr::except(\$this->attributes, \$except);
\$instance = new static;
\$instance->setRawAttributes(\$attributes);
return \$instance->setRelations(\$this->relations);
}
/**
* Get all of the current attributes on the model.
*
* @return array
*/
public function getAttributes()
{
return \$this->attributes;
}
/**
* Set the array of model attributes. No checking is done.
*
* @param array \$attributes
* @param bool \$sync
* @return \$this
*/
public function setRawAttributes(array \$attributes, \$sync = false)
{
\$this->attributes = \$attributes;
if (\$sync) {
\$this->syncOriginal();
}
return \$this;
}
/**
* Get the model's original attribute values.
*
* @param string|null \$key
* @param mixed \$default
* @return mixed|array
*/
public function getOriginal(\$key = null, \$default = null)
{
return Arr::get(\$this->original, \$key, \$default);
}
/**
* Sync the original attributes with the current.
*
* @return \$this
*/
public function syncOriginal()
{
\$this->original = \$this->attributes;
return \$this;
}
/**
* Sync a single original attribute with its current value.
*
* @param string \$attribute
* @return \$this
*/
public function syncOriginalAttribute(\$attribute)
{
\$this->original[\$attribute] = \$this->attributes[\$attribute];
return \$this;
}
/**
* Determine if the model or given attribute(s) have been modified.
*
* @param array|string|null \$attributes
* @return bool
*/
public function isDirty(\$attributes = null)
{
\$dirty = \$this->getDirty();
if (is_null(\$attributes)) {
return count(\$dirty) > 0;
}
if (! is_array(\$attributes)) {
\$attributes = func_get_args();
}
foreach (\$attributes as \$attribute) {
if (array_key_exists(\$attribute, \$dirty)) {
return true;
}
}
return false;
}
/**
* Get the attributes that have been changed since last sync.
*
* @return array
*/
public function getDirty()
{
\$dirty = [];
foreach (\$this->attributes as \$key => \$value) {
if (! array_key_exists(\$key, \$this->original)) {
\$dirty[\$key] = \$value;
} elseif (\$value !== \$this->original[\$key] &&
! \$this->originalIsNumericallyEquivalent(\$key)) {
\$dirty[\$key] = \$value;
}
}
return \$dirty;
}
/**
* Determine if the new and old values for a given key are numerically equivalent.
*
* @param string \$key
* @return bool
*/
protected function originalIsNumericallyEquivalent(\$key)
{
\$current = \$this->attributes[\$key];
\$original = \$this->original[\$key];
return is_numeric(\$current) && is_numeric(\$original) && strcmp((string) \$current, (string) \$original) === 0;
}
/**
* Get all the loaded relations for the instance.
*
* @return array
*/
public function getRelations()
{
return \$this->relations;
}
/**
* Get a specified relationship.
*
* @param string \$relation
* @return mixed
*/
public function getRelation(\$relation)
{
return \$this->relations[\$relation];
}
/**
* Determine if the given relation is loaded.
*
* @param string \$key
* @return bool
*/
public function relationLoaded(\$key)
{
return array_key_exists(\$key, \$this->relations);
}
/**
* Set the specific relationship in the model.
*
* @param string \$relation
* @param mixed \$value
* @return \$this
*/
public function setRelation(\$relation, \$value)
{
\$this->relations[\$relation] = \$value;
return \$this;
}
/**
* Set the entire relations array on the model.
*
* @param array \$relations
* @return \$this
*/
public function setRelations(array \$relations)
{
\$this->relations = \$relations;
return \$this;
}
/**
* Get the database connection for the model.
*
* @return \\Illuminate\\Database\\Connection
*/
public function getConnection()
{
return static::resolveConnection(\$this->getConnectionName());
}
/**
* Get the current connection name for the model.
*
* @return string
*/
public function getConnectionName()
{
return \$this->connection;
}
/**
* Set the connection associated with the model.
*
* @param string \$name
* @return \$this
*/
public function setConnection(\$name)
{
\$this->connection = \$name;
return \$this;
}
/**
* Resolve a connection instance.
*
* @param string|null \$connection
* @return \\Illuminate\\Database\\Connection
*/
public static function resolveConnection(\$connection = null)
{
return static::\$resolver->connection(\$connection);
}
/**
* Get the connection resolver instance.
*
* @return \\Illuminate\\Database\\ConnectionResolverInterface
*/
public static function getConnectionResolver()
{
return static::\$resolver;
}
/**
* Set the connection resolver instance.
*
* @param \\Illuminate\\Database\\ConnectionResolverInterface \$resolver
* @return void
*/
public static function setConnectionResolver(Resolver \$resolver)
{
static::\$resolver = \$resolver;
}
/**
* Unset the connection resolver for models.
*
* @return void
*/
public static function unsetConnectionResolver()
{
static::\$resolver = null;
}
/**
* Get the event dispatcher instance.
*
* @return \\Illuminate\\Contracts\\Events\\Dispatcher
*/
public static function getEventDispatcher()
{
return static::\$dispatcher;
}
/**
* Set the event dispatcher instance.
*
* @param \\Illuminate\\Contracts\\Events\\Dispatcher \$dispatcher
* @return void
*/
public static function setEventDispatcher(Dispatcher \$dispatcher)
{
static::\$dispatcher = \$dispatcher;
}
/**
* Unset the event dispatcher for models.
*
* @return void
*/
public static function unsetEventDispatcher()
{
static::\$dispatcher = null;
}
/**
* Get the mutated attributes for a given instance.
*
* @return array
*/
public function getMutatedAttributes()
{
\$class = static::class;
if (! isset(static::\$mutatorCache[\$class])) {
static::cacheMutatedAttributes(\$class);
}
return static::\$mutatorCache[\$class];
}
/**
* Extract and cache all the mutated attributes of a class.
*
* @param string \$class
* @return void
*/
public static function cacheMutatedAttributes(\$class)
{
\$mutatedAttributes = [];
// Here we will extract all of the mutated attributes so that we can quickly
// spin through them after we export models to their array form, which we
// need to be fast. This'll let us know the attributes that can mutate.
if (preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|\$)/', implode(';', get_class_methods(\$class)), \$matches)) {
foreach (\$matches[1] as \$match) {
if (static::\$snakeAttributes) {
\$match = Str::snake(\$match);
}
\$mutatedAttributes[] = lcfirst(\$match);
}
}
static::\$mutatorCache[\$class] = \$mutatedAttributes;
}
/**
* Dynamically retrieve attributes on the model.
*
* @param string \$key
* @return mixed
*/
public function __get(\$key)
{
return \$this->getAttribute(\$key);
}
/**
* Dynamically set attributes on the model.
*
* @param string \$key
* @param mixed \$value
* @return void
*/
public function __set(\$key, \$value)
{
\$this->setAttribute(\$key, \$value);
}
/**
* Determine if the given attribute exists.
*
* @param mixed \$offset
* @return bool
*/
public function offsetExists(\$offset)
{
return isset(\$this->\$offset);
}
/**
* Get the value for a given offset.
*
* @param mixed \$offset
* @return mixed
*/
public function offsetGet(\$offset)
{
return \$this->\$offset;
}
/**
* Set the value for a given offset.
*
* @param mixed \$offset
* @param mixed \$value
* @return void
*/
public function offsetSet(\$offset, \$value)
{
\$this->\$offset = \$value;
}
/**
* Unset the value for a given offset.
*
* @param mixed \$offset
* @return void
*/
public function offsetUnset(\$offset)
{
unset(\$this->\$offset);
}
/**
* Determine if an attribute or relation exists on the model.
*
* @param string \$key
* @return bool
*/
public function __isset(\$key)
{
return ! is_null(\$this->getAttribute(\$key));
}
/**
* Unset an attribute on the model.
*
* @param string \$key
* @return void
*/
public function __unset(\$key)
{
unset(\$this->attributes[\$key], \$this->relations[\$key]);
}
/**
* Handle dynamic method calls into the model.
*
* @param string \$method
* @param array \$parameters
* @return mixed
*/
public function __call(\$method, \$parameters)
{
if (in_array(\$method, ['increment', 'decrement'])) {
return call_user_func_array([\$this, \$method], \$parameters);
}
\$query = \$this->newQuery();
return call_user_func_array([\$query, \$method], \$parameters);
}
/**
* Handle dynamic static method calls into the method.
*
* @param string \$method
* @param array \$parameters
* @return mixed
*/
public static function __callStatic(\$method, \$parameters)
{
\$instance = new static;
return call_user_func_array([\$instance, \$method], \$parameters);
}
/**
* Convert the model to its string representation.
*
* @return string
*/
public function __toString()
{
return \$this->toJson();
}
/**
* When a model is being unserialized, check if it needs to be booted.
*
* @return void
*/
public function __wakeup()
{
\$this->bootIfNotBooted();
}
}`;
// Reset `lastIndex` if this regex is defined globally
// regex.lastIndex = 0;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for JavaScript, please visit: https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions