1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21: 22:
23: class NGroupedTableSelection extends NTableSelection
24: {
25:
26: protected $refTable;
27:
28:
29: protected $column;
30:
31:
32: protected $active;
33:
34:
35:
36: 37: 38: 39: 40: 41:
42: public function __construct(NTableSelection $refTable, $table, $column)
43: {
44: parent::__construct($table, $refTable->connection);
45: $this->refTable = $refTable;
46: $this->column = $column;
47: }
48:
49:
50:
51: 52: 53: 54: 55: 56:
57: public function setActive($active)
58: {
59: $this->active = $active;
60: return $this;
61: }
62:
63:
64:
65:
66: public function through($column)
67: {
68: trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::related("' . $this->name . '", "' . $column . '") instead.', E_USER_WARNING);
69: $this->column = $column;
70: $this->delimitedColumn = $this->refTable->connection->getSupplementalDriver()->delimite($this->column);
71: return $this;
72: }
73:
74:
75:
76: public function select($columns)
77: {
78: if (!$this->sqlBuilder->getSelect()) {
79: $this->sqlBuilder->addSelect("$this->name.$this->column");
80: }
81:
82: return parent::select($columns);
83: }
84:
85:
86:
87: public function order($columns)
88: {
89: if (!$this->sqlBuilder->getOrder()) {
90:
91: $this->sqlBuilder->addOrder("$this->name.$this->column" . (preg_match('~\bDESC\z~i', $columns) ? ' DESC' : ''));
92: }
93:
94: return parent::order($columns);
95: }
96:
97:
98:
99:
100:
101:
102:
103: public function aggregation($function)
104: {
105: $aggregation = & $this->getRefTable($refPath)->aggregation[$refPath . $function . $this->getSql() . json_encode($this->sqlBuilder->getParameters())];
106:
107: if ($aggregation === NULL) {
108: $aggregation = array();
109:
110: $selection = $this->createSelectionInstance();
111: $selection->getSqlBuilder()->importConditions($this->getSqlBuilder());
112: $selection->select($function);
113: $selection->select("$this->name.$this->column");
114: $selection->group("$this->name.$this->column");
115:
116: foreach ($selection as $row) {
117: $aggregation[$row[$this->column]] = $row;
118: }
119: }
120:
121: if (isset($aggregation[$this->active])) {
122: foreach ($aggregation[$this->active] as $val) {
123: return $val;
124: }
125: }
126: }
127:
128:
129:
130: public function count($column = NULL)
131: {
132: $return = parent::count($column);
133: return isset($return) ? $return : 0;
134: }
135:
136:
137:
138:
139:
140:
141:
142: protected function execute()
143: {
144: if ($this->rows !== NULL) {
145: return;
146: }
147:
148: $hash = md5($this->getSql() . json_encode($this->sqlBuilder->getParameters()));
149:
150: $referencing = & $this->getRefTable($refPath)->referencing[$refPath . $hash];
151: $this->rows = & $referencing['rows'];
152: $this->referenced = & $referencing['refs'];
153: $this->accessedColumns = & $referencing['accessed'];
154: $refData = & $referencing['data'];
155:
156: if ($refData === NULL) {
157: $limit = $this->sqlBuilder->getLimit();
158: $rows = count($this->refTable->rows);
159: if ($limit && $rows > 1) {
160: $this->sqlBuilder->setLimit(NULL, NULL);
161: }
162: parent::execute();
163: $this->sqlBuilder->setLimit($limit, NULL);
164: $refData = array();
165: $offset = array();
166: $this->accessColumn($this->column);
167: foreach ((array) $this->rows as $key => $row) {
168: $ref = & $refData[$row[$this->column]];
169: $skip = & $offset[$row[$this->column]];
170: if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->sqlBuilder->getOffset())) {
171: $ref[$key] = $row;
172: } else {
173: unset($this->rows[$key]);
174: }
175: $skip++;
176: unset($ref, $skip);
177: }
178: }
179:
180: $this->data = & $refData[$this->active];
181: if ($this->data === NULL) {
182: $this->data = array();
183: } else {
184: foreach ($this->data as $row) {
185: $row->setTable($this);
186: }
187: reset($this->data);
188: $this->checkReferenced = TRUE;
189: }
190: }
191:
192:
193:
194: protected function getRefTable(& $refPath)
195: {
196: $refObj = $this->refTable;
197: $refPath = $this->name . '.';
198: while ($refObj instanceof NGroupedTableSelection) {
199: $refPath .= $refObj->name . '.';
200: $refObj = $refObj->refTable;
201: }
202:
203: return $refObj;
204: }
205:
206:
207:
208:
209:
210:
211:
212: public function insert($data)
213: {
214: if ($data instanceof Traversable && !$data instanceof NTableSelection) {
215: $data = iterator_to_array($data);
216: }
217:
218: if (NValidators::isList($data)) {
219: foreach (array_keys($data) as $key) {
220: $data[$key][$this->column] = $this->active;
221: }
222: } else {
223: $data[$this->column] = $this->active;
224: }
225:
226: return parent::insert($data);
227: }
228:
229:
230:
231: public function update($data)
232: {
233: $builder = $this->sqlBuilder;
234:
235: $this->sqlBuilder = clone $this->sqlBuilder;
236: $this->where($this->column, $this->active);
237: $return = parent::update($data);
238:
239: $this->sqlBuilder = $builder;
240: return $return;
241: }
242:
243:
244:
245: public function delete()
246: {
247: $builder = $this->sqlBuilder;
248:
249: $this->sqlBuilder = clone $this->sqlBuilder;
250: $this->where($this->column, $this->active);
251: $return = parent::delete();
252:
253: $this->sqlBuilder = $builder;
254: return $return;
255: }
256:
257: }
258: