Jump to content

Custom admin button to clone page


suntrop
 Share

Recommended Posts

I'd like to add a button next to PW's built in Save button on the edit page to clone a page. I can't use the Clone module from PW, because there need to be some other code be executed.

I had seen some related posts here, but my code doesn't work properly. When I click the button, the page will get cloned 6 times instead of only once.

The page has a PageTable field on it with 5 sub-pages. Perhaps the hook gets executed for every child? It doesn't make any difference if I remove the $copy->save() action.

Saved in /site/init.php

wire()->addHookBefore('ProcessPageEdit::processInput', NULL, 'cloneAsOrder');
function cloneAsOrder($event) {

	$p = $event->object->getPage();
	$event->replace = true;

	if ( wire()->input->post('submit_clone_as_order') ) {

		$parent = wire()->pages->get('/crm/accounting/order/');
		$copy = wire()->pages->clone($p, $parent);

		// $copy->parent = '/crm/accounting/order/';
		$copy->template = 'order';
		$copy->title = 'UNFINISHED-';
		$copy->name = 'unfinished-r327' . date('Y-m-d-h:i:s');

		// $copy->removeStatus("published");
		// $copy->addStatus("unpublished");

		$copy->save();

		// wire()->message('Copy created:' . $p->title . ' » <a href="' . $copy->url . '">' . $copy->title . '"</a>');
	}

}

And … is it possible to clone a page without publishing it? I will need (later) a hook that hooks into the publishing method and save an order number. That number will come from a 'next doc number' and gets incremented automatically.

Link to comment
Share on other sites

7 minutes ago, suntrop said:

I can't use the Clone module from PW, because there need to be some other code be executed.

Is there some reason you can't hook into: ProcessPageClone::process and execute your additional code there?

Link to comment
Share on other sites

15 hours ago, adrian said:

Is there some reason you can't hook into: ProcessPageClone::process and execute your additional code there?

Yes. At the end I need three buttons and each must clone the page to different destinations, with different templates and different code that runs before the page gets saved. If here is just one clone button I can’t distinguish “how” the page needs to be copied.

Link to comment
Share on other sites

hi suntrop,

I don't know why and I don't know if this is the best option (hooking is for sure also fine, or even better), but I like to create custom endpoints in the admin for that purpose via a ProcessModule. There i create an execute method (like executeMycustomcopyfunction) so that you can call this endpoint easily like this:

<a href="/admin/page/mymodule/mycustomcopyfunction/?pagetocopy=123&newparent=456&copychildren=1">copy to new parent with children</a>

In this method you can do whatever you want (don't forget to check permissions if that's important in your case). Somehow I found this way easier than hooking :) 

One drawback could be that you need to check if the page has some unmodified changes. I use my clone link on an overview-table so thats no factor in my case since the page is not being edited when clicking the clone link.

Link to comment
Share on other sites

That is a nice solution! I will definitely try this if I can't get my hook to work … but I really would like to know what the problem is with my code. And when it works, I go and try your solution and compare them :-) I am always happy to see how other people find their way to the same outcome.

However, on that custom endpoint I would have to run just the same code and clone the page. Well … I'll test it now :-) 

  • Like 1
Link to comment
Share on other sites

23 hours ago, suntrop said:

When I click the button, the page will get cloned 6 times instead of only once

This is what I use when using the ProcessPageEdit::processInput hook. Put these as the first lines inside the function.

        // ProcessPageEdit's processInput function may go recursive, so we want to skip
        // the instances where it does that by checking the second argument named "level"
        $level = $event->arguments(1);
        if($level > 0) return;

 

  • Like 3
Link to comment
Share on other sites

// EDIT

It works now. There is a conflict with another Pages::saveReady hook, that updates the title, when a particular field is changed. It seems $page->isChanged('fieldname') is true when I create a new page and the field was already set in the source. I'll see how to get a workaround for this. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...