Skip to content

Commit 37c47cc

Browse files
committed
with() method added
1 parent ac671e5 commit 37c47cc

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"php": ">=7.2.0",
1515
"ext-pdo": "*",
1616
"yiisoft/yii2": "~2.0.0",
17-
"smoren/query-relation-manager": "1.0.0"
17+
"smoren/query-relation-manager": "1.0.1"
1818
},
1919
"autoload": {
2020
"psr-4": {

src/ActiveRecord/QueryRelationManager.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use Smoren\Yii2\QueryRelationManager\Base\QueryRelationManagerBase;
88
use Smoren\Yii2\QueryRelationManager\Base\QueryWrapperInterface;
99
use Smoren\Yii2\QueryRelationManager\Base\QueryRelationManagerException;
10+
use yii\db\ActiveQuery;
11+
use yii\db\ActiveRecord;
1012

1113
/**
1214
* Class for making queries for getting data from database with relations and filters
@@ -15,6 +17,75 @@
1517
*/
1618
class QueryRelationManager extends QueryRelationManagerBase
1719
{
20+
public function with(
21+
string $relationName, string $relationAlias, ?string $parentClassName = null, string $joinType = 'left',
22+
?string $extraJoinCondition = null, ?array $extraJoinParams = []
23+
): self
24+
{
25+
$parentClassName = $parentClassName ?? $this->mainClassName;
26+
27+
if(!class_exists($parentClassName)) {
28+
throw new QueryRelationManagerException("class {$parentClassName} not exists");
29+
}
30+
31+
if(!isset($this->mapClassNameToTableAlias[$parentClassName])) {
32+
throw new QueryRelationManagerException("class {$parentClassName} not used in query");
33+
}
34+
$parentAlias = $this->mapClassNameToTableAlias[$parentClassName];
35+
36+
/** @var ActiveRecord $inst */
37+
$inst = new $parentClassName;
38+
if(!($inst instanceof ActiveRecord)) {
39+
throw new QueryRelationManagerException("class {$parentClassName} is not an instance of ActiveRecord");
40+
}
41+
42+
$methodName = 'get'.ucfirst($relationName);
43+
if(!method_exists($inst, $methodName)) {
44+
throw new QueryRelationManagerException("method {$parentClassName}::{$methodName}() not exists");
45+
}
46+
47+
/** @var ActiveQuery $activeQuery */
48+
$activeQuery = $inst->$methodName();
49+
if(!($activeQuery instanceof ActiveQuery)) {
50+
throw new QueryRelationManagerException("method {$parentClassName}::{$methodName}() returned non-ActiveQuery instance");
51+
}
52+
53+
if($activeQuery->via) {
54+
throw new QueryRelationManagerException('cannot use relations with "via" section yet');
55+
}
56+
if(!$activeQuery->link || !count($activeQuery->link)) {
57+
throw new QueryRelationManagerException('cannot use relations without "link" section');
58+
}
59+
60+
$fieldJoinBy = null;
61+
$fieldJoinTo = null;
62+
$extraConditions = [];
63+
foreach($activeQuery->link as $key => $val) {
64+
if($fieldJoinBy === null) {
65+
$fieldJoinBy = $key;
66+
$fieldJoinTo = $val;
67+
} else {
68+
$extraConditions[] = "{$relationAlias}.{$key} = {$parentAlias}.{$val}";
69+
}
70+
}
71+
if(count($extraConditions)) {
72+
$extraJoinCondition = implode(' AND ', $extraConditions)." {$extraJoinCondition}";
73+
}
74+
75+
if($activeQuery->multiple) {
76+
return $this->withMultiple(
77+
$relationName, $activeQuery->modelClass, $relationAlias,
78+
$parentAlias, $fieldJoinBy, $fieldJoinTo, $joinType,
79+
$extraJoinCondition, $extraJoinParams, $activeQuery->modelClass::primaryKey()[0]
80+
);
81+
} else {
82+
return $this->withSingle(
83+
$relationName, $activeQuery->modelClass, $relationAlias,
84+
$parentAlias, $fieldJoinBy, $fieldJoinTo, $joinType,
85+
$extraJoinCondition, $extraJoinParams, $activeQuery->modelClass::primaryKey()[0]
86+
);
87+
}
88+
}
1889

1990
/**
2091
* Возвращает имя таблицы по классу сущности ActiveRecord

0 commit comments

Comments
 (0)