Exemplo n.º 1
0
 /**
  * Save data to this table. If a primary key value is given, that row will be
  * updated; otherwise, a new row will be inserted.
  *
  * @param array  $data The data to insert.
  * @param string $pkValue The value of the record's PK. Null if the record doesn't exist.
  * @return \Tabulate\DB\Record The updated or inserted record.
  * @throws Exception If the user doesn't have permission, or something else has gone wrong.
  */
 public function saveRecord($data, $pkValue = null, $trackChanges = true)
 {
     // Changeset only created here if not already in progress.
     if ($trackChanges) {
         $changesetComment = isset($data['changeset_comment']) ? $data['changeset_comment'] : null;
         $changeTracker = new ChangeTracker($this->getDatabase(), $changesetComment);
     }
     $columns = $this->getColumns();
     /*
      * Go through all data and clean it up before saving.
      */
     $sqlValues = array();
     foreach ($data as $field => $value) {
         // Make sure this column exists in the DB.
         if (!isset($columns[$field])) {
             unset($data[$field]);
             continue;
         }
         $column = $this->getColumn($field);
         if ($column->isBoolean()) {
             // Boolean values.
             $zeroValues = array(0, '0', false, 'false', 'FALSE', 'off', 'OFF', 'no', 'NO');
             if ((null === $value || '' === $value) && $column->nullable()) {
                 $data[$field] = null;
             } elseif (in_array($value, $zeroValues, true)) {
                 $data[$field] = false;
             } else {
                 $data[$field] = true;
             }
             $sqlValues[$field] = ":{$field}";
         } elseif (!$column->allowsEmptyString() && '' === $value && $column->nullable()) {
             // Empty strings.
             $data[$field] = null;
             $sqlValues[$field] = ":{$field}";
         } elseif ('' === $value && $column->isAutoIncrement()) {
             $data[$field] = null;
             $sqlValues[$field] = ":{$field}";
         } elseif (is_null($value) && $column->nullable()) {
             // Nulls.
             $data[$field] = null;
             $sqlValues[$field] = ":{$field}";
         } elseif ($column->getType() === 'point') {
             // POINT columns.
             $sqlValues[$field] = "GeomFromText(:{$field})";
         } else {
             // Everything else.
             $sqlValues[$field] = ":{$field}";
         }
     }
     // Find the PK.
     $pkName = $this->getPkColumn()->getName();
     // Compile SQL for insert and update statements.
     $itemsForSetClause = array();
     foreach ($sqlValues as $field => $escd_datum) {
         $itemsForSetClause[] = "`{$field}` = {$escd_datum}";
     }
     $setClause = 'SET ' . join(', ', $itemsForSetClause);
     if (isset($changeTracker)) {
         $changeTracker->beforeSave($this, $data, $pkValue);
     }
     if (!empty($pkValue)) {
         // Update?
         // Check permission.
         if (!$this->getDatabase()->checkGrant(Grants::UPDATE, $this->getName())) {
             throw new \Exception('You do not have permission to update data in this table ' . $this->getName());
         }
         $data[$pkName] = $pkValue;
         $sql = 'UPDATE ' . $this->getName() . " {$setClause} WHERE `{$pkName}` = :{$pkName};";
         $this->database->query($sql, $data);
         $newPkValue = isset($data[$pkName]) ? $data[$pkName] : $pkValue;
     } else {
         // Or insert?
         // Check permission.
         if (!$this->getDatabase()->checkGrant(Grants::CREATE, $this->getName())) {
             throw new \Exception('You do not have permission to insert records into table ' . $this->getName());
         }
         $sql = 'INSERT INTO ' . $this->getName() . ' ' . $setClause . ';';
         $this->database->query($sql, $data);
         if ($this->getPkColumn()->isAutoIncrement()) {
             // Use the last insert ID.
             $newPkValue = $this->database->lastInsertId();
         } elseif (isset($data[$pkName])) {
             // Or the PK value provided in the data.
             $newPkValue = $data[$pkName];
         } else {
             // If neither of those work, how can we find out the new PK value?
             throw new \Exception("Unable to determine the value of the new record's prmary key.");
         }
     }
     $newRecord = $this->getRecord($newPkValue);
     if (!$newRecord instanceof Record) {
         throw new Exception("Unable to fetch record with PK of: <code>" . var_export($newPkValue, true) . '</code>');
     }
     // Save the changes.
     if (isset($changeTracker)) {
         $changeTracker->after_save($this, $newRecord);
     }
     // Show errors again, reset the record count,
     // and return the new or updated record.
     $this->recordCounter->clear();
     return $newRecord;
 }