1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-16 03:34:33 +02:00

Fix issue processwire/processwire-issues where clone of page having FieldsetPage field was not cloning the FieldsetPage portion of it

This commit is contained in:
Ryan Cramer
2018-01-29 09:16:03 -05:00
parent 90efe9b14a
commit e917c93d76
3 changed files with 40 additions and 12 deletions

View File

@@ -75,6 +75,7 @@
* @property PageRender $render May be used for field markup rendering like $page->render->title. #pw-advanced
* @property bool $loaderCache Whether or not pages loaded as a result of this one may be cached by PagesLoaderCache. #pw-internal
*
* @property Page|null $_cloning Internal runtime use, contains Page being cloned (source), when this Page is the new copy (target). #pw-internal
* @property bool|null $_hasAutogenName Internal runtime use, set by Pages class when page as auto-generated name. #pw-internal
* @property bool|null $_forceSaveParents Internal runtime/debugging use, force a page to refresh its pages_parents DB entries on save(). #pw-internal
*

View File

@@ -15,12 +15,12 @@ class PagesEditor extends Wire {
/**
* Are we currently cloning a page?
*
* This is true only when the clone() method is currently in progress.
* This is greater than 0 only when the clone() method is currently in progress.
*
* @var bool
* @var int
*
*/
protected $cloning = false;
protected $cloning = 0;
/**
* Name for autogenerated page names when fields to generate name aren't populated
@@ -44,9 +44,16 @@ class PagesEditor extends Wire {
$this->addHookAfter('Fieldtype::sleepValue', $this, 'hookFieldtypeSleepValueStripMB4');
}
}
public function isCloning() {
return $this->cloning;
/**
* Are we currently in a page clone?
*
* @param bool $getDepth Get depth (int) rather than state (bool)?
* @return bool|int
*
*/
public function isCloning($getDepth = false) {
return $getDepth ? $this->cloning : $this->cloning > 0;
}
/**
@@ -1101,7 +1108,7 @@ class PagesEditor extends Wire {
}
/**
* Clone an entire page, it's assets and children and return it.
* Clone an entire page (including fields, file assets, and optionally children) and return it.
*
* @param Page $page Page that you want to clone
* @param Page $parent New parent, if different (default=same parent)
@@ -1149,6 +1156,7 @@ class PagesEditor extends Wire {
// clone in memory
$copy = clone $page;
$copy->setQuietly('_cloning', $page);
$copy->id = isset($options['forceID']) ? (int) $options['forceID'] : 0;
$copy->setIsNew(true);
$copy->name = $name;
@@ -1185,19 +1193,23 @@ class PagesEditor extends Wire {
$o = $copy->outputFormatting;
$copy->setOutputFormatting(false);
$this->pages->cloneReady($page, $copy);
$this->cloning++;
$options['ignoreFamily'] = true; // skip family checks during clone
try {
$this->cloning = true;
$options['ignoreFamily'] = true; // skip family checks during clone
$this->pages->save($copy, $options);
} catch(\Exception $e) {
$this->cloning = false;
$this->cloning--;
$copy->setQuietly('_cloning', null);
throw $e;
}
$this->cloning = false;
$this->cloning--;
$copy->setOutputFormatting($o);
// check to make sure the clone has worked so far
if(!$copy->id || $copy->id == $page->id) return $this->pages->newNullPage();
if(!$copy->id || $copy->id == $page->id) {
$copy->setQuietly('_cloning', null);
return $this->pages->newNullPage();
}
// copy $page's files over to new page
if(PagefilesManager::hasFiles($page)) {
@@ -1234,9 +1246,11 @@ class PagesEditor extends Wire {
}
}
$copy->setQuietly('_cloning', null);
$copy->resetTrackChanges();
$this->pages->cloned($page, $copy);
$this->pages->debugLog('clone', "page=$page, parent=$parent", $copy);
$copy->setTrackChanges(false);
return $copy;
}

View File

@@ -363,6 +363,19 @@ class FieldtypeFieldsetPage extends FieldtypeRepeater implements ConfigurableMod
public function ___savePageField(Page $page, Field $field) {
if(!$page->id || !$field->id) return false;
if($page->get('_cloning') instanceof Page) {
// $page is being cloned, so lets also clone the FieldsetPage
$source = $page->get('_cloning')->get($field->name);
if(!$source->id) return false;
$target = $this->wire('pages')->clone($source, null, false, array(
'uncacheAll' => false,
'set' => array('name' => self::repeaterPageNamePrefix . $page->id)
));
if(!$target->id) return false;
$page->set($field->name, $target);
}
$value = $page->get($field->name);
if(!$value instanceof Page) return false;