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 array of new values {@see NTableRow::update()} */
 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:      * @internal
 45:      * @ignore
 46:      */
 47:     public function setTable(NTableSelection $table)
 48:     {
 49:         $this->table = $table;
 50:     }
 51: 
 52: 
 53: 
 54:     /**
 55:      * @internal
 56:      * @ignore
 57:      */
 58:     public function getTable()
 59:     {
 60:         return $this->table;
 61:     }
 62: 
 63: 
 64: 
 65:     public function __toString()
 66:     {
 67:         try {
 68:             return (string) $this->getPrimary();
 69:         } catch (Exception $e) {
 70:             trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
 71:         }
 72:     }
 73: 
 74: 
 75: 
 76:     /**
 77:      * @return array
 78:      */
 79:     public function toArray()
 80:     {
 81:         $this->access(NULL);
 82:         return $this->data;
 83:     }
 84: 
 85: 
 86: 
 87:     /**
 88:      * Returns primary key value.
 89:      * @param  bool
 90:      * @return mixed
 91:      */
 92:     public function getPrimary($need = TRUE)
 93:     {
 94:         $primary = $this->table->getPrimary();
 95:         if (!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:         } else {
104:             $primaryVal = array();
105:             foreach ($primary as $key) {
106:                 if (!isset($this->data[$key])) {
107:                     if ($need) {
108:                         throw new InvalidStateException("Row does not contain primary $key column data.");
109:                     } else {
110:                         return NULL;
111:                     }
112:                 }
113:                 $primaryVal[$key] = $this->data[$key];
114:             }
115:             return $primaryVal;
116:         }
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:     /**
134:      * Returns referenced row.
135:      * @param  string
136:      * @param  string
137:      * @return NTableRow or NULL if the row does not exist
138:      */
139:     public function ref($key, $throughColumn = NULL)
140:     {
141:         if (!$throughColumn) {
142:             list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
143:         }
144: 
145:         return $this->getReference($key, $throughColumn);
146:     }
147: 
148: 
149: 
150:     /**
151:      * Returns referencing rows.
152:      * @param  string
153:      * @param  string
154:      * @return NGroupedTableSelection
155:      */
156:     public function related($key, $throughColumn = NULL)
157:     {
158:         if (strpos($key, '.') !== FALSE) {
159:             list($key, $throughColumn) = explode('.', $key);
160:         } elseif (!$throughColumn) {
161:             list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getHasManyReference($this->table->getName(), $key);
162:         }
163: 
164:         return $this->table->getReferencingTable($key, $throughColumn, $this[$this->table->getPrimary()]);
165:     }
166: 
167: 
168: 
169:     /**
170:      * Updates row.
171:      * @param  array or NULL for all modified values
172:      * @return int number of affected rows or FALSE in case of an error
173:      */
174:     public function update($data = NULL)
175:     {
176:         if ($data === NULL) {
177:             $data = $this->modified;
178:         }
179:         return $this->table->getConnection()
180:             ->table($this->table->getName())
181:             ->find($this->getPrimary())
182:             ->update($data);
183:     }
184: 
185: 
186: 
187:     /**
188:      * Deletes row.
189:      * @return int number of affected rows or FALSE in case of an error
190:      */
191:     public function delete()
192:     {
193:         $res = $this->table->getConnection()
194:             ->table($this->table->getName())
195:             ->find($this->getPrimary())
196:             ->delete();
197: 
198:         if ($res > 0 && ($signature = $this->getSignature(FALSE))) {
199:             unset($this->table[$signature]);
200:         }
201: 
202:         return $res;
203:     }
204: 
205: 
206: 
207:     /********************* interface IteratorAggregate ****************d*g**/
208: 
209: 
210: 
211:     public function getIterator()
212:     {
213:         $this->access(NULL);
214:         return new ArrayIterator($this->data);
215:     }
216: 
217: 
218: 
219:     /********************* interface ArrayAccess & magic accessors ****************d*g**/
220: 
221: 
222: 
223:     /**
224:      * Stores value in column.
225:      * @param  string column name
226:      * @param  string value
227:      * @return void
228:      */
229:     public function offsetSet($key, $value)
230:     {
231:         $this->__set($key, $value);
232:     }
233: 
234: 
235: 
236:     /**
237:      * Returns value of column.
238:      * @param  string column name
239:      * @return string
240:      */
241:     public function offsetGet($key)
242:     {
243:         return $this->__get($key);
244:     }
245: 
246: 
247: 
248:     /**
249:      * Tests if column exists.
250:      * @param  string column name
251:      * @return bool
252:      */
253:     public function offsetExists($key)
254:     {
255:         return $this->__isset($key);
256:     }
257: 
258: 
259: 
260:     /**
261:      * Removes column from data.
262:      * @param  string column name
263:      * @return void
264:      */
265:     public function offsetUnset($key)
266:     {
267:         $this->__unset($key);
268:     }
269: 
270: 
271: 
272:     public function __set($key, $value)
273:     {
274:         $this->data[$key] = $value;
275:         $this->modified[$key] = $value;
276:     }
277: 
278: 
279: 
280:     public function &__get($key)
281:     {
282:         $this->access($key);
283:         if (array_key_exists($key, $this->data)) {
284:             return $this->data[$key];
285:         }
286: 
287:         list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
288:         $referenced = $this->getReference($table, $column);
289:         if ($referenced !== FALSE) {
290:             $this->access($key, FALSE);
291:             return $referenced;
292:         }
293: 
294:         $this->access($key, NULL);
295:         throw new MemberAccessException("Cannot read an undeclared column \"$key\".");
296:     }
297: 
298: 
299: 
300:     public function __isset($key)
301:     {
302:         $this->access($key);
303:         if (array_key_exists($key, $this->data)) {
304:             return isset($this->data[$key]);
305:         }
306:         $this->access($key, NULL);
307:         return FALSE;
308:     }
309: 
310: 
311: 
312:     public function __unset($key)
313:     {
314:         unset($this->data[$key]);
315:         unset($this->modified[$key]);
316:     }
317: 
318: 
319: 
320:     /**
321:      * @internal
322:      */
323:     public function access($key, $cache = TRUE)
324:     {
325:         if ($this->table->getConnection()->getCache() && !isset($this->modified[$key]) && $this->table->access($key, $cache)) {
326:             $this->data = $this->table[$this->getSignature()]->data;
327:         }
328:     }
329: 
330: 
331: 
332:     protected function getReference($table, $column)
333:     {
334:         if (array_key_exists($column, $this->data)) {
335:             $this->access($column);
336: 
337:             $value = $this->data[$column];
338:             $value = $value instanceof NTableRow ? $value->getPrimary() : $value;
339: 
340:             $referenced = $this->table->getReferencedTable($table, $column, !empty($this->modified[$column]));
341:             $referenced = isset($referenced[$value]) ? $referenced[$value] : NULL; // referenced row may not exist
342: 
343:             if (!empty($this->modified[$column])) { // cause saving changed column and prevent regenerating referenced table for $column
344:                 $this->modified[$column] = 0; // 0 fails on empty, pass on isset
345:             }
346: 
347:             return $referenced;
348:         }
349: 
350:         return FALSE;
351:     }
352: 
353: }
354: 
Nette Framework 2.0.7 (for PHP 5.2, prefixed) API API documentation generated by ApiGen 2.8.0