| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- <?php
- namespace Illuminate\Database\Eloquent\Concerns;
- trait GuardsAttributes
- {
- /**
- * The attributes that are mass assignable.
- *
- * @var array<int, string>
- */
- protected $fillable = [];
- /**
- * The attributes that aren't mass assignable.
- *
- * @var array<string>|bool
- */
- protected $guarded = ['*'];
- /**
- * Indicates if all mass assignment is enabled.
- *
- * @var bool
- */
- protected static $unguarded = false;
- /**
- * The actual columns that exist on the database and can be guarded.
- *
- * @var array<string>
- */
- protected static $guardableColumns = [];
- /**
- * Get the fillable attributes for the model.
- *
- * @return array<string>
- */
- public function getFillable()
- {
- return $this->fillable;
- }
- /**
- * Set the fillable attributes for the model.
- *
- * @param array<string> $fillable
- * @return $this
- */
- public function fillable(array $fillable)
- {
- $this->fillable = $fillable;
- return $this;
- }
- /**
- * Merge new fillable attributes with existing fillable attributes on the model.
- *
- * @param array<string> $fillable
- * @return $this
- */
- public function mergeFillable(array $fillable)
- {
- $this->fillable = array_values(array_unique(array_merge($this->fillable, $fillable)));
- return $this;
- }
- /**
- * Get the guarded attributes for the model.
- *
- * @return array<string>
- */
- public function getGuarded()
- {
- return $this->guarded === false
- ? []
- : $this->guarded;
- }
- /**
- * Set the guarded attributes for the model.
- *
- * @param array<string> $guarded
- * @return $this
- */
- public function guard(array $guarded)
- {
- $this->guarded = $guarded;
- return $this;
- }
- /**
- * Merge new guarded attributes with existing guarded attributes on the model.
- *
- * @param array<string> $guarded
- * @return $this
- */
- public function mergeGuarded(array $guarded)
- {
- $this->guarded = array_values(array_unique(array_merge($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 the 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 the attribute is explicitly listed in the "guarded" array then we can
- // return false immediately. This means this attribute is definitely not
- // fillable and there is no point in going any further in this method.
- if ($this->isGuarded($key)) {
- return false;
- }
- return empty($this->getFillable()) &&
- ! str_contains($key, '.') &&
- ! str_starts_with($key, '_');
- }
- /**
- * Determine if the given key is guarded.
- *
- * @param string $key
- * @return bool
- */
- public function isGuarded($key)
- {
- if (empty($this->getGuarded())) {
- return false;
- }
- return $this->getGuarded() == ['*'] ||
- ! empty(preg_grep('/^'.preg_quote($key, '/').'$/i', $this->getGuarded())) ||
- ! $this->isGuardableColumn($key);
- }
- /**
- * Determine if the given column is a valid, guardable column.
- *
- * @param string $key
- * @return bool
- */
- protected function isGuardableColumn($key)
- {
- if (! isset(static::$guardableColumns[get_class($this)])) {
- $columns = $this->getConnection()
- ->getSchemaBuilder()
- ->getColumnListing($this->getTable());
- if (empty($columns)) {
- return true;
- }
- static::$guardableColumns[get_class($this)] = $columns;
- }
- return in_array($key, static::$guardableColumns[get_class($this)]);
- }
- /**
- * Determine if the model is totally guarded.
- *
- * @return bool
- */
- public function totallyGuarded()
- {
- return count($this->getFillable()) === 0 && $this->getGuarded() == ['*'];
- }
- /**
- * 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;
- }
- }
|