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