]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Controllers/GaletteController.php
eccd54abb09e745438a9d510b873892456b62391
[galette.git] / galette / lib / Galette / Controllers / GaletteController.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Galette main controller
7 *
8 * PHP version 5
9 *
10 * Copyright © 2019-2020 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Entity
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2019-2020 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @version SVN: $Id$
34 * @link http://galette.tuxfamily.org
35 * @since Available since 0.9.4dev - 2019-12-02
36 */
37
38 namespace Galette\Controllers;
39
40 use Slim\Http\Request;
41 use Slim\Http\Response;
42 use Galette\Core\Logo;
43 use Galette\Core\PrintLogo;
44 use Galette\Core\GaletteMail;
45 use Galette\Core\SysInfos;
46 use Galette\Entity\Contribution;
47 use Galette\Entity\FieldsCategories;
48 use Galette\Entity\Status;
49 use Galette\Entity\Texts;
50 use Galette\Filters\MembersList;
51 use Galette\IO\News;
52 use Galette\IO\Charts;
53 use Galette\IO\PdfMembersCards;
54 use Galette\IO\PdfContribution;
55 use Galette\Repository\Members;
56 use Galette\Repository\Reminders;
57 use Analog\Analog;
58
59 /**
60 * Galette main controller
61 *
62 * @category Controllers
63 * @name GaletteController
64 * @package Galette
65 * @author Johan Cwiklinski <johan@x-tnd.be>
66 * @copyright 2019-2020 The Galette Team
67 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
68 * @link http://galette.tuxfamily.org
69 * @since Available since 0.9.4dev - 2019-12-02
70 */
71
72 class GaletteController extends AbstractController
73 {
74 /**
75 * Main route
76 *
77 * @param Request $request PSR Request
78 * @param Response $response PSR Response
79 * @param array $args Request arguments
80 *
81 * @return Response
82 */
83 public function slash(Request $request, Response $response, array $args = []) :Response
84 {
85 return $this->galetteRedirect($request, $response, $args);
86 }
87
88 /**
89 * System information
90 *
91 * @param Request $request PSR Request
92 * @param Response $response PSR Response
93 *
94 * @return Response
95 */
96 public function systemInformation(Request $request, Response $response) :Response
97 {
98 $sysinfos = new SysInfos();
99 $raw_infos = $sysinfos->getRawData(
100 $this->zdb,
101 $this->preferences,
102 $this->plugins
103 );
104
105 // display page
106 $this->view->render(
107 $response,
108 'sysinfos.tpl',
109 array(
110 'page_title' => _T("System information"),
111 'rawinfos' => $raw_infos
112 )
113 );
114 return $response;
115 }
116
117 /**
118 * Dashboard page
119 *
120 * @param Request $request PSR Request
121 * @param Response $response PSR Response
122 *
123 * @return Response
124 */
125 public function dashboard(Request $request, Response $response) :Response
126 {
127 $news = new News($this->preferences->pref_rss_url);
128
129 $params = [
130 'page_title' => _T("Dashboard"),
131 'contentcls' => 'desktop',
132 'news' => $news->getPosts(),
133 'show_dashboard' => $_COOKIE['show_galette_dashboard']
134 ];
135
136 $hide_telemetry = true;
137 if ($this->login->isAdmin()) {
138 $telemetry = new \Galette\Util\Telemetry(
139 $this->zdb,
140 $this->preferences,
141 $this->plugins
142 );
143 $params['reguuid'] = $telemetry->getRegistrationUuid();
144 $params['telemetry_sent'] = $telemetry->isSent();
145 $params['registered'] = $telemetry->isRegistered();
146
147 $hide_telemetry = $telemetry->isSent() && $telemetry->isRegistered()
148 || isset($_COOKIE['hide_galette_telemetry']) && $_COOKIE['hide_galette_telemetry'];
149 }
150 $params['hide_telemetry'] = $hide_telemetry;
151
152 // display page
153 $this->view->render(
154 $response,
155 'desktop.tpl',
156 $params
157 );
158 return $response;
159 }
160
161 /**
162 * Preferences page
163 *
164 * @param Request $request PSR Request
165 * @param Response $response PSR Response
166 *
167 * @return Response
168 */
169 public function preferences(Request $request, Response $response) :Response
170 {
171 // flagging required fields
172 $required = array(
173 'pref_nom' => 1,
174 'pref_lang' => 1,
175 'pref_numrows' => 1,
176 'pref_log' => 1,
177 'pref_statut' => 1,
178 'pref_etiq_marges_v' => 1,
179 'pref_etiq_marges_h' => 1,
180 'pref_etiq_hspace' => 1,
181 'pref_etiq_vspace' => 1,
182 'pref_etiq_hsize' => 1,
183 'pref_etiq_vsize' => 1,
184 'pref_etiq_cols' => 1,
185 'pref_etiq_rows' => 1,
186 'pref_etiq_corps' => 1,
187 'pref_card_abrev' => 1,
188 'pref_card_strip' => 1,
189 'pref_card_marges_v' => 1,
190 'pref_card_marges_h' => 1,
191 'pref_card_hspace' => 1,
192 'pref_card_vspace' => 1
193 );
194
195 if ($this->login->isSuperAdmin() && GALETTE_MODE !== 'DEMO') {
196 $required['pref_admin_login'] = 1;
197 }
198
199 $prefs_fields = $this->preferences->getFieldsNames();
200 // collect data
201 foreach ($prefs_fields as $fieldname) {
202 $pref[$fieldname] = $this->preferences->$fieldname;
203 }
204
205 //on error, user values are stored into session
206 if ($this->session->entered_preferences) {
207 $pref = array_merge($pref, $this->session->entered_preferences);
208 $this->session->entered_preferences = null;
209 }
210
211 //List available themes
212 $themes = array();
213 $d = dir(GALETTE_THEMES_PATH);
214 while (($entry = $d->read()) !== false) {
215 $full_entry = GALETTE_THEMES_PATH . $entry;
216 if ($entry != '.'
217 && $entry != '..'
218 && is_dir($full_entry)
219 && file_exists($full_entry.'/page.tpl')
220 ) {
221 $themes[] = $entry;
222 }
223 }
224 $d->close();
225
226 $m = new Members();
227 $s = new Status($this->zdb);
228
229 // display page
230 $this->view->render(
231 $response,
232 'preferences.tpl',
233 array(
234 'page_title' => _T("Settings"),
235 'staff_members' => $m->getStaffMembersList(true),
236 'time' => time(),
237 'pref' => $pref,
238 'pref_numrows_options' => array(
239 10 => '10',
240 20 => '20',
241 50 => '50',
242 100 => '100'
243 ),
244 'print_logo' => $this->print_logo,
245 'required' => $required,
246 'themes' => $themes,
247 'statuts' => $s->getList(),
248 'accounts_options' => array(
249 Members::ALL_ACCOUNTS => _T("All accounts"),
250 Members::ACTIVE_ACCOUNT => _T("Active accounts"),
251 Members::INACTIVE_ACCOUNT => _T("Inactive accounts")
252 )
253 )
254 );
255 return $response;
256 }
257
258 /**
259 * Store preferences
260 *
261 * @param Request $request PSR Request
262 * @param Response $response PSR Response
263 *
264 * @return Response
265 */
266 public function storePreferences(Request $request, Response $response) :Response
267 {
268 $post = $request->getParsedBody();
269 $error_detected = [];
270 $warning_detected = [];
271
272 // Validation
273 if (isset($post['valid']) && $post['valid'] == '1') {
274 if ($this->preferences->check($post, $this->login)) {
275 if (!$this->preferences->store()) {
276 $error_detected[] = _T("An SQL error has occurred while storing preferences. Please try again, and contact the administrator if the problem persists.");
277 } else {
278 $this->flash->addMessage(
279 'success_detected',
280 _T("Preferences has been saved.")
281 );
282 }
283 $warning_detected = array_merge($warning_detected, $this->preferences->checkCardsSizes());
284
285 // picture upload
286 if (GALETTE_MODE !== 'DEMO' && isset($_FILES['logo'])) {
287 if ($_FILES['logo']['error'] === UPLOAD_ERR_OK) {
288 if ($_FILES['logo']['tmp_name'] !='') {
289 if (is_uploaded_file($_FILES['logo']['tmp_name'])) {
290 $res = $this->logo->store($_FILES['logo']);
291 if ($res < 0) {
292 $error_detected[] = $this->logo->getErrorMessage($res);
293 } else {
294 $this->logo = new Logo();
295 }
296 }
297 }
298 } elseif ($_FILES['logo']['error'] !== UPLOAD_ERR_NO_FILE) {
299 Analog::log(
300 $this->logo->getPhpErrorMessage($_FILES['logo']['error']),
301 Analog::WARNING
302 );
303 $error_detected[] = $this->logo->getPhpErrorMessage(
304 $_FILES['logo']['error']
305 );
306 }
307 }
308
309 if (GALETTE_MODE !== 'DEMO' && isset($post['del_logo'])) {
310 if (!$this->logo->delete()) {
311 $error_detected[] = _T("Delete failed");
312 } else {
313 $this->logo = new Logo(); //get default Logo
314 }
315 }
316
317 // Card logo upload
318 if (GALETTE_MODE !== 'DEMO' && isset($_FILES['card_logo'])) {
319 if ($_FILES['card_logo']['error'] === UPLOAD_ERR_OK) {
320 if ($_FILES['card_logo']['tmp_name'] !='') {
321 if (is_uploaded_file($_FILES['card_logo']['tmp_name'])) {
322 $res = $this->print_logo->store($_FILES['card_logo']);
323 if ($res < 0) {
324 $error_detected[] = $this->print_logo->getErrorMessage($res);
325 } else {
326 $this->print_logo = new PrintLogo();
327 }
328 }
329 }
330 } elseif ($_FILES['card_logo']['error'] !== UPLOAD_ERR_NO_FILE) {
331 Analog::log(
332 $this->print_logo->getPhpErrorMessage($_FILES['card_logo']['error']),
333 Analog::WARNING
334 );
335 $error_detected[] = $this->print_logo->getPhpErrorMessage(
336 $_FILES['card_logo']['error']
337 );
338 }
339 }
340
341 if (GALETTE_MODE !== 'DEMO' && isset($post['del_card_logo'])) {
342 if (!$this->print_logo->delete()) {
343 $error_detected[] = _T("Delete failed");
344 } else {
345 $this->print_logo = new PrintLogo();
346 }
347 }
348 } else {
349 $error_detected = $this->preferences->getErrors();
350 }
351
352 if (count($error_detected) > 0) {
353 $this->session->entered_preferences = $post;
354 //report errors
355 foreach ($error_detected as $error) {
356 $this->flash->addMessage(
357 'error_detected',
358 $error
359 );
360 }
361 }
362
363 if (count($warning_detected) > 0) {
364 //report warnings
365 foreach ($warning_detected as $warning) {
366 $this->flash->addMessage(
367 'warning_detected',
368 $warning
369 );
370 }
371 }
372 }
373
374 return $response
375 ->withStatus(301)
376 ->withHeader('Location', $this->router->pathFor('preferences'));
377 }
378
379 /**
380 * Test mail parameters
381 *
382 * @param Request $request PSR Request
383 * @param Response $response PSR Response
384 *
385 * @return Response
386 */
387 public function testEmail(Request $request, Response $response) :Response
388 {
389 $sent = false;
390 if (!$this->preferences->pref_mail_method > GaletteMail::METHOD_DISABLED) {
391 $this->flash->addMessage(
392 'error_detected',
393 _T("You asked Galette to send a test email, but email has been disabled in the preferences.")
394 );
395 } else {
396 $get = $request->getQueryParams();
397 $dest = (isset($get['adress']) ? $get['adress'] : $this->preferences->pref_email_newadh);
398 if (GaletteMail::isValidEmail($dest)) {
399 $mail = new GaletteMail($this->preferences);
400 $mail->setSubject(_T('Test message'));
401 $mail->setRecipients(
402 array(
403 $dest => _T("Galette admin")
404 )
405 );
406 $mail->setMessage(_T('Test message.'));
407 $sent = $mail->send();
408
409 if ($sent) {
410 $this->flash->addMessage(
411 'success_detected',
412 str_replace(
413 '%email',
414 $dest,
415 _T("An email has been sent to %email")
416 )
417 );
418 } else {
419 $this->flash->addMessage(
420 'error_detected',
421 str_replace(
422 '%email',
423 $dest,
424 _T("No email sent to %email")
425 )
426 );
427 }
428 } else {
429 $this->flash->addMessage(
430 'error_detected',
431 _T("Invalid email adress!")
432 );
433 }
434 }
435
436 if (!$request->isXhr()) {
437 return $response
438 ->withStatus(301)
439 ->withHeader('Location', $this->router->pathFor('preferences'));
440 } else {
441 return $response->withJson(
442 [
443 'sent' => $sent
444 ]
445 );
446 }
447 }
448
449 /**
450 * Charts page
451 *
452 * @param Request $request PSR Request
453 * @param Response $response PSR Response
454 *
455 * @return Response
456 */
457 public function charts(Request $request, Response $response) :Response
458 {
459 $charts = new Charts(
460 array(
461 Charts::MEMBERS_STATUS_PIE,
462 Charts::MEMBERS_STATEDUE_PIE,
463 Charts::CONTRIBS_TYPES_PIE,
464 Charts::COMPANIES_OR_NOT,
465 Charts::CONTRIBS_ALLTIME
466 )
467 );
468
469 // display page
470 $this->view->render(
471 $response,
472 'charts.tpl',
473 array(
474 'page_title' => _T("Charts"),
475 'charts' => $charts->getCharts(),
476 'require_charts' => true
477 )
478 );
479 return $response;
480 }
481
482 /**
483 * Core fields configuration page
484 *
485 * @param Request $request PSR Request
486 * @param Response $response PSR Response
487 *
488 * @return Response
489 */
490 public function configureCoreFields(Request $request, Response $response) :Response
491 {
492 $fc = $this->fields_config;
493
494 $params = [
495 'page_title' => _T("Fields configuration"),
496 'time' => time(),
497 'categories' => FieldsCategories::getList($this->zdb),
498 'categorized_fields' => $fc->getCategorizedFields(),
499 'non_required' => $fc->getNonRequired()
500 ];
501
502 // display page
503 $this->view->render(
504 $response,
505 'config_fields.tpl',
506 $params
507 );
508 return $response;
509 }
510
511 /**
512 * Process core fields configuration
513 *
514 * @param Request $request PSR Request
515 * @param Response $response PSR Response
516 *
517 * @return Response
518 */
519 public function storeCoreFieldsConfig(Request $request, Response $response) :Response
520 {
521 $post = $request->getParsedBody();
522 $fc = $this->fields_config;
523
524 $pos = 0;
525 $current_cat = 0;
526 $res = array();
527 foreach ($post['fields'] as $abs_pos => $field) {
528 if ($current_cat != $post[$field . '_category']) {
529 //reset position when category has changed
530 $pos = 0;
531 //set new current category
532 $current_cat = $post[$field . '_category'];
533 }
534
535 $required = null;
536 if (isset($post[$field . '_required'])) {
537 $required = $post[$field . '_required'];
538 } else {
539 $required = false;
540 }
541
542 $res[$current_cat][] = array(
543 'field_id' => $field,
544 'label' => $post[$field . '_label'],
545 'category' => $post[$field . '_category'],
546 'visible' => $post[$field . '_visible'],
547 'required' => $required
548 );
549 $pos++;
550 }
551 //okay, we've got the new array, we send it to the
552 //Object that will store it in the database
553 $success = $fc->setFields($res);
554 FieldsCategories::setCategories($this->zdb, $post['categories']);
555 if ($success === true) {
556 $this->flash->addMessage(
557 'success_detected',
558 _T("Fields configuration has been successfully stored")
559 );
560 } else {
561 $this->flash->addMessage(
562 'error_detected',
563 _T("An error occurred while storing fields configuration :(")
564 );
565 }
566
567 return $response
568 ->withStatus(301)
569 ->withHeader('Location', $this->router->pathFor('configureCoreFields'));
570 }
571
572 /**
573 * Core lists configuration page
574 *
575 * @param Request $request PSR Request
576 * @param Response $response PSR Response
577 * @param array $args Request arguments
578 *
579 * @return Response
580 */
581 public function configureListFields(Request $request, Response $response, array $args = []) :Response
582 {
583 $table = $args['table'];
584 //TODO: check if type table exists
585
586 $lc = $this->lists_config;
587
588 $params = [
589 'page_title' => _T("Lists configuration"),
590 'table' => $table,
591 'time' => time(),
592 'listed_fields' => $lc->getListedFields(),
593 'remaining_fields' => $lc->getRemainingFields()
594 ];
595
596 // display page
597 $this->view->render(
598 $response,
599 'config_lists.tpl',
600 $params
601 );
602 return $response;
603 }
604
605 /**
606 * Process list fields configuration
607 *
608 * @param Request $request PSR Request
609 * @param Response $response PSR Response
610 * @param array $args Request arguments
611 *
612 * @return Response
613 */
614 public function storeListFields(Request $request, Response $response, array $args = []) :Response
615 {
616 $post = $request->getParsedBody();
617
618 $lc = $this->lists_config;
619 $fields = [];
620 foreach ($post['fields'] as $field) {
621 $fields[] = $lc->getField($field);
622 }
623 $success = $lc->setListFields($fields);
624
625 if ($success === true) {
626 $this->flash->addMessage(
627 'success_detected',
628 _T("List configuration has been successfully stored")
629 );
630 } else {
631 $this->flash->addMessage(
632 'error_detected',
633 _T("An error occurred while storing list configuration :(")
634 );
635 }
636
637 return $response
638 ->withStatus(301)
639 ->withHeader('Location', $this->router->pathFor('configureListFields', $args));
640 }
641
642 /**
643 * Fake data page
644 *
645 * @param Request $request PSR Request
646 * @param Response $response PSR Response
647 *
648 * @return Response
649 */
650 public function fakeData(Request $request, Response $response) :Response
651 {
652 $params = [
653 'page_title' => _T('Generate fake data'),
654 'number_members' => \Galette\Util\FakeData::DEFAULT_NB_MEMBERS,
655 'number_contrib' => \Galette\Util\FakeData::DEFAULT_NB_CONTRIB,
656 'number_groups' => \Galette\Util\FakeData::DEFAULT_NB_GROUPS,
657 'number_transactions' => \Galette\Util\FakeData::DEFAULT_NB_TRANSACTIONS,
658 'photos' => \Galette\Util\FakeData::DEFAULT_PHOTOS
659 ];
660
661 // display page
662 $this->view->render(
663 $response,
664 'fake_data.tpl',
665 $params
666 );
667 return $response;
668 }
669
670 /**
671 * Generate fake data
672 *
673 * @param Request $request PSR Request
674 * @param Response $response PSR Response
675 *
676 * @return Response
677 */
678 public function doFakeData(Request $request, Response $response) :Response
679 {
680 $post = $request->getParsedBody();
681
682 $fakedata = new \Galette\Util\FakeData($this->zdb, $this->i18n);
683
684 $fakedata->setDependencies(
685 $this->preferences,
686 $this->members_fields,
687 $this->history,
688 $this->login
689 );
690
691 $fakedata
692 ->setNbMembers($post['number_members'])
693 ->setNbGroups($post['number_groups'])
694 ->setNbTransactions($post['number_transactions'])
695 ->setMaxContribs($post['number_contrib'])
696 ->setWithPhotos(isset($post['photos']));
697
698 $fakedata->generate();
699
700 $report = $fakedata->getReport();
701
702 foreach ($report['success'] as $success) {
703 $this->flash->addMessage(
704 'success_detected',
705 $success
706 );
707 }
708
709 foreach ($report['errors'] as $error) {
710 $this->flash->addMessage(
711 'error_detected',
712 $error
713 );
714 }
715
716 foreach ($report['warnings'] as $warning) {
717 $this->flash->addMessage(
718 'warning_detected',
719 $warning
720 );
721 }
722
723 return $response
724 ->withStatus(301)
725 ->withHeader('Location', $this->router->pathFor('slash'));
726 }
727
728 /**
729 * Reminders page
730 *
731 * @param Request $request PSR Request
732 * @param Response $response PSR Response
733 *
734 * @return Response
735 */
736 public function reminders(Request $request, Response $response) :Response
737 {
738 $texts = new Texts($this->preferences, $this->router);
739
740 $previews = array(
741 'impending' => $texts->getTexts('impendingduedate', $this->preferences->pref_lang),
742 'late' => $texts->getTexts('lateduedate', $this->preferences->pref_lang)
743 );
744
745 $members = new Members();
746 $reminders = $members->getRemindersCount();
747
748 // display page
749 $this->view->render(
750 $response,
751 'reminder.tpl',
752 [
753 'page_title' => _T("Reminders"),
754 'previews' => $previews,
755 'count_impending' => $reminders['impending'],
756 'count_impending_nomail' => $reminders['nomail']['impending'],
757 'count_late' => $reminders['late'],
758 'count_late_nomail' => $reminders['nomail']['late']
759 ]
760 );
761 return $response;
762 }
763
764 /**
765 * Main route
766 *
767 * @param Request $request PSR Request
768 * @param Response $response PSR Response
769 *
770 * @return Response
771 */
772 public function doReminders(Request $request, Response $response) :Response
773 {
774 $error_detected = [];
775 $warning_detected = [];
776 $success_detected = [];
777
778 $post = $request->getParsedBody();
779 $texts = new Texts($this->preferences, $this->router);
780 $selected = null;
781 if (isset($post['reminders'])) {
782 $selected = $post['reminders'];
783 }
784 $reminders = new Reminders($selected);
785
786 $labels = false;
787 $labels_members = array();
788 if (isset($post['reminder_wo_mail'])) {
789 $labels = true;
790 }
791
792 $list_reminders = $reminders->getList($this->zdb, $labels);
793 if (count($list_reminders) == 0) {
794 $warning_detected[] = _T("No reminder to send for now.");
795 } else {
796 foreach ($list_reminders as $reminder) {
797 if ($labels === false) {
798 //send reminders by email
799 $sent = $reminder->send($texts, $this->history, $this->zdb);
800
801 if ($sent === true) {
802 $success_detected[] = $reminder->getMessage();
803 } else {
804 $error_detected[] = $reminder->getMessage();
805 }
806 } else {
807 //generate labels for members without email address
808 $labels_members[] = $reminder->member_id;
809 }
810 }
811
812 if ($labels === true) {
813 if (count($labels_members) > 0) {
814 $session_var = 'filters_reminders_labels';
815 $labels_filters = new MembersList();
816 $labels_filters->selected = $labels_members;
817 $this->session->$session_var = $labels_filters;
818 return $response
819 ->withStatus(307)
820 ->withHeader(
821 'Location',
822 $this->router->pathFor('pdf-member-labels') . '?session_var=' . $session_var
823 );
824 } else {
825 $error_detected[] = _T("There are no member to proceed.");
826 }
827 }
828
829 if (count($error_detected) > 0) {
830 array_unshift(
831 $error_detected,
832 _T("Reminder has not been sent:")
833 );
834 }
835
836 if (count($success_detected) > 0) {
837 array_unshift(
838 $success_detected,
839 _T("Sent reminders:")
840 );
841 }
842 }
843
844 //flash messages if any
845 if (count($error_detected) > 0) {
846 foreach ($error_detected as $error) {
847 $this->flash->addMessage('error_detected', $error);
848 }
849 }
850 if (count($warning_detected) > 0) {
851 foreach ($warning_detected as $warning) {
852 $this->flash->addMessage('warning_detected', $warning);
853 }
854 }
855 if (count($success_detected) > 0) {
856 foreach ($success_detected as $success) {
857 $this->flash->addMessage('success_detected', $success);
858 }
859 }
860
861 return $response
862 ->withStatus(301)
863 ->withHeader('Location', $this->router->pathFor('reminders'));
864 }
865
866 /**
867 * Main route
868 *
869 * @param Request $request PSR Request
870 * @param Response $response PSR Response
871 * @param array $args Request arguments
872 *
873 * @return Response
874 */
875 public function filterReminders(Request $request, Response $response, array $args = []) :Response
876 {
877 //always reset filters
878 $filters = new MembersList();
879 $filters->filter_account = Members::ACTIVE_ACCOUNT;
880
881 $membership = ($args['membership'] === 'nearly' ?
882 Members::MEMBERSHIP_NEARLY :
883 Members::MEMBERSHIP_LATE);
884 $filters->membership_filter = $membership;
885
886 //TODO: filter on reminder may take care of parent email as well
887 $mail = ($args['mail'] === 'withmail' ?
888 Members::FILTER_W_EMAIL :
889 Members::FILTER_WO_EMAIL);
890 $filters->email_filter = $mail;
891
892 $this->session->filter_members = $filters;
893
894 return $response
895 ->withStatus(301)
896 ->withHeader('Location', $this->router->pathFor('members'));
897 }
898
899 /**
900 * Direct document page
901 *
902 * @param Request $request PSR Request
903 * @param Response $response PSR Response
904 * @param array $args Request arguments
905 *
906 * @return Response
907 */
908 public function documentLink(Request $request, Response $response, array $args = []) :Response
909 {
910 // display page
911 $this->view->render(
912 $response,
913 'directlink.tpl',
914 array(
915 'hash' => $args['hash'],
916 'page_title' => _T('Download document')
917 )
918 );
919 return $response;
920 }
921 }