1: <?php
2:
3: namespace Baril\Orderly\Concerns;
4:
5: use Baril\Orderly\GroupException;
6:
7: /**
8: * @property string|array $groupColumn Name of the "group" column
9: */
10: trait Groupable
11: {
12: /**
13: * Return the name of the "group" field.
14: *
15: * @return string|null
16: */
17: public function getGroupColumn()
18: {
19: return property_exists($this, 'groupColumn') ? $this->groupColumn : null;
20: }
21:
22: /**
23: * Return the group for $this.
24: *
25: * @param bool $original If set to true, the method will return the "original" value.
26: * @return mixed
27: */
28: public function getGroup($original = false)
29: {
30: $groupColumn = $this->getGroupColumn();
31: if (is_null($groupColumn)) {
32: return null;
33: }
34: if (!is_array($groupColumn)) {
35: return $original ? $this->getOriginal($groupColumn) : $this->{$groupColumn};
36: }
37:
38: $group = [];
39: foreach ($groupColumn as $column) {
40: $group[] = $original ? $this->getOriginal($column) : $this->$column;
41: }
42: return $group;
43: }
44:
45: /**
46: * Restrict the query to the provided group.
47: *
48: * @param \Illuminate\Database\Eloquent\Builder $query
49: * @param mixed $group
50: */
51: public function scopeWhereGroup($query, $group)
52: {
53: $groupColumn = (array) $this->getGroupColumn();
54: $group = is_null($group) ? [ null ] : array_values((array) $group);
55: foreach ($group as $i => $value) {
56: $query->where($groupColumn[$i], $value);
57: }
58: }
59:
60: /**
61: * Restrict the query to the provided groups.
62: *
63: * @param \Illuminate\Database\Eloquent\Builder $query
64: * @param array $groups
65: */
66: public function scopeWhereGroupIn($query, $groups)
67: {
68: $query->where(function ($query) use ($groups) {
69: foreach ($groups as $group) {
70: $query->orWhere(function ($query) use ($group) {
71: $this->scopeWhereGroup($query, $group);
72: });
73: }
74: });
75: }
76:
77: /**
78: * Get a new query builder for the model's group.
79: *
80: * @param boolean $excludeThis
81: * @return \Illuminate\Database\Eloquent\Builder
82: */
83: public function newQueryInSameGroup($excludeThis = false)
84: {
85: $query = $this->newQuery();
86: $groupColumn = (array) $this->getGroupColumn();
87: if ($groupColumn) {
88: $group = [];
89: foreach ($groupColumn as $column) {
90: $group[] = $this->$column;
91: }
92: $query->whereGroup($group);
93: }
94: if ($excludeThis) {
95: $query->whereKeyNot($this->getKey());
96: }
97: return $query;
98: }
99:
100: /**
101: * Check if $this belongs to the same group as the provided $model.
102: *
103: * @param static $model
104: * @return bool
105: *
106: * @throws GroupException
107: */
108: public function isInSameGroupAs($model)
109: {
110: if (!$model instanceof static) {
111: throw new GroupException('Both models must belong to the same class!');
112: }
113: $groupColumn = (array) $this->getGroupColumn();
114: foreach ($groupColumn as $column) {
115: if ($model->$column != $this->$column) {
116: return false;
117: }
118: }
119: return true;
120: }
121: }
122: