Duplicating a propel object
Today I needed to quickly duplicate some rows in a table that is in a Symfony application. I am using the admin generator so I also have the schema as a Propel series of objects.
I did a quick search on Google and did not find any place on how to effectively duplicate a Propel object which in turn would duplicate the row in a table.
Basically, what I need is another record with the same values except the primary key which is an autoincremented integer.
Here is the snipped of code that I added to the Propel object.
public function duplicate()
{
// duplicate object
$ap = clone $this;
$values = $ap->toArray( );
$values2 = array();
// create array of fields with null so we can force all values to be modified
foreach( $values as $idx => $v )
{
$values2[ $idx ] = null;
}
// force all values to be changed so the doInsert inserts the values.
$ap->fromArray( $values2 );
$ap->fromArray( $values );
$ap->setIsActive(false);
$ap->setId(null);
$ap->setNew(true);
$ap->save();
return $ap;
}
Is there is another easier way, maybe provided by Propel, which I could not find, please let me know.
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.
Comments
Be careful with deepCopy when I used it I remember being surprised a couple of times.
I also recall that there seemed to be an issue with multiple field primary keys as well
My bug report here:
http://trac.symfony-project.org/ticket/4836
It’s unreviewed, which may be a nice way of saying I was doing something else wrong
I found some thing that works better, using propel’s built in functionality
$objCopy = null;
$objCopy = $objRow->copy();
$objCopy->setName(“foo”);
$objCopy->save();
There is actually something ready to use in Propel: in your Model’s base class you can find the following:
[code]
/**
* Makes a copy of this object that will be inserted as a new row in table when saved.
* It creates a new object filling in the simple attributes, but skipping any primary
* keys that are defined for the table.
*
* If desired, this method can also make copies of all associated (fkey referrers)
* objects.
*
* @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
* @return Contract Clone of current object.
* @throws PropelException
*/
public function copy($deepCopy = false)
{
// we use get_class(), because this might be a subclass
$clazz = get_class($this);
$copyObj = new $clazz();
$this->copyInto($copyObj, $deepCopy);
return $copyObj;
}
[/code]