Jump to content

Cloning page with children via API fails


simonsays
 Share

Recommended Posts

Hello everyone,

I am trying to clone a page using PW API.

Here's the function:

    public function copy() {
        $input = $this->wire('input');
        if ($input->post->submit && $this->canEdit()) {
            $original = $this->wire('page');
            $pages = $this->wire('pages');
            $original->of(false);
            $copy = $pages->clone($original);
            $copy->title .= ' - Copy';
            $copy->save();
        }
        $this->wire('session')->redirect($copy->path);
    }

Works fine, when a page does not have children, but fails completely when there are child pages throwing me the following error...

Fatal error: Exception: Can’t save page 0: /campaign-demo-1/section-text-image-first/: Call $page->of(false); before getting/setting values that will be modified and saved. [Page::statusCorrupted] fields: text_align (in C:\xampp\htdocs\t2cms\wire\core\PagesEditor.php line 515) #0 C:\xampp\htdocs\t2cms\wire\core\Pages.php(411): ProcessWire\PagesEditor->save(Object(ProcessWire\Page), Array) #1 C:\xampp\htdocs\t2cms\wire\core\Wire.php(386): ProcessWire\Pages->___save(Object(ProcessWire\Page), Array) #2 C:\xampp\htdocs\t2cms\wire\core\WireHooks.php(723): ProcessWire\Wire->_callMethod('___save', Array) #3 C:\xampp\htdocs\t2cms\wire\core\Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Pages), 'save', Array) #4 C:\xampp\htdocs\t2cms\wire\core\PagesEditor.php(1199): ProcessWire\Wire->__call('save', Array) #5 C:\xampp\htdocs\t2cms\wire\core\Pages.php(514): ProcessWire\PagesEditor->_clone(Object(ProcessWire\Page), Object(ProcessWire\Page), true, Array) #6 [internal function]: ProcessWire\Pages->___clone(Object( in C:\xampp\htdocs\t2cms\index.php on line 64

where campaign-demo is the page, that I copy, and section-text-image-first is a child page.

I already tried looping through $original->children and setting ->of(false) but to no avail. Does anyone know what the problem might be?

Thanks in advance!

Edited by simonsays
Link to comment
Share on other sites

I am the original TS. Can't post anymore, seems that I've been banned just for asking this question. Wow...

17 hours ago, dragan said:

perhaps specify the new page name as well?


$copy->name .= '-copy';

The error is thrown when clone() method is called.

15 hours ago, elabx said:

Shouldn't output formatting be turned off in the $copy page, which is the one getting saved?

Tried both ways.

Link to comment
Share on other sites

28 minutes ago, Deniss Surnin said:

I am the original TS. Can't post anymore, seems that I've been banned just for asking this question.

Moderator Note

@simonsays, @Deniss Surnin

That's incorrect. You have not been banned. After their initial post, new users are only allowed one more post within the first 24 hours. After this time period, they can post normally. Could you try posting again using your original handle? Let us know if you still experience problems. If its working, you'll have to delete you new handle (Deniss Surnin).

Edited by kongondo
Link to comment
Share on other sites

Maybe you are calling $copy->of(false) in the wrong place.

This works for me, cloning a page with children and grandchildren.

$copy = $pages->clone($page);
//$copy->parent = '/cloned-parent/';
$copy->title .= $page->title . ' - copy';
$copy->name = $sanitizer->pageName($copy->title);
$copy->of(false);
$copy->save();

 

  • Like 2
Link to comment
Share on other sites

5 hours ago, kongondo said:

Maybe you are calling $copy->of(false) in the wrong place.

This works for me, cloning a page with children and grandchildren.


$copy = $pages->clone($page);
//$copy->parent = '/cloned-parent/';
$copy->title .= $page->title . ' - copy';
$copy->name = $sanitizer->pageName($copy->title);
$copy->of(false);
$copy->save();

 

THIS has happened to me multiple times calling it in the wrong place.

Link to comment
Share on other sites

5 hours ago, kongondo said:

Maybe you are calling $copy->of(false) in the wrong place.

This works for me, cloning a page with children and grandchildren.


$copy = $pages->clone($page);
//$copy->parent = '/cloned-parent/';
$copy->title .= $page->title . ' - copy';
$copy->name = $sanitizer->pageName($copy->title);
$copy->of(false);
$copy->save();

 

Apparently your page does not have children or custom fields like mine.

I don't think I explained my problem clear enough. For some reason both the page and its children output formatting is set to true. Therefore, cloning fails.

Explicitly setting the ORIGINAL (not COPY) formatting to false allows me to copy pages without children. But for some reason, child OF always resets to true. So, when a clone method is called recursively, the $page is set back to of()=true.

I have found the problem in the code, but unable to solve it.

In PagesEditor.php this code inside __clone method

		$o = $copy->outputFormatting;
		$copy->setOutputFormatting(false);
		$this->pages->cloneReady($page, $copy);
		$this->cloning++;
		$options['ignoreFamily'] = true; // skip family checks during clone
		try {
			$this->pages->save($copy, $options);
		} catch(\Exception $e) {
			$this->cloning--;
			$copy->setQuietly('_cloning', null); 
			throw $e;
		}

always sets children output formatting back to TRUE.

This makes zero sense. The fields are not formatted or changed in any manner, so I strongly suspect a bug.

One more option - take a look how admin copies a page with children? Where can I find this code?

Link to comment
Share on other sites

1 hour ago, simonsays said:

Apparently your page does not have children

Like I stated, my page has children and grandchildren ;).

1 hour ago, simonsays said:

custom fields like mine

It does have custom fields...but yeah, maybe not like yours. So, maybe, show us the custom fields you have. Otherwise, it's a bit more difficult to help. Also, ProcessWire version.

Link to comment
Share on other sites

I was able to reproduce this issue. It seems to occur when any of the pages being cloned have file or image fields in their template.

If the parent page has a file/image field but not the children then setting output formatting off before cloning the page seems to work. But if the child pages have a file/image field then setting output formatting off on those children doesn't work.

But I don't think output formatting should need to be off when cloning a page - the clone() docs make no mention of output formatting and don't show it being set in the example code, and indeed it doesn't need to be off unless a file/image field is present.

And seeing as setting output formatting off in the child pages still doesn't allow for a successful clone I'd say this is a bug. @simonsays, do you want to open an issue for this in the GitHub issues repo?

  • Like 1
Link to comment
Share on other sites

On 4/28/2018 at 1:19 AM, Robin S said:

I was able to reproduce this issue. It seems to occur when any of the pages being cloned have file or image fields in their template.

If the parent page has a file/image field but not the children then setting output formatting off before cloning the page seems to work. But if the child pages have a file/image field then setting output formatting off on those children doesn't work.

But I don't think output formatting should need to be off when cloning a page - the clone() docs make no mention of output formatting and don't show it being set in the example code, and indeed it doesn't need to be off unless a file/image field is present.

And seeing as setting output formatting off in the child pages still doesn't allow for a successful clone I'd say this is a bug. @simonsays, do you want to open an issue for this in the GitHub issues repo?

Yes definitely, but first and foremost must properly describe the issue and steps to reproduce.

What confuses me, is that cloning perfectly works in admin (that's why I wanted to find that bit in the source code), but not in my method.

And in my specific case the parent does not have an image field, but still fails. And I do not understand, how this line

$this->pages->save($copy, $options);

sets children OF to true.

@Robin S what were your steps to reproduce?

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...