diff --git a/core/model/Translatable.php b/core/model/Translatable.php index f74fc6d81..5cd84cbb0 100755 --- a/core/model/Translatable.php +++ b/core/model/Translatable.php @@ -371,7 +371,7 @@ class Translatable extends DataObjectDecorator { * Determine if the DataObject has any own translatable field (not inherited). * @return boolean */ - function hasOwnFields() { + function hasOwnTranslatableFields() { $ownFields = $this->owner->stat('db'); if ($ownFields == singleton($this->owner->parentClass())->stat('db'))return false; foreach ((array)$this->translatableFields as $translatableField) { @@ -380,12 +380,23 @@ class Translatable extends DataObjectDecorator { return false; } + /** + * Determine if a table needs Versioned support + * This is called at db/build time + * + * @param string $table Table name + * @return boolean + */ + function isVersionedTable($table) { + // Every _lang table wants Versioned support + return ($this->owner->databaseFields() && $this->hasOwnTranslatableFields()); + } function augmentDatabase() { if (! $this->stat('enabled')) return false; Translatable::set_reading_lang(Translatable::default_lang()); $table = $this->owner->class; - if(($fields = $this->owner->databaseFields()) && $this->hasOwnFields()) { + if(($fields = $this->owner->databaseFields()) && $this->hasOwnTranslatableFields()) { //Calculate the required fields foreach ($fields as $field => $type) { if (array_search($field,$this->translatableFields) === false) unset($fields[$field]); @@ -432,13 +443,17 @@ class Translatable extends DataObjectDecorator { $SessionOrigID = Session::get($this->owner->ID.'_originalLangID'); $manipulation["{$table}_lang"]['fields']['OriginalLangID'] = $this->owner->ID = ( $SessionOrigID ? $SessionOrigID : Translatable::$creatingFromID); - $manipulation["{$table}_lang"]['fields']['Lang'] = "'$lang'" ; - //$manipulation["{$table}_lang"]['id'] = $manipulation["{$table}_lang"]['fields']['ID'] = DB::getNextID("{$table}_lang"); $manipulation["{$table}_lang"]['RecordID'] = $manipulation["{$table}_lang"]['fields']['OriginalLangID']; + // populate lang field + $manipulation["{$table}_lang"]['fields']['Lang'] = "'$lang'" ; + // get a valid id, pre-inserting + DB::query("INSERT INTO {$table}_lang SET Created = NOW(), Lang = '$lang'"); + $manipulation["{$table}_lang"]['id'] = $manipulation["{$table}_lang"]['fields']['ID'] = DB::getGeneratedID("{$table}_lang"); + $manipulation["{$table}_lang"]['command'] = 'update'; // we don't have to insert anything in $table if we are inserting in $table_lang unset($manipulation[$table]); - // now dataobjects create a record before the real write in the base table, so we have to delete it - 20/08/2007 - DB::query("DELETE FROM $table WHERE ID=$fakeID"); + // now dataobjects may create a record before the real write in the base table, so we have to delete it - 20/08/2007 + if (is_numeric($fakeID)) DB::query("DELETE FROM $table WHERE ID=$fakeID"); } else { if (!isset($manipulation[$table]['fields']['OriginalLangID'])) { @@ -582,7 +597,7 @@ class Translatable extends DataObjectDecorator { */ function fieldsInExtraTables($table){ - if(($fields = $this->owner->databaseFields()) && $this->hasOwnFields()) { + if(($fields = $this->owner->databaseFields()) && $this->hasOwnTranslatableFields()) { //Calculate the required fields foreach ($fields as $field => $type) { if (array_search($field,$this->translatableFields) === false) unset($fields[$field]); diff --git a/core/model/Versioned.php b/core/model/Versioned.php index 701d092ab..6f5b2a679 100755 --- a/core/model/Versioned.php +++ b/core/model/Versioned.php @@ -145,18 +145,19 @@ class Versioned extends DataObjectDecorator { if ($suffix) $table = "{$classTable}_$suffix"; else $table = $classTable; - $tableList = DB::tableList(); - if(($fields = $this->owner->databaseFields()) && isset($tableList[strtolower($table)])) { + if(($fields = $this->owner->databaseFields())) { $indexes = $this->owner->databaseIndexes(); if($this->owner->parentClass() == "DataObject") { $rootTable = true; } - if ($suffix) { - $fields = $this->owner->getExtension($allSuffixes[$suffix])->fieldsInExtraTables($suffix); + if ($suffix && ($ext = $this->owner->getExtension($allSuffixes[$suffix]))) { + if (!$ext->isVersionedTable($table)) continue; + $fields = $ext->fieldsInExtraTables($suffix); $indexes = $fields['indexes']; $fields = $fields['db']; - } + } else if (!$ext) continue; + // Create tables for other stages foreach($this->stages as $stage) { @@ -255,7 +256,7 @@ class Versioned extends DataObjectDecorator { // Add any extra, unchanged fields to the version record. $data = DB::query("SELECT * FROM $table WHERE ID = $id")->record(); if($data) foreach($data as $k => $v) { - $newManipulation['fields'][$k] = "'" . addslashes($v) . "'"; + if (!isset($newManipulation['fields'][$k])) $newManipulation['fields'][$k] = "'" . addslashes($v) . "'"; } // Set up a new entry in (table)_versions @@ -281,8 +282,7 @@ class Versioned extends DataObjectDecorator { // Putting a Version of -1 is a signal to leave the version table alone, despite their being no version if($manipulation[$table]['fields']['Version'] < 0) unset($manipulation[$table]['fields']['Version']); - // TODO : better check (canbeversioned?) - //if(get_parent_class($table) != "DataObject") unset($manipulation[$table]['fields']['Version']); + if(!$this->hasVersionField($table)) unset($manipulation[$table]['fields']['Version']); // Grab a version number - it should be the same across all tables. if(isset($manipulation[$table]['fields']['Version'])) $thisVersion = $manipulation[$table]['fields']['Version']; @@ -299,6 +299,12 @@ class Versioned extends DataObjectDecorator { if(isset($thisVersion)) $this->owner->Version = str_replace("'","",$thisVersion); } + /** + * Determine if a table is supporting the Versioned extensions (e.g. $table_versions does exists) + * + * @param string $table Table name + * @return boolean + */ function canBeVersioned($table) { $tableParts = explode('_',$table); @@ -318,6 +324,17 @@ class Versioned extends DataObjectDecorator { return true; } + /** + * Check if a certain table has the 'Version' field + * + * @param string $table Table name + * @return boolean Returns false if the field isn't in the table, true otherwise + */ + function hasVersionField($table) { + + $tableParts = explode('_',$table); + return ('DataObject' == get_parent_class($tableParts[0])); + } function extendWithSuffix($table) { foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) { if ($this->owner->hasExtension($versionableExtension)) {