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

Classes

  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://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 NTableRow extends NObject implements IteratorAggregate, ArrayAccess
 19: {
 20:     /** @var NTableSelection */
 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 NTableRow::update()} */
 30:     private $modified = array();
 31: 
 32: 
 33:     public function __construct(array $data, NTableSelection $table)
 34:     {
 35:         $this->data = $data;
 36:         $this->table = $table;
 37:     }
 38: 
 39: 
 40:     /**
 41:      * @internal
 42:      * @ignore
 43:      */
 44:     public function setTable(NTableSelection $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:             if (func_num_args()) {
 66:                 throw $e;
 67:             }
 68:             trigger_error("Exception in " . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
 69:         }
 70:     }
 71: 
 72: 
 73:     /**
 74:      * @return array
 75:      */
 76:     public function toArray()
 77:     {
 78:         $this->accessColumn(NULL);
 79:         return $this->data;
 80:     }
 81: 
 82: 
 83:     /**
 84:      * Returns primary key value.
 85:      * @param  bool
 86:      * @return mixed
 87:      */
 88:     public function getPrimary($need = TRUE)
 89:     {
 90:         $primary = $this->table->getPrimary($need);
 91:         if ($primary === NULL) {
 92:             return NULL;
 93: 
 94:         } elseif (!is_array($primary)) {
 95:             if (isset($this->data[$primary])) {
 96:                 return $this->data[$primary];
 97:             } elseif ($need) {
 98:                 throw new InvalidStateException("Row does not contain primary $primary column data.");
 99:             } else {
100:                 return NULL;
101:             }
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:      * Returns row signature (composition of primary keys)
122:      * @param  bool
123:      * @return string
124:      */
125:     public function getSignature($need = TRUE)
126:     {
127:         return implode('|', (array) $this->getPrimary($need));
128:     }
129: 
130: 
131:     /**
132:      * Returns referenced row.
133:      * @param  string
134:      * @param  string
135:      * @return NTableRow or NULL if the row does not exist
136:      */
137:     public function ref($key, $throughColumn = NULL)
138:     {
139:         if (!$throughColumn) {
140:             list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
141:         }
142: 
143:         return $this->getReference($key, $throughColumn);
144:     }
145: 
146: 
147:     /**
148:      * Returns referencing rows.
149:      * @param  string
150:      * @param  string
151:      * @return NGroupedTableSelection
152:      */
153:     public function related($key, $throughColumn = NULL)
154:     {
155:         if (strpos($key, '.') !== FALSE) {
156:             list($key, $throughColumn) = explode('.', $key);
157:         } elseif (!$throughColumn) {
158:             list($key, $throughColumn) = $this->table->getConnection()->getDatabaseReflection()->getHasManyReference($this->table->getName(), $key);
159:         }
160: 
161:         return $this->table->getReferencingTable($key, $throughColumn, $this[$this->table->getPrimary()]);
162:     }
163: 
164: 
165:     /**
166:      * Updates row.
167:      * @param  array or NULL for all modified values
168:      * @return int number of affected rows or FALSE in case of an error
169:      */
170:     public function update($data = NULL)
171:     {
172:         if ($data instanceof Traversable) {
173:             $data = iterator_to_array($data);
174:         }
175:         if ($data === NULL) {
176:             $data = $this->modified;
177:         }
178:         return $this->table->getConnection()
179:             ->table($this->table->getName())
180:             ->wherePrimary($this->getPrimary())
181:             ->update($data);
182:     }
183: 
184: 
185:     /**
186:      * Deletes row.
187:      * @return int number of affected rows or FALSE in case of an error
188:      */
189:     public function delete()
190:     {
191:         $res = $this->table->getConnection()
192:             ->table($this->table->getName())
193:             ->wherePrimary($this->getPrimary())
194:             ->delete();
195: 
196:         if ($res > 0 && ($signature = $this->getSignature(FALSE))) {
197:             unset($this->table[$signature]);
198:         }
199: 
200:         return $res;
201:     }
202: 
203: 
204:     /********************* interface IteratorAggregate ****************d*g**/
205: 
206: 
207:     public function getIterator()
208:     {
209:         $this->accessColumn(NULL);
210:         return new ArrayIterator($this->data);
211:     }
212: 
213: 
214:     /********************* interface ArrayAccess & magic accessors ****************d*g**/
215: 
216: 
217:     /**
218:      * Stores value in column.
219:      * @param  string column name
220:      * @param  string value
221:      * @return void
222:      */
223:     public function offsetSet($key, $value)
224:     {
225:         $this->__set($key, $value);
226:     }
227: 
228: 
229:     /**
230:      * Returns value of column.
231:      * @param  string column name
232:      * @return string
233:      */
234:     public function offsetGet($key)
235:     {
236:         return $this->__get($key);
237:     }
238: 
239: 
240:     /**
241:      * Tests if column exists.
242:      * @param  string column name
243:      * @return bool
244:      */
245:     public function offsetExists($key)
246:     {
247:         return $this->__isset($key);
248:     }
249: 
250: 
251:     /**
252:      * Removes column from data.
253:      * @param  string column name
254:      * @return void
255:      */
256:     public function offsetUnset($key)
257:     {
258:         $this->__unset($key);
259:     }
260: 
261: 
262:     public function __set($key, $value)
263:     {
264:         $this->data[$key] = $value;
265:         $this->modified[$key] = $value;
266:     }
267: 
268: 
269:     public function &__get($key)
270:     {
271:         $this->accessColumn($key);
272:         if (array_key_exists($key, $this->data)) {
273:             return $this->data[$key];
274:         }
275: 
276:         try {
277:             list($table, $column) = $this->table->getConnection()->getDatabaseReflection()->getBelongsToReference($this->table->getName(), $key);
278:             $referenced = $this->getReference($table, $column);
279:             if ($referenced !== FALSE) {
280:                 $this->accessColumn($key, FALSE);
281:                 return $referenced;
282:             }
283:         } catch(NMissingReferenceException $e) {}
284: 
285:         $this->removeAccessColumn($key);
286:         throw new MemberAccessException("Cannot read an undeclared column '$key'.");
287:     }
288: 
289: 
290:     public function __isset($key)
291:     {
292:         $this->accessColumn($key);
293:         if (array_key_exists($key, $this->data)) {
294:             return isset($this->data[$key]);
295:         }
296:         $this->removeAccessColumn($key);
297:         return FALSE;
298:     }
299: 
300: 
301:     public function __unset($key)
302:     {
303:         unset($this->data[$key]);
304:         unset($this->modified[$key]);
305:     }
306: 
307: 
308:     protected function accessColumn($key, $selectColumn = TRUE)
309:     {
310:         if (isset($this->modified[$key])) {
311:             return;
312:         }
313: 
314:         $this->table->accessColumn($key, $selectColumn);
315:         if ($this->table->getDataRefreshed() && !$this->dataRefreshed) {
316:             $this->data = $this->table[$this->getSignature()]->data;
317:             $this->dataRefreshed = TRUE;
318:         }
319:     }
320: 
321: 
322:     protected function removeAccessColumn($key)
323:     {
324:         $this->table->removeAccessColumn($key);
325:     }
326: 
327: 
328:     protected function getReference($table, $column)
329:     {
330:         $this->accessColumn($column);
331:         if (array_key_exists($column, $this->data)) {
332:             $value = $this->data[$column];
333:             $value = $value instanceof NTableRow ? $value->getPrimary() : $value;
334: 
335:             $referenced = $this->table->getReferencedTable($table, $column, !empty($this->modified[$column]));
336:             $referenced = isset($referenced[$value]) ? $referenced[$value] : NULL; // referenced row may not exist
337: 
338:             if (!empty($this->modified[$column])) { // cause saving changed column and prevent regenerating referenced table for $column
339:                 $this->modified[$column] = 0; // 0 fails on empty, pass on isset
340:             }
341: 
342:             return $referenced;
343:         }
344: 
345:         return FALSE;
346:     }
347: 
348: }
349: 
Nette Framework 2.0.18 (for PHP 5.2, prefixed) API documentation generated by ApiGen 2.8.0