Add actions over the list of private dialogs

Delete or transfer to the archive folder of one or more dialog at a time.
This commit is contained in:
Visman 2021-04-04 21:16:29 +07:00
parent bdffcdbb3b
commit 4518ed1189
4 changed files with 230 additions and 5 deletions

View file

@ -13,8 +13,11 @@ namespace ForkBB\Models\Pages\PM;
use ForkBB\Core\Validator;
use ForkBB\Models\Page;
use ForkBB\Models\Pages\PM\AbstractPM;
use ForkBB\Models\Forum\Model as Forum;
use ForkBB\Models\User\Model as User;
use ForkBB\Models\Pages\PostFormTrait;
use ForkBB\Models\Pages\PostValidatorTrait;
use ForkBB\Models\PM\Cnst;
use ForkBB\Models\PM\PPost;
use ForkBB\Models\PM\PTopic;
use InvalidArgumentException;
use function \ForkBB\__;
@ -35,11 +38,206 @@ class PMView extends AbstractPM
return $this->c->Message->message('Not Found', true, 404);
}
$this->pmIndex = $this->pms->area;
$this->pmIndex = $this->pms->area;
if ('POST' === $method) {
$this->c->Lang->load('validator');
$v = $this->c->Validator->reset()
->addValidators([
'action_process' => [$this, 'vActionProcess'],
])->addRules([
'token' => 'token:PMAction',
'ids' => 'required|array',
'ids.*' => 'required|integer|min:1|max:9999999999',
'confirm' => 'integer',
Cnst::ACTION_ARCHIVE => 'string',
Cnst::ACTION_DELETE => 'string',
'action' => 'action_process',
])->addAliases([
])->addArguments([
'token' => $this->args,
])->addMessages([
'ids' => 'No dialogs',
]);
if ($v->validation($_POST)) {
if (null === $v->action) {
$this->nameTpl = 'pm/form';
$this->form = $this->formConfirm($v, $this->args);
$this->formId = 'id-pmcnfrm-form';
$this->formTitle = Cnst::PT_ARCHIVE === $this->vStatus ? 'InfoSaveQt' : 'InfoDeleteQt';
$this->pmCrumbs[] = __(Cnst::PT_ARCHIVE === $this->vStatus ? 'InfoSaveQ' : 'InfoDeleteQ');
return $this;
} elseif (1 !== $v->confirm) {
return $this->c->Redirect->page('PMAction', $this->args)->message('No confirm redirect');
} else {
$topics = $this->pms->loadByIds(Cnst::PTOPIC, $v->ids);
foreach ($topics as $topic) {
$topic->status = $this->vStatus;
}
// удаление (при $topic->isFullDeleted) или обновление диалогов и пользователя
$this->pms->delete(...$topics); // ????
if (Cnst::PT_ARCHIVE === $this->vStatus) {
$message = 'Dialogues moved to archive redirect';
$args['action'] = Cnst::ACTION_ARCHIVE;
} else {
$message = 'Dialogues deleted redirect';
unset($args['second']);
}
unset($args['more1']);
return $this->c->Redirect->page('PMAction', $args)->message($message);
}
}
$this->fIswev = $v->getErrors();
}
$this->nameTpl = 'pm/view';
$this->pmList = $this->pms->pmListCurPage();
$this->pagination = $this->pms->pagination;
if ($this->pmList) {
$this->form = $this->form($this->args);
}
return $this;
}
/**
* Определяет действие
*/
public function vActionProcess(Validator $v, $action)
{
if (! empty($v->getErrors())) {
return $action;
}
if (! empty($v->{Cnst::ACTION_ARCHIVE}) ) {
$this->vStatus = Cnst::PT_ARCHIVE;
if ($this->user->g_pm_limit > 0) {
if ($this->pms->totalArchive >= $this->user->g_pm_limit) {
$v->addError('Archive is full');
return $action;
} elseif ($this->pms->totalArchive + \count($v->ids) > $this->user->g_pm_limit) {
$v->addError('Cannot be moved');
return $action;
}
}
} elseif (! empty($v->{Cnst::ACTION_DELETE})) {
$this->vStatus = Cnst::PT_DELETED;
} else {
$v->addError('Unknown action selected');
return $action;
}
foreach ($v->ids as $id) {
if (! $this->pms->accessTopic($id)) {
$v->addError(['Dialogue %s is not yours', $id]);
return $action;
}
}
return $action;
}
/**
* Создает массив данных для формы подтверждения
*/
protected function formConfirm(Validator $v, array $args): array
{
$headers = [];
foreach ($this->pms->loadByIds(Cnst::PTOPIC, $v->ids) as $topic) {
$headers[] = __(['Dialogue %s', $topic->name]);
}
$btn = Cnst::PT_ARCHIVE === $this->vStatus ? Cnst::ACTION_ARCHIVE : Cnst::ACTION_DELETE;
$form = [
'action' => $this->c->Router->link('PMAction', $args),
'hidden' => [
'token' => $this->c->Csrf->create('PMAction', $args),
'ids' => $v->ids,
'action' => $v->{$btn},
],
'sets' => [
'info' => [
'info' => [
[
'value' => \implode('<br>', $headers),
'html' => true,
],
],
],
'action' => [
'fields' => [
'confirm' => [
'type' => 'checkbox',
'label' => __(Cnst::PT_ARCHIVE === $this->vStatus ? 'InfoSaveQm' : 'InfoDeleteQm'),
'value' => '1',
'checked' => false,
],
],
],
],
'btns' => [
$btn => [
'type' => 'submit',
'value' => __($v->{$btn}),
],
'cancel' => [
'type' => 'btn',
'value' => __('Cancel'),
'link' => $this->c->Router->link('PMAction', $args),
],
],
];
return $form;
}
/**
* Создает массив данных для формы удалени/переноса в архив
*/
protected function form(array $args): array
{
$form = [
'id' => 'id-form-pmview',
'action' => $this->c->Router->link('PMAction', $args),
'hidden' => [
'token' => $this->c->Csrf->create('PMAction', $args),
],
'sets' => [],
'btns' => [],
];
if (Cnst::ACTION_ARCHIVE !== $this->pms->area) {
$form['btns'][Cnst::ACTION_ARCHIVE] = [
'class' => 'origin',
'type' => 'submit',
'value' => __('To archive'),
];
}
$form['btns'][Cnst::ACTION_DELETE] = [
'class' => 'origin',
'type' => 'submit',
'value' => __('Delete'),
];
return $form;
}
}

View file

@ -0,0 +1,9 @@
@extends ('layouts/pm')
@if ($form = $p->form)
<section id="{{ $p->formId }}" class="f-pmform">
<h2>{!! __($p->formTitle) !!}</h2>
<div class="f-fdiv">
@include ('layouts/form')
</div>
</section>
@endif

View file

@ -47,7 +47,7 @@
@else
<li id="ptopic-{{ $topic->id }}" class="f-row @if ($topic->hasNew) f-fnew @endif @if ($topic->closed) f-fclosed @endif">
<div class="f-cell f-cmain">
<input id="checkbox-{{ $topic->id }}" class="f-fch" type="checkbox" name="ids[{{ $topic->id }}]" value="{{ $topic->id }}">
<input id="checkbox-{{ $topic->id }}" class="f-fch" type="checkbox" name="ids[{{ $topic->id }}]" value="{{ $topic->id }}" form="id-form-pmview">
<label class="f-ficon" for="checkbox-{{ $topic->id }}" title="{{ __('Select') }}"></label>
<div class="f-finfo">
<h3>
@ -89,9 +89,14 @@
</div>
@endif
</section>
@if ($p->pagination)
@if ($p->pagination || $p->form)
<div class="f-nav-links">
<div class="f-nlinks-a f-nlbpm">
@if ($form = $p->form)
<div class="f-actions-links">
@include ('layouts/form')
</div>
@endif
@yield ('pagination')
</div>
</div>

View file

@ -2447,6 +2447,19 @@ html[lang="ru"] #fork details[open] > summary::after {
border-top: 0.0625rem dotted;
}
#id-form-pmview .f-btns {
padding: 0;
}
#id-form-pmview .f-fbtn {
margin: 0 0 0.625rem 0;
}
#id-pmcnfrm-form.f-pmform .f-fbtn {
width: auto;
display: inline-block;
}
@media screen and (min-width: 50rem) {
#fork .f-nav-pm-links {
margin-right: 0;