1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21:
22: class NGroupedTableSelection extends NTableSelection
23: {
24:
25: private $refTable;
26:
27:
28: private $column;
29:
30:
31: private $delimitedColumn;
32:
33:
34: private $active;
35:
36:
37:
38: public function __construct($name, NTableSelection $refTable, $column, $active = NULL)
39: {
40: parent::__construct($name, $refTable->connection);
41: $this->refTable = $refTable;
42: $this->column = $column;
43: $this->delimitedColumn = $this->connection->getSupplementalDriver()->delimite($this->column);
44: $this->active = $active;
45: }
46:
47:
48:
49:
50: public function through($column)
51: {
52: trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::related("' . $this->name . '", "' . $column . '") instead.', E_USER_WARNING);
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: $aggregation = & $this->refTable->aggregation[$function . implode('', $this->where) . implode('', $this->conditions)];
84: if ($aggregation === NULL) {
85: $aggregation = array();
86:
87: $selection = new NTableSelection($this->name, $this->connection);
88: $selection->where = $this->where;
89: $selection->parameters = $this->parameters;
90: $selection->conditions = $this->conditions;
91:
92: $selection->select($function);
93: $selection->select("{$this->name}.{$this->column}");
94: $selection->group("{$this->name}.{$this->column}");
95:
96: foreach ($selection as $row) {
97: $aggregation[$row[$this->column]] = $row;
98: }
99: }
100:
101: if (isset($aggregation[$this->active])) {
102: foreach ($aggregation[$this->active] as $val) {
103: return $val;
104: }
105: }
106: }
107:
108:
109:
110: public function count($column = '')
111: {
112: $return = parent::count($column);
113: return isset($return) ? $return : 0;
114: }
115:
116:
117:
118: public function insert($data)
119: {
120: if ($data instanceof Traversable && !$data instanceof NTableSelection) {
121: $data = iterator_to_array($data);
122: }
123:
124: if (NValidators::isList($data)) {
125: foreach (array_keys($data) as $key) {
126: $data[$key][$this->column] = $this->active;
127: }
128: } else {
129: $data[$this->column] = $this->active;
130: }
131:
132: return parent::insert($data);
133: }
134:
135:
136:
137: public function update($data)
138: {
139: $condition = array($this->where, $this->parameters);
140:
141: $this->where[0] = "$this->delimitedColumn = ?";
142: $this->parameters[0] = $this->active;
143: $return = parent::update($data);
144:
145: list($this->where, $this->parameters) = $condition;
146: return $return;
147: }
148:
149:
150:
151: public function delete()
152: {
153: $condition = array($this->where, $this->parameters);
154:
155: $this->where[0] = "$this->delimitedColumn = ?";
156: $this->parameters[0] = $this->active;
157: $return = parent::delete();
158:
159: list($this->where, $this->parameters) = $condition;
160: return $return;
161: }
162:
163:
164:
165: protected function execute()
166: {
167: if ($this->rows !== NULL) {
168: return;
169: }
170:
171: $hash = md5($this->getSql() . json_encode($this->parameters));
172: $referencing = & $this->refTable->referencing[$hash];
173: if ($referencing === NULL) {
174: $limit = $this->limit;
175: $rows = count($this->refTable->rows);
176: if ($this->limit && $rows > 1) {
177: $this->limit = NULL;
178: }
179: parent::execute();
180: $this->limit = $limit;
181: $referencing = array();
182: $offset = array();
183: foreach ($this->rows as $key => $row) {
184: $ref = & $referencing[$row[$this->column]];
185: $skip = & $offset[$row[$this->column]];
186: if ($limit === NULL || $rows <= 1 || (count($ref) < $limit && $skip >= $this->offset)) {
187: $ref[$key] = $row;
188: } else {
189: unset($this->rows[$key]);
190: }
191: $skip++;
192: unset($ref, $skip);
193: }
194: }
195:
196: $this->data = & $referencing[$this->active];
197: if ($this->data === NULL) {
198: $this->data = array();
199: } else {
200: reset($this->data);
201: }
202: }
203:
204: }
205: