1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21:
22: class NTableRow extends NObject implements IteratorAggregate, ArrayAccess
23: {
24:
25: private $table;
26:
27:
28: private $data;
29:
30:
31: private $modified = array();
32:
33:
34:
35: public function __construct(array $data, NTableSelection $table)
36: {
37: $this->data = $data;
38: $this->table = $table;
39: }
40:
41:
42:
43: public function __toString()
44: {
45: try {
46: return (string) $this->getPrimary();
47: } catch (Exception $e) {
48: NDebugger::toStringException($e);
49: }
50: }
51:
52:
53:
54: 55: 56:
57: public function toArray()
58: {
59: $this->access(NULL);
60: return $this->data;
61: }
62:
63:
64:
65: 66: 67: 68:
69: public function getPrimary()
70: {
71: if (!isset($this->data[$this->table->getPrimary()])) {
72: throw new NotSupportedException("Table {$this->table->getName()} does not have any primary key.");
73: }
74: return $this[$this->table->getPrimary()];
75: }
76:
77:
78:
79: 80: 81: 82: 83: 84:
85: public function ref($key, $throughColumn = NULL)
86: {
87: list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
88: $column = ($tmp=$throughColumn) ? $tmp : $column;
89: return $this->getReference($table, $column);
90: }
91:
92:
93:
94: 95: 96: 97: 98: 99:
100: public function related($key, $throughColumn = NULL)
101: {
102: if (strpos($key, '.') !== FALSE) {
103: list($key, $throughColumn) = explode('.', $key);
104: }
105:
106: list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getHasManyReference($this->table->getName(), $key);
107: return $this->table->getReferencingTable($table, ($tmp=$throughColumn) ? $tmp : $column, $this[$this->table->getPrimary()]);
108: }
109:
110:
111:
112: 113: 114: 115: 116:
117: public function update($data = NULL)
118: {
119: if ($data === NULL) {
120: $data = $this->modified;
121: }
122: return $this->table->getConnection()->table($this->table->getName())
123: ->where($this->table->getPrimary(), $this[$this->table->getPrimary()])
124: ->update($data);
125: }
126:
127:
128:
129: 130: 131: 132:
133: public function delete()
134: {
135: return $this->table->getConnection()->table($this->table->getName())
136: ->where($this->table->getPrimary(), $this[$this->table->getPrimary()])
137: ->delete();
138: }
139:
140:
141:
142:
143:
144:
145:
146: public function getIterator()
147: {
148: $this->access(NULL);
149: return new ArrayIterator($this->data);
150: }
151:
152:
153:
154:
155:
156:
157:
158: 159: 160: 161: 162:
163: public function offsetSet($key, $value)
164: {
165: $this->__set($key, $value);
166: }
167:
168:
169:
170: 171: 172: 173: 174:
175: public function offsetGet($key)
176: {
177: return $this->__get($key);
178: }
179:
180:
181:
182: 183: 184: 185: 186:
187: public function offsetExists($key)
188: {
189: return $this->__isset($key);
190: }
191:
192:
193:
194: 195: 196: 197: 198:
199: public function offsetUnset($key)
200: {
201: $this->__unset($key);
202: }
203:
204:
205:
206: public function __set($key, $value)
207: {
208: $this->data[$key] = $value;
209: $this->modified[$key] = $value;
210: }
211:
212:
213:
214: public function &__get($key)
215: {
216: $this->access($key);
217: if (array_key_exists($key, $this->data)) {
218: return $this->data[$key];
219: }
220: $this->access($key, TRUE);
221:
222: list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
223: $referenced = $this->getReference($table, $column);
224: if ($referenced !== FALSE) {
225: return $referenced;
226: }
227:
228: throw new MemberAccessException("Cannot read an undeclared column \"$key\".");
229: }
230:
231:
232:
233: public function __isset($key)
234: {
235: $this->access($key);
236: if (array_key_exists($key, $this->data)) {
237: return isset($this->data[$key]);
238: }
239: $this->access($key, TRUE);
240: return FALSE;
241: }
242:
243:
244:
245: public function __unset($key)
246: {
247: unset($this->data[$key]);
248: unset($this->modified[$key]);
249: }
250:
251:
252:
253: public function access($key, $delete = FALSE)
254: {
255: if ($this->table->getConnection()->getCache() && !isset($this->modified[$key]) && $this->table->access($key, $delete)) {
256: $id = (isset($this->data[$this->table->getPrimary()]) ? $this->data[$this->table->getPrimary()] : $this->data);
257: $this->data = $this->table[$id]->data;
258: }
259: }
260:
261:
262:
263: protected function getReference($table, $column)
264: {
265: if (array_key_exists($column, $this->data)) {
266: $this->access($column);
267:
268: $value = $this->data[$column];
269: $value = $value instanceof NTableRow ? $value->getPrimary() : $value;
270:
271: $referenced = $this->table->getReferencedTable($table, $column, !empty($this->modified[$column]));
272: $referenced = isset($referenced[$value]) ? $referenced[$value] : NULL;
273:
274: if (!empty($this->modified[$column])) {
275: $this->modified[$column] = 0;
276: }
277:
278: return $referenced;
279: }
280:
281: return FALSE;
282: }
283:
284: }
285: