/** * Copy one object into another including has-one fields * * @param DataObject $copyFrom * @param DataObject $newObject * @param Boolean $overwriteValues - overwrite values that exist * * @return CopyFactory */ public function copyObject($copyFrom, $newObject, $overwriteValues = true) { //get ignore fields if ($newObject->hasMethod("getIgnoreInCopyFields")) { $this->setIgnoreFields($newObject->getIgnoreInCopyFields()); } elseif ($array = Config::inst()->get($newObject->ClassName, "ignore_in_copy_fields")) { if (is_array($array) && count($array)) { $this->setIgnoreFields($array); } } //get copy field $this->addIgnoreField($newObject->CopyFromFieldName($withID = true)); $this->addIgnoreField($newObject->CopiedFromFieldName($withID = true)); //get copy-able fields $dbFields = Config::inst()->get($copyFrom->ClassName, "db"); $hasOneFields = Config::inst()->get($copyFrom->ClassName, "has_one"); //has-one fields fixup foreach ($hasOneFields as $key => $field) { $hasOneFields[$key . "ID"] = $field; unset($hasOneFields[$key]); } $fields = $dbFields + $hasOneFields; //remove ignore fields ... foreach ($this->ignoreFields as $ignoreField) { unset($fields[$ignoreField]); } //flip $fields = array_keys($fields); if ($this->recordSession) { self::add_to_session("\n\t\t\t\t\t====================================\n\t\t\t\t\t*** COPYING INTO\n\t\t\t\t\t" . ($this->myClassName != $copyFrom->ClassName ? "ERROR: ClassName mismatch: " . $this->myClassName . " != " . $copyFrom->ClassName : "") . "\n\t\t\t\t\tValues will " . ($overwriteValues ? "" : "NOT") . " be overridden.\n\t\t\t\t\tDB Fields: " . implode(", ", array_keys($dbFields)) . "\n\t\t\t\t\tHAS ONE Fields: " . implode(", ", array_keys($hasOneFields)) . "\n\t\t\t\t\tIGNORE Fields: " . implode(", ", $this->ignoreFields) . "\n\t\t\t\t\tFINAL Fields: " . implode(", ", $fields) . "\n\t\t\t\t\t====================================\n\t\t\t\t", $copyFrom, $newObject); } if ($this->recordSession) { $copySessionRecording = ""; } foreach ($fields as $field) { if (!$newObject->{$field} || $overwriteValues) { $value = $copyFrom->{$field}; if (is_object($value)) { $value = $value->raw(); } if ($this->recordSession) { $copySessionRecording .= "\r\nSetting '{$field}' to '{$value}'"; } if ($this->isForReal) { $newObject->{$field} = $value; } } } $copyField = $newObject->CopyFromFieldName($withID = true); $copyFieldCompleted = $newObject->CopiedFromFieldName($withID = true); //important - reset, so that it does not get into a loop. if ($this->recordSession) { self::add_to_session("\n\t\t\t{$copySessionRecording}\n\t\t\tsetting '{$copyField}' to zero\n\t\t\tsetting '{$copyFieldCompleted}' to '" . $copyFrom->ID . "'", $copyFrom, $newObject); } if ($this->isForReal) { $newObject->{$copyFieldCompleted} = $copyFrom->ID; if ($newObject->exists()) { $newObject->{$copyField} = 0; } $newObject->write(); } //now we do all the other methods ... if ($newObject->hasMethod("doCopyFactory")) { if ($this->recordSession) { self::add_to_session("Now calling doCopyFactory ... ", $copyFrom, $newObject); } $newObject->doCopyFactory($this, $copyFrom); } return $this; }