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

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