Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

Classes

  • ActiveRow
  • GroupedSelection
  • Selection
  • SqlBuilder

Interfaces

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