Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • GroupedTableSelection
  • SqlBuilder
  • TableRow
  • TableSelection
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  * @package Nette\Database\Table
  7:  */
  8: 
  9: 
 10: 
 11: /**
 12:  * Single row representation.
 13:  * ActiveRow is based on the great library NotORM http://www.notorm.com written by Jakub Vrana.
 14:  *
 15:  * @author     Jakub Vrana
 16:  * @package Nette\Database\Table
 17:  */
 18: class TableRow extends Object implements IteratorAggregate, ArrayAccess
 19: {
 20:     /** @var TableSelection */
 21:     private $table;
 22: 
 23:     /** @var array of row data */
 24:     private $data;
 25: 
 26:     /** @var bool */
 27:     private $dataRefreshed = FALSE;
 28: 
 29:     /** @var array of new values {@see TableRow::update()} */
 30:     private $modified = array();
 31: 
 32: 
 33:     public function __construct(array $data, TableSelection $table)
 34:     {
 35:         $this->data = $data;
 36:         $this->table = $table;
 37:     }
 38: 
 39: 
 40:     /**
 41:      * @internal
 42:      * @ignore
 43:      */
 44:     public function setTable(TableSelection $table)
 45:     {
 46:         $this->table = $table;
 47:     }
 48: 
 49: 
 50:     /**
 51:      * @internal
 52:      * @ignore
 53:      */
 54:     public function getTable()
 55:     {
 56:         return $this->table;
 57:     }
 58: 
 59: 
 60:     public function __toString()
 61:     {
 62:         try {
 63:             return (string) $this->getPrimary();
 64:         } catch (Exception $e) {
 65:             trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
 66:         }
 67:     }
 68: 
 69: 
 70:     /**
 71:      * @return array
 72:      */
 73:     public function toArray()
 74:     {
 75:         $this->accessColumn(NULL);
 76:         return $this->data;
 77:     }
 78: 
 79: 
 80:     /**
 81:      * Returns primary key value.
 82:      * @param  bool
 83:      * @return mixed
 84:      */
 85:     public function getPrimary($need = TRUE)
 86:     {
 87:         $primary = $this->table->getPrimary($need);
 88:         if ($primary === NULL) {
 89:             return NULL;
 90: 
 91:         } elseif (!is_array($primary)) {
 92:             if (isset($this->data[$primary])) {
 93:                 return $this->data[$primary];
 94:             } elseif ($need) {
 95:                 throw new InvalidStateException("Row does not contain primary $primary column data.");
 96:             } else {
 97:                 return NULL;
 98:             }
 99: 
100:         } else {
101:             $primaryVal = array();
102:             foreach ($primary as $key) {
103:                 if (!isset($this->data[$key])) {
104:                     if ($need) {
105:                         throw new InvalidStateException("Row does not contain primary $key column data.");
106:                     } else {
107:                         return NULL;
108:                     }
109:                 }
110:                 $primaryVal[$key] = $this->data[$key];
111:             }
112:             return $primaryVal;
113:         }
114:     }
115: 
116: 
117:     /**
118:      * Returns row signature (composition of primary keys)
119:      * @param  bool
120:      * @return string
121:      */
122:     public function getSignature($need = TRUE)
123:     {
124:         return implode('|', (array) $this->getPrimary($need));
125:     }
126: 
127: 
128:     /**
129:      * Returns referenced row.
130:      * @param  string
131:      * @param  string
132:      * @return TableRow or NULL if the row does not exist
133:      */
134:     public function ref($key, $throughColumn = NULL)
135:     {
136:         if (!$throughColumn) {
137:             list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
138:         }
139: 
140:         return $this->getReference($key, $throughColumn);
141:     }
142: 
143: 
144:     /**
145:      * Returns referencing rows.
146:      * @param  string
147:      * @param  string
148:      * @return GroupedTableSelection
149:      */
150:     public function related($key, $throughColumn = NULL)
151:     {
152:         if (strpos($key, '.') !== FALSE) {
153:             list($key, $throughColumn) = explode('.', $key);
154:         } elseif (!$throughColumn) {
155:             list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getHasManyReference($this->table->getName(), $key);
156:         }
157: 
158:         return $this->table->getReferencingTable($key, $throughColumn, $this[$this->table->getPrimary()]);
159:     }
160: 
161: 
162:     /**
163:      * Updates row.
164:      * @param  array or NULL for all modified values
165:      * @return int number of affected rows or FALSE in case of an error
166:      */
167:     public function update($data = NULL)
168:     {
169:         if ($data instanceof Traversable) {
170:             $data = iterator_to_array($data);
171:         }
172:         if ($data === NULL) {
173:             $data = $this->modified;
174:         }
175:         return $this->table->getConnection()
176:             ->table($this->table->getName())
177:             ->wherePrimary($this->getPrimary())
178:             ->update($data);
179:     }
180: 
181: 
182:     /**
183:      * Deletes row.
184:      * @return int number of affected rows or FALSE in case of an error
185:      */
186:     public function delete()
187:     {
188:         $res = $this->table->getConnection()
189:             ->table($this->table->getName())
190:             ->wherePrimary($this->getPrimary())
191:             ->delete();
192: 
193:         if ($res > 0 && ($signature = $this->getSignature(FALSE))) {
194:             unset($this->table[$signature]);
195:         }
196: 
197:         return $res;
198:     }
199: 
200: 
201:     /********************* interface IteratorAggregate ****************d*g**/
202: 
203: 
204:     public function getIterator()
205:     {
206:         $this->accessColumn(NULL);
207:         return new ArrayIterator($this->data);
208:     }
209: 
210: 
211:     /********************* interface ArrayAccess & magic accessors ****************d*g**/
212: 
213: 
214:     /**
215:      * Stores value in column.
216:      * @param  string column name
217:      * @param  string value
218:      * @return void
219:      */
220:     public function offsetSet($key, $value)
221:     {
222:         $this->__set($key, $value);
223:     }
224: 
225: 
226:     /**
227:      * Returns value of column.
228:      * @param  string column name
229:      * @return string
230:      */
231:     public function offsetGet($key)
232:     {
233:         return $this->__get($key);
234:     }
235: 
236: 
237:     /**
238:      * Tests if column exists.
239:      * @param  string column name
240:      * @return bool
241:      */
242:     public function offsetExists($key)
243:     {
244:         return $this->__isset($key);
245:     }
246: 
247: 
248:     /**
249:      * Removes column from data.
250:      * @param  string column name
251:      * @return void
252:      */
253:     public function offsetUnset($key)
254:     {
255:         $this->__unset($key);
256:     }
257: 
258: 
259:     public function __set($key, $value)
260:     {
261:         $this->data[$key] = $value;
262:         $this->modified[$key] = $value;
263:     }
264: 
265: 
266:     public function &__get($key)
267:     {
268:         $this->accessColumn($key);
269:         if (array_key_exists($key, $this->data)) {
270:             return $this->data[$key];
271:         }
272: 
273:         try {
274:             list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
275:             $referenced = $this->getReference($table, $column);
276:             if ($referenced !== FALSE) {
277:                 $this->accessColumn($key, FALSE);
278:                 return $referenced;
279:             }
280:         } catch(MissingReferenceException $e) {}
281: 
282:         $this->removeAccessColumn($key);
283:         throw new MemberAccessException("Cannot read an undeclared column \"$key\".");
284:     }
285: 
286: 
287:     public function __isset($key)
288:     {
289:         $this->accessColumn($key);
290:         if (array_key_exists($key, $this->data)) {
291:             return isset($this->data[$key]);
292:         }
293:         $this->removeAccessColumn($key);
294:         return FALSE;
295:     }
296: 
297: 
298:     public function __unset($key)
299:     {
300:         unset($this->data[$key]);
301:         unset($this->modified[$key]);
302:     }
303: 
304: 
305:     protected function accessColumn($key, $selectColumn = TRUE)
306:     {
307:         if (isset($this->modified[$key])) {
308:             return;
309:         }
310: 
311:         $this->table->accessColumn($key, $selectColumn);
312:         if ($this->table->getDataRefreshed() && !$this->dataRefreshed) {
313:             $this->data = $this->table[$this->getSignature()]->data;
314:             $this->dataRefreshed = TRUE;
315:         }
316:     }
317: 
318: 
319:     protected function removeAccessColumn($key)
320:     {
321:         $this->table->removeAccessColumn($key);
322:     }
323: 
324: 
325:     protected function getReference($table, $column)
326:     {
327:         $this->accessColumn($column);
328:         if (array_key_exists($column, $this->data)) {
329:             $value = $this->data[$column];
330:             $value = $value instanceof TableRow ? $value->getPrimary() : $value;
331: 
332:             $referenced = $this->table->getReferencedTable($table, $column, !empty($this->modified[$column]));
333:             $referenced = isset($referenced[$value]) ? $referenced[$value] : NULL; // referenced row may not exist
334: 
335:             if (!empty($this->modified[$column])) { // cause saving changed column and prevent regenerating referenced table for $column
336:                 $this->modified[$column] = 0; // 0 fails on empty, pass on isset
337:             }
338: 
339:             return $referenced;
340:         }
341: 
342:         return FALSE;
343:     }
344: 
345: }
346: 
Nette Framework 2.0.14 (for PHP 5.2, un-prefixed) API API documentation generated by ApiGen 2.8.0