Pivot.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?php
  2. namespace Illuminate\Database\Eloquent\Relations;
  3. use Illuminate\Support\Str;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Database\Eloquent\Builder;
  6. class Pivot extends Model
  7. {
  8. /**
  9. * The parent model of the relationship.
  10. *
  11. * @var \Illuminate\Database\Eloquent\Model
  12. */
  13. public $pivotParent;
  14. /**
  15. * The name of the foreign key column.
  16. *
  17. * @var string
  18. */
  19. protected $foreignKey;
  20. /**
  21. * The name of the "other key" column.
  22. *
  23. * @var string
  24. */
  25. protected $relatedKey;
  26. /**
  27. * The attributes that aren't mass assignable.
  28. *
  29. * @var array
  30. */
  31. protected $guarded = [];
  32. /**
  33. * Create a new pivot model instance.
  34. *
  35. * @param \Illuminate\Database\Eloquent\Model $parent
  36. * @param array $attributes
  37. * @param string $table
  38. * @param bool $exists
  39. * @return static
  40. */
  41. public static function fromAttributes(Model $parent, $attributes, $table, $exists = false)
  42. {
  43. $instance = new static;
  44. // The pivot model is a "dynamic" model since we will set the tables dynamically
  45. // for the instance. This allows it work for any intermediate tables for the
  46. // many to many relationship that are defined by this developer's classes.
  47. $instance->setConnection($parent->getConnectionName())
  48. ->setTable($table)
  49. ->forceFill($attributes)
  50. ->syncOriginal();
  51. // We store off the parent instance so we will access the timestamp column names
  52. // for the model, since the pivot model timestamps aren't easily configurable
  53. // from the developer's point of view. We can use the parents to get these.
  54. $instance->pivotParent = $parent;
  55. $instance->exists = $exists;
  56. $instance->timestamps = $instance->hasTimestampAttributes();
  57. return $instance;
  58. }
  59. /**
  60. * Create a new pivot model from raw values returned from a query.
  61. *
  62. * @param \Illuminate\Database\Eloquent\Model $parent
  63. * @param array $attributes
  64. * @param string $table
  65. * @param bool $exists
  66. * @return static
  67. */
  68. public static function fromRawAttributes(Model $parent, $attributes, $table, $exists = false)
  69. {
  70. $instance = static::fromAttributes($parent, [], $table, $exists);
  71. $instance->setRawAttributes($attributes, true);
  72. return $instance;
  73. }
  74. /**
  75. * Set the keys for a save update query.
  76. *
  77. * @param \Illuminate\Database\Eloquent\Builder $query
  78. * @return \Illuminate\Database\Eloquent\Builder
  79. */
  80. protected function setKeysForSaveQuery(Builder $query)
  81. {
  82. if (isset($this->attributes[$this->getKeyName()])) {
  83. return parent::setKeysForSaveQuery($query);
  84. }
  85. $query->where($this->foreignKey, $this->getOriginal(
  86. $this->foreignKey, $this->getAttribute($this->foreignKey)
  87. ));
  88. return $query->where($this->relatedKey, $this->getOriginal(
  89. $this->relatedKey, $this->getAttribute($this->relatedKey)
  90. ));
  91. }
  92. /**
  93. * Delete the pivot model record from the database.
  94. *
  95. * @return int
  96. */
  97. public function delete()
  98. {
  99. if (isset($this->attributes[$this->getKeyName()])) {
  100. return parent::delete();
  101. }
  102. return $this->getDeleteQuery()->delete();
  103. }
  104. /**
  105. * Get the query builder for a delete operation on the pivot.
  106. *
  107. * @return \Illuminate\Database\Eloquent\Builder
  108. */
  109. protected function getDeleteQuery()
  110. {
  111. return $this->newQuery()->where([
  112. $this->foreignKey => $this->getOriginal($this->foreignKey, $this->getAttribute($this->foreignKey)),
  113. $this->relatedKey => $this->getOriginal($this->relatedKey, $this->getAttribute($this->relatedKey)),
  114. ]);
  115. }
  116. /**
  117. * Get the table associated with the model.
  118. *
  119. * @return string
  120. */
  121. public function getTable()
  122. {
  123. if (! isset($this->table)) {
  124. $this->setTable(str_replace(
  125. '\\', '', Str::snake(Str::singular(class_basename($this)))
  126. ));
  127. }
  128. return $this->table;
  129. }
  130. /**
  131. * Get the foreign key column name.
  132. *
  133. * @return string
  134. */
  135. public function getForeignKey()
  136. {
  137. return $this->foreignKey;
  138. }
  139. /**
  140. * Get the "related key" column name.
  141. *
  142. * @return string
  143. */
  144. public function getRelatedKey()
  145. {
  146. return $this->relatedKey;
  147. }
  148. /**
  149. * Get the "related key" column name.
  150. *
  151. * @return string
  152. */
  153. public function getOtherKey()
  154. {
  155. return $this->getRelatedKey();
  156. }
  157. /**
  158. * Set the key names for the pivot model instance.
  159. *
  160. * @param string $foreignKey
  161. * @param string $relatedKey
  162. * @return $this
  163. */
  164. public function setPivotKeys($foreignKey, $relatedKey)
  165. {
  166. $this->foreignKey = $foreignKey;
  167. $this->relatedKey = $relatedKey;
  168. return $this;
  169. }
  170. /**
  171. * Determine if the pivot model has timestamp attributes.
  172. *
  173. * @return bool
  174. */
  175. public function hasTimestampAttributes()
  176. {
  177. return array_key_exists($this->getCreatedAtColumn(), $this->attributes);
  178. }
  179. /**
  180. * Get the name of the "created at" column.
  181. *
  182. * @return string
  183. */
  184. public function getCreatedAtColumn()
  185. {
  186. return $this->pivotParent->getCreatedAtColumn();
  187. }
  188. /**
  189. * Get the name of the "updated at" column.
  190. *
  191. * @return string
  192. */
  193. public function getUpdatedAtColumn()
  194. {
  195. return $this->pivotParent->getUpdatedAtColumn();
  196. }
  197. }