Jump to content
Neeks

Copying image from one page to another...To clone or not to clone....

Recommended Posts

I want to copy all the content from one $page to another $page.

The use case:  To create drafting workflows. The contents of one page needs to be copied to replace another. 

The problem points:  images and files don't copy with my current approach. So far it looks like you have to: copy the files /assets/your-page-id/ to /assets/your-new-page-id/, then do a search and replace on any Rich Text Fields fields that contained the paths for those images. (easy search and replace)

Are there any system tools for migrating images and files from one page to another. It seems like clone does this all automatically. I would love to leverage existing tools if they exist before trying to build my own. Also I wonder if this is the correct way to copy the non-filesystem based data : $pageA->image = $pageB->image; $pageA->save()? 

Method #1: for copying fields from one page to another: (thanks to some tips from Soma, it works great, but does not yet work on image fields, or files)

    public function copyFields ($sourcePage, $destinationPage)
    {
        //Copy Fields between pages
        $destinationPage->of(false);
        $sourcePage->of(false);
        $debugMsg = '';
        foreach ($destinationPage->template->fieldgroup as $field) {
            if ($destinationPage->$field != $sourcePage->$field) {
                $destinationPage->$field = $sourcePage->$field;
                $debugMsg .= $field . ",";
            }
        }
        $this->message("Fields Copied: $debugMsg", Notice::debug);
        return $destinationPage;
    }

(If there are any system tools for dealing with, the migration of images and files from one page to another id love to learn about them, even if they are low level like "the process wire method for creating asset folders, and copying files" if such functions exist...otherwise ill use the basics.)

Can't you just clone the page?

I tried cloning the page. It works AWSOME!!! except! I am unable to transfer the ID from the page being replaced by the clone, to the clone. When Id's Change page relationships can break. While clone works awesome at copying data between pages, not being able to change the ID of a page post clone, makes me think it might not be a viable option for copying data of one page with another.  If any one wants to look at my simple method for replacing a page with a clone and offer a suggestions...

Method #2 Cloning a draft page to replace original content page 

private function pushDraft ($draft)
{
$page = $this->getSourceFromDraft($draft);

    //Backup important fields before we delete our Original page.
    $pageOriginalParent = $page->parent;
    $pageOriginalName = $page->name;
    $pageOriginalId = $page->id;
    //store revision history on draft page just so it does not get deleted
    $this->movePathHisory($pageOriginalId, $draft->id);

    //delete original page
    wire('pages')->delete($page);

    //Clone a copy of draft to replace original page
    //we save a copy of the draft page and original page else where in case we need to revert.
    $replacementPage = wire('pages')->clone($draft, $pageOriginalParent);
    $replacementPage->name = $pageOriginalName;

    $replacementPage->id = $pageOriginalId;
    //This is the part that does not work as It might.
    //The assignment happens in memory but not in the database of file system on save. 
    //there might be a really good reason for this though, I don't imagine people need
    //change page ids that often.
    $replacementPage->save();

    $this->moveRevisionHistory($draft->id, $replacementPage->id);
    return $replacementPage;
}

Share this post


Link to post
Share on other sites

Solved it by reading how $pages->clone() does it, and just doing that....

I also see that $pages->clone() has the ability to set an argument to specify a page ID which solves my issue of cloning a page and not having the the page ID I want after the clone.

//copies the fields of one page to replace the fields of another page.
function copyFields ($sourcePage, $destinationPage)
{
    //Copy Fields between pages
    $destinationPage->of(false);
    $sourcePage->of(false);

    foreach ($destinationPage->template->fieldgroup as $field){
            if($field->type instanceOf FieldtypeTable){
                //You get duplicare SQL index errors if you don't use clone.
                $destinationPage->$field = clone $sourcePage->$field;
            }elseif($field->type instanceOf FieldtypeTextarea){
                //Update image an file links in rich text fields
                $destinationPage->$field = str_replace("/files/{$sourcePage->id}/","/files/{$destinationPage->id}/",$sourcePage->$field);
            }else{
                $destinationPage->$field = $sourcePage->$field;
            }
    }

    // Copy $sourcePage's files over to new page
    if(PagefilesManager::hasFiles($sourcePage)) {
        $destinationPage->filesManager->init($destinationPage);
        $sourcePage->filesManager->copyFiles($destinationPage->filesManager->path());
    }
 
    return $destinationPage;
}
  • Like 2

Share this post


Link to post
Share on other sites

Thanks for this.

I do get the assets copied over to the destination page's asset folder, but somehow the actual contents of the fields do not get copied over. I wonder, why that might be? They have the exact same fields. Textarea, Image and File. Same result, if all or some of the fields have content.

I do get the echo for all the fields per the foreach.

Here is how I run it:

include 'index.php';

//copies the fields of one page to replace the fields of another page.
function copyFields ($sourcePage, $destinationPage)
{
    //Copy Fields between pages
    $destinationPage->of(false);
    $sourcePage->of(false);

    foreach ($destinationPage->template->fieldgroup as $field){
            if($field->type instanceOf FieldtypeTable){
                //You get duplicate SQL index errors if you don't use clone.
                $destinationPage->$field = clone $sourcePage->$field;
            }elseif($field->type instanceOf FieldtypeTextarea){
                //Update image and file links in rich text fields
                $destinationPage->$field = str_replace("/files/{$sourcePage->id}/","/files/{$destinationPage->id}/",$sourcePage->$field);
                echo "kloonattu textarea";
            }else{
                $destinationPage->$field = $sourcePage->$field;
                echo "kloonattu joku kenttä";
            }
    }
    

    // Copy $sourcePage's files over to new page
    if(PagefilesManager::hasFiles($sourcePage)) {
        $destinationPage->filesManager->init($destinationPage);
        $sourcePage->filesManager->copyFiles($destinationPage->filesManager->path());
    }
 
    return $destinationPage;
}

$lahde = $pages->get('1077');
$kohde = $pages->get('1225');

copyFields($lahde, $kohde);

Share this post


Link to post
Share on other sites

Perhaps just a missing

$destinationPage->save();

after the foreach?

  • Like 1

Share this post


Link to post
Share on other sites

Perhaps just a missing

$destinationPage->save();

after the foreach?

Thanks! That was it :)

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...