From 5291a5ea2cfea5e68334ac3a749786821da5483b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Ho=CC=88=C3=9Fl?= Date: Sun, 14 Jul 2024 12:53:16 +0200 Subject: [PATCH] Motion filters now also affect exports --- History.md | 1 + controllers/MotionExportTraits.php | 9 +++- controllers/admin/MotionListController.php | 40 ++++++++------ models/forms/AdminMotionFilterForm.php | 56 +++++++++++++++----- views/admin/motion-list/_list_all_export.php | 9 +++- views/admin/motion-list/list_all.php | 3 +- 6 files changed, 84 insertions(+), 34 deletions(-) diff --git a/History.md b/History.md index 9ef8e7b66..9df83f636 100644 --- a/History.md +++ b/History.md @@ -2,6 +2,7 @@ ## Version 4.14.1 [not released yet] +- If a filter is set in the motion list, this will also filter the motions to be exported in the export row above (PDFs, ODTs, ODS etc.). - Bugfix: The PDF export with included proposed procedures was sometimes broken. - Bugfix: When multiple versions of a motion exist, the ODT / PDF export list showed all versions, instead of only the newest one. - Bugfix: If a motion replaces one of a different consultation, editing as an admin removed the connection between these two motion versions. diff --git a/controllers/MotionExportTraits.php b/controllers/MotionExportTraits.php index d196769cd..0cfda06b4 100644 --- a/controllers/MotionExportTraits.php +++ b/controllers/MotionExportTraits.php @@ -168,8 +168,13 @@ private function getMotionsAndTemplate(string $motionTypeId, bool $inactive, boo { /** @var TexTemplate $texTemplate */ $texTemplate = null; - // @TODO Maybe support multiple motion types - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, (int) $motionTypeId, $inactive); + + $search = AdminMotionFilterForm::getForConsultationFromRequest( + $this->consultation, + $this->consultation->motions, + $this->getRequestValue('Search') + ); + $imotions = $search->getMotionsForExport($this->consultation, (int) $motionTypeId, $inactive); if ($motionTypeId !== '' && $motionTypeId !== '0') { $motionTypeIds = explode(',', $motionTypeId); diff --git a/controllers/admin/MotionListController.php b/controllers/admin/MotionListController.php index d83074483..c03feb576 100644 --- a/controllers/admin/MotionListController.php +++ b/controllers/admin/MotionListController.php @@ -193,6 +193,17 @@ protected function actionListallProposalAmendments(): void } } + /** + * @param Motion[] $motions + */ + private function getSearchForm(array $motions): AdminMotionFilterForm + { + return AdminMotionFilterForm::getForConsultationFromRequest( + $this->consultation, + $motions, + $this->getRequestValue('Search') + ); + } public function actionIndex(?string $motionId = null): ResponseInterface { @@ -243,21 +254,12 @@ public function actionIndex(?string $motionId = null): ResponseInterface $motions = $consultation->motions; } - /** @var AdminMotionFilterForm $search */ - $search = new $motionListClass($consultation, $motions, $privilegeScreening); if ($this->isRequestSet('reset')) { RequestContext::getSession()->set('motionListSearch' . $consultation->id, null); return new RedirectResponse(UrlHelper::createUrl('/admin/motion-list/index')); } - if ($this->getRequestValue('Search')) { - $attributes = $this->getRequestValue('Search'); - RequestContext::getSession()->set('motionListSearch' . $consultation->id, $attributes); - $search->setAttributes($attributes); - } elseif (RequestContext::getSession()->get('motionListSearch' . $consultation->id)) { - $search->setAttributes(RequestContext::getSession()->get('motionListSearch' . $consultation->id)); - } + $search = $this->getSearchForm($motions); - /** @var AdminMotionFilterForm $search */ return new HtmlResponse($this->render('list_all', [ 'motionId' => $motionId, 'entries' => $search->getSorted(), @@ -312,7 +314,8 @@ public function actionMotionOdslistall(bool $inactive): BinaryFileResponse public function actionMotionOdslist(int $motionTypeId, bool $textCombined = false, int $inactive = 0): ResponseInterface { - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); + $search = $this->getSearchForm($this->consultation->motions); + $imotions = $search->getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); $motionType = $this->consultation->getMotionType($motionTypeId); $filename = Tools::sanitizeFilename($motionType->titlePlural, false); @@ -326,7 +329,8 @@ public function actionMotionOdslist(int $motionTypeId, bool $textCombined = fals public function actionMotionOpenslides(int $motionTypeId, int $version = 1): ResponseInterface { - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, $motionTypeId, false); + $search = $this->getSearchForm($this->consultation->motions); + $imotions = $search->getMotionsForExport($this->consultation, $motionTypeId, false); $motionType = $this->consultation->getMotionType($motionTypeId); $filename = Tools::sanitizeFilename($motionType->titlePlural, false); @@ -345,7 +349,8 @@ public function actionMotionOpenslides(int $motionTypeId, int $version = 1): Res public function actionMotionCommentsXlsx(int $motionTypeId, int $inactive = 0): ResponseInterface { - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); + $search = $this->getSearchForm($this->consultation->motions); + $imotions = $search->getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); $motionType = $this->consultation->getMotionType($motionTypeId); $filename = Tools::sanitizeFilename(\Yii::t('export', 'Kommentare') . '-' . $motionType->titlePlural, false); @@ -358,7 +363,8 @@ public function actionMotionCommentsXlsx(int $motionTypeId, int $inactive = 0): public function actionMotionPdfziplist(int $motionTypeId = 0, int $inactive = 0): ResponseInterface { - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); + $search = $this->getSearchForm($this->consultation->motions); + $imotions = $search->getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); $zip = new ZipWriter(); foreach ($imotions as $imotion) { @@ -394,7 +400,8 @@ public function actionMotionPdfziplist(int $motionTypeId = 0, int $inactive = 0) public function actionMotionOdtziplist(int $motionTypeId = 0, int $inactive = 0): ResponseInterface { - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); + $search = $this->getSearchForm($this->consultation->motions); + $imotions = $search->getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); $zip = new ZipWriter(); foreach ($imotions as $imotion) { @@ -415,7 +422,8 @@ public function actionMotionOdtziplist(int $motionTypeId = 0, int $inactive = 0) public function actionMotionOdtall(int $motionTypeId = 0, int $inactive = 0): ResponseInterface { - $imotions = AdminMotionFilterForm::getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); + $search = $this->getSearchForm($this->consultation->motions); + $imotions = $search->getMotionsForExport($this->consultation, $motionTypeId, ($inactive === 1)); $doc = $imotions[0]->getMyMotionType()->createOdtTextHandler(); diff --git a/models/forms/AdminMotionFilterForm.php b/models/forms/AdminMotionFilterForm.php index 9553e4dcf..47b01a916 100644 --- a/models/forms/AdminMotionFilterForm.php +++ b/models/forms/AdminMotionFilterForm.php @@ -8,7 +8,7 @@ use app\models\settings\{AntragsgruenApp, PrivilegeQueryContext, Privileges}; use app\models\exceptions\{ExceptionBase, ResponseException}; use app\models\http\HtmlErrorResponse; -use app\components\{IMotionStatusFilter, Tools, UrlHelper}; +use app\components\{IMotionStatusFilter, RequestContext, Tools, UrlHelper}; use app\models\db\{Amendment, AmendmentSupporter, Consultation, ConsultationSettingsTag, IMotion, ISupporter, Motion, MotionSupporter, User}; use yii\helpers\Html; @@ -63,6 +63,25 @@ public static function getClassToUse(): string return AdminMotionFilterForm::class; } + /** + * @param Motion[] $motions + */ + public static function getForConsultationFromRequest(Consultation $consultation, array $motions, ?array $searchParams): AdminMotionFilterForm + { + $motionListClass = AdminMotionFilterForm::getClassToUse(); + $privilegeScreening = User::havePrivilege($consultation, Privileges::PRIVILEGE_SCREENING, PrivilegeQueryContext::anyRestriction()); + + $search = new $motionListClass($consultation, $motions, $privilegeScreening); + if ($searchParams) { + RequestContext::getSession()->set('motionListSearch' . $consultation->id, $searchParams); + $search->setAttributes($searchParams); + } elseif (RequestContext::getSession()->get('motionListSearch' . $consultation->id)) { + $search->setAttributes(RequestContext::getSession()->get('motionListSearch' . $consultation->id)); + } + + return $search; + } + /** * @param Motion[] $allMotions */ @@ -177,13 +196,18 @@ public function setCurrentRoute(array $route): void $this->route = $route; } - public function getCurrentUrl(array $add = []): string + public function getSearchUrlParams(): array { $attributes = []; foreach ($this->getAttributes() as $key => $val) { $attributes['Search[' . $key . ']'] = $val; } - return UrlHelper::createUrl(array_merge($this->route, $attributes, $add)); + return $attributes; + } + + public function getCurrentUrl(array $add = []): string + { + return UrlHelper::createUrl(array_merge($this->route, $this->getSearchUrlParams(), $add)); } private ?array $versionNames = null; @@ -1281,10 +1305,12 @@ public function showListActions(): string /** * Returns motions and statute amendments + * If a filter is set via the motion filter, then this will return exactly what the motion list will show (only filtered by type). + * Otherwise, the inactive-flag will be considered. * * @return IMotion[] */ - public static function getMotionsForExport(Consultation $consultation, ?int $motionTypeId, bool $inactive): array + public function getMotionsForExport(Consultation $consultation, ?int $motionTypeId, bool $inactive): array { if ($motionTypeId) { try { @@ -1294,19 +1320,23 @@ public static function getMotionsForExport(Consultation $consultation, ?int $mot } } - $privilegeScreening = User::havePrivilege($consultation, Privileges::PRIVILEGE_SCREENING, PrivilegeQueryContext::anyRestriction()); + if ($this->isDefaultSettings()) { + if ($motionTypeId > 0) { + $this->motionType = $motionTypeId; + } - $motionListClass = AdminMotionFilterForm::getClassToUse(); - $search = new $motionListClass($consultation, $consultation->motions, $privilegeScreening); - if ($motionTypeId > 0) { - $search->motionType = $motionTypeId; - } + $imotions = $this->getSorted(); + $filter = IMotionStatusFilter::adminExport($consultation, $inactive); + $allIMotions = $filter->filterIMotions($imotions); + } else { + if ($motionTypeId > 0) { + $this->motionType = $motionTypeId; + } - $imotions = $search->getSorted(); + $allIMotions = $this->getSorted(); + } try { - $filter = IMotionStatusFilter::adminExport($consultation, $inactive); - $allIMotions = $filter->filterIMotions($imotions); if (count($allIMotions) === 0) { throw new ResponseException(new HtmlErrorResponse(404, \Yii::t('motion', 'none_yet'))); } diff --git a/views/admin/motion-list/_list_all_export.php b/views/admin/motion-list/_list_all_export.php index 5db750853..845ed7fb7 100644 --- a/views/admin/motion-list/_list_all_export.php +++ b/views/admin/motion-list/_list_all_export.php @@ -3,13 +3,14 @@ /** * @var \app\controllers\Base $controller * @var Yii\web\View $this + * @var AdminMotionFilterForm $search * @var bool $hasProposedProcedures * @var bool $hasResponsibilities */ +use app\models\forms\AdminMotionFilterForm; use app\models\settings\Privileges; use app\components\{HTMLTools, UrlHelper}; -use app\models\settings\AntragsgruenApp; use yii\helpers\Html; $controller = $this->context; @@ -19,9 +20,13 @@ $hasOpenslides = $consultation->getSettings()->openslidesExportEnabled; $hasInactiveFunctionality = (!$hasResponsibilities || !$hasProposedProcedures || !$hasOpenslides); -$getExportLinkLi = function ($title, $route, $motionTypeId, $cssClass) { +$getExportLinkLi = function ($title, $route, $motionTypeId, $cssClass) use ($search) { $params = array_merge($route, ['motionTypeId' => $motionTypeId, 'inactive' => '0']); $paramsTmpl = array_merge($route, ['motionTypeId' => $motionTypeId, 'inactive' => 'INACTIVE']); + if (!$search->isDefaultSettings()) { + $params = array_merge($params, $search->getSearchUrlParams()); + $paramsTmpl = array_merge($paramsTmpl, $search->getSearchUrlParams()); + } if ($route[0] === 'amendment/pdfcollection') { $params['filename'] = Yii::t('con', 'feed_amendments') . '.pdf'; $paramsTmpl['filename'] = Yii::t('con', 'feed_amendments') . '.pdf'; diff --git a/views/admin/motion-list/list_all.php b/views/admin/motion-list/list_all.php index 4ce26ca02..57506b061 100644 --- a/views/admin/motion-list/list_all.php +++ b/views/admin/motion-list/list_all.php @@ -58,7 +58,8 @@ echo $this->render('_list_all_export', [ 'hasProposedProcedures' => $hasProposedProcedures, - 'hasResponsibilities' => $hasResponsibilities, + 'hasResponsibilities' => $hasResponsibilities, + 'search' => $search, ]); echo '
';