src/ORM/DataObject.php
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
        $rightData = DataObject::getSchema()->fieldSpecs(get_class($rightObj));
        foreach ($rightData as $key => $rightSpec) {
            // Don't merge ID
            if ($key === 'ID') {
                continue;
            }

            // Only merge relations if allowed
            if ($rightSpec === 'ForeignKey' && !$includeRelations) {
                continue;
            }

            // 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->manyMany()) {
                foreach ($manyMany as $relationship => $class) {
                    /** @var DataObject $leftComponents */
                    $leftComponents = $leftObj->getManyManyComponents($relationship);
                    $rightComponents = $rightObj->getManyManyComponents($relationship);
                    if ($rightComponents && $rightComponents->exists()) {
                        $leftComponents->addMany($rightComponents->column('ID'));
                    }
                    $leftComponents->write();
                }
            }

            if ($hasMany = $this->hasMany()) {
                foreach ($hasMany as $relationship => $class) {
                    $leftComponents = $leftObj->getComponents($relationship);
                    $rightComponents = $rightObj->getComponents($relationship);
                    if ($rightComponents && $rightComponents->exists()) {
                        $leftComponents->addMany($rightComponents->column('ID'));
                    }
                    $leftComponents->write();
                }
            }
        }

        return true;
    }
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
        $rightData = DataObject::getSchema()->fieldSpecs(get_class($rightObj));
        foreach ($rightData as $key => $rightSpec) {
            // Don't merge ID
            if ($key === 'ID') {
                continue;
            }

            // Only merge relations if allowed
            if ($rightSpec === 'ForeignKey' && !$includeRelations) {
                continue;
            }

            // 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->manyMany()) {
                foreach ($manyMany as $relationship => $class) {
                    /** @var DataObject $leftComponents */
                    $leftComponents = $leftObj->getManyManyComponents($relationship);
                    $rightComponents = $rightObj->getManyManyComponents($relationship);
                    if ($rightComponents && $rightComponents->exists()) {
                        $leftComponents->addMany($rightComponents->column('ID'));
                    }
                    $leftComponents->write();
                }
            }

            if ($hasMany = $this->hasMany()) {
                foreach ($hasMany as $relationship => $class) {
                    $leftComponents = $leftObj->getComponents($relationship);
                    $rightComponents = $rightObj->getComponents($relationship);
                    if ($rightComponents && $rightComponents->exists()) {
                        $leftComponents->addMany($rightComponents->column('ID'));
                    }
                    $leftComponents->write();
                }
            }
        }

        return true;
    }
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 $ rightData = DataObject :: getSchema ( ) -> fieldSpecs ( get_class ( $ rightObj ) ) ; foreach ( $ rightData as $ key => $ rightSpec ) { // Don't merge ID if ( $ key === 'ID' ) { continue ; } // Only merge relations if allowed if ( $ rightSpec === 'ForeignKey' && ! $ includeRelations ) { continue ; } // 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 -> manyMany ( ) ) { foreach ( $ manyMany as $ relationship => $ class ) { /** @var DataObject $leftComponents */ $ leftComponents = $ leftObj -> getManyManyComponents ( $ relationship ) ; $ rightComponents = $ rightObj -> getManyManyComponents ( $ relationship ) ; if ( $ rightComponents && $ rightComponents -> exists ( ) ) { $ leftComponents -> addMany ( $ rightComponents -> column ( 'ID' ) ) ; } $ leftComponents -> write ( ) ; } } if ( $ hasMany = $ this -> hasMany ( ) ) { foreach ( $ hasMany as $ relationship => $ class ) { $ leftComponents = $ leftObj -> getComponents ( $ relationship ) ; $ rightComponents = $ rightObj -> getComponents ( $ relationship ) ; if ( $ rightComponents && $ rightComponents -> exists ( ) ) { $ leftComponents -> addMany ( $ rightComponents -> column ( 'ID' ) ) ; } $ leftComponents -> write ( ) ; } } } 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 DataObject $rightObj
@param string $priority left|right Determines who wins in case of a conflict (optional)
@param bool $includeRelations Merge any existing relations (optional)
@param bool $overwriteWithEmpty Overwrite existing left values with empty right values.
Only applicable with $priority='right'. (optional)
@return Boolean
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 .