@@ -51,32 +51,95 @@ protected function applyHas(
5151 ) {
5252 $ relationNames = explode ('. ' , $ relationName );
5353 $ model = $ this ->model ;
54+ // $relations = [];
55+ // foreach ($relationNames as $name) {
56+ // $relation = $model::getRelation($name);
57+ // $model = $relation->foreignModel;
58+ // $relations[] = $relation;
59+ // }
60+ // if (!count($relations)) return;
61+
62+ $ relationGroups = [];
63+ $ dbName = null ;
5464 $ relations = [];
5565 foreach ($ relationNames as $ name ) {
5666 $ relation = $ model ::getRelation ($ name );
5767 $ model = $ relation ->foreignModel ;
68+
69+ if ($ dbName !== $ model ::dbName ()) {
70+ if (!empty ($ relations )) {
71+ $ relationGroups [] = $ relations ;
72+ }
73+ $ dbName = $ model ::dbName ();
74+ $ relations = [];
75+ }
76+
5877 $ relations [] = $ relation ;
5978 }
60- if (!count ($ relations )) return ;
79+ if (!empty ($ relations )) {
80+ $ relationGroups [] = $ relations ;
81+ }
82+ if (!count ($ relationGroups )) return ;
83+ // foreach ($relationGroups as $relations) {
84+ // foreach ($relations as $relation) {
85+ // echo dumpOrm($relation);
86+ // }
87+ // echo '<hr>';
88+ // }
89+ // exit();
90+
6191
62- if ($ hasCount = func_num_args () > 3 ) {
92+ if (func_num_args () > 3 ) {
6393 $ this ->prepareValueAndOperator (
6494 $ value , $ operator , func_num_args () === 4
6595 );
96+ $ opval = [$ operator , $ value ];
97+ } else {
98+ $ opval = null ;
6699 }
67100
68- $ relations = array_reverse ( $ relations );
69- $ query = $ this -> realApplyHas ( $ relations , $ operator , $ value , $ hasCount );
101+
102+ // exit( );
70103
104+ // $relations = array_reverse($relations);
105+ // $query = $this->realApplyHas($relations, $operator, $value, $isCount);
71106
72- if (count ($ relations ) < 2 && $ hasCount ) {
73- $ this ->where ($ query , $ operator , $ value );
74- echo dumpOrm ($ this ->getSql ());
75- echo dumpOrm ($ this ->getBindings ());
107+ $ last = count ($ relationGroups ) - 1 ;
108+ if (0 === $ last ) {
109+ $ relations = array_reverse ($ relationGroups [0 ]);
110+ $ query = $ this ->realApplyHas ($ relations , $ opval );
111+
112+ if (count ($ relations ) < 2 && $ opval ) {
113+ $ this ->where ($ query , ...$ opval );
114+ echo dumpOrm ($ this ->getSql ());
115+ echo dumpOrm ($ this ->getBindings ());
116+ } else {
117+ $ this ->whereExists ($ query );
118+ }
76119 } else {
77- $ this ->whereExists ($ query );
120+ $ ids = null ;
121+ foreach ($ relationGroups as $ i => $ relations ) {
122+ $ ids = $ this ->applyGroupHas (
123+ $ relations , $ ids , $ last === $ i ? $ opval : null
124+ );
125+ // $relations = array_reverse($relations);
126+ // $query = $this->realApplyHas($relations, $last === $i ? $opval : null);
127+ // var_dump($query);
128+ // echo '<br>';
129+ }
130+ $ this ->whereIn ($ this ->primaryKey (), $ ids );
78131 }
79132
133+
134+ // if (count($relations) < 2 && $opval) {
135+ // $this->where($query, ...$opval);
136+ // echo dumpOrm($this->getSql());
137+ // echo dumpOrm($this->getBindings());
138+ // } else {
139+ // $this->whereExists($query);
140+ // }
141+
142+
80143 // if (in_array($operator, ['<', '<='])) {
81144 // $query = $this->realApplyNotHas($relations, $operator);
82145 // $this->orWhereNotExists($query);
@@ -86,29 +149,85 @@ protected function applyHas(
86149 // $this->whereRaw('EXISTS (SELECT COUNT(`id`) AS `count_id` FROM `company` WHERE `user`.`id` = `company`.`user_id` AND (SELECT COUNT(`id`) AS `count_id` FROM `user` WHERE `company`.`user_id` = `user`.`id`) > 100)');
87150 }
88151
89- protected function realApplyHas ($ relations , $ operator , $ value , bool $ hasCount = false )
152+ protected function applyGroupHas ($ relations , array $ ids = null , array $ opval = null )
153+ {
154+ echo dumpOrm ($ relations );
155+ $ relations = array_reverse ($ relations );
156+ $ last = count ($ relations ) - 1 ;
157+ $ q = clone $ this ;
158+ $ q ->db = $ relations [0 ]->foreignModel ::db ();
159+ $ q ->withs = [];
160+ $ q ->has = [];
161+ $ q ->resetFrom ($ relations [0 ]->localModel ::tableName ());
162+ if ($ ids ) {
163+ $ q ->whereIn ($ relations [0 ]->localKey (true ), $ ids );
164+ $ ids = null ;
165+ // $q->resetSelect(['iid' => $relations[0]->foreignKey(true)]);
166+ array_pop ($ relations );
167+ } else {
168+ //
169+ }
170+ $ query = $ q ->realApplyHas ($ relations , $ opval );
171+ if (count ($ relations ) < 2 && $ opval ) {
172+ $ q ->where ($ query , ...$ opval );
173+ } else {
174+ $ q ->whereExists ($ query );
175+ }
176+ echo '<div class="block gray"><h3 class="title">SQL:</h3> ' ;
177+ echo dumpOrm ($ q ->getSql ());
178+ echo dumpOrm ($ q ->getBindings ());
179+ echo '</div> ' ;
180+ $ models = $ q ->get ();
181+ echo dumpOrm ($ models );
182+ $ ids = [];
183+ foreach ($ models as $ model ) {
184+ $ ids [] = $ model ->id ;
185+ }
186+ echo dumpOrm ($ ids );
187+ return $ ids ;
188+ }
189+
190+ protected function realApplyHas ($ relations , array $ opval = null )
90191 {
91192 $ query = null ;
92193 foreach ($ relations as $ i => $ relation ) {
93- $ query = function ($ q ) use (
94- $ relation , $ query , $ value , $ operator , $ hasCount , $ i
95- ) {
194+ $ query = function ($ q ) use ($ relation , $ query , $ opval , $ i ) {
96195 $ q ->from ($ relation ->foreignTable );
97196 $ q ->whereColumn ($ relation ->localKey (true ), $ relation ->foreignKey (false ));
98197 if ($ query ) {
99- if (1 == $ i && $ hasCount ) {
100- $ q ->where ($ query , $ operator , $ value );
101- } else {
102- $ q ->whereExists ($ query );
103- }
104- } else if (0 == $ i && $ hasCount ) {
198+ if (1 == $ i && $ opval ) $ q ->where ($ query , ...$ opval );
199+ else $ q ->whereExists ($ query );
200+ } else if (0 == $ i && $ opval ) {
105201 $ q ->count ('id ' );
106202 }
107203 };
108204 }
109205 return $ query ;
110206 }
111207
208+ // protected function realApplyHas($relations, $operator, $value, bool $isCount = false)
209+ // {
210+ // $query = null;
211+ // foreach ($relations as $i => $relation) {
212+ // $query = function ($q) use (
213+ // $relation, $query, $value, $operator, $isCount, $i
214+ // ) {
215+ // $q->from($relation->foreignTable);
216+ // $q->whereColumn($relation->localKey(true), $relation->foreignKey(false));
217+ // if ($query) {
218+ // if (1 == $i && $isCount) {
219+ // $q->where($query, $operator, $value);
220+ // } else {
221+ // $q->whereExists($query);
222+ // }
223+ // } else if (0 == $i && $isCount) {
224+ // $q->count('id');
225+ // }
226+ // };
227+ // }
228+ // return $query;
229+ // }
230+
112231 protected function realApplyNotHas ($ relations , $ operator , bool $ isAnd = false )
113232 {
114233 $ query = null ;
0 commit comments