mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
inform-merges
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@45483 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
9ce552a6dc
commit
83eb3c3110
@ -120,6 +120,9 @@ class DataObject extends Controller {
|
||||
* Caution: Doesn't duplicate relations.
|
||||
*
|
||||
* @return DataObject
|
||||
* Caution: Doesn't duplicate relations.
|
||||
*
|
||||
* @return DataObject
|
||||
*/
|
||||
function duplicate($doWrite = true) {
|
||||
$className = $this->class;
|
||||
@ -384,6 +387,93 @@ class DataObject extends Controller {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges data and relations from another object of same class,
|
||||
* without conflict resolution. Allows to specify which
|
||||
* dataset takes priority in case its not empty.
|
||||
* has_one-relations are just transferred with priority 'right'.
|
||||
* has_many and many_many-relations are added regardless of priority.
|
||||
*
|
||||
* Caution: has_many/many_many relations are moved rather than duplicated,
|
||||
* meaning they are not connected to the merged object any longer.
|
||||
* Caution: Just saves updated has_many/many_many relations to the database,
|
||||
* doesn't write the updated object itself (just writes the object-properties).
|
||||
* Caution: Does not delete the merged object.
|
||||
* Caution: Does now overwrite Created date on the original object.
|
||||
*
|
||||
* @param $obj DataObject
|
||||
* @param $priority String left|right Determines who wins in case of a conflict (optional)
|
||||
* @param $includeRelations Boolean Merge any existing relations (optional)
|
||||
* @param $overwriteWithEmpty Boolean Overwrite existing left values with empty right values.
|
||||
* Only applicable with $priority='right'. (optional)
|
||||
* @return Boolean
|
||||
*/
|
||||
public function merge($rightObj, $priority = 'right', $includeRelations = true, $overwriteWithEmpty = false) {
|
||||
$leftObj = $this;
|
||||
|
||||
if($leftObj->ClassName != $rightObj->ClassName) {
|
||||
// we can't merge similiar subclasses because they might have additional relations
|
||||
user_error("DataObject->merge(): Invalid object class '{$rightObj->ClassName}'
|
||||
(expected '{$leftObj->ClassName}').", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!$rightObj->ID) {
|
||||
user_error("DataObject->merge(): Please write your merged-in object to the database before merging,
|
||||
to make sure all relations are transferred properly.').", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
// makes sure we don't merge data like ID or ClassName
|
||||
$leftData = $leftObj->customDatabaseFields();
|
||||
$rightData = $rightObj->customDatabaseFields();
|
||||
|
||||
foreach($rightData as $key=>$rightVal) {
|
||||
// don't merge conflicting values if priority is 'left'
|
||||
if($priority == 'left' && $leftObj->{$key} !== $rightObj->{$key}) continue;
|
||||
|
||||
// don't overwrite existing left values with empty right values (if $overwriteWithEmpty is set)
|
||||
if($priority == 'right' && !$overwriteWithEmpty && empty($rightObj->{$key})) continue;
|
||||
|
||||
// TODO remove redundant merge of has_one fields
|
||||
$leftObj->{$key} = $rightObj->{$key};
|
||||
}
|
||||
|
||||
// merge relations
|
||||
if($includeRelations) {
|
||||
if($manyMany = $this->many_many()) {
|
||||
foreach($manyMany as $relationship => $class) {
|
||||
$leftComponents = $leftObj->getManyManyComponents($relationship);
|
||||
$rightComponents = $rightObj->getManyManyComponents($relationship);
|
||||
if($rightComponents && $rightComponents->exists()) $leftComponents->addMany($rightComponents->column('ID'));
|
||||
$leftComponents->write();
|
||||
}
|
||||
}
|
||||
|
||||
if($hasMany = $this->has_many()) {
|
||||
foreach($hasMany as $relationship => $class) {
|
||||
$leftComponents = $leftObj->getComponents($relationship);
|
||||
$rightComponents = $rightObj->getComponents($relationship);
|
||||
if($rightComponents && $rightComponents->exists()) $leftComponents->addMany($rightComponents->column('ID'));
|
||||
$leftComponents->write();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($hasOne = $this->has_one()) {
|
||||
foreach($hasOne as $relationship => $class) {
|
||||
$leftComponent = $leftObj->getComponent($relationship);
|
||||
$rightComponent = $rightObj->getComponent($relationship);
|
||||
if($leftComponent->exists() && $rightComponent->exists() && $priority == 'right') {
|
||||
$leftObj->{$relationship . 'ID'} = $rightObj->{$relationship . 'ID'};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the record to think that all its data has changed.
|
||||
* Doesn't write to the database.
|
||||
|
@ -677,6 +677,23 @@ class Form extends ViewableData {
|
||||
if($this->buttonClickedFunc == $action->actionName()) return $action;
|
||||
}
|
||||
}
|
||||
|
||||
function dropDatalessField(){
|
||||
foreach($this->Fields() as $field){
|
||||
if(get_class($field)!='SelectionGroup'&&get_class($field)!='TableListField'&&!is_subclass_of($field, 'TableListField')){
|
||||
if((get_class($field)=='DatalessField' ||is_subclass_of($field, 'DatalessField'))&&get_class($field)!='HeaderField'&&get_class($field)!='LabelField'){
|
||||
$this->Fields()->removeByName($field->Name());
|
||||
}elseif($field->isComposite()){
|
||||
$field->dropDatalessField();
|
||||
}else{
|
||||
if(get_class($field) != "HeaderField" &&get_class($field) != "LabelField"&& $field->Value() === NULL){
|
||||
$this->Fields()->removeByName($field->Name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default button that should be clicked when another one isn't available
|
||||
*/
|
||||
@ -766,21 +783,4 @@ class Form extends ViewableData {
|
||||
$data['ajax'] = 1;
|
||||
return $this->testSubmission($action, $data);
|
||||
}
|
||||
function dropDatalessField(){
|
||||
foreach($this->Fields() as $field){
|
||||
if(get_class($field)!='SelectionGroup'&&get_class($field)!='TableListField'&&!is_subclass_of($field, 'TableListField')){
|
||||
if((get_class($field)=='DatalessField' ||is_subclass_of($field, 'DatalessField'))&&get_class($field)!='HeaderField'&&get_class($field)!='LabelField'){
|
||||
$this->Fields()->removeByName($field->Name());
|
||||
}elseif($field->isComposite()){
|
||||
$field->dropDatalessField();
|
||||
}else{
|
||||
if(get_class($field) != "HeaderField" &&get_class($field) != "LabelField"&& $field->Value() === NULL){
|
||||
$this->Fields()->removeByName($field->Name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,13 +33,6 @@ class FormAction extends FormField {
|
||||
return $this->extraData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't show the <label>-tags in DefaultFieldHolder
|
||||
*/
|
||||
function FieldHolder() {
|
||||
return $this->Field();
|
||||
}
|
||||
|
||||
function Field() {
|
||||
$titleAttr = $this->description ? "title=\"" . Convert::raw2att($this->description) . "\"" : '';
|
||||
return "<input class=\"action " . $this->extraClass() . "\" id=\"" . $this->id() . "\" type=\"submit\" name=\"{$this->name}\" value=\"" . $this->attrTitle() . "\" $titleAttr />\n";
|
||||
|
Loading…
Reference in New Issue
Block a user