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