Skip to content

Commit ba063a5

Browse files
author
Mauro Cassani
committed
Join feature
1 parent d03ad79 commit ba063a5

File tree

4 files changed

+167
-4
lines changed

4 files changed

+167
-4
lines changed

README.md

+39
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,45 @@ foreach ($qb->getResults() as $element){
115115
* `DATE_ASC`
116116
* `DATE_DESC`
117117

118+
## Joins
119+
120+
You can join arrays. Please consider this full example:
121+
122+
```php
123+
use ArrayQuery\QueryBuilder;
124+
125+
$users = [
126+
[
127+
'id' => 1,
128+
'name' => 'Mauro Cassani',
129+
'id_category' => 3,
130+
'email' => '[email protected]'
131+
],[
132+
'id' => 2,
133+
'name' => 'Mario Rossi',
134+
'id_category' => 3,
135+
'email' => '[email protected]'
136+
],[
137+
'id' => 3,
138+
'name' => 'Maria Bianchi',
139+
'id_category' => 1,
140+
'email' => '[email protected]'
141+
]
142+
];
143+
$category = [
144+
'id' => 3,
145+
'name' => 'Web Developer'
146+
];
147+
148+
$qb = QueryBuilder::create($users)
149+
->join($category, 'category', 'id_category', 'id')
150+
->addCriterion('category.id', 3);
151+
152+
foreach ($qb->getResults() as $element){
153+
// ...
154+
}
155+
```
156+
118157
## Performing Queries
119158

120159
You can add criteria and specify limit and offset for your query results:

src/Filters/JoinFilter.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* This file is part of the ArrayQuery package.
4+
*
5+
* (c) Mauro Cassani<https://github.com/mauretto78>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace ArrayQuery\Filters;
12+
13+
class JoinFilter extends AbstractFilter
14+
{
15+
/**
16+
* @param array $results
17+
* @param null $joinArray
18+
* @return array
19+
*/
20+
public static function filter(array $results, $joinArray = null)
21+
{
22+
if ($joinArray) {
23+
foreach ($joinArray as $join) {
24+
foreach ($results as $key => $result) {
25+
$arrayToJoin = $join['array'];
26+
$arrayName = $join['arrayName'];
27+
$parentKey = $join['parentKey'];
28+
$foreignKey = $join['foreignKey'];
29+
30+
if (array_key_exists($parentKey, $result) && $arrayToJoin[$foreignKey] === $result[$parentKey]) {
31+
$results[$key][$arrayName] = $arrayToJoin;
32+
} else {
33+
unset($results[$key]);
34+
}
35+
}
36+
}
37+
}
38+
39+
return $results;
40+
}
41+
}

src/QueryBuilder.php

+27-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ArrayQuery\Exceptions\NotValidLimitsOfArrayException;
1818
use ArrayQuery\Exceptions\NotValidSortingOperatorException;
1919
use ArrayQuery\Filters\CriterionFilter;
20+
use ArrayQuery\Filters\JoinFilter;
2021
use ArrayQuery\Filters\SortingFilter;
2122
use ArrayQuery\Filters\LimitFilter;
2223

@@ -37,6 +38,11 @@ class QueryBuilder
3738
*/
3839
private $limit;
3940

41+
/**
42+
* @var array
43+
*/
44+
private $join;
45+
4046
/**
4147
* @var array
4248
*/
@@ -171,12 +177,24 @@ public function limit($offset, $length)
171177
return $this;
172178
}
173179

180+
public function join($array, $arrayName, $parentKey, $foreignKey)
181+
{
182+
$this->join[] = [
183+
'array' => $array,
184+
'arrayName' => $arrayName,
185+
'parentKey' => $parentKey,
186+
'foreignKey' => $foreignKey,
187+
];
188+
189+
return $this;
190+
}
191+
174192
/**
175193
* @return array
176194
*/
177195
public function getResults()
178196
{
179-
$results = $this->applySortingFilter($this->applyLimitFilter($this->applyCriteriaFilter()));
197+
$results = $this->applySortingFilter($this->applyLimitFilter($this->applyCriteriaFilter($this->applyJoinFilter())));
180198

181199
return array_map([$this, 'castElementToArray'], $results);
182200
}
@@ -199,18 +217,23 @@ private function applyLimitFilter(array $array)
199217
return LimitFilter::filter($array, $this->limit);
200218
}
201219

220+
private function applyJoinFilter()
221+
{
222+
return JoinFilter::filter($this->array, $this->join);
223+
}
224+
202225
/**
203226
* @return array
204227
*/
205-
private function applyCriteriaFilter()
228+
private function applyCriteriaFilter(array $array)
206229
{
207230
if (count($this->criteria) === 0) {
208-
return $this->array;
231+
return $array;
209232
}
210233

211234
foreach ($this->criteria as $criterion) {
212235
$results = array_filter(
213-
(isset($results)) ? $results : $this->array, function ($element) use ($criterion) {
236+
(isset($results)) ? $results : $array, function ($element) use ($criterion) {
214237
return CriterionFilter::filter($criterion, $element);
215238
}
216239
);

tests/QueryBuilderTest.php

+60
Original file line numberDiff line numberDiff line change
@@ -507,4 +507,64 @@ public function it_should_get_results_from_a_query_with_equals_date_sorted_by_da
507507
$this->assertEquals('Clementine Bauch', $results[0]['name']);
508508
}
509509
}
510+
511+
/**
512+
* @test
513+
*/
514+
public function it_should_get_results_from_a_query_with_joins()
515+
{
516+
$users = [
517+
[
518+
'id' => 1,
519+
'name' => 'Mauro Cassani',
520+
'id_category' => 3,
521+
'email' => '[email protected]'
522+
],[
523+
'id' => 2,
524+
'name' => 'Mario Rossi',
525+
'id_category' => 3,
526+
'email' => '[email protected]'
527+
],[
528+
'id' => 3,
529+
'name' => 'Maria Bianchi',
530+
'id_category' => 1,
531+
'email' => '[email protected]'
532+
]
533+
];
534+
$category = [
535+
'id' => 3,
536+
'name' => 'Web Developer'
537+
];
538+
539+
$qb = QueryBuilder::create($users)
540+
->join($category, 'category', 'id_category', 'id')
541+
->addCriterion('category.id', 3);
542+
543+
$results = $qb->getResults();
544+
$expectedArray = [
545+
[
546+
'id' => 1,
547+
'name' => 'Mauro Cassani',
548+
'id_category' => 3,
549+
'email' => '[email protected]',
550+
'category'=> [
551+
'id' => 3,
552+
'name' => 'Web Developer'
553+
]
554+
],
555+
[
556+
'id' => 2,
557+
'name' => 'Mario Rossi',
558+
'id_category' => 3,
559+
'email' => '[email protected]',
560+
'category'=> [
561+
'id' => 3,
562+
'name' => 'Web Developer'
563+
]
564+
]
565+
];
566+
567+
$this->assertEquals($results, $expectedArray);
568+
$this->assertEquals(2, $qb->getCount());
569+
}
510570
}

0 commit comments

Comments
 (0)