From faa0d4f4df31b1cb8975cefb8ac98f21affb365a Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Wed, 3 Oct 2018 11:50:30 -0400 Subject: [PATCH] Update ProcessPageTrash module to be more clear, showing confirmation before page list, and adding option to specify time limit. Also now reports more verbose info about the trash operation including a "pages trashed per second" rate for comparison purposes on different DB engines and settings. Related to processwire/processwire-issues#692 --- wire/modules/Process/ProcessPageTrash.module | 126 +++++++++++++------ 1 file changed, 90 insertions(+), 36 deletions(-) diff --git a/wire/modules/Process/ProcessPageTrash.module b/wire/modules/Process/ProcessPageTrash.module index 47337977..9d10ae35 100644 --- a/wire/modules/Process/ProcessPageTrash.module +++ b/wire/modules/Process/ProcessPageTrash.module @@ -16,12 +16,14 @@ class ProcessPageTrash extends Process { const debug = false; + const defaultTimeLimit = 30; + const defaultPageLimit = 0; public static function getModuleInfo() { return array( 'title' => __('Page Trash', __FILE__), // getModuleInfo title 'summary' => __('Handles emptying of Page trash', __FILE__), // getModuleInfo summary - 'version' => 102, + 'version' => 103, 'permanent' => true, ); } @@ -34,26 +36,53 @@ class ProcessPageTrash extends Process { if(!$this->wire('user')->isSuperuser()) throw new WirePermissionException(); $input = $this->wire('input'); + + $timeLimit = abs((int) $input->post('time_limit')); + if($timeLimit > 0) $this->session->setFor($this, 'timeLimit', $timeLimit); - if($input->post('submit_empty') && $input->post('confirm_empty')) { - $this->session->CSRF->validate(); - $result = $this->wire('pages')->emptyTrash(array( - 'verbose' => true - )); - if(self::debug) $this->warning($result); - $message = $this->_('Emptied the trash') . ' ' . - sprintf($this->_n('(%d page)', '(%d pages)', $result['numDeleted']), $result['numDeleted']); - if($result['numRemain'] > 0) { - $message .= ' - ' . $this->_('Not all pages could be deleted'); - } - $this->session->message($message); - // redirect to admin root after emptying trash - $this->session->redirect($this->wire('config')->urls('admin')); - return ''; - } else { + if(!$input->post('submit_empty') || !$input->post('confirm_empty')) { // render a form showing what pages are in the trash and confirming they want to empty it + if($input->post('submit_empty')) $this->warning($this->_('You must check the box to confirm')); return $this->render(); } + + $this->session->CSRF->validate(); + + $options = array( + 'verbose' => true, + 'timeLimit' => $timeLimit > 0 ? $timeLimit : self::defaultTimeLimit, + ); + + $result = $this->wire('pages')->emptyTrash($options); + if(self::debug) $this->warning($result); + $error = false; + + $message = sprintf($this->_n('Deleted %d page', 'Deleted %d pages', $result['numDeleted']), $result['numDeleted']); + + if($result['numDeleted'] && $result['pagesPerSecond'] && $result['numDeleted'] > $result['pagesPerSecond']) { + $message .= ' ' . sprintf($this->_('(%d pages per second)'), $result['pagesPerSecond']); + } + + if($result['numRemain'] > 0) { + $message .= ' - ' . sprintf($this->_('Not all pages could be deleted (%d remain)'), $result['numRemain']); + $error = true; + } + + if($result['timeExpired']) { + $message .= ' - ' . sprintf($this->_('Time limit reached (%d seconds)'), "$options[timeLimit]"); + $error = true; + } + + if($error) { + $this->session->warning($message); + $this->session->redirect('./'); + } else { + // redirect to admin root after emptying trash + $this->session->message($message); + $this->session->redirect($this->wire('config')->urls('admin')); + } + + return ''; // unreachable due to redirects above } /** @@ -62,44 +91,69 @@ class ProcessPageTrash extends Process { */ protected function render() { - $trashPages = $this->pages->get($this->config->trashPageID)->children("limit=2, status<" . Page::statusMax); + // $trashPages = $this->pages->get($this->config->trashPageID)->children("limit=2, status<" . Page::statusMax); + $trashTotal = $this->pages->trasher()->getTrashTotal(); /** @var InputfieldForm $form */ $form = $this->modules->get("InputfieldForm"); $form->attr('action', './'); $form->attr('method', 'post'); - if(!count($trashPages)) return "

" . $this->_("The trash is empty") . "

"; - - /** @var InputfieldMarkup $field */ - $field = $this->modules->get("InputfieldMarkup"); - $field->label = $this->_("The following pages are in the trash"); - /** @var ProcessPageList $pageList */ - $pageList = $this->modules->get('ProcessPageList'); - $pageList->set('id', $this->config->trashPageID); - $pageList->set('showRootPage', false); - $field->value = $pageList->execute(); - $form->add($field); + if(!$trashTotal) return "

" . $this->_("The trash is empty") . "

"; /** @var InputfieldCheckbox $field */ $field = $this->modules->get("InputfieldCheckbox"); $field->attr('name', 'confirm_empty'); $field->attr('value', 1); - $field->label = $this->_('Empty trash'); - $field->description = $this->_("Please confirm that you want to empty the page trash."); - $field->notes = $this->_("If there are too many items in the trash, you may have to empty it multiple times."); + $field->label2 = $this->_('Empty the trash (confirm)'); + $field->label = sprintf( + $this->_n('Permanently delete %d page in the trash?', 'Permanently delete %d pages in the trash?', $trashTotal), + $trashTotal + ); + if($trashTotal > 100) { + $field->notes = $this->_("If there are too many items in the trash, you may have to empty it multiple times."); + } $form->add($field); + + /** @var InputfieldMarkup $field */ + $field = $this->modules->get("InputfieldMarkup"); + $field->label = $this->_('Pages in the trash'); + $field->icon = 'list'; + $field->collapsed = Inputfield::collapsedYes; + /** @var ProcessPageList $pageList */ + $pageList = $this->modules->get('ProcessPageList'); + $pageList->set('id', $this->config->trashPageID); + $pageList->set('showRootPage', false); + $field->value = $pageList->execute(); + $form->add($field); + + /** @var InputfieldInteger $f */ + $f = $this->modules->get('InputfieldInteger'); + $f->attr('name', 'time_limit'); + $f->label = $this->_('Time limit (in seconds)'); + $timeLimit = (int) $this->session->getFor($this, 'timeLimit'); + $f->attr('value', $timeLimit > 0 ? $timeLimit : self::defaultTimeLimit); + $f->icon = 'clock-o'; + $f->collapsed = Inputfield::collapsedYes; + $form->add($f); /** @var InputfieldSubmit $field */ $field = $this->modules->get("InputfieldSubmit"); $field->attr('name', 'submit_empty'); + $field->showInHeader(true); + $field->icon = 'trash'; + $form->add($field); + + /** @var InputfieldSubmit $field */ + $field = $this->modules->get("InputfieldButton"); + $field->attr('name', 'submit_cancel'); + $field->setSecondary(true); + $field->value = $this->_('Cancel'); + $field->href = $this->wire('config')->urls->admin; + $field->icon = 'times'; $form->add($field); return $form->render(); } - - public function ___executeForce() { - } - }