251 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Illuminate\Database\Eloquent\Concerns;
 | 
						|
 | 
						|
use Illuminate\Support\Str;
 | 
						|
 | 
						|
trait GuardsAttributes
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * The attributes that are mass assignable.
 | 
						|
     *
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected $fillable = [];
 | 
						|
 | 
						|
    /**
 | 
						|
     * The attributes that aren't mass assignable.
 | 
						|
     *
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    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
 | 
						|
     */
 | 
						|
    protected static $guardableColumns = [];
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Merge new fillable attributes with existing fillable attributes on the model.
 | 
						|
     *
 | 
						|
     * @param  array  $fillable
 | 
						|
     * @return $this
 | 
						|
     */
 | 
						|
    public function mergeFillable(array $fillable)
 | 
						|
    {
 | 
						|
        $this->fillable = array_merge($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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Merge new guarded attributes with existing guarded attributes on the model.
 | 
						|
     *
 | 
						|
     * @param  array  $guarded
 | 
						|
     * @return $this
 | 
						|
     */
 | 
						|
    public function mergeGuarded(array $guarded)
 | 
						|
    {
 | 
						|
        $this->guarded = 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 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()) &&
 | 
						|
            strpos($key, '.') === false &&
 | 
						|
            ! Str::startsWith($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)])) {
 | 
						|
            static::$guardableColumns[get_class($this)] = $this->getConnection()
 | 
						|
                        ->getSchemaBuilder()
 | 
						|
                        ->getColumnListing($this->getTable());
 | 
						|
        }
 | 
						|
 | 
						|
        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;
 | 
						|
    }
 | 
						|
}
 |