1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21:
22: class TableRow extends Object 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, TableSelection $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: Debugger::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:
114: public function related($key, $throughColumn = NULL, $forceNewInstance = FALSE)
115: {
116: if (strpos($key, '.') !== FALSE) {
117: list($key, $throughColumn) = explode('.', $key);
118: } elseif (!is_string($throughColumn)) {
119: list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getHasManyReference($this->table->getName(), $key);
120: }
121:
122: return $this->table->getReferencingTable($key, $throughColumn, $this[$this->table->getPrimary()], $forceNewInstance);
123: }
124:
125:
126:
127: 128: 129: 130: 131:
132: public function update($data = NULL)
133: {
134: if ($data === NULL) {
135: $data = $this->modified;
136: }
137: return $this->table->getConnection()->table($this->table->getName())
138: ->where($this->table->getPrimary(), $this[$this->table->getPrimary()])
139: ->update($data);
140: }
141:
142:
143:
144: 145: 146: 147:
148: public function delete()
149: {
150: return $this->table->getConnection()->table($this->table->getName())
151: ->where($this->table->getPrimary(), $this[$this->table->getPrimary()])
152: ->delete();
153: }
154:
155:
156:
157:
158:
159:
160:
161: public function getIterator()
162: {
163: $this->access(NULL);
164: return new ArrayIterator($this->data);
165: }
166:
167:
168:
169:
170:
171:
172:
173: 174: 175: 176: 177: 178:
179: public function offsetSet($key, $value)
180: {
181: $this->__set($key, $value);
182: }
183:
184:
185:
186: 187: 188: 189: 190:
191: public function offsetGet($key)
192: {
193: return $this->__get($key);
194: }
195:
196:
197:
198: 199: 200: 201: 202:
203: public function offsetExists($key)
204: {
205: return $this->__isset($key);
206: }
207:
208:
209:
210: 211: 212: 213: 214:
215: public function offsetUnset($key)
216: {
217: $this->__unset($key);
218: }
219:
220:
221:
222: public function __set($key, $value)
223: {
224: $this->data[$key] = $value;
225: $this->modified[$key] = $value;
226: }
227:
228:
229:
230: public function &__get($key)
231: {
232: $this->access($key);
233: if (array_key_exists($key, $this->data)) {
234: return $this->data[$key];
235: }
236:
237: list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
238: $referenced = $this->getReference($table, $column);
239: if ($referenced !== FALSE) {
240: $this->access($key, FALSE);
241: return $referenced;
242: }
243:
244: $this->access($key, NULL);
245: throw new MemberAccessException("Cannot read an undeclared column \"$key\".");
246: }
247:
248:
249:
250: public function __isset($key)
251: {
252: $this->access($key);
253: if (array_key_exists($key, $this->data)) {
254: return isset($this->data[$key]);
255: }
256: $this->access($key, NULL);
257: return FALSE;
258: }
259:
260:
261:
262: public function __unset($key)
263: {
264: unset($this->data[$key]);
265: unset($this->modified[$key]);
266: }
267:
268:
269:
270: 271: 272:
273: public function access($key, $cache = TRUE)
274: {
275: if ($this->table->getConnection()->getCache() && !isset($this->modified[$key]) && $this->table->access($key, $cache)) {
276: $id = (isset($this->data[$this->table->getPrimary()]) ? $this->data[$this->table->getPrimary()] : $this->data);
277: $this->data = $this->table[$id]->data;
278: }
279: }
280:
281:
282:
283: protected function getReference($table, $column)
284: {
285: if (array_key_exists($column, $this->data)) {
286: $this->access($column);
287:
288: $value = $this->data[$column];
289: $value = $value instanceof TableRow ? $value->getPrimary() : $value;
290:
291: $referenced = $this->table->getReferencedTable($table, $column, !empty($this->modified[$column]));
292: $referenced = isset($referenced[$value]) ? $referenced[$value] : NULL;
293:
294: if (!empty($this->modified[$column])) {
295: $this->modified[$column] = 0;
296: }
297:
298: return $referenced;
299: }
300:
301: return FALSE;
302: }
303:
304: }
305: