GuardsAttributes.php 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Concerns;
  3. use Illuminate\Support\Str;
  4. trait GuardsAttributes
  5. {
  6. /**
  7. * The attributes that are mass assignable.
  8. *
  9. * @var array
  10. */
  11. protected $fillable = [];
  12. /**
  13. * The attributes that aren't mass assignable.
  14. *
  15. * @var array
  16. */
  17. protected $guarded = ['*'];
  18. /**
  19. * Indicates if all mass assignment is enabled.
  20. *
  21. * @var bool
  22. */
  23. protected static $unguarded = false;
  24. /**
  25. * Get the fillable attributes for the model.
  26. *
  27. * @return array
  28. */
  29. public function getFillable()
  30. {
  31. return $this->fillable;
  32. }
  33. /**
  34. * Set the fillable attributes for the model.
  35. *
  36. * @param array $fillable
  37. * @return $this
  38. */
  39. public function fillable(array $fillable)
  40. {
  41. $this->fillable = $fillable;
  42. return $this;
  43. }
  44. /**
  45. * Get the guarded attributes for the model.
  46. *
  47. * @return array
  48. */
  49. public function getGuarded()
  50. {
  51. return $this->guarded;
  52. }
  53. /**
  54. * Set the guarded attributes for the model.
  55. *
  56. * @param array $guarded
  57. * @return $this
  58. */
  59. public function guard(array $guarded)
  60. {
  61. $this->guarded = $guarded;
  62. return $this;
  63. }
  64. /**
  65. * Disable all mass assignable restrictions.
  66. *
  67. * @param bool $state
  68. * @return void
  69. */
  70. public static function unguard($state = true)
  71. {
  72. static::$unguarded = $state;
  73. }
  74. /**
  75. * Enable the mass assignment restrictions.
  76. *
  77. * @return void
  78. */
  79. public static function reguard()
  80. {
  81. static::$unguarded = false;
  82. }
  83. /**
  84. * Determine if current state is "unguarded".
  85. *
  86. * @return bool
  87. */
  88. public static function isUnguarded()
  89. {
  90. return static::$unguarded;
  91. }
  92. /**
  93. * Run the given callable while being unguarded.
  94. *
  95. * @param callable $callback
  96. * @return mixed
  97. */
  98. public static function unguarded(callable $callback)
  99. {
  100. if (static::$unguarded) {
  101. return $callback();
  102. }
  103. static::unguard();
  104. try {
  105. return $callback();
  106. } finally {
  107. static::reguard();
  108. }
  109. }
  110. /**
  111. * Determine if the given attribute may be mass assigned.
  112. *
  113. * @param string $key
  114. * @return bool
  115. */
  116. public function isFillable($key)
  117. {
  118. if (static::$unguarded) {
  119. return true;
  120. }
  121. // If the key is in the "fillable" array, we can of course assume that it's
  122. // a fillable attribute. Otherwise, we will check the guarded array when
  123. // we need to determine if the attribute is black-listed on the model.
  124. if (in_array($key, $this->getFillable())) {
  125. return true;
  126. }
  127. // If the attribute is explicitly listed in the "guarded" array then we can
  128. // return false immediately. This means this attribute is definitely not
  129. // fillable and there is no point in going any further in this method.
  130. if ($this->isGuarded($key)) {
  131. return false;
  132. }
  133. return empty($this->getFillable()) &&
  134. ! Str::startsWith($key, '_');
  135. }
  136. /**
  137. * Determine if the given key is guarded.
  138. *
  139. * @param string $key
  140. * @return bool
  141. */
  142. public function isGuarded($key)
  143. {
  144. return in_array($key, $this->getGuarded()) || $this->getGuarded() == ['*'];
  145. }
  146. /**
  147. * Determine if the model is totally guarded.
  148. *
  149. * @return bool
  150. */
  151. public function totallyGuarded()
  152. {
  153. return count($this->getFillable()) == 0 && $this->getGuarded() == ['*'];
  154. }
  155. /**
  156. * Get the fillable attributes of a given array.
  157. *
  158. * @param array $attributes
  159. * @return array
  160. */
  161. protected function fillableFromArray(array $attributes)
  162. {
  163. if (count($this->getFillable()) > 0 && ! static::$unguarded) {
  164. return array_intersect_key($attributes, array_flip($this->getFillable()));
  165. }
  166. return $attributes;
  167. }
  168. }