Namespaces

  • 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

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