forked from canni/YiiMongoDbSuite
-
Notifications
You must be signed in to change notification settings - Fork 2
/
EMongoSort.php
212 lines (195 loc) · 6.79 KB
/
EMongoSort.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<?php
/**
* @author Ianaré Sévi
* @author Dariusz Górecki <[email protected]>
* @author Invenzzia Group, open-source division of CleverIT company http://www.invenzzia.org
* @copyright 2011 CleverIT http://www.cleverit.com.pl
* @license New BSD license
* @version 1.3
* @category ext
* @package ext.YiiMongoDbSuite
*/
/**
* EMongoSort
* @since v1.3.4
*
* Represents information relevant to sorting EMongoDocument dataProviders.
*/
class EMongoSort extends CSort
{
private $_directions;
/**
* Modifies the query criteria by changing its {@link EMongoRecordDataProvider::order} property.
* This method will use {@link directions} to determine which columns need to be sorted.
* They will be put in the ORDER BY clause. If the criteria already has non-empty {@link EMongoRecordDataProvider::order} value,
* the new value will be appended to it.
* @param EMongoRecordDataProvider $criteria the query criteria
*/
public function applyOrder($criteria)
{
$order = $this->getOrderBy();
if (!empty($order))
{
$criteria->setSort($order);
// todo JOIN this new array properly with existing sort criteria - it just overwrites it now
//if(!empty($criteria->order))
// $criteria->order.=', ';
//$criteria->order.=$order;
}
}
/**
* @return string the order-by columns represented by this sort object.
* This can be put in the ORDER BY clause of a SQL statement.
* @since 1.1.0
* @bedezign Added criteria for new Yii version
*/
public function getOrderBy($criteria = NULL)
{
$directions = $this->getDirections();
if (empty($directions))
return is_array($this->defaultOrder) ? $this->defaultOrder : array(); // use the defaultOrder
else
{
$orders = array();
foreach ($directions as $attribute => $direction)
$orders[$attribute] = $direction;
return $orders;
}
}
/**
* Generates a hyperlink that can be clicked to cause sorting.
* @param string $attribute the attribute name. This must be the actual attribute name, not alias.
* @param string $label the link label. If null, the label will be determined according
* to the attribute (see {@link resolveLabel}).
* @param array $htmlOptions additional HTML attributes for the hyperlink tag
* @return string the generated hyperlink
*/
public function link($attribute, $label = null, $htmlOptions = array())
{
// todo make sure this works with relations?
if ($label === null)
$label = $this->resolveLabel($attribute);
if (($definition = $this->resolveAttribute($attribute)) === false)
return $label;
$directions = $this->getDirections();
if (isset($directions[$attribute]))
{
$class = ($directions[$attribute] == EMongoCriteria::SORT_DESC) ? 'desc' : 'asc';
if (isset($htmlOptions['class']))
$htmlOptions['class'].=' ' . $class;
else
$htmlOptions['class'] = $class;
$direction = $directions[$attribute];
unset($directions[$attribute]);
}
else if (is_array($definition) && isset($definition['default']))
$direction = $definition['default'];
else
$direction = EMongoCriteria::SORT_ASC;
if ($this->multiSort)
$directions = array_merge(array($attribute => $direction), $directions);
else
$directions = array($attribute => $direction);
$url = $this->createUrl(Yii::app()->getController(), $directions);
return $this->createLink($attribute, $label, $url, $htmlOptions);
}
/**
* Resolves the attribute label for the specified attribute.
* This will invoke {@link CActiveRecord::getAttributeLabel} to determine what label to use.
* If the attribute refers to a virtual attribute declared in {@link attributes},
* then the label given in the {@link attributes} will be returned instead.
* @param string $attribute the attribute name.
* @return string the attribute label
*/
public function resolveLabel($attribute)
{
// todo provide support for getAttributeLabel()
return $attribute;
}
/**
* Returns the currently requested sort information.
* @return array sort directions indexed by attribute names.
* The sort direction is true if the corresponding attribute should be
* sorted in descending order.
*/
public function getDirections()
{
if ($this->_directions === null)
{
$this->_directions = array();
if (isset($_GET[$this->sortVar]))
{
$attributes = explode($this->separators[0], $_GET[$this->sortVar]);
foreach ($attributes as $attribute)
{
if (($pos = strrpos($attribute, $this->separators[1])) !== false)
{
$descending = substr($attribute, $pos + 1) === $this->descTag;
if ($descending)
{
$attribute = substr($attribute, 0, $pos);
$direction = EMongoCriteria::SORT_DESC;
}
else
$direction = EMongoCriteria::SORT_ASC;
}
else
$direction = EMongoCriteria::SORT_ASC;
if (($this->resolveAttribute($attribute)) !== false)
{
$this->_directions[$attribute] = $direction;
if (!$this->multiSort)
return $this->_directions;
}
}
}
if ($this->_directions === array() && is_array($this->defaultOrder))
$this->_directions = $this->defaultOrder;
}
return $this->_directions;
}
/**
* Returns the sort direction of the specified attribute in the current request.
* @param string $attribute the attribute name
* @return mixed the sort direction of the attribute. True if the attribute should be sorted in descending order,
* false if in ascending order, and null if the attribute doesn't need to be sorted.
*/
public function getDirection($attribute)
{
$this->getDirections();
return isset($this->_directions[$attribute]) ? $this->_directions[$attribute] : null;
}
/**
* Creates a URL that can lead to generating sorted data.
* @param CController $controller the controller that will be used to create the URL.
* @param array $directions the sort directions indexed by attribute names.
* The sort direction is true if the corresponding attribute should be
* sorted in descending order.
* @return string the URL for sorting
*/
public function createUrl($controller, $directions)
{
$sorts = array();
foreach ($directions as $attribute => $direction)
{
if ($direction == EMongoCriteria::SORT_DESC)
$sorts[] = $attribute;
else
$sorts[] = $attribute . $this->separators[1] . $this->descTag;
}
$params = $this->params === null ? $_GET : $this->params;
$params[$this->sortVar] = implode($this->separators[0], $sorts);
return $controller->createUrl($this->route, $params);
}
/**
* Returns the real definition of an attribute given its name.
*
* @param string $attribute the attribute name that the user requests to sort on
* @return mixed the attribute name or the virtual attribute definition. False if the attribute cannot be sorted.
*/
public function resolveAttribute($attribute)
{
// todo flesh this out more so it only works with valid sorting attributes
return $attribute;
}
}