3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
6 * Galette PDF controller
10 * Copyright © 2019 The Galette Team
12 * This file is part of Galette (http://galette.tuxfamily.org).
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.
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.
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/>.
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2019 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 * @link http://galette.tuxfamily.org
34 * @since Available since 0.9.4dev - 2019-12-05
37 namespace Galette\Controllers
;
39 use Slim\Http\Request
;
40 use Slim\Http\Response
;
42 use Galette\Core\Links
;
43 use Galette\Entity\Adherent
;
44 use Galette\Entity\Contribution
;
45 use Galette\Entity\PdfModel
;
46 use Galette\Filters\MembersList
;
48 use Galette\IO\PdfAttendanceSheet
;
49 use Galette\IO\PdfContribution
;
50 use Galette\IO\PdfGroups
;
51 use Galette\IO\PdfMembersCards
;
52 use Galette\IO\PdfMembersLabels
;
53 use Galette\Repository\Members
;
54 use Galette\Repository\Groups
;
55 use Galette\Repository\PdfModels
;
58 * Galette PDF controller
60 * @category Controllers
61 * @name GaletteController
63 * @author Johan Cwiklinski <johan@x-tnd.be>
64 * @copyright 2019 The Galette Team
65 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
66 * @link http://galette.tuxfamily.org
67 * @since Available since 0.9.4dev - 2019-12-05
70 class PdfController
extends AbstractController
75 * @param Response $response PSR Response
76 * @param Pdf $pdf PDF to output
80 protected function sendResponse(Response
$response, Pdf
$pdf): Response
83 ->withHeader('Content-type', 'application/pdf')
84 ->withHeader('Content-Disposition', 'attachment;filename="' . $pdf->getFileName() . '"')
85 ->write($pdf->download());
92 * @param Request $request PSR Request
93 * @param Response $response PSR Response
94 * @param array $args Request arguments
98 public function membersCards(Request
$request, Response
$response, array $args = []): Response
100 if ($this->session
->filter_members
) {
101 $filters = $this->session
->filter_members
;
103 $filters = new MembersList();
107 isset($args[Adherent
::PK
])
108 && $args[Adherent
::PK
] > 0
110 $id_adh = (int)$args[Adherent
::PK
];
111 $deps = ['dynamics' => true];
112 if ($this->login
->id
== $id_adh) {
113 $deps['dues'] = true;
120 if (!$adh->canEdit($this->login
)) {
121 $this->flash
->addMessage(
123 _T("You do not have permission for requested URL.")
130 $this->router
->pathFor('me')
134 //check if member is up to date
135 if ($this->login
->id
== $id_adh) {
136 if (!$adh->isUp2Date()) {
138 'Member ' . $id_adh . ' is not up to date; cannot get his PDF member card',
143 ->withHeader('Location', $this->router
->pathFor('slash'));
147 // If we are called from a member's card, get unique id value
150 if (count($filters->selected
) == 0) {
152 'No member selected to generate members cards',
155 $this->flash
->addMessage(
157 _T("No member was selected, please check at least one name.")
162 ->withHeader('Location', $this->router
->pathFor('members'));
166 // Fill array $selected with selected ids
168 if (isset($unique) && $unique) {
169 $selected[] = $unique;
171 $selected = $filters->selected
;
175 $members = $m->getArrayList(
177 array('nom_adh', 'prenom_adh'),
181 if (!is_array($members) ||
count($members) < 1) {
183 'An error has occurred, unable to get members list.',
187 $this->flash
->addMessage(
189 _T("Unable to get members list.")
194 ->withHeader('Location', $this->router
->pathFor('members'));
197 $pdf = new PdfMembersCards($this->preferences
);
198 $pdf->drawCards($members);
200 return $this->sendResponse($response, $pdf);
206 * @param Request $request PSR Request
207 * @param Response $response PSR Response
211 public function membersLabels(Request
$request, Response
$response): Response
213 $post = $request->getParsedBody();
214 $get = $request->getQueryParams();
216 $session_var = $post['session_var'] ??
$get['session_var'] ??
'filter_members';
218 if (isset($this->session
->$session_var)) {
219 $filters = $this->session
->$session_var;
221 $filters = new MembersList();
227 && $get['from'] === 'mailing'
229 //if we're from mailing, we have to retrieve
230 //its unreachables members for labels
231 $mailing = $this->session
->mailing
;
232 $members = $mailing->unreachables
;
234 if (count($filters->selected
) == 0) {
235 Analog
::log('No member selected to generate labels', Analog
::INFO
);
236 $this->flash
->addMessage(
238 _T("No member was selected, please check at least one name.")
243 ->withHeader('Location', $this->router
->pathFor('members'));
247 $members = $m->getArrayList(
249 array('nom_adh', 'prenom_adh')
253 if (!is_array($members) ||
count($members) < 1) {
255 'An error has occurred, unable to get members list.',
259 $this->flash
->addMessage(
261 _T("Unable to get members list.")
266 ->withHeader('Location', $this->router
->pathFor('members'));
269 $pdf = new PdfMembersLabels($this->preferences
);
270 $pdf->drawLabels($members);
272 return $this->sendResponse($response, $pdf);
278 * @param Request $request PSR Request
279 * @param Response $response PSR Response
280 * @param array $args Request arguments
284 public function adhesionForm(Request
$request, Response
$response, array $args = []): Response
286 $id_adh = isset($args[Adherent
::PK
]) ?
(int)$args[Adherent
::PK
] : null;
287 $adh = new Adherent($this->zdb
, $id_adh, ['dynamics' => true]);
289 if ($id_adh !== null && !$adh->canEdit($this->login
)) {
290 $this->flash
->addMessage(
292 _T("You do not have permission for requested URL.")
299 $this->router
->pathFor('me')
303 $form = $this->preferences
->pref_adhesion_form
;
304 $pdf = new $form($adh, $this->zdb
, $this->preferences
);
306 return $this->sendResponse($response, $pdf);
310 * PDF attendance sheet configuration page
312 * @param Request $request PSR Request
313 * @param Response $response PSR Response
314 * @param array $args Request arguments
318 public function attendanceSheetConfig(Request
$request, Response
$response, array $args = []): Response
320 $post = $request->getParsedBody();
322 if ($this->session
->filter_members
!== null) {
323 $filters = $this->session
->filter_members
;
325 $filters = new MembersList();
328 // check for ajax mode
332 ||
isset($post['ajax'])
333 && $post['ajax'] == 'true'
337 //retrieve selected members
338 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
340 $filters->selected
= $selection;
341 $this->session
->filter_members
= $filters;
343 $selection = $filters->selected
;
349 'attendance_sheet_details.tpl',
351 'page_title' => _T("Attendance sheet configuration"),
353 'selection' => $selection
360 * PDF attendance sheet
362 * @param Request $request PSR Request
363 * @param Response $response PSR Response
367 public function attendanceSheet(Request
$request, Response
$response): Response
369 $post = $request->getParsedBody();
371 if ($this->session
->filter_members
!== null) {
372 $filters = $this->session
->filter_members
;
374 $filters = new MembersList();
377 //retrieve selected members
378 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
380 $filters->selected
= $selection;
381 $this->session
->filter_members
= $filters;
383 if (count($filters->selected
) == 0) {
384 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
385 $this->flash
->addMessage(
387 _T("No member selected to generate attendance sheet")
392 ->withHeader('Location', $this->router
->pathFor('members'));
396 $members = $m->getArrayList(
398 array('nom_adh', 'prenom_adh'),
402 if (!is_array($members) ||
count($members) < 1) {
403 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
404 $this->flash
->addMessage(
406 _T("No member selected to generate attendance sheet")
411 ->withHeader('Location', $this->router
->pathFor('members'));
414 $doc_title = _T("Attendance sheet");
415 if (isset($post['sheet_type']) && trim($post['sheet_type']) != '') {
416 $doc_title = $post['sheet_type'];
420 'doc_title' => $doc_title,
421 'title' => $post['sheet_title'] ??
null,
422 'subtitle' => $post['sheet_sub_title'] ??
null,
423 'sheet_date' => $post['sheet_date'] ??
null
425 $pdf = new PdfAttendanceSheet($this->zdb
, $this->preferences
, $data);
426 //with or without images?
427 if (isset($post['sheet_photos']) && $post['sheet_photos'] === '1') {
430 $pdf->drawSheet($members);
432 return $this->sendResponse($response, $pdf);
438 * @param Request $request PSR Request
439 * @param Response $response PSR Response
440 * @param array $args Request arguments
444 public function contribution(Request
$request, Response
$response, array $args = []): Response
446 $contribution = new Contribution($this->zdb
, $this->login
, (int)$args['id']);
447 if ($contribution->id
== '') {
448 //not possible to load contribution, exit
449 $this->flash
->addMessage(
454 _T("Unable to load contribution #%id!")
459 ->withHeader('Location', $this->router
->pathFor(
461 ['type' => 'contributions']
464 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
465 return $this->sendResponse($response, $pdf);
472 * @param Request $request PSR Request
473 * @param Response $response PSR Response
474 * @param array $args Request arguments
478 public function group(Request
$request, Response
$response, array $args = []): Response
480 $groups = new Groups($this->zdb
, $this->login
);
483 if (isset($args['id'])) {
484 $groups_list = $groups->getList(true, $args['id']);
486 $groups_list = $groups->getList();
489 if (!is_array($groups_list) ||
count($groups_list) < 1) {
491 'An error has occurred, unable to get groups list.',
495 $this->flash
->addMessage(
497 _T("Unable to get groups list.")
502 ->withHeader('Location', $this->router
->pathFor('groups'));
505 $pdf = new PdfGroups($this->preferences
);
506 $pdf->draw($groups_list, $this->login
);
508 return $this->sendResponse($response, $pdf);
514 * @param Request $request PSR Request
515 * @param Response $response PSR Response
516 * @param array $args Request arguments
520 public function models(Request
$request, Response
$response, array $args = []): Response
523 if (isset($_POST[PdfModel
::PK
])) {
524 $id = (int)$_POST[PdfModel
::PK
];
525 } elseif (isset($args['id'])) {
526 $id = (int)$args['id'];
530 $ms = new PdfModels($this->zdb
, $this->preferences
, $this->login
);
531 $models = $ms->getList();
534 foreach ($models as $m) {
535 if ($m->id
=== $id) {
544 //Render directly template if we called from ajax,
545 //render in a full page otherwise
548 ||
isset($request->getQueryParams()['ajax'])
549 && $request->getQueryParams()['ajax'] == 'true'
551 $tpl = 'gestion_pdf_content.tpl';
552 $params['model'] = $model;
554 $tpl = 'gestion_pdf.tpl';
556 'page_title' => _T("PDF models"),
574 * @param Request $request PSR Request
575 * @param Response $response PSR Response
576 * @param array $args Request arguments
580 public function storeModels(Request
$request, Response
$response, array $args = []): Response
582 $post = $request->getParsedBody();
584 if (isset($post['model_type'])) {
585 $type = (int)$post['model_type'];
588 $error_detected = [];
589 if ($type === null) {
590 $error_detected[] = _T("Missing PDF model type!");
592 $class = PdfModel
::getTypeClass($type);
593 if (isset($post[PdfModel
::PK
])) {
594 $model = new $class($this->zdb
, $this->preferences
, (int)$_POST[PdfModel
::PK
]);
596 $model = new $class($this->zdb
, $this->preferences
);
600 $model->header
= $post['model_header'];
601 $model->footer
= $post['model_footer'];
602 $model->type
= $type;
603 if (isset($post['model_body'])) {
604 $model->body
= $post['model_body'];
606 if (isset($post['model_title'])) {
607 $model->title
= $post['model_title'];
609 if (isset($post['model_body'])) {
610 $model->subtitle
= $post['model_subtitle'];
612 if (isset($post['model_styles'])) {
613 $model->styles
= $post['model_styles'];
615 $res = $model->store();
617 $this->flash
->addMessage(
619 _T("Model has been successfully stored!")
622 $error_detected[] = _T("Model has not been stored :(");
624 } catch (\Exception
$e) {
625 $error_detected[] = $e->getMessage();
629 if (count($error_detected) > 0) {
630 foreach ($error_detected as $error) {
631 $this->flash
->addMessage(
640 ->withHeader('Location', $this->router
->pathFor('pdfModels', ['id' => $model->id
]));
645 * Get direct document
647 * @param Request $request PSR Request
648 * @param Response $response PSR Response
649 * @param array $args Request arguments
653 public function directlinkDocument(Request
$request, Response
$response, array $args = []): Response
655 $hash = $args['hash'];
656 $post = $request->getParsedBody();
657 $email = $post['email'];
659 $links = new Links($this->zdb
);
660 $valid = $links->isHashValid($hash, $email);
662 if ($valid === false) {
663 $this->flash
->addMessage(
668 return $response->withStatus(301)
669 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
675 if ($target === Links
::TARGET_MEMBERCARD
) {
677 $members = $m->getArrayList(
679 array('nom_adh', 'prenom_adh'),
683 if (!is_array($members) ||
count($members) < 1) {
685 'An error has occurred, unable to get members list.',
689 $this->flash
->addMessage(
691 _T("Unable to get members list.")
696 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
699 $pdf = new PdfMembersCards($this->preferences
);
700 $pdf->drawCards($members);
702 $contribution = new Contribution($this->zdb
, $this->login
, $id);
703 if ($contribution->id
== '') {
704 //not possible to load contribution, exit
705 $this->flash
->addMessage(
710 _T("Unable to load contribution #%id!")
715 ->withHeader('Location', $this->router
->pathFor(
720 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
724 return $this->sendResponse($response, $pdf);