mirror of
https://github.com/processwire/processwire.git
synced 2025-08-09 08:17:12 +02:00
Update PagesEditor::delete() method to track already-deleted pages to prevent duplicate calls from nested repeaters and such.
This commit is contained in:
@@ -28,6 +28,22 @@ class PagesEditor extends Wire {
|
|||||||
*/
|
*/
|
||||||
protected $pages;
|
protected $pages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleted page ID tracking
|
||||||
|
*
|
||||||
|
* @var array of [ id => id ]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $deleted = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete recursion level
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $deleteLevel = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct
|
* Construct
|
||||||
*
|
*
|
||||||
@@ -1098,7 +1114,7 @@ class PagesEditor extends Wire {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permanently delete a page and it's fields.
|
* Permanently delete a page and its fields.
|
||||||
*
|
*
|
||||||
* Unlike trash(), pages deleted here are not restorable.
|
* Unlike trash(), pages deleted here are not restorable.
|
||||||
*
|
*
|
||||||
@@ -1121,19 +1137,35 @@ class PagesEditor extends Wire {
|
|||||||
'uncacheAll' => false,
|
'uncacheAll' => false,
|
||||||
'recursive' => is_bool($recursive) ? $recursive : false,
|
'recursive' => is_bool($recursive) ? $recursive : false,
|
||||||
// internal use properties:
|
// internal use properties:
|
||||||
|
// internal recursion level: incremented only by delete operations initiated by this method
|
||||||
'_level' => 0,
|
'_level' => 0,
|
||||||
|
// internal delete branch: Page object when deleting a branch
|
||||||
'_deleteBranch' => false,
|
'_deleteBranch' => false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// page IDs for all delete operations, cleared out once no longer recursive
|
||||||
|
static $deleted = array();
|
||||||
|
|
||||||
|
// external recursion level: all recursive delete operations including those initiated from hooks
|
||||||
|
static $level = 0;
|
||||||
|
|
||||||
if(is_array($recursive)) $options = $recursive;
|
if(is_array($recursive)) $options = $recursive;
|
||||||
$options = array_merge($defaults, $options);
|
$options = array_merge($defaults, $options);
|
||||||
|
|
||||||
|
// check if page already deleted in a recursive call
|
||||||
|
if(isset($deleted[$page->id])) {
|
||||||
|
// page already deleted, return result from that call
|
||||||
|
return $options['recursive'] ? $deleted[$page->id] : true;
|
||||||
|
}
|
||||||
|
|
||||||
$this->isDeleteable($page, true); // throws WireException
|
$this->isDeleteable($page, true); // throws WireException
|
||||||
|
|
||||||
$numDeleted = 0;
|
$numDeleted = 0;
|
||||||
$numChildren = $page->numChildren;
|
$numChildren = $page->numChildren;
|
||||||
$deleteBranch = false;
|
$deleteBranch = false;
|
||||||
|
$level++;
|
||||||
|
|
||||||
if($numChildren) {
|
if($numChildren) try {
|
||||||
if(!$options['recursive']) {
|
if(!$options['recursive']) {
|
||||||
throw new WireException("Can't delete Page $page because it has one or more children.");
|
throw new WireException("Can't delete Page $page because it has one or more children.");
|
||||||
}
|
}
|
||||||
@@ -1144,17 +1176,21 @@ class PagesEditor extends Wire {
|
|||||||
}
|
}
|
||||||
foreach($page->children('include=all') as $child) {
|
foreach($page->children('include=all') as $child) {
|
||||||
/** @var Page $child */
|
/** @var Page $child */
|
||||||
|
if(isset($deleted[$child->id])) continue;
|
||||||
$options['_level']++;
|
$options['_level']++;
|
||||||
$result = $this->pages->delete($child, true, $options);
|
$result = $this->pages->delete($child, true, $options);
|
||||||
$options['_level']--;
|
$options['_level']--;
|
||||||
if(!$result) throw new WireException("Error doing recursive page delete, stopped by page $child");
|
if(!$result) throw new WireException("Error doing recursive page delete, stopped by page $child");
|
||||||
$numDeleted += $result;
|
$numDeleted += $result;
|
||||||
}
|
}
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$level = 0;
|
||||||
|
$deleted = array();
|
||||||
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// trigger a hook to indicate delete is ready and WILL occur
|
// trigger a hook to indicate delete is ready and WILL occur
|
||||||
$this->pages->deleteReady($page, $options);
|
$this->pages->deleteReady($page, $options);
|
||||||
|
|
||||||
$this->clear($page);
|
$this->clear($page);
|
||||||
|
|
||||||
$database = $this->wire()->database;
|
$database = $this->wire()->database;
|
||||||
@@ -1165,10 +1201,20 @@ class PagesEditor extends Wire {
|
|||||||
$this->pages->sortfields()->delete($page);
|
$this->pages->sortfields()->delete($page);
|
||||||
$page->setTrackChanges(false);
|
$page->setTrackChanges(false);
|
||||||
$page->status = Page::statusDeleted; // no need for bitwise addition here, as this page is no longer relevant
|
$page->status = Page::statusDeleted; // no need for bitwise addition here, as this page is no longer relevant
|
||||||
$this->pages->deleted($page, $options);
|
|
||||||
$numDeleted++;
|
$numDeleted++;
|
||||||
|
$deleted[$page->id] = $numDeleted;
|
||||||
|
$this->pages->deleted($page, $options);
|
||||||
|
|
||||||
if($deleteBranch) $this->pages->deletedBranch($page, $options, $numDeleted);
|
if($deleteBranch) $this->pages->deletedBranch($page, $options, $numDeleted);
|
||||||
if($options['uncacheAll']) $this->pages->uncacheAll($page);
|
if($options['uncacheAll']) $this->pages->uncacheAll($page);
|
||||||
|
|
||||||
|
if($level > 0) $level--;
|
||||||
|
if($level < 1) {
|
||||||
|
// back at root call, reset all tracking
|
||||||
|
$deleted = array();
|
||||||
|
$level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$this->pages->debugLog('delete', $page, true);
|
$this->pages->debugLog('delete', $page, true);
|
||||||
|
|
||||||
return $options['recursive'] ? $numDeleted : true;
|
return $options['recursive'] ? $numDeleted : true;
|
||||||
|
Reference in New Issue
Block a user