public function save() { $Q = new ImpSQLBuilder($this->DBTable); foreach ($this->Properties as $P => $PropDef) { if (is_array($PropDef)) { $Type = $PropDef['type']; } else { $Type = $PropDef; } switch ($Type) { case 'collection': break; case 'timestamp': $Q->addValue($P, time(), 'time'); // CHANGED: timestamps are set to time() to avoid discrepancies between PHP and database timezones break; case 'datetime': case 'date': if ($P == 'Created' and $this->{$P} == 0) { // We automatically set the Created column if it's unset: $Q->addValue($P, time(), 'time'); } else { $Q->addValue($P, (int) $this->{$P}, 'time'); } break; case 'object': // Convert from a full object to its ID: if (!empty($this->{$P})) { $Q->addValue($P, is_object($this->{$P}) ? $this->{$P}->ID : (int) $this->{$P}); } else { $Q->addValue($P, false); } break; case 'boolean': // Convert from boolean true/false to 1/0 for a BIT column $Q->addValue($P, $this->{$P} ? 1 : 0); break; case 'set': // We convert from an array of key => true/false to a // comma separated string of the keys whose value was true. // This matches the way the MySQL SET column type // behaves. $Q->addValue($P, implode(',', array_keys(array_filter($this->{$P}))), 'set'); break; case 'enum': $Q->addValue($P, $this->{$P}, 'enum'); break; case 'integer': $Q->addValue($P, (int) $this->{$P}); break; case 'currency': $Q->addValue($P, (double) $this->{$P}); break; default: $Q->addValue($P, empty($this->{$P}) ? false : $this->{$P}); } } if (!empty($this->ID)) { if ($this->_trackChanges) { $this->recordChanges(); } $Q->addConstraint('ID=' . $this->ID); self::$DB->execute($Q->generateUpdate()); assert(self::$DB->getAffectedRowCount() <= 1); } else { self::$DB->execute($Q->generateInsert()); $this->ID = self::$DB->getLastInsertId(); } return true; }