-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSubQueryBehavior.php
80 lines (73 loc) · 2.28 KB
/
SubQueryBehavior.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
/**
* SubQueryBehavior
*
* Adds two methods to the model which can be used to generate subqueries for
* conditions and virtual fields. Check the documentation on GitHub for usage
* examples.
*
* @author Frank de Graaf (Phally)
* @link https://www.github.com/Phally/SubQuery
* @license MIT
*/
class SubQueryBehavior extends ModelBehavior {
/**
* Map of datasource aliases.
*
* @var array
*/
protected $_nameMap = array();
/**
* Creates a formatted subquery condition to use in the conditions array. It
* will return a datasource expression which the core will accept as a
* complete condition.
*
* @param Model $model Instance of the primary model.
* @param Model $on Instance of the model to use for the subquery.
* @param array $condition A single condition definition (like: array('id NOT' => $query)).
* @return stdObject A datasource expression containing the subquery condition.
*/
public function subQueryCondition(Model $model, Model $on, array $condition) {
list($field, $query) = each($condition);
$not = false;
if (stripos($field, 'NOT')) {
$not = true;
$field = str_replace('NOT', '', $field);
}
$field = $model->getDataSource()->name("{$model->alias}.$field");
$sql = 'IN (' . $this->_getQuery($on, $query) . ')';
if ($not) {
$sql = 'NOT ' . $sql;
}
$sql = "$field $sql";
return $model->getDataSource()->expression($sql);
}
/**
* Gets a subquery for use as a virtual field for example.
*
* @param Model $model Instance of the primary model.
* @param array $query The find() query.
* @param boolean $virtualField Using false here will wrap the query in a datasource expression.
* @return type
*/
public function subQuery(Model $model, array $query, $virtualField = true) {
$sql = $this->_getQuery($model, $query);
if ($virtualField) {
return $sql;
}
return $model->getDataSource()->expression('(' . $sql . ')');
}
/**
* Gets the raw SQL for a query.
*
* @param Model $model Instance of the model to run the query on.
* @param array $query The find() query.
* @return string Raw SQL.
*/
protected function _getQuery(Model $model, array $query) {
$db = $model->getDataSource();
$query['table'] = $db->fullTableName($model);
$result = $db->buildStatement($query, $model);
return $result;
}
}