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
34 * @link http://galette.tuxfamily.org
35 * @since Available since 0.9.4dev - 2019-12-05
38 namespace Galette\Controllers
;
40 use Slim\Http\Request
;
41 use Slim\Http\Response
;
43 use Galette\Core\Links
;
44 use Galette\Entity\Adherent
;
45 use Galette\Entity\Contribution
;
46 use Galette\Entity\PdfModel
;
47 use Galette\Filters\MembersList
;
49 use Galette\IO\PdfAttendanceSheet
;
50 use Galette\IO\PdfContribution
;
51 use Galette\IO\PdfGroups
;
52 use Galette\IO\PdfMembersCards
;
53 use Galette\IO\PdfMembersLabels
;
54 use Galette\Repository\Members
;
55 use Galette\Repository\Groups
;
56 use Galette\Repository\PdfModels
;
59 * Galette PDF controller
61 * @category Controllers
62 * @name GaletteController
64 * @author Johan Cwiklinski <johan@x-tnd.be>
65 * @copyright 2019 The Galette Team
66 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
67 * @link http://galette.tuxfamily.org
68 * @since Available since 0.9.4dev - 2019-12-05
71 class PdfController
extends AbstractController
76 * @param Response $response PSR Response
77 * @param Pdf $pdf PDF to output
81 protected function sendResponse(Response
$response, Pdf
$pdf): Response
84 ->withHeader('Content-type', 'application/pdf')
85 ->withHeader('Content-Disposition', 'attachment;filename="' . $pdf->getFileName() . '"')
86 ->write($pdf->download());
93 * @param Request $request PSR Request
94 * @param Response $response PSR Response
95 * @param array $args Request arguments
99 public function membersCards(Request
$request, Response
$response, array $args = []): Response
101 if ($this->session
->filter_members
) {
102 $filters = $this->session
->filter_members
;
104 $filters = new MembersList();
108 isset($args[Adherent
::PK
])
109 && $args[Adherent
::PK
] > 0
111 $id_adh = $args[Adherent
::PK
];
112 $deps = ['dynamics' => true];
113 if ($this->login
->id
== $id_adh) {
114 $deps['dues'] = true;
121 if (!$adh->canEdit($this->login
)) {
122 $this->flash
->addMessage(
124 _T("You do not have permission for requested URL.")
131 $this->router
->pathFor('me')
135 //check if member is up to date
136 if ($this->login
->id
== $id_adh) {
137 if (!$adh->isUp2Date()) {
139 'Member ' . $id_adh . ' is not up to date; cannot get his PDF member card',
144 ->withHeader('Location', $this->router
->pathFor('slash'));
148 // If we are called from a member's card, get unique id value
151 if (count($filters->selected
) == 0) {
153 'No member selected to generate members cards',
156 $this->flash
->addMessage(
158 _T("No member was selected, please check at least one name.")
163 ->withHeader('Location', $this->router
->pathFor('members'));
167 // Fill array $selected with selected ids
169 if (isset($unique) && $unique) {
170 $selected[] = $unique;
172 $selected = $filters->selected
;
176 $members = $m->getArrayList(
178 array('nom_adh', 'prenom_adh'),
182 if (!is_array($members) ||
count($members) < 1) {
184 'An error has occurred, unable to get members list.',
188 $this->flash
->addMessage(
190 _T("Unable to get members list.")
195 ->withHeader('Location', $this->router
->pathFor('members'));
198 $pdf = new PdfMembersCards($this->preferences
);
199 $pdf->drawCards($members);
201 return $this->sendResponse($response, $pdf);
207 * @param Request $request PSR Request
208 * @param Response $response PSR Response
212 public function membersLabels(Request
$request, Response
$response): Response
214 $post = $request->getParsedBody();
215 $get = $request->getQueryParams();
217 $session_var = $post['session_var'] ??
$get['session_var'] ??
'filter_members';
219 if (isset($this->session
->$session_var)) {
220 $filters = $this->session
->$session_var;
222 $filters = new MembersList();
228 && $get['from'] === 'mailing'
230 //if we're from mailing, we have to retrieve
231 //its unreachables members for labels
232 $mailing = $this->session
->mailing
;
233 $members = $mailing->unreachables
;
235 if (count($filters->selected
) == 0) {
236 Analog
::log('No member selected to generate labels', Analog
::INFO
);
237 $this->flash
->addMessage(
239 _T("No member was selected, please check at least one name.")
244 ->withHeader('Location', $this->router
->pathFor('members'));
248 $members = $m->getArrayList(
250 array('nom_adh', 'prenom_adh')
254 if (!is_array($members) ||
count($members) < 1) {
256 'An error has occurred, unable to get members list.',
260 $this->flash
->addMessage(
262 _T("Unable to get members list.")
267 ->withHeader('Location', $this->router
->pathFor('members'));
270 $pdf = new PdfMembersLabels($this->preferences
);
271 $pdf->drawLabels($members);
273 return $this->sendResponse($response, $pdf);
279 * @param Request $request PSR Request
280 * @param Response $response PSR Response
281 * @param array $args Request arguments
285 public function adhesionForm(Request
$request, Response
$response, array $args = []): Response
287 $id_adh = isset($args[Adherent
::PK
]) ?
(int)$args[Adherent
::PK
] : null;
288 $adh = new Adherent($this->zdb
, $id_adh, ['dynamics' => true]);
290 if ($id_adh !== null && !$adh->canEdit($this->login
)) {
291 $this->flash
->addMessage(
293 _T("You do not have permission for requested URL.")
300 $this->router
->pathFor('me')
304 $form = $this->preferences
->pref_adhesion_form
;
305 $pdf = new $form($adh, $this->zdb
, $this->preferences
);
307 return $this->sendResponse($response, $pdf);
311 * PDF attendance sheet configuration page
313 * @param Request $request PSR Request
314 * @param Response $response PSR Response
315 * @param array $args Request arguments
319 public function attendanceSheetConfig(Request
$request, Response
$response, array $args = []): Response
321 $post = $request->getParsedBody();
323 if ($this->session
->filter_members
!== null) {
324 $filters = $this->session
->filter_members
;
326 $filters = new MembersList();
329 // check for ajax mode
333 ||
isset($post['ajax'])
334 && $post['ajax'] == 'true'
338 //retrieve selected members
339 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
341 $filters->selected
= $selection;
342 $this->session
->filter_members
= $filters;
344 $selection = $filters->selected
;
350 'attendance_sheet_details.tpl',
352 'page_title' => _T("Attendance sheet configuration"),
354 'selection' => $selection
361 * PDF attendance sheet
363 * @param Request $request PSR Request
364 * @param Response $response PSR Response
368 public function attendanceSheet(Request
$request, Response
$response): Response
370 $post = $request->getParsedBody();
372 if ($this->session
->filter_members
!== null) {
373 $filters = $this->session
->filter_members
;
375 $filters = new MembersList();
378 //retrieve selected members
379 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
381 $filters->selected
= $selection;
382 $this->session
->filter_members
= $filters;
384 if (count($filters->selected
) == 0) {
385 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
386 $this->flash
->addMessage(
388 _T("No member selected to generate attendance sheet")
393 ->withHeader('Location', $this->router
->pathFor('members'));
397 $members = $m->getArrayList(
399 array('nom_adh', 'prenom_adh'),
403 if (!is_array($members) ||
count($members) < 1) {
404 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
405 $this->flash
->addMessage(
407 _T("No member selected to generate attendance sheet")
412 ->withHeader('Location', $this->router
->pathFor('members'));
415 $doc_title = _T("Attendance sheet");
416 if (isset($post['sheet_type']) && trim($post['sheet_type']) != '') {
417 $doc_title = $post['sheet_type'];
421 'doc_title' => $doc_title,
422 'title' => $post['sheet_title'] ??
null,
423 'subtitle' => $post['sheet_sub_title'] ??
null,
424 'sheet_date' => $post['sheet_date'] ??
null
426 $pdf = new PdfAttendanceSheet($this->zdb
, $this->preferences
, $data);
427 //with or without images?
428 if (isset($post['sheet_photos']) && $post['sheet_photos'] === '1') {
431 $pdf->drawSheet($members);
433 return $this->sendResponse($response, $pdf);
439 * @param Request $request PSR Request
440 * @param Response $response PSR Response
441 * @param array $args Request arguments
445 public function contribution(Request
$request, Response
$response, array $args = []): Response
447 $contribution = new Contribution($this->zdb
, $this->login
, (int)$args['id']);
448 if ($contribution->id
== '') {
449 //not possible to load contribution, exit
450 $this->flash
->addMessage(
455 _T("Unable to load contribution #%id!")
460 ->withHeader('Location', $this->router
->pathFor(
462 ['type' => 'contributions']
465 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
466 return $this->sendResponse($response, $pdf);
473 * @param Request $request PSR Request
474 * @param Response $response PSR Response
475 * @param array $args Request arguments
479 public function group(Request
$request, Response
$response, array $args = []): Response
481 $groups = new Groups($this->zdb
, $this->login
);
484 if (isset($args['id'])) {
485 $groups_list = $groups->getList(true, $args['id']);
487 $groups_list = $groups->getList();
490 if (!is_array($groups_list) ||
count($groups_list) < 1) {
492 'An error has occurred, unable to get groups list.',
496 $this->flash
->addMessage(
498 _T("Unable to get groups list.")
503 ->withHeader('Location', $this->router
->pathFor('groups'));
506 $pdf = new PdfGroups($this->preferences
);
507 $pdf->draw($groups_list, $this->login
);
509 return $this->sendResponse($response, $pdf);
515 * @param Request $request PSR Request
516 * @param Response $response PSR Response
517 * @param array $args Request arguments
521 public function models(Request
$request, Response
$response, array $args = []): Response
524 if (isset($_POST[PdfModel
::PK
])) {
525 $id = (int)$_POST[PdfModel
::PK
];
526 } elseif (isset($args['id'])) {
527 $id = (int)$args['id'];
531 $ms = new PdfModels($this->zdb
, $this->preferences
, $this->login
);
532 $models = $ms->getList();
535 foreach ($models as $m) {
536 if ($m->id
=== $id) {
545 //Render directly template if we called from ajax,
546 //render in a full page otherwise
549 ||
isset($request->getQueryParams()['ajax'])
550 && $request->getQueryParams()['ajax'] == 'true'
552 $tpl = 'gestion_pdf_content.tpl';
553 $params['model'] = $model;
555 $tpl = 'gestion_pdf.tpl';
557 'page_title' => _T("PDF models"),
575 * @param Request $request PSR Request
576 * @param Response $response PSR Response
577 * @param array $args Request arguments
581 public function storeModels(Request
$request, Response
$response, array $args = []): Response
583 $post = $request->getParsedBody();
585 if (isset($post['model_type'])) {
586 $type = (int)$post['model_type'];
589 if ($type === null) {
590 $this->flash
->addMessage(
592 _T("Missing PDF model type!")
595 $class = PdfModel
::getTypeClass($type);
596 if (isset($post[PdfModel
::PK
])) {
597 $model = new $class($this->zdb
, $this->preferences
, (int)$_POST[PdfModel
::PK
]);
599 $model = new $class($this->zdb
, $this->preferences
);
603 $model->header
= $post['model_header'];
604 $model->footer
= $post['model_footer'];
605 $model->type
= $type;
606 if (isset($post['model_body'])) {
607 $model->body
= $post['model_body'];
609 if (isset($post['model_title'])) {
610 $model->title
= $post['model_title'];
612 if (isset($post['model_body'])) {
613 $model->subtitle
= $post['model_subtitle'];
615 if (isset($post['model_styles'])) {
616 $model->styles
= $post['model_styles'];
618 $res = $model->store();
620 $this->flash
->addMessage(
622 _T("Model has been successfully stored!")
625 $this->flash
->addMessage(
627 _T("Model has not been stored :(")
630 } catch (\Exception
$e) {
631 $error_detected[] = $e->getMessage();
637 ->withHeader('Location', $this->router
->pathFor('pdfModels', ['id' => $model->id
]));
642 * Get direct document
644 * @param Request $request PSR Request
645 * @param Response $response PSR Response
646 * @param array $args Request arguments
650 public function directlinkDocument(Request
$request, Response
$response, array $args = []): Response
652 $hash = $args['hash'];
653 $post = $request->getParsedBody();
654 $email = $post['email'];
656 $links = new Links($this->zdb
);
657 $valid = $links->isHashValid($hash, $email);
659 if ($valid === false) {
660 $this->flash
->addMessage(
665 return $response->withStatus(301)
666 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
672 if ($target === Links
::TARGET_MEMBERCARD
) {
674 $members = $m->getArrayList(
676 array('nom_adh', 'prenom_adh'),
680 if (!is_array($members) ||
count($members) < 1) {
682 'An error has occurred, unable to get members list.',
686 $this->flash
->addMessage(
688 _T("Unable to get members list.")
693 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
696 $pdf = new PdfMembersCards($this->preferences
);
697 $pdf->drawCards($members);
699 $contribution = new Contribution($this->zdb
, $this->login
, $id);
700 if ($contribution->id
== '') {
701 //not possible to load contribution, exit
702 $this->flash
->addMessage(
707 _T("Unable to load contribution #%id!")
712 ->withHeader('Location', $this->router
->pathFor(
717 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
721 return $this->sendResponse($response, $pdf);