Model.php 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406
  1. <?php
  2. namespace Illuminate\Database\Eloquent;
  3. use ArrayAccess;
  4. use Illuminate\Contracts\Broadcasting\HasBroadcastChannel;
  5. use Illuminate\Contracts\Queue\QueueableCollection;
  6. use Illuminate\Contracts\Queue\QueueableEntity;
  7. use Illuminate\Contracts\Routing\UrlRoutable;
  8. use Illuminate\Contracts\Support\Arrayable;
  9. use Illuminate\Contracts\Support\CanBeEscapedWhenCastToString;
  10. use Illuminate\Contracts\Support\Jsonable;
  11. use Illuminate\Database\ConnectionResolverInterface as Resolver;
  12. use Illuminate\Database\Eloquent\Collection as EloquentCollection;
  13. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  14. use Illuminate\Database\Eloquent\Relations\Concerns\AsPivot;
  15. use Illuminate\Database\Eloquent\Relations\HasManyThrough;
  16. use Illuminate\Database\Eloquent\Relations\Pivot;
  17. use Illuminate\Support\Arr;
  18. use Illuminate\Support\Collection as BaseCollection;
  19. use Illuminate\Support\Str;
  20. use Illuminate\Support\Traits\ForwardsCalls;
  21. use JsonSerializable;
  22. use LogicException;
  23. use Stringable;
  24. abstract class Model implements Arrayable, ArrayAccess, CanBeEscapedWhenCastToString, HasBroadcastChannel, Jsonable, JsonSerializable, QueueableEntity, Stringable, UrlRoutable
  25. {
  26. use Concerns\HasAttributes,
  27. Concerns\HasEvents,
  28. Concerns\HasGlobalScopes,
  29. Concerns\HasRelationships,
  30. Concerns\HasTimestamps,
  31. Concerns\HasUniqueIds,
  32. Concerns\HidesAttributes,
  33. Concerns\GuardsAttributes,
  34. ForwardsCalls;
  35. /**
  36. * The connection name for the model.
  37. *
  38. * @var string|null
  39. */
  40. protected $connection;
  41. /**
  42. * The table associated with the model.
  43. *
  44. * @var string
  45. */
  46. protected $table;
  47. /**
  48. * The primary key for the model.
  49. *
  50. * @var string
  51. */
  52. protected $primaryKey = 'id';
  53. /**
  54. * The "type" of the primary key ID.
  55. *
  56. * @var string
  57. */
  58. protected $keyType = 'int';
  59. /**
  60. * Indicates if the IDs are auto-incrementing.
  61. *
  62. * @var bool
  63. */
  64. public $incrementing = true;
  65. /**
  66. * The relations to eager load on every query.
  67. *
  68. * @var array
  69. */
  70. protected $with = [];
  71. /**
  72. * The relationship counts that should be eager loaded on every query.
  73. *
  74. * @var array
  75. */
  76. protected $withCount = [];
  77. /**
  78. * Indicates whether lazy loading will be prevented on this model.
  79. *
  80. * @var bool
  81. */
  82. public $preventsLazyLoading = false;
  83. /**
  84. * The number of models to return for pagination.
  85. *
  86. * @var int
  87. */
  88. protected $perPage = 15;
  89. /**
  90. * Indicates if the model exists.
  91. *
  92. * @var bool
  93. */
  94. public $exists = false;
  95. /**
  96. * Indicates if the model was inserted during the object's lifecycle.
  97. *
  98. * @var bool
  99. */
  100. public $wasRecentlyCreated = false;
  101. /**
  102. * Indicates that the object's string representation should be escaped when __toString is invoked.
  103. *
  104. * @var bool
  105. */
  106. protected $escapeWhenCastingToString = false;
  107. /**
  108. * The connection resolver instance.
  109. *
  110. * @var \Illuminate\Database\ConnectionResolverInterface
  111. */
  112. protected static $resolver;
  113. /**
  114. * The event dispatcher instance.
  115. *
  116. * @var \Illuminate\Contracts\Events\Dispatcher
  117. */
  118. protected static $dispatcher;
  119. /**
  120. * The array of booted models.
  121. *
  122. * @var array
  123. */
  124. protected static $booted = [];
  125. /**
  126. * The array of trait initializers that will be called on each new instance.
  127. *
  128. * @var array
  129. */
  130. protected static $traitInitializers = [];
  131. /**
  132. * The array of global scopes on the model.
  133. *
  134. * @var array
  135. */
  136. protected static $globalScopes = [];
  137. /**
  138. * The list of models classes that should not be affected with touch.
  139. *
  140. * @var array
  141. */
  142. protected static $ignoreOnTouch = [];
  143. /**
  144. * Indicates whether lazy loading should be restricted on all models.
  145. *
  146. * @var bool
  147. */
  148. protected static $modelsShouldPreventLazyLoading = false;
  149. /**
  150. * The callback that is responsible for handling lazy loading violations.
  151. *
  152. * @var callable|null
  153. */
  154. protected static $lazyLoadingViolationCallback;
  155. /**
  156. * Indicates if an exception should be thrown instead of silently discarding non-fillable attributes.
  157. *
  158. * @var bool
  159. */
  160. protected static $modelsShouldPreventSilentlyDiscardingAttributes = false;
  161. /**
  162. * The callback that is responsible for handling discarded attribute violations.
  163. *
  164. * @var callable|null
  165. */
  166. protected static $discardedAttributeViolationCallback;
  167. /**
  168. * Indicates if an exception should be thrown when trying to access a missing attribute on a retrieved model.
  169. *
  170. * @var bool
  171. */
  172. protected static $modelsShouldPreventAccessingMissingAttributes = false;
  173. /**
  174. * The callback that is responsible for handling missing attribute violations.
  175. *
  176. * @var callable|null
  177. */
  178. protected static $missingAttributeViolationCallback;
  179. /**
  180. * Indicates if broadcasting is currently enabled.
  181. *
  182. * @var bool
  183. */
  184. protected static $isBroadcasting = true;
  185. /**
  186. * The name of the "created at" column.
  187. *
  188. * @var string|null
  189. */
  190. const CREATED_AT = 'created_at';
  191. /**
  192. * The name of the "updated at" column.
  193. *
  194. * @var string|null
  195. */
  196. const UPDATED_AT = 'updated_at';
  197. /**
  198. * Create a new Eloquent model instance.
  199. *
  200. * @param array $attributes
  201. * @return void
  202. */
  203. public function __construct(array $attributes = [])
  204. {
  205. $this->bootIfNotBooted();
  206. $this->initializeTraits();
  207. $this->syncOriginal();
  208. $this->fill($attributes);
  209. }
  210. /**
  211. * Check if the model needs to be booted and if so, do it.
  212. *
  213. * @return void
  214. */
  215. protected function bootIfNotBooted()
  216. {
  217. if (! isset(static::$booted[static::class])) {
  218. static::$booted[static::class] = true;
  219. $this->fireModelEvent('booting', false);
  220. static::booting();
  221. static::boot();
  222. static::booted();
  223. $this->fireModelEvent('booted', false);
  224. }
  225. }
  226. /**
  227. * Perform any actions required before the model boots.
  228. *
  229. * @return void
  230. */
  231. protected static function booting()
  232. {
  233. //
  234. }
  235. /**
  236. * Bootstrap the model and its traits.
  237. *
  238. * @return void
  239. */
  240. protected static function boot()
  241. {
  242. static::bootTraits();
  243. }
  244. /**
  245. * Boot all of the bootable traits on the model.
  246. *
  247. * @return void
  248. */
  249. protected static function bootTraits()
  250. {
  251. $class = static::class;
  252. $booted = [];
  253. static::$traitInitializers[$class] = [];
  254. foreach (class_uses_recursive($class) as $trait) {
  255. $method = 'boot'.class_basename($trait);
  256. if (method_exists($class, $method) && ! in_array($method, $booted)) {
  257. forward_static_call([$class, $method]);
  258. $booted[] = $method;
  259. }
  260. if (method_exists($class, $method = 'initialize'.class_basename($trait))) {
  261. static::$traitInitializers[$class][] = $method;
  262. static::$traitInitializers[$class] = array_unique(
  263. static::$traitInitializers[$class]
  264. );
  265. }
  266. }
  267. }
  268. /**
  269. * Initialize any initializable traits on the model.
  270. *
  271. * @return void
  272. */
  273. protected function initializeTraits()
  274. {
  275. foreach (static::$traitInitializers[static::class] as $method) {
  276. $this->{$method}();
  277. }
  278. }
  279. /**
  280. * Perform any actions required after the model boots.
  281. *
  282. * @return void
  283. */
  284. protected static function booted()
  285. {
  286. //
  287. }
  288. /**
  289. * Clear the list of booted models so they will be re-booted.
  290. *
  291. * @return void
  292. */
  293. public static function clearBootedModels()
  294. {
  295. static::$booted = [];
  296. static::$globalScopes = [];
  297. }
  298. /**
  299. * Disables relationship model touching for the current class during given callback scope.
  300. *
  301. * @param callable $callback
  302. * @return void
  303. */
  304. public static function withoutTouching(callable $callback)
  305. {
  306. static::withoutTouchingOn([static::class], $callback);
  307. }
  308. /**
  309. * Disables relationship model touching for the given model classes during given callback scope.
  310. *
  311. * @param array $models
  312. * @param callable $callback
  313. * @return void
  314. */
  315. public static function withoutTouchingOn(array $models, callable $callback)
  316. {
  317. static::$ignoreOnTouch = array_values(array_merge(static::$ignoreOnTouch, $models));
  318. try {
  319. $callback();
  320. } finally {
  321. static::$ignoreOnTouch = array_values(array_diff(static::$ignoreOnTouch, $models));
  322. }
  323. }
  324. /**
  325. * Determine if the given model is ignoring touches.
  326. *
  327. * @param string|null $class
  328. * @return bool
  329. */
  330. public static function isIgnoringTouch($class = null)
  331. {
  332. $class = $class ?: static::class;
  333. if (! get_class_vars($class)['timestamps'] || ! $class::UPDATED_AT) {
  334. return true;
  335. }
  336. foreach (static::$ignoreOnTouch as $ignoredClass) {
  337. if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) {
  338. return true;
  339. }
  340. }
  341. return false;
  342. }
  343. /**
  344. * Indicate that models should prevent lazy loading, silently discarding attributes, and accessing missing attributes.
  345. *
  346. * @param bool $shouldBeStrict
  347. * @return void
  348. */
  349. public static function shouldBeStrict(bool $shouldBeStrict = true)
  350. {
  351. static::preventLazyLoading($shouldBeStrict);
  352. static::preventSilentlyDiscardingAttributes($shouldBeStrict);
  353. static::preventAccessingMissingAttributes($shouldBeStrict);
  354. }
  355. /**
  356. * Prevent model relationships from being lazy loaded.
  357. *
  358. * @param bool $value
  359. * @return void
  360. */
  361. public static function preventLazyLoading($value = true)
  362. {
  363. static::$modelsShouldPreventLazyLoading = $value;
  364. }
  365. /**
  366. * Register a callback that is responsible for handling lazy loading violations.
  367. *
  368. * @param callable|null $callback
  369. * @return void
  370. */
  371. public static function handleLazyLoadingViolationUsing(?callable $callback)
  372. {
  373. static::$lazyLoadingViolationCallback = $callback;
  374. }
  375. /**
  376. * Prevent non-fillable attributes from being silently discarded.
  377. *
  378. * @param bool $value
  379. * @return void
  380. */
  381. public static function preventSilentlyDiscardingAttributes($value = true)
  382. {
  383. static::$modelsShouldPreventSilentlyDiscardingAttributes = $value;
  384. }
  385. /**
  386. * Register a callback that is responsible for handling discarded attribute violations.
  387. *
  388. * @param callable|null $callback
  389. * @return void
  390. */
  391. public static function handleDiscardedAttributeViolationUsing(?callable $callback)
  392. {
  393. static::$discardedAttributeViolationCallback = $callback;
  394. }
  395. /**
  396. * Prevent accessing missing attributes on retrieved models.
  397. *
  398. * @param bool $value
  399. * @return void
  400. */
  401. public static function preventAccessingMissingAttributes($value = true)
  402. {
  403. static::$modelsShouldPreventAccessingMissingAttributes = $value;
  404. }
  405. /**
  406. * Register a callback that is responsible for handling missing attribute violations.
  407. *
  408. * @param callable|null $callback
  409. * @return void
  410. */
  411. public static function handleMissingAttributeViolationUsing(?callable $callback)
  412. {
  413. static::$missingAttributeViolationCallback = $callback;
  414. }
  415. /**
  416. * Execute a callback without broadcasting any model events for all model types.
  417. *
  418. * @param callable $callback
  419. * @return mixed
  420. */
  421. public static function withoutBroadcasting(callable $callback)
  422. {
  423. $isBroadcasting = static::$isBroadcasting;
  424. static::$isBroadcasting = false;
  425. try {
  426. return $callback();
  427. } finally {
  428. static::$isBroadcasting = $isBroadcasting;
  429. }
  430. }
  431. /**
  432. * Fill the model with an array of attributes.
  433. *
  434. * @param array $attributes
  435. * @return $this
  436. *
  437. * @throws \Illuminate\Database\Eloquent\MassAssignmentException
  438. */
  439. public function fill(array $attributes)
  440. {
  441. $totallyGuarded = $this->totallyGuarded();
  442. $fillable = $this->fillableFromArray($attributes);
  443. foreach ($fillable as $key => $value) {
  444. // The developers may choose to place some attributes in the "fillable" array
  445. // which means only those attributes may be set through mass assignment to
  446. // the model, and all others will just get ignored for security reasons.
  447. if ($this->isFillable($key)) {
  448. $this->setAttribute($key, $value);
  449. } elseif ($totallyGuarded || static::preventsSilentlyDiscardingAttributes()) {
  450. if (isset(static::$discardedAttributeViolationCallback)) {
  451. call_user_func(static::$discardedAttributeViolationCallback, $this, [$key]);
  452. } else {
  453. throw new MassAssignmentException(sprintf(
  454. 'Add [%s] to fillable property to allow mass assignment on [%s].',
  455. $key, get_class($this)
  456. ));
  457. }
  458. }
  459. }
  460. if (count($attributes) !== count($fillable) &&
  461. static::preventsSilentlyDiscardingAttributes()) {
  462. $keys = array_diff(array_keys($attributes), array_keys($fillable));
  463. if (isset(static::$discardedAttributeViolationCallback)) {
  464. call_user_func(static::$discardedAttributeViolationCallback, $this, $keys);
  465. } else {
  466. throw new MassAssignmentException(sprintf(
  467. 'Add fillable property [%s] to allow mass assignment on [%s].',
  468. implode(', ', $keys),
  469. get_class($this)
  470. ));
  471. }
  472. }
  473. return $this;
  474. }
  475. /**
  476. * Fill the model with an array of attributes. Force mass assignment.
  477. *
  478. * @param array $attributes
  479. * @return $this
  480. */
  481. public function forceFill(array $attributes)
  482. {
  483. return static::unguarded(fn () => $this->fill($attributes));
  484. }
  485. /**
  486. * Qualify the given column name by the model's table.
  487. *
  488. * @param string $column
  489. * @return string
  490. */
  491. public function qualifyColumn($column)
  492. {
  493. if (str_contains($column, '.')) {
  494. return $column;
  495. }
  496. return $this->getTable().'.'.$column;
  497. }
  498. /**
  499. * Qualify the given columns with the model's table.
  500. *
  501. * @param array $columns
  502. * @return array
  503. */
  504. public function qualifyColumns($columns)
  505. {
  506. return collect($columns)->map(function ($column) {
  507. return $this->qualifyColumn($column);
  508. })->all();
  509. }
  510. /**
  511. * Create a new instance of the given model.
  512. *
  513. * @param array $attributes
  514. * @param bool $exists
  515. * @return static
  516. */
  517. public function newInstance($attributes = [], $exists = false)
  518. {
  519. // This method just provides a convenient way for us to generate fresh model
  520. // instances of this current model. It is particularly useful during the
  521. // hydration of new objects via the Eloquent query builder instances.
  522. $model = new static;
  523. $model->exists = $exists;
  524. $model->setConnection(
  525. $this->getConnectionName()
  526. );
  527. $model->setTable($this->getTable());
  528. $model->mergeCasts($this->casts);
  529. $model->fill((array) $attributes);
  530. return $model;
  531. }
  532. /**
  533. * Create a new model instance that is existing.
  534. *
  535. * @param array $attributes
  536. * @param string|null $connection
  537. * @return static
  538. */
  539. public function newFromBuilder($attributes = [], $connection = null)
  540. {
  541. $model = $this->newInstance([], true);
  542. $model->setRawAttributes((array) $attributes, true);
  543. $model->setConnection($connection ?: $this->getConnectionName());
  544. $model->fireModelEvent('retrieved', false);
  545. return $model;
  546. }
  547. /**
  548. * Begin querying the model on a given connection.
  549. *
  550. * @param string|null $connection
  551. * @return \Illuminate\Database\Eloquent\Builder
  552. */
  553. public static function on($connection = null)
  554. {
  555. // First we will just create a fresh instance of this model, and then we can set the
  556. // connection on the model so that it is used for the queries we execute, as well
  557. // as being set on every relation we retrieve without a custom connection name.
  558. $instance = new static;
  559. $instance->setConnection($connection);
  560. return $instance->newQuery();
  561. }
  562. /**
  563. * Begin querying the model on the write connection.
  564. *
  565. * @return \Illuminate\Database\Eloquent\Builder
  566. */
  567. public static function onWriteConnection()
  568. {
  569. return static::query()->useWritePdo();
  570. }
  571. /**
  572. * Get all of the models from the database.
  573. *
  574. * @param array|string $columns
  575. * @return \Illuminate\Database\Eloquent\Collection<int, static>
  576. */
  577. public static function all($columns = ['*'])
  578. {
  579. return static::query()->get(
  580. is_array($columns) ? $columns : func_get_args()
  581. );
  582. }
  583. /**
  584. * Begin querying a model with eager loading.
  585. *
  586. * @param array|string $relations
  587. * @return \Illuminate\Database\Eloquent\Builder
  588. */
  589. public static function with($relations)
  590. {
  591. return static::query()->with(
  592. is_string($relations) ? func_get_args() : $relations
  593. );
  594. }
  595. /**
  596. * Eager load relations on the model.
  597. *
  598. * @param array|string $relations
  599. * @return $this
  600. */
  601. public function load($relations)
  602. {
  603. $query = $this->newQueryWithoutRelationships()->with(
  604. is_string($relations) ? func_get_args() : $relations
  605. );
  606. $query->eagerLoadRelations([$this]);
  607. return $this;
  608. }
  609. /**
  610. * Eager load relationships on the polymorphic relation of a model.
  611. *
  612. * @param string $relation
  613. * @param array $relations
  614. * @return $this
  615. */
  616. public function loadMorph($relation, $relations)
  617. {
  618. if (! $this->{$relation}) {
  619. return $this;
  620. }
  621. $className = get_class($this->{$relation});
  622. $this->{$relation}->load($relations[$className] ?? []);
  623. return $this;
  624. }
  625. /**
  626. * Eager load relations on the model if they are not already eager loaded.
  627. *
  628. * @param array|string $relations
  629. * @return $this
  630. */
  631. public function loadMissing($relations)
  632. {
  633. $relations = is_string($relations) ? func_get_args() : $relations;
  634. $this->newCollection([$this])->loadMissing($relations);
  635. return $this;
  636. }
  637. /**
  638. * Eager load relation's column aggregations on the model.
  639. *
  640. * @param array|string $relations
  641. * @param string $column
  642. * @param string|null $function
  643. * @return $this
  644. */
  645. public function loadAggregate($relations, $column, $function = null)
  646. {
  647. $this->newCollection([$this])->loadAggregate($relations, $column, $function);
  648. return $this;
  649. }
  650. /**
  651. * Eager load relation counts on the model.
  652. *
  653. * @param array|string $relations
  654. * @return $this
  655. */
  656. public function loadCount($relations)
  657. {
  658. $relations = is_string($relations) ? func_get_args() : $relations;
  659. return $this->loadAggregate($relations, '*', 'count');
  660. }
  661. /**
  662. * Eager load relation max column values on the model.
  663. *
  664. * @param array|string $relations
  665. * @param string $column
  666. * @return $this
  667. */
  668. public function loadMax($relations, $column)
  669. {
  670. return $this->loadAggregate($relations, $column, 'max');
  671. }
  672. /**
  673. * Eager load relation min column values on the model.
  674. *
  675. * @param array|string $relations
  676. * @param string $column
  677. * @return $this
  678. */
  679. public function loadMin($relations, $column)
  680. {
  681. return $this->loadAggregate($relations, $column, 'min');
  682. }
  683. /**
  684. * Eager load relation's column summations on the model.
  685. *
  686. * @param array|string $relations
  687. * @param string $column
  688. * @return $this
  689. */
  690. public function loadSum($relations, $column)
  691. {
  692. return $this->loadAggregate($relations, $column, 'sum');
  693. }
  694. /**
  695. * Eager load relation average column values on the model.
  696. *
  697. * @param array|string $relations
  698. * @param string $column
  699. * @return $this
  700. */
  701. public function loadAvg($relations, $column)
  702. {
  703. return $this->loadAggregate($relations, $column, 'avg');
  704. }
  705. /**
  706. * Eager load related model existence values on the model.
  707. *
  708. * @param array|string $relations
  709. * @return $this
  710. */
  711. public function loadExists($relations)
  712. {
  713. return $this->loadAggregate($relations, '*', 'exists');
  714. }
  715. /**
  716. * Eager load relationship column aggregation on the polymorphic relation of a model.
  717. *
  718. * @param string $relation
  719. * @param array $relations
  720. * @param string $column
  721. * @param string|null $function
  722. * @return $this
  723. */
  724. public function loadMorphAggregate($relation, $relations, $column, $function = null)
  725. {
  726. if (! $this->{$relation}) {
  727. return $this;
  728. }
  729. $className = get_class($this->{$relation});
  730. $this->{$relation}->loadAggregate($relations[$className] ?? [], $column, $function);
  731. return $this;
  732. }
  733. /**
  734. * Eager load relationship counts on the polymorphic relation of a model.
  735. *
  736. * @param string $relation
  737. * @param array $relations
  738. * @return $this
  739. */
  740. public function loadMorphCount($relation, $relations)
  741. {
  742. return $this->loadMorphAggregate($relation, $relations, '*', 'count');
  743. }
  744. /**
  745. * Eager load relationship max column values on the polymorphic relation of a model.
  746. *
  747. * @param string $relation
  748. * @param array $relations
  749. * @param string $column
  750. * @return $this
  751. */
  752. public function loadMorphMax($relation, $relations, $column)
  753. {
  754. return $this->loadMorphAggregate($relation, $relations, $column, 'max');
  755. }
  756. /**
  757. * Eager load relationship min column values on the polymorphic relation of a model.
  758. *
  759. * @param string $relation
  760. * @param array $relations
  761. * @param string $column
  762. * @return $this
  763. */
  764. public function loadMorphMin($relation, $relations, $column)
  765. {
  766. return $this->loadMorphAggregate($relation, $relations, $column, 'min');
  767. }
  768. /**
  769. * Eager load relationship column summations on the polymorphic relation of a model.
  770. *
  771. * @param string $relation
  772. * @param array $relations
  773. * @param string $column
  774. * @return $this
  775. */
  776. public function loadMorphSum($relation, $relations, $column)
  777. {
  778. return $this->loadMorphAggregate($relation, $relations, $column, 'sum');
  779. }
  780. /**
  781. * Eager load relationship average column values on the polymorphic relation of a model.
  782. *
  783. * @param string $relation
  784. * @param array $relations
  785. * @param string $column
  786. * @return $this
  787. */
  788. public function loadMorphAvg($relation, $relations, $column)
  789. {
  790. return $this->loadMorphAggregate($relation, $relations, $column, 'avg');
  791. }
  792. /**
  793. * Increment a column's value by a given amount.
  794. *
  795. * @param string $column
  796. * @param float|int $amount
  797. * @param array $extra
  798. * @return int
  799. */
  800. protected function increment($column, $amount = 1, array $extra = [])
  801. {
  802. return $this->incrementOrDecrement($column, $amount, $extra, 'increment');
  803. }
  804. /**
  805. * Decrement a column's value by a given amount.
  806. *
  807. * @param string $column
  808. * @param float|int $amount
  809. * @param array $extra
  810. * @return int
  811. */
  812. protected function decrement($column, $amount = 1, array $extra = [])
  813. {
  814. return $this->incrementOrDecrement($column, $amount, $extra, 'decrement');
  815. }
  816. /**
  817. * Run the increment or decrement method on the model.
  818. *
  819. * @param string $column
  820. * @param float|int $amount
  821. * @param array $extra
  822. * @param string $method
  823. * @return int
  824. */
  825. protected function incrementOrDecrement($column, $amount, $extra, $method)
  826. {
  827. if (! $this->exists) {
  828. return $this->newQueryWithoutRelationships()->{$method}($column, $amount, $extra);
  829. }
  830. $this->{$column} = $this->isClassDeviable($column)
  831. ? $this->deviateClassCastableAttribute($method, $column, $amount)
  832. : $this->{$column} + ($method === 'increment' ? $amount : $amount * -1);
  833. $this->forceFill($extra);
  834. if ($this->fireModelEvent('updating') === false) {
  835. return false;
  836. }
  837. if ($this->isClassDeviable($column)) {
  838. $amount = (clone $this)->setAttribute($column, $amount)->getAttributeFromArray($column);
  839. }
  840. return tap($this->setKeysForSaveQuery($this->newQueryWithoutScopes())->{$method}($column, $amount, $extra), function () use ($column) {
  841. $this->syncChanges();
  842. $this->fireModelEvent('updated', false);
  843. $this->syncOriginalAttribute($column);
  844. });
  845. }
  846. /**
  847. * Update the model in the database.
  848. *
  849. * @param array $attributes
  850. * @param array $options
  851. * @return bool
  852. */
  853. public function update(array $attributes = [], array $options = [])
  854. {
  855. if (! $this->exists) {
  856. return false;
  857. }
  858. return $this->fill($attributes)->save($options);
  859. }
  860. /**
  861. * Update the model in the database within a transaction.
  862. *
  863. * @param array $attributes
  864. * @param array $options
  865. * @return bool
  866. *
  867. * @throws \Throwable
  868. */
  869. public function updateOrFail(array $attributes = [], array $options = [])
  870. {
  871. if (! $this->exists) {
  872. return false;
  873. }
  874. return $this->fill($attributes)->saveOrFail($options);
  875. }
  876. /**
  877. * Update the model in the database without raising any events.
  878. *
  879. * @param array $attributes
  880. * @param array $options
  881. * @return bool
  882. */
  883. public function updateQuietly(array $attributes = [], array $options = [])
  884. {
  885. if (! $this->exists) {
  886. return false;
  887. }
  888. return $this->fill($attributes)->saveQuietly($options);
  889. }
  890. /**
  891. * Increment a column's value by a given amount without raising any events.
  892. *
  893. * @param string $column
  894. * @param float|int $amount
  895. * @param array $extra
  896. * @return int
  897. */
  898. protected function incrementQuietly($column, $amount = 1, array $extra = [])
  899. {
  900. return static::withoutEvents(function () use ($column, $amount, $extra) {
  901. return $this->incrementOrDecrement($column, $amount, $extra, 'increment');
  902. });
  903. }
  904. /**
  905. * Decrement a column's value by a given amount without raising any events.
  906. *
  907. * @param string $column
  908. * @param float|int $amount
  909. * @param array $extra
  910. * @return int
  911. */
  912. protected function decrementQuietly($column, $amount = 1, array $extra = [])
  913. {
  914. return static::withoutEvents(function () use ($column, $amount, $extra) {
  915. return $this->incrementOrDecrement($column, $amount, $extra, 'decrement');
  916. });
  917. }
  918. /**
  919. * Save the model and all of its relationships.
  920. *
  921. * @return bool
  922. */
  923. public function push()
  924. {
  925. if (! $this->save()) {
  926. return false;
  927. }
  928. // To sync all of the relationships to the database, we will simply spin through
  929. // the relationships and save each model via this "push" method, which allows
  930. // us to recurse into all of these nested relations for the model instance.
  931. foreach ($this->relations as $models) {
  932. $models = $models instanceof Collection
  933. ? $models->all() : [$models];
  934. foreach (array_filter($models) as $model) {
  935. if (! $model->push()) {
  936. return false;
  937. }
  938. }
  939. }
  940. return true;
  941. }
  942. /**
  943. * Save the model and all of its relationships without raising any events to the parent model.
  944. *
  945. * @return bool
  946. */
  947. public function pushQuietly()
  948. {
  949. return static::withoutEvents(fn () => $this->push());
  950. }
  951. /**
  952. * Save the model to the database without raising any events.
  953. *
  954. * @param array $options
  955. * @return bool
  956. */
  957. public function saveQuietly(array $options = [])
  958. {
  959. return static::withoutEvents(fn () => $this->save($options));
  960. }
  961. /**
  962. * Save the model to the database.
  963. *
  964. * @param array $options
  965. * @return bool
  966. */
  967. public function save(array $options = [])
  968. {
  969. $this->mergeAttributesFromCachedCasts();
  970. $query = $this->newModelQuery();
  971. // If the "saving" event returns false we'll bail out of the save and return
  972. // false, indicating that the save failed. This provides a chance for any
  973. // listeners to cancel save operations if validations fail or whatever.
  974. if ($this->fireModelEvent('saving') === false) {
  975. return false;
  976. }
  977. // If the model already exists in the database we can just update our record
  978. // that is already in this database using the current IDs in this "where"
  979. // clause to only update this model. Otherwise, we'll just insert them.
  980. if ($this->exists) {
  981. $saved = $this->isDirty() ?
  982. $this->performUpdate($query) : true;
  983. }
  984. // If the model is brand new, we'll insert it into our database and set the
  985. // ID attribute on the model to the value of the newly inserted row's ID
  986. // which is typically an auto-increment value managed by the database.
  987. else {
  988. $saved = $this->performInsert($query);
  989. if (! $this->getConnectionName() &&
  990. $connection = $query->getConnection()) {
  991. $this->setConnection($connection->getName());
  992. }
  993. }
  994. // If the model is successfully saved, we need to do a few more things once
  995. // that is done. We will call the "saved" method here to run any actions
  996. // we need to happen after a model gets successfully saved right here.
  997. if ($saved) {
  998. $this->finishSave($options);
  999. }
  1000. return $saved;
  1001. }
  1002. /**
  1003. * Save the model to the database within a transaction.
  1004. *
  1005. * @param array $options
  1006. * @return bool
  1007. *
  1008. * @throws \Throwable
  1009. */
  1010. public function saveOrFail(array $options = [])
  1011. {
  1012. return $this->getConnection()->transaction(fn () => $this->save($options));
  1013. }
  1014. /**
  1015. * Perform any actions that are necessary after the model is saved.
  1016. *
  1017. * @param array $options
  1018. * @return void
  1019. */
  1020. protected function finishSave(array $options)
  1021. {
  1022. $this->fireModelEvent('saved', false);
  1023. if ($this->isDirty() && ($options['touch'] ?? true)) {
  1024. $this->touchOwners();
  1025. }
  1026. $this->syncOriginal();
  1027. }
  1028. /**
  1029. * Perform a model update operation.
  1030. *
  1031. * @param \Illuminate\Database\Eloquent\Builder $query
  1032. * @return bool
  1033. */
  1034. protected function performUpdate(Builder $query)
  1035. {
  1036. // If the updating event returns false, we will cancel the update operation so
  1037. // developers can hook Validation systems into their models and cancel this
  1038. // operation if the model does not pass validation. Otherwise, we update.
  1039. if ($this->fireModelEvent('updating') === false) {
  1040. return false;
  1041. }
  1042. // First we need to create a fresh query instance and touch the creation and
  1043. // update timestamp on the model which are maintained by us for developer
  1044. // convenience. Then we will just continue saving the model instances.
  1045. if ($this->usesTimestamps()) {
  1046. $this->updateTimestamps();
  1047. }
  1048. // Once we have run the update operation, we will fire the "updated" event for
  1049. // this model instance. This will allow developers to hook into these after
  1050. // models are updated, giving them a chance to do any special processing.
  1051. $dirty = $this->getDirtyForUpdate();
  1052. if (count($dirty) > 0) {
  1053. $this->setKeysForSaveQuery($query)->update($dirty);
  1054. $this->syncChanges();
  1055. $this->fireModelEvent('updated', false);
  1056. }
  1057. return true;
  1058. }
  1059. /**
  1060. * Set the keys for a select query.
  1061. *
  1062. * @param \Illuminate\Database\Eloquent\Builder $query
  1063. * @return \Illuminate\Database\Eloquent\Builder
  1064. */
  1065. protected function setKeysForSelectQuery($query)
  1066. {
  1067. $query->where($this->getKeyName(), '=', $this->getKeyForSelectQuery());
  1068. return $query;
  1069. }
  1070. /**
  1071. * Get the primary key value for a select query.
  1072. *
  1073. * @return mixed
  1074. */
  1075. protected function getKeyForSelectQuery()
  1076. {
  1077. return $this->original[$this->getKeyName()] ?? $this->getKey();
  1078. }
  1079. /**
  1080. * Set the keys for a save update query.
  1081. *
  1082. * @param \Illuminate\Database\Eloquent\Builder $query
  1083. * @return \Illuminate\Database\Eloquent\Builder
  1084. */
  1085. protected function setKeysForSaveQuery($query)
  1086. {
  1087. $query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
  1088. return $query;
  1089. }
  1090. /**
  1091. * Get the primary key value for a save query.
  1092. *
  1093. * @return mixed
  1094. */
  1095. protected function getKeyForSaveQuery()
  1096. {
  1097. return $this->original[$this->getKeyName()] ?? $this->getKey();
  1098. }
  1099. /**
  1100. * Perform a model insert operation.
  1101. *
  1102. * @param \Illuminate\Database\Eloquent\Builder $query
  1103. * @return bool
  1104. */
  1105. protected function performInsert(Builder $query)
  1106. {
  1107. if ($this->usesUniqueIds()) {
  1108. $this->setUniqueIds();
  1109. }
  1110. if ($this->fireModelEvent('creating') === false) {
  1111. return false;
  1112. }
  1113. // First we'll need to create a fresh query instance and touch the creation and
  1114. // update timestamps on this model, which are maintained by us for developer
  1115. // convenience. After, we will just continue saving these model instances.
  1116. if ($this->usesTimestamps()) {
  1117. $this->updateTimestamps();
  1118. }
  1119. // If the model has an incrementing key, we can use the "insertGetId" method on
  1120. // the query builder, which will give us back the final inserted ID for this
  1121. // table from the database. Not all tables have to be incrementing though.
  1122. $attributes = $this->getAttributesForInsert();
  1123. if ($this->getIncrementing()) {
  1124. $this->insertAndSetId($query, $attributes);
  1125. }
  1126. // If the table isn't incrementing we'll simply insert these attributes as they
  1127. // are. These attribute arrays must contain an "id" column previously placed
  1128. // there by the developer as the manually determined key for these models.
  1129. else {
  1130. if (empty($attributes)) {
  1131. return true;
  1132. }
  1133. $query->insert($attributes);
  1134. }
  1135. // We will go ahead and set the exists property to true, so that it is set when
  1136. // the created event is fired, just in case the developer tries to update it
  1137. // during the event. This will allow them to do so and run an update here.
  1138. $this->exists = true;
  1139. $this->wasRecentlyCreated = true;
  1140. $this->fireModelEvent('created', false);
  1141. return true;
  1142. }
  1143. /**
  1144. * Insert the given attributes and set the ID on the model.
  1145. *
  1146. * @param \Illuminate\Database\Eloquent\Builder $query
  1147. * @param array $attributes
  1148. * @return void
  1149. */
  1150. protected function insertAndSetId(Builder $query, $attributes)
  1151. {
  1152. $id = $query->insertGetId($attributes, $keyName = $this->getKeyName());
  1153. $this->setAttribute($keyName, $id);
  1154. }
  1155. /**
  1156. * Destroy the models for the given IDs.
  1157. *
  1158. * @param \Illuminate\Support\Collection|array|int|string $ids
  1159. * @return int
  1160. */
  1161. public static function destroy($ids)
  1162. {
  1163. if ($ids instanceof EloquentCollection) {
  1164. $ids = $ids->modelKeys();
  1165. }
  1166. if ($ids instanceof BaseCollection) {
  1167. $ids = $ids->all();
  1168. }
  1169. $ids = is_array($ids) ? $ids : func_get_args();
  1170. if (count($ids) === 0) {
  1171. return 0;
  1172. }
  1173. // We will actually pull the models from the database table and call delete on
  1174. // each of them individually so that their events get fired properly with a
  1175. // correct set of attributes in case the developers wants to check these.
  1176. $key = ($instance = new static)->getKeyName();
  1177. $count = 0;
  1178. foreach ($instance->whereIn($key, $ids)->get() as $model) {
  1179. if ($model->delete()) {
  1180. $count++;
  1181. }
  1182. }
  1183. return $count;
  1184. }
  1185. /**
  1186. * Delete the model from the database.
  1187. *
  1188. * @return bool|null
  1189. *
  1190. * @throws \LogicException
  1191. */
  1192. public function delete()
  1193. {
  1194. $this->mergeAttributesFromCachedCasts();
  1195. if (is_null($this->getKeyName())) {
  1196. throw new LogicException('No primary key defined on model.');
  1197. }
  1198. // If the model doesn't exist, there is nothing to delete so we'll just return
  1199. // immediately and not do anything else. Otherwise, we will continue with a
  1200. // deletion process on the model, firing the proper events, and so forth.
  1201. if (! $this->exists) {
  1202. return;
  1203. }
  1204. if ($this->fireModelEvent('deleting') === false) {
  1205. return false;
  1206. }
  1207. // Here, we'll touch the owning models, verifying these timestamps get updated
  1208. // for the models. This will allow any caching to get broken on the parents
  1209. // by the timestamp. Then we will go ahead and delete the model instance.
  1210. $this->touchOwners();
  1211. $this->performDeleteOnModel();
  1212. // Once the model has been deleted, we will fire off the deleted event so that
  1213. // the developers may hook into post-delete operations. We will then return
  1214. // a boolean true as the delete is presumably successful on the database.
  1215. $this->fireModelEvent('deleted', false);
  1216. return true;
  1217. }
  1218. /**
  1219. * Delete the model from the database without raising any events.
  1220. *
  1221. * @return bool
  1222. */
  1223. public function deleteQuietly()
  1224. {
  1225. return static::withoutEvents(fn () => $this->delete());
  1226. }
  1227. /**
  1228. * Delete the model from the database within a transaction.
  1229. *
  1230. * @return bool|null
  1231. *
  1232. * @throws \Throwable
  1233. */
  1234. public function deleteOrFail()
  1235. {
  1236. if (! $this->exists) {
  1237. return false;
  1238. }
  1239. return $this->getConnection()->transaction(fn () => $this->delete());
  1240. }
  1241. /**
  1242. * Force a hard delete on a soft deleted model.
  1243. *
  1244. * This method protects developers from running forceDelete when the trait is missing.
  1245. *
  1246. * @return bool|null
  1247. */
  1248. public function forceDelete()
  1249. {
  1250. return $this->delete();
  1251. }
  1252. /**
  1253. * Perform the actual delete query on this model instance.
  1254. *
  1255. * @return void
  1256. */
  1257. protected function performDeleteOnModel()
  1258. {
  1259. $this->setKeysForSaveQuery($this->newModelQuery())->delete();
  1260. $this->exists = false;
  1261. }
  1262. /**
  1263. * Begin querying the model.
  1264. *
  1265. * @return \Illuminate\Database\Eloquent\Builder
  1266. */
  1267. public static function query()
  1268. {
  1269. return (new static)->newQuery();
  1270. }
  1271. /**
  1272. * Get a new query builder for the model's table.
  1273. *
  1274. * @return \Illuminate\Database\Eloquent\Builder
  1275. */
  1276. public function newQuery()
  1277. {
  1278. return $this->registerGlobalScopes($this->newQueryWithoutScopes());
  1279. }
  1280. /**
  1281. * Get a new query builder that doesn't have any global scopes or eager loading.
  1282. *
  1283. * @return \Illuminate\Database\Eloquent\Builder|static
  1284. */
  1285. public function newModelQuery()
  1286. {
  1287. return $this->newEloquentBuilder(
  1288. $this->newBaseQueryBuilder()
  1289. )->setModel($this);
  1290. }
  1291. /**
  1292. * Get a new query builder with no relationships loaded.
  1293. *
  1294. * @return \Illuminate\Database\Eloquent\Builder
  1295. */
  1296. public function newQueryWithoutRelationships()
  1297. {
  1298. return $this->registerGlobalScopes($this->newModelQuery());
  1299. }
  1300. /**
  1301. * Register the global scopes for this builder instance.
  1302. *
  1303. * @param \Illuminate\Database\Eloquent\Builder $builder
  1304. * @return \Illuminate\Database\Eloquent\Builder
  1305. */
  1306. public function registerGlobalScopes($builder)
  1307. {
  1308. foreach ($this->getGlobalScopes() as $identifier => $scope) {
  1309. $builder->withGlobalScope($identifier, $scope);
  1310. }
  1311. return $builder;
  1312. }
  1313. /**
  1314. * Get a new query builder that doesn't have any global scopes.
  1315. *
  1316. * @return \Illuminate\Database\Eloquent\Builder|static
  1317. */
  1318. public function newQueryWithoutScopes()
  1319. {
  1320. return $this->newModelQuery()
  1321. ->with($this->with)
  1322. ->withCount($this->withCount);
  1323. }
  1324. /**
  1325. * Get a new query instance without a given scope.
  1326. *
  1327. * @param \Illuminate\Database\Eloquent\Scope|string $scope
  1328. * @return \Illuminate\Database\Eloquent\Builder
  1329. */
  1330. public function newQueryWithoutScope($scope)
  1331. {
  1332. return $this->newQuery()->withoutGlobalScope($scope);
  1333. }
  1334. /**
  1335. * Get a new query to restore one or more models by their queueable IDs.
  1336. *
  1337. * @param array|int $ids
  1338. * @return \Illuminate\Database\Eloquent\Builder
  1339. */
  1340. public function newQueryForRestoration($ids)
  1341. {
  1342. return $this->newQueryWithoutScopes()->whereKey($ids);
  1343. }
  1344. /**
  1345. * Create a new Eloquent query builder for the model.
  1346. *
  1347. * @param \Illuminate\Database\Query\Builder $query
  1348. * @return \Illuminate\Database\Eloquent\Builder|static
  1349. */
  1350. public function newEloquentBuilder($query)
  1351. {
  1352. return new Builder($query);
  1353. }
  1354. /**
  1355. * Get a new query builder instance for the connection.
  1356. *
  1357. * @return \Illuminate\Database\Query\Builder
  1358. */
  1359. protected function newBaseQueryBuilder()
  1360. {
  1361. return $this->getConnection()->query();
  1362. }
  1363. /**
  1364. * Create a new Eloquent Collection instance.
  1365. *
  1366. * @param array $models
  1367. * @return \Illuminate\Database\Eloquent\Collection
  1368. */
  1369. public function newCollection(array $models = [])
  1370. {
  1371. return new Collection($models);
  1372. }
  1373. /**
  1374. * Create a new pivot model instance.
  1375. *
  1376. * @param \Illuminate\Database\Eloquent\Model $parent
  1377. * @param array $attributes
  1378. * @param string $table
  1379. * @param bool $exists
  1380. * @param string|null $using
  1381. * @return \Illuminate\Database\Eloquent\Relations\Pivot
  1382. */
  1383. public function newPivot(self $parent, array $attributes, $table, $exists, $using = null)
  1384. {
  1385. return $using ? $using::fromRawAttributes($parent, $attributes, $table, $exists)
  1386. : Pivot::fromAttributes($parent, $attributes, $table, $exists);
  1387. }
  1388. /**
  1389. * Determine if the model has a given scope.
  1390. *
  1391. * @param string $scope
  1392. * @return bool
  1393. */
  1394. public function hasNamedScope($scope)
  1395. {
  1396. return method_exists($this, 'scope'.ucfirst($scope));
  1397. }
  1398. /**
  1399. * Apply the given named scope if possible.
  1400. *
  1401. * @param string $scope
  1402. * @param array $parameters
  1403. * @return mixed
  1404. */
  1405. public function callNamedScope($scope, array $parameters = [])
  1406. {
  1407. return $this->{'scope'.ucfirst($scope)}(...$parameters);
  1408. }
  1409. /**
  1410. * Convert the model instance to an array.
  1411. *
  1412. * @return array
  1413. */
  1414. public function toArray()
  1415. {
  1416. return array_merge($this->attributesToArray(), $this->relationsToArray());
  1417. }
  1418. /**
  1419. * Convert the model instance to JSON.
  1420. *
  1421. * @param int $options
  1422. * @return string
  1423. *
  1424. * @throws \Illuminate\Database\Eloquent\JsonEncodingException
  1425. */
  1426. public function toJson($options = 0)
  1427. {
  1428. $json = json_encode($this->jsonSerialize(), $options);
  1429. if (json_last_error() !== JSON_ERROR_NONE) {
  1430. throw JsonEncodingException::forModel($this, json_last_error_msg());
  1431. }
  1432. return $json;
  1433. }
  1434. /**
  1435. * Convert the object into something JSON serializable.
  1436. *
  1437. * @return mixed
  1438. */
  1439. public function jsonSerialize(): mixed
  1440. {
  1441. return $this->toArray();
  1442. }
  1443. /**
  1444. * Reload a fresh model instance from the database.
  1445. *
  1446. * @param array|string $with
  1447. * @return static|null
  1448. */
  1449. public function fresh($with = [])
  1450. {
  1451. if (! $this->exists) {
  1452. return;
  1453. }
  1454. return $this->setKeysForSelectQuery($this->newQueryWithoutScopes())
  1455. ->useWritePdo()
  1456. ->with(is_string($with) ? func_get_args() : $with)
  1457. ->first();
  1458. }
  1459. /**
  1460. * Reload the current model instance with fresh attributes from the database.
  1461. *
  1462. * @return $this
  1463. */
  1464. public function refresh()
  1465. {
  1466. if (! $this->exists) {
  1467. return $this;
  1468. }
  1469. $this->setRawAttributes(
  1470. $this->setKeysForSelectQuery($this->newQueryWithoutScopes())
  1471. ->useWritePdo()
  1472. ->firstOrFail()
  1473. ->attributes
  1474. );
  1475. $this->load(collect($this->relations)->reject(function ($relation) {
  1476. return $relation instanceof Pivot
  1477. || (is_object($relation) && in_array(AsPivot::class, class_uses_recursive($relation), true));
  1478. })->keys()->all());
  1479. $this->syncOriginal();
  1480. return $this;
  1481. }
  1482. /**
  1483. * Clone the model into a new, non-existing instance.
  1484. *
  1485. * @param array|null $except
  1486. * @return static
  1487. */
  1488. public function replicate(?array $except = null)
  1489. {
  1490. $defaults = array_values(array_filter([
  1491. $this->getKeyName(),
  1492. $this->getCreatedAtColumn(),
  1493. $this->getUpdatedAtColumn(),
  1494. ...$this->uniqueIds(),
  1495. 'laravel_through_key',
  1496. ]));
  1497. $attributes = Arr::except(
  1498. $this->getAttributes(), $except ? array_unique(array_merge($except, $defaults)) : $defaults
  1499. );
  1500. return tap(new static, function ($instance) use ($attributes) {
  1501. $instance->setRawAttributes($attributes);
  1502. $instance->setRelations($this->relations);
  1503. $instance->fireModelEvent('replicating', false);
  1504. });
  1505. }
  1506. /**
  1507. * Clone the model into a new, non-existing instance without raising any events.
  1508. *
  1509. * @param array|null $except
  1510. * @return static
  1511. */
  1512. public function replicateQuietly(?array $except = null)
  1513. {
  1514. return static::withoutEvents(fn () => $this->replicate($except));
  1515. }
  1516. /**
  1517. * Determine if two models have the same ID and belong to the same table.
  1518. *
  1519. * @param \Illuminate\Database\Eloquent\Model|null $model
  1520. * @return bool
  1521. */
  1522. public function is($model)
  1523. {
  1524. return ! is_null($model) &&
  1525. $this->getKey() === $model->getKey() &&
  1526. $this->getTable() === $model->getTable() &&
  1527. $this->getConnectionName() === $model->getConnectionName();
  1528. }
  1529. /**
  1530. * Determine if two models are not the same.
  1531. *
  1532. * @param \Illuminate\Database\Eloquent\Model|null $model
  1533. * @return bool
  1534. */
  1535. public function isNot($model)
  1536. {
  1537. return ! $this->is($model);
  1538. }
  1539. /**
  1540. * Get the database connection for the model.
  1541. *
  1542. * @return \Illuminate\Database\Connection
  1543. */
  1544. public function getConnection()
  1545. {
  1546. return static::resolveConnection($this->getConnectionName());
  1547. }
  1548. /**
  1549. * Get the current connection name for the model.
  1550. *
  1551. * @return string|null
  1552. */
  1553. public function getConnectionName()
  1554. {
  1555. return $this->connection;
  1556. }
  1557. /**
  1558. * Set the connection associated with the model.
  1559. *
  1560. * @param string|null $name
  1561. * @return $this
  1562. */
  1563. public function setConnection($name)
  1564. {
  1565. $this->connection = $name;
  1566. return $this;
  1567. }
  1568. /**
  1569. * Resolve a connection instance.
  1570. *
  1571. * @param string|null $connection
  1572. * @return \Illuminate\Database\Connection
  1573. */
  1574. public static function resolveConnection($connection = null)
  1575. {
  1576. return static::$resolver->connection($connection);
  1577. }
  1578. /**
  1579. * Get the connection resolver instance.
  1580. *
  1581. * @return \Illuminate\Database\ConnectionResolverInterface|null
  1582. */
  1583. public static function getConnectionResolver()
  1584. {
  1585. return static::$resolver;
  1586. }
  1587. /**
  1588. * Set the connection resolver instance.
  1589. *
  1590. * @param \Illuminate\Database\ConnectionResolverInterface $resolver
  1591. * @return void
  1592. */
  1593. public static function setConnectionResolver(Resolver $resolver)
  1594. {
  1595. static::$resolver = $resolver;
  1596. }
  1597. /**
  1598. * Unset the connection resolver for models.
  1599. *
  1600. * @return void
  1601. */
  1602. public static function unsetConnectionResolver()
  1603. {
  1604. static::$resolver = null;
  1605. }
  1606. /**
  1607. * Get the table associated with the model.
  1608. *
  1609. * @return string
  1610. */
  1611. public function getTable()
  1612. {
  1613. return $this->table ?? Str::snake(Str::pluralStudly(class_basename($this)));
  1614. }
  1615. /**
  1616. * Set the table associated with the model.
  1617. *
  1618. * @param string $table
  1619. * @return $this
  1620. */
  1621. public function setTable($table)
  1622. {
  1623. $this->table = $table;
  1624. return $this;
  1625. }
  1626. /**
  1627. * Get the primary key for the model.
  1628. *
  1629. * @return string
  1630. */
  1631. public function getKeyName()
  1632. {
  1633. return $this->primaryKey;
  1634. }
  1635. /**
  1636. * Set the primary key for the model.
  1637. *
  1638. * @param string $key
  1639. * @return $this
  1640. */
  1641. public function setKeyName($key)
  1642. {
  1643. $this->primaryKey = $key;
  1644. return $this;
  1645. }
  1646. /**
  1647. * Get the table qualified key name.
  1648. *
  1649. * @return string
  1650. */
  1651. public function getQualifiedKeyName()
  1652. {
  1653. return $this->qualifyColumn($this->getKeyName());
  1654. }
  1655. /**
  1656. * Get the auto-incrementing key type.
  1657. *
  1658. * @return string
  1659. */
  1660. public function getKeyType()
  1661. {
  1662. return $this->keyType;
  1663. }
  1664. /**
  1665. * Set the data type for the primary key.
  1666. *
  1667. * @param string $type
  1668. * @return $this
  1669. */
  1670. public function setKeyType($type)
  1671. {
  1672. $this->keyType = $type;
  1673. return $this;
  1674. }
  1675. /**
  1676. * Get the value indicating whether the IDs are incrementing.
  1677. *
  1678. * @return bool
  1679. */
  1680. public function getIncrementing()
  1681. {
  1682. return $this->incrementing;
  1683. }
  1684. /**
  1685. * Set whether IDs are incrementing.
  1686. *
  1687. * @param bool $value
  1688. * @return $this
  1689. */
  1690. public function setIncrementing($value)
  1691. {
  1692. $this->incrementing = $value;
  1693. return $this;
  1694. }
  1695. /**
  1696. * Get the value of the model's primary key.
  1697. *
  1698. * @return mixed
  1699. */
  1700. public function getKey()
  1701. {
  1702. return $this->getAttribute($this->getKeyName());
  1703. }
  1704. /**
  1705. * Get the queueable identity for the entity.
  1706. *
  1707. * @return mixed
  1708. */
  1709. public function getQueueableId()
  1710. {
  1711. return $this->getKey();
  1712. }
  1713. /**
  1714. * Get the queueable relationships for the entity.
  1715. *
  1716. * @return array
  1717. */
  1718. public function getQueueableRelations()
  1719. {
  1720. $relations = [];
  1721. foreach ($this->getRelations() as $key => $relation) {
  1722. if (! method_exists($this, $key)) {
  1723. continue;
  1724. }
  1725. $relations[] = $key;
  1726. if ($relation instanceof QueueableCollection) {
  1727. foreach ($relation->getQueueableRelations() as $collectionValue) {
  1728. $relations[] = $key.'.'.$collectionValue;
  1729. }
  1730. }
  1731. if ($relation instanceof QueueableEntity) {
  1732. foreach ($relation->getQueueableRelations() as $entityValue) {
  1733. $relations[] = $key.'.'.$entityValue;
  1734. }
  1735. }
  1736. }
  1737. return array_unique($relations);
  1738. }
  1739. /**
  1740. * Get the queueable connection for the entity.
  1741. *
  1742. * @return string|null
  1743. */
  1744. public function getQueueableConnection()
  1745. {
  1746. return $this->getConnectionName();
  1747. }
  1748. /**
  1749. * Get the value of the model's route key.
  1750. *
  1751. * @return mixed
  1752. */
  1753. public function getRouteKey()
  1754. {
  1755. return $this->getAttribute($this->getRouteKeyName());
  1756. }
  1757. /**
  1758. * Get the route key for the model.
  1759. *
  1760. * @return string
  1761. */
  1762. public function getRouteKeyName()
  1763. {
  1764. return $this->getKeyName();
  1765. }
  1766. /**
  1767. * Retrieve the model for a bound value.
  1768. *
  1769. * @param mixed $value
  1770. * @param string|null $field
  1771. * @return \Illuminate\Database\Eloquent\Model|null
  1772. */
  1773. public function resolveRouteBinding($value, $field = null)
  1774. {
  1775. return $this->resolveRouteBindingQuery($this, $value, $field)->first();
  1776. }
  1777. /**
  1778. * Retrieve the model for a bound value.
  1779. *
  1780. * @param mixed $value
  1781. * @param string|null $field
  1782. * @return \Illuminate\Database\Eloquent\Model|null
  1783. */
  1784. public function resolveSoftDeletableRouteBinding($value, $field = null)
  1785. {
  1786. return $this->resolveRouteBindingQuery($this, $value, $field)->withTrashed()->first();
  1787. }
  1788. /**
  1789. * Retrieve the child model for a bound value.
  1790. *
  1791. * @param string $childType
  1792. * @param mixed $value
  1793. * @param string|null $field
  1794. * @return \Illuminate\Database\Eloquent\Model|null
  1795. */
  1796. public function resolveChildRouteBinding($childType, $value, $field)
  1797. {
  1798. return $this->resolveChildRouteBindingQuery($childType, $value, $field)->first();
  1799. }
  1800. /**
  1801. * Retrieve the child model for a bound value.
  1802. *
  1803. * @param string $childType
  1804. * @param mixed $value
  1805. * @param string|null $field
  1806. * @return \Illuminate\Database\Eloquent\Model|null
  1807. */
  1808. public function resolveSoftDeletableChildRouteBinding($childType, $value, $field)
  1809. {
  1810. return $this->resolveChildRouteBindingQuery($childType, $value, $field)->withTrashed()->first();
  1811. }
  1812. /**
  1813. * Retrieve the child model query for a bound value.
  1814. *
  1815. * @param string $childType
  1816. * @param mixed $value
  1817. * @param string|null $field
  1818. * @return \Illuminate\Database\Eloquent\Relations\Relation
  1819. */
  1820. protected function resolveChildRouteBindingQuery($childType, $value, $field)
  1821. {
  1822. $relationship = $this->{$this->childRouteBindingRelationshipName($childType)}();
  1823. $field = $field ?: $relationship->getRelated()->getRouteKeyName();
  1824. if ($relationship instanceof HasManyThrough ||
  1825. $relationship instanceof BelongsToMany) {
  1826. $field = $relationship->getRelated()->getTable().'.'.$field;
  1827. }
  1828. return $relationship instanceof Model
  1829. ? $relationship->resolveRouteBindingQuery($relationship, $value, $field)
  1830. : $relationship->getRelated()->resolveRouteBindingQuery($relationship, $value, $field);
  1831. }
  1832. /**
  1833. * Retrieve the child route model binding relationship name for the given child type.
  1834. *
  1835. * @param string $childType
  1836. * @return string
  1837. */
  1838. protected function childRouteBindingRelationshipName($childType)
  1839. {
  1840. return Str::plural(Str::camel($childType));
  1841. }
  1842. /**
  1843. * Retrieve the model for a bound value.
  1844. *
  1845. * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation $query
  1846. * @param mixed $value
  1847. * @param string|null $field
  1848. * @return \Illuminate\Contracts\Database\Eloquent\Builder
  1849. */
  1850. public function resolveRouteBindingQuery($query, $value, $field = null)
  1851. {
  1852. return $query->where($field ?? $this->getRouteKeyName(), $value);
  1853. }
  1854. /**
  1855. * Get the default foreign key name for the model.
  1856. *
  1857. * @return string
  1858. */
  1859. public function getForeignKey()
  1860. {
  1861. return Str::snake(class_basename($this)).'_'.$this->getKeyName();
  1862. }
  1863. /**
  1864. * Get the number of models to return per page.
  1865. *
  1866. * @return int
  1867. */
  1868. public function getPerPage()
  1869. {
  1870. return $this->perPage;
  1871. }
  1872. /**
  1873. * Set the number of models to return per page.
  1874. *
  1875. * @param int $perPage
  1876. * @return $this
  1877. */
  1878. public function setPerPage($perPage)
  1879. {
  1880. $this->perPage = $perPage;
  1881. return $this;
  1882. }
  1883. /**
  1884. * Determine if lazy loading is disabled.
  1885. *
  1886. * @return bool
  1887. */
  1888. public static function preventsLazyLoading()
  1889. {
  1890. return static::$modelsShouldPreventLazyLoading;
  1891. }
  1892. /**
  1893. * Determine if discarding guarded attribute fills is disabled.
  1894. *
  1895. * @return bool
  1896. */
  1897. public static function preventsSilentlyDiscardingAttributes()
  1898. {
  1899. return static::$modelsShouldPreventSilentlyDiscardingAttributes;
  1900. }
  1901. /**
  1902. * Determine if accessing missing attributes is disabled.
  1903. *
  1904. * @return bool
  1905. */
  1906. public static function preventsAccessingMissingAttributes()
  1907. {
  1908. return static::$modelsShouldPreventAccessingMissingAttributes;
  1909. }
  1910. /**
  1911. * Get the broadcast channel route definition that is associated with the given entity.
  1912. *
  1913. * @return string
  1914. */
  1915. public function broadcastChannelRoute()
  1916. {
  1917. return str_replace('\\', '.', get_class($this)).'.{'.Str::camel(class_basename($this)).'}';
  1918. }
  1919. /**
  1920. * Get the broadcast channel name that is associated with the given entity.
  1921. *
  1922. * @return string
  1923. */
  1924. public function broadcastChannel()
  1925. {
  1926. return str_replace('\\', '.', get_class($this)).'.'.$this->getKey();
  1927. }
  1928. /**
  1929. * Dynamically retrieve attributes on the model.
  1930. *
  1931. * @param string $key
  1932. * @return mixed
  1933. */
  1934. public function __get($key)
  1935. {
  1936. return $this->getAttribute($key);
  1937. }
  1938. /**
  1939. * Dynamically set attributes on the model.
  1940. *
  1941. * @param string $key
  1942. * @param mixed $value
  1943. * @return void
  1944. */
  1945. public function __set($key, $value)
  1946. {
  1947. $this->setAttribute($key, $value);
  1948. }
  1949. /**
  1950. * Determine if the given attribute exists.
  1951. *
  1952. * @param mixed $offset
  1953. * @return bool
  1954. */
  1955. public function offsetExists($offset): bool
  1956. {
  1957. try {
  1958. return ! is_null($this->getAttribute($offset));
  1959. } catch (MissingAttributeException) {
  1960. return false;
  1961. }
  1962. }
  1963. /**
  1964. * Get the value for a given offset.
  1965. *
  1966. * @param mixed $offset
  1967. * @return mixed
  1968. */
  1969. public function offsetGet($offset): mixed
  1970. {
  1971. return $this->getAttribute($offset);
  1972. }
  1973. /**
  1974. * Set the value for a given offset.
  1975. *
  1976. * @param mixed $offset
  1977. * @param mixed $value
  1978. * @return void
  1979. */
  1980. public function offsetSet($offset, $value): void
  1981. {
  1982. $this->setAttribute($offset, $value);
  1983. }
  1984. /**
  1985. * Unset the value for a given offset.
  1986. *
  1987. * @param mixed $offset
  1988. * @return void
  1989. */
  1990. public function offsetUnset($offset): void
  1991. {
  1992. unset($this->attributes[$offset], $this->relations[$offset]);
  1993. }
  1994. /**
  1995. * Determine if an attribute or relation exists on the model.
  1996. *
  1997. * @param string $key
  1998. * @return bool
  1999. */
  2000. public function __isset($key)
  2001. {
  2002. return $this->offsetExists($key);
  2003. }
  2004. /**
  2005. * Unset an attribute on the model.
  2006. *
  2007. * @param string $key
  2008. * @return void
  2009. */
  2010. public function __unset($key)
  2011. {
  2012. $this->offsetUnset($key);
  2013. }
  2014. /**
  2015. * Handle dynamic method calls into the model.
  2016. *
  2017. * @param string $method
  2018. * @param array $parameters
  2019. * @return mixed
  2020. */
  2021. public function __call($method, $parameters)
  2022. {
  2023. if (in_array($method, ['increment', 'decrement', 'incrementQuietly', 'decrementQuietly'])) {
  2024. return $this->$method(...$parameters);
  2025. }
  2026. if ($resolver = $this->relationResolver(static::class, $method)) {
  2027. return $resolver($this);
  2028. }
  2029. if (Str::startsWith($method, 'through') &&
  2030. method_exists($this, $relationMethod = Str::of($method)->after('through')->lcfirst()->toString())) {
  2031. return $this->through($relationMethod);
  2032. }
  2033. return $this->forwardCallTo($this->newQuery(), $method, $parameters);
  2034. }
  2035. /**
  2036. * Handle dynamic static method calls into the model.
  2037. *
  2038. * @param string $method
  2039. * @param array $parameters
  2040. * @return mixed
  2041. */
  2042. public static function __callStatic($method, $parameters)
  2043. {
  2044. return (new static)->$method(...$parameters);
  2045. }
  2046. /**
  2047. * Convert the model to its string representation.
  2048. *
  2049. * @return string
  2050. */
  2051. public function __toString()
  2052. {
  2053. return $this->escapeWhenCastingToString
  2054. ? e($this->toJson())
  2055. : $this->toJson();
  2056. }
  2057. /**
  2058. * Indicate that the object's string representation should be escaped when __toString is invoked.
  2059. *
  2060. * @param bool $escape
  2061. * @return $this
  2062. */
  2063. public function escapeWhenCastingToString($escape = true)
  2064. {
  2065. $this->escapeWhenCastingToString = $escape;
  2066. return $this;
  2067. }
  2068. /**
  2069. * Prepare the object for serialization.
  2070. *
  2071. * @return array
  2072. */
  2073. public function __sleep()
  2074. {
  2075. $this->mergeAttributesFromCachedCasts();
  2076. $this->classCastCache = [];
  2077. $this->attributeCastCache = [];
  2078. return array_keys(get_object_vars($this));
  2079. }
  2080. /**
  2081. * When a model is being unserialized, check if it needs to be booted.
  2082. *
  2083. * @return void
  2084. */
  2085. public function __wakeup()
  2086. {
  2087. $this->bootIfNotBooted();
  2088. $this->initializeTraits();
  2089. }
  2090. }