1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21:
22: class GroupedTableSelection extends TableSelection
23: {
24:
25: private $refTable;
26:
27:
28: private $column;
29:
30:
31: private $delimitedColumn;
32:
33:
34: public $active;
35:
36:
37:
38: public function __construct($name, TableSelection $refTable, $column)
39: {
40: parent::__construct($name, $refTable->connection);
41: $this->refTable = $refTable;
42: $this->through($column);
43: }
44:
45:
46:
47: 48: 49: 50: 51:
52: public function through($column)
53: {
54: $this->column = $column;
55: $this->delimitedColumn = $this->refTable->connection->getSupplementalDriver()->delimite($this->column);
56: return $this;
57: }
58:
59:
60:
61: public function select($columns)
62: {
63: if (!$this->select) {
64: $this->select[] = "$this->delimitedName.$this->delimitedColumn";
65: }
66: return parent::select($columns);
67: }
68:
69:
70:
71: public function order($columns)
72: {
73: if (!$this->order) {
74: $this->order[] = "$this->delimitedName.$this->delimitedColumn"
75: . (preg_match('~\\bDESC$~i', $columns) ? ' DESC' : '');
76: }
77: return parent::order($columns);
78: }
79:
80:
81:
82: public function aggregation($function)
83: {
84: $join = $this->createJoins(implode(',', $this->conditions), TRUE) + $this->createJoins($function);
85: $column = ($join ? "$this->delimitedName." : '') . $this->delimitedColumn;
86: $query = "SELECT $function, $column FROM $this->delimitedName" . implode($join);
87: if ($this->where) {
88: $query .= ' WHERE (' . implode(') AND (', $this->where) . ')';
89: }
90: $query .= " GROUP BY $column";
91: $aggregation = & $this->refTable->aggregation[$query];
92: if ($aggregation === NULL) {
93: $aggregation = array();
94: foreach ($this->query($query, $this->parameters) as $row) {
95: $aggregation[$row[$this->column]] = $row;
96: }
97: }
98:
99:
100: if (isset($aggregation[$this->active])) {
101: foreach ($aggregation[$this->active] as $val) {
102: return $val;
103: }
104: }
105: }
106:
107:
108:
109: public function count($column = '')
110: {
111: $return = parent::count($column);
112: return isset($return) ? $return : 0;
113: }
114:
115:
116:
117: public function insert($data)
118: {
119: if ($data instanceof Traversable && !$data instanceof TableSelection) {
120: $data = iterator_to_array($data);
121: }
122: if (is_array($data)) {
123: $data[$this->column] = $this->active;
124: }
125: return parent::insert($data);
126: }
127:
128:
129:
130: public function update($data)
131: {
132: $where = $this->where;
133: $this->where[0] = "$this->delimitedColumn = " . $this->connection->quote($this->active);
134: $return = parent::update($data);
135: $this->where = $where;
136: return $return;
137: }
138:
139:
140:
141: public function delete()
142: {
143: $where = $this->where;
144: $this->where[0] = "$this->delimitedColumn = " . $this->connection->quote($this->active);
145: $return = parent::delete();
146: $this->where = $where;
147: return $return;
148: }
149:
150:
151:
152: protected function execute()
153: {
154: if ($this->rows !== NULL) {
155: return;
156: }
157:
158: $referencing = & $this->refTable->referencing[$this->getSql()];
159: if ($referencing === NULL) {
160: $limit = $this->limit;
161: $rows = count($this->refTable->rows);
162: if ($this->limit && $rows > 1) {
163: $this->limit = NULL;
164: }
165: parent::execute();
166: $this->limit = $limit;
167: $referencing = array();
168: $offset = array();
169: foreach ($this->rows as $key => $row) {
170: $ref = & $referencing[$row[$this->column]];
171: $skip = & $offset[$row[$this->column]];
172: if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->offset)) {
173: $ref[$key] = $row;
174: } else {
175: unset($this->rows[$key]);
176: }
177: $skip++;
178: unset($ref, $skip);
179: }
180: }
181:
182: $this->data = & $referencing[$this->active];
183: if ($this->data === NULL) {
184: $this->data = array();
185: }
186: }
187:
188: }
189: