Closed willemverspyck closed 4 years ago
What about working in the
AdminInterface::getNewInstance();
Method directly ?
Code is
public function getNewInstance()
{
$object = $this->getModelManager()->getModelInstance($this->getClass());
$this->appendParentObject($object);
foreach ($this->getExtensions() as $extension) {
$extension->alterNewInstance($this, $object);
}
return $object;
}
You could say that if the request is /create?from=33
it will clone the object with the id 33 instead.
Thanks @VincentLanglet
Ok, will override the "getNewInstance" for this. Is a copy method without persisting maybe interesting as PR for Sonata Admin Bundle?
It's always nice to add feature so a copyAction could theoricaly be interesting.
If we look at the RouteBuilder,
public function build(AdminInterface $admin, RouteCollection $collection)
{
$collection->add('list');
$collection->add('create');
$collection->add('batch');
$collection->add('edit', sprintf('%s/edit', $admin->getRouterIdParameter()));
$collection->add('delete', sprintf('%s/delete', $admin->getRouterIdParameter()));
$collection->add('show', sprintf('%s/show', $admin->getRouterIdParameter()));
$collection->add('export');
if ($this->manager->hasReader($admin->getClass())) {
$collection->add('history', sprintf('%s/history', $admin->getRouterIdParameter()));
$collection->add('history_view_revision', sprintf('%s/history/{revision}/view', $admin->getRouterIdParameter()));
$collection->add('history_compare_revisions', sprintf('%s/history/{base_revision}/{compare_revision}/compare', $admin->getRouterIdParameter()));
}
if ($admin->isAclEnabled()) {
$collection->add('acl', sprintf('%s/acl', $admin->getRouterIdParameter()));
}
// add children urls
foreach ($admin->getChildren() as $children) {
$collection->addCollection($children->getRoutes());
}
}
We'll need to add $collection->add('clone');
(and a clone button, and so on).
But I don't know if we can consider as BC the fact to add such a huge feature...
I added the "cloneAction" (https://github.com/willemverspyck/SonataAdminBundle/commit/8dd1b6a04f2a7b8fa14e94b35ae9f7259292c771), but wanted to check if this is compliant with the code style of Sonata, before I create tests for this and add some documentation :-)
My idea was:
/**
*
*/
public function __clone()
{
unset($this->id);
$this->setName(sprintf('%s (Copy)', $this->getName()));
}
I don't like the code "$this->getRequest()->query->set('subclass', $classNames[$className]);", but on many classes or templates $this->getRequest()->query->get('subclass') is used. I need to refactor to much to make this work with discriminators / subclasses.
@sonata-project/contributors What do you think about the clone action ? Should with add this action or should we close this ?
Feature Request
For some entities I want to make it possible to copy an entity using the __clone() method of PHP without saving them first. So the form is prefilled and you have to click the "Create" button before persisting it to the database. I can create an "cloneAction" in the CRUDController which is almost a copy of "createAction", but "createAction" has some method that are private and those can not be used in my own CRUDController.
I already tried the "preCreate", but that doesn't work because it isn't a reference:
If you change the $object parameters to &$object it works, but adding &$object as PR will be an BC break :-(
I can me an PR with a "cloneAction" if this is interesting for Sonata, or create a new version of "preCreate" with a reference $object with another name (and maybe returning the new object) or create a new method "getNewInstance" in CRUDController that I can override in my own CRUDController:
What will you advice?