1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-12 01:34:31 +02:00

Initial commit to new repo (carried over from: https://github.com/ryancramerdesign/ProcessWire/tree/devns)

This commit is contained in:
Ryan Cramer
2016-09-02 14:55:17 -04:00
parent cfae5fc6f3
commit bac5b0de5d
1691 changed files with 279091 additions and 1 deletions

199
wire/core/PagesTrash.php Normal file
View File

@@ -0,0 +1,199 @@
<?php namespace ProcessWire;
/**
* ProcessWire Pages Trash
*
* Implements page trash/restore/empty methods of the $pages API variable
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* https://processwire.com
*
*/
class PagesTrash extends Wire {
/**
* @var Pages
*
*/
protected $pages;
public function __construct(Pages $pages) {
$this->pages = $pages;
}
/**
* Move a page to the trash
*
* If you have already set the parent to somewhere in the trash, then this method won't attempt to set it again.
*
* @param Page $page
* @param bool $save Set to false if you will perform the save() call, as is the case when called from the Pages::save() method.
* @return bool
* @throws WireException
*
*/
public function trash(Page $page, $save = true) {
if(!$this->pages->isDeleteable($page) || $page->template->noTrash) {
throw new WireException("This page may not be placed in the trash");
}
if(!$trash = $this->pages->get($this->config->trashPageID)) {
throw new WireException("Unable to load trash page defined by config::trashPageID");
}
$page->addStatus(Page::statusTrash);
if(!$page->parent->isTrash()) {
$parentPrevious = $page->parent;
$page->parent = $trash;
} else if($page->parentPrevious && $page->parentPrevious->id != $page->parent->id) {
$parentPrevious = $page->parentPrevious;
} else {
$parentPrevious = null;
}
if(!preg_match('/^' . $page->id . '(\.\d+\.\d+)?_.+/', $page->name)) {
// make the name unique when in trash, to avoid namespace collision and maintain parent restore info
$name = $page->id;
if($parentPrevious && $parentPrevious->id) {
$name .= "." . $parentPrevious->id;
$name .= "." . $page->sort;
}
$page->name = ($name . "_" . $page->name);
// do the same for other languages, if present
$languages = $this->wire('languages');
if($languages && $this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
foreach($languages as $language) {
if($language->isDefault()) continue;
$langName = $page->get("name$language->id");
if(!strlen($langName)) continue;
$page->set("name$language->id", $name . "_" . $langName);
}
}
}
if($save) $this->pages->save($page);
$this->pages->editor()->savePageStatus($page->id, Page::statusTrash, true, false);
$this->pages->trashed($page);
$this->pages->debugLog('trash', $page, true);
return true;
}
/**
* Restore a page from the trash back to a non-trash state
*
* Note that this method assumes already have set a new parent, but have not yet saved.
* If you do not set a new parent, then it will restore to the original parent, when possible.
*
* @param Page $page
* @param bool $save Set to false if you only want to prep the page for restore (i.e. being saved elsewhere)
* @return bool
*
*/
public function restore(Page $page, $save = true) {
if(preg_match('/^(' . $page->id . ')((?:\.\d+\.\d+)?)_(.+)$/', $page->name, $matches)) {
if($matches[2]) {
/** @noinspection PhpUnusedLocalVariableInspection */
list($unused, $parentID, $sort) = explode('.', $matches[2]);
$parentID = (int) $parentID;
$sort = (int) $sort;
} else {
$parentID = 0;
$sort = 0;
}
$prefix = $matches[1] . $matches[2] . '_';
$name = $matches[3];
if($parentID && $page->parent->isTrash() && !$page->parentPrevious) {
// no new parent was defined, so use the one in the page name
$newParent = $this->pages->get($parentID);
if($newParent->id && $newParent->id != $page->id) {
$page->parent = $newParent;
$page->sort = $sort;
}
}
if(!count($page->parent->children("name=$name, include=all"))) {
$page->name = $name; // remove namespace collision info if no collision
// do the same for other languages, when applicable
if($this->wire('languages') && $this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
foreach($this->wire('languages') as $language) {
if($language->isDefault()) continue;
$langName = $page->get("name$language->id");
if(strpos($langName, $prefix) !== 0) continue;
$langName = str_replace($prefix, '', $langName);
$page->set("name$language->id", $langName);
}
}
}
}
if(!$page->parent->isTrash()) {
$page->removeStatus(Page::statusTrash);
if($save) $page->save();
$this->pages->editor()->savePageStatus($page->id, Page::statusTrash, true, true);
$this->pages->restored($page);
$this->pages->debugLog('restore', $page, true);
} else {
if($save) $page->save();
}
return true;
}
/**
* Delete all pages in the trash
*
* Populates error notices when there are errors deleting specific pages.
*
* @return int Returns total number of pages deleted from trash.
* This number is negative or 0 if not all pages could be deleted and error notices may be present.
*
*/
public function emptyTrash() {
$trashPage = $this->pages->get($this->wire('config')->trashPageID);
$selector = "include=all, has_parent=$trashPage, children.count=0, status=" . Page::statusTrash;
$totalDeleted = 0;
$lastTotalInTrash = 0;
$numBatches = 0;
do {
set_time_limit(60 * 10);
$totalInTrash = $this->pages->count($selector);
if(!$totalInTrash || $totalInTrash == $lastTotalInTrash) break;
$lastTotalInTrash = $totalInTrash;
$items = $this->pages->find("$selector, limit=100");
$cnt = $items->count();
foreach($items as $item) {
try {
$totalDeleted += $this->pages->delete($item, true);
} catch(\Exception $e) {
$this->error($e->getMessage());
}
}
$this->pages->uncacheAll();
$numBatches++;
} while($cnt);
// just in case anything left in the trash, use a backup method
$trashPage = $this->pages->get($trashPage->id); // fresh copy
$trashPages = $trashPage->children("include=all");
foreach($trashPages as $t) {
try {
$totalDeleted += $this->pages->delete($t, true);
} catch(\Exception $e) {
$this->error($e->getMessage());
}
}
$this->pages->uncacheAll();
if($totalDeleted) {
$totalInTrash = $this->pages->count("has_parent=$trashPage, include=all, status=" . Page::statusTrash);
if($totalInTrash) $totalDeleted = $totalDeleted * -1;
}
return $totalDeleted;
}
}