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
;
40 use Slim\Http\Request
;
41 use Slim\Http\Response
;
43 use Galette\Core\Links
;
44 use Galette\Core\Login
;
45 use Galette\Entity\Adherent
;
46 use Galette\Entity\Contribution
;
47 use Galette\Entity\PdfModel
;
48 use Galette\Filters\MembersList
;
50 use Galette\IO\PdfAttendanceSheet
;
51 use Galette\IO\PdfContribution
;
52 use Galette\IO\PdfGroups
;
53 use Galette\IO\PdfMembersCards
;
54 use Galette\IO\PdfMembersLabels
;
55 use Galette\Repository\Members
;
56 use Galette\Repository\Groups
;
57 use Galette\Repository\PdfModels
;
60 * Galette PDF controller
62 * @category Controllers
63 * @name GaletteController
65 * @author Johan Cwiklinski <johan@x-tnd.be>
66 * @copyright 2019 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-05
72 class PdfController
extends AbstractController
77 * @param Response $response PSR Response
78 * @param Pdf $pdf PDF to output
82 protected function sendResponse(Response
$response, Pdf
$pdf): Response
85 ->withHeader('Content-type', 'application/pdf')
86 ->withHeader('Content-Disposition', 'attachment;filename="' . $pdf->getFileName() . '"')
87 ->write($pdf->download());
93 * @param Request $request PSR Request
94 * @param Response $response PSR Response
95 * @param integer $id_adh Member id
99 public function membersCards(Request
$request, Response
$response, int $id_adh = null): Response
101 if ($this->session
->filter_members
) {
102 $filters = $this->session
->filter_members
;
104 $filters = new MembersList();
107 if ($id_adh !== null && $id_adh > 0) {
108 $deps = ['dynamics' => true];
109 if ($this->login
->id
=== $id_adh) {
110 $deps['dues'] = true;
117 if (!$adh->canEdit($this->login
)) {
118 $this->flash
->addMessage(
120 _T("You do not have permission for requested URL.")
127 $this->router
->pathFor('me')
131 //check if member is up to date
132 if ($this->login
->id
== $id_adh) {
133 if (!$adh->isUp2Date()) {
135 'Member ' . $id_adh . ' is not up to date; cannot get his PDF member card',
140 ->withHeader('Location', $this->router
->pathFor('slash'));
144 // If we are called from a member's card, get unique id value
147 if (count($filters->selected
) == 0) {
149 'No member selected to generate members cards',
152 $this->flash
->addMessage(
154 _T("No member was selected, please check at least one name.")
159 ->withHeader('Location', $this->router
->pathFor('members'));
163 // Fill array $selected with selected ids
165 if (isset($unique) && $unique) {
166 $selected[] = $unique;
168 $selected = $filters->selected
;
172 $members = $m->getArrayList(
174 array('nom_adh', 'prenom_adh'),
178 if (!is_array($members) ||
count($members) < 1) {
180 'An error has occurred, unable to get members list.',
184 $this->flash
->addMessage(
186 _T("Unable to get members list.")
191 ->withHeader('Location', $this->router
->pathFor('members'));
194 $pdf = new PdfMembersCards($this->preferences
);
195 $pdf->drawCards($members);
197 return $this->sendResponse($response, $pdf);
203 * @param Request $request PSR Request
204 * @param Response $response PSR Response
208 public function membersLabels(Request
$request, Response
$response): Response
210 $post = $request->getParsedBody();
211 $get = $request->getQueryParams();
213 $session_var = $post['session_var'] ??
$get['session_var'] ??
'filter_members';
215 if (isset($this->session
->$session_var)) {
216 $filters = $this->session
->$session_var;
218 $filters = new MembersList();
224 && $get['from'] === 'mailing'
226 //if we're from mailing, we have to retrieve
227 //its unreachables members for labels
228 $mailing = $this->session
->mailing
;
229 $members = $mailing->unreachables
;
231 if (count($filters->selected
) == 0) {
232 Analog
::log('No member selected to generate labels', Analog
::INFO
);
233 $this->flash
->addMessage(
235 _T("No member was selected, please check at least one name.")
240 ->withHeader('Location', $this->router
->pathFor('members'));
244 $members = $m->getArrayList(
246 array('nom_adh', 'prenom_adh')
250 if (!is_array($members) ||
count($members) < 1) {
252 'An error has occurred, unable to get members list.',
256 $this->flash
->addMessage(
258 _T("Unable to get members list.")
263 ->withHeader('Location', $this->router
->pathFor('members'));
266 $pdf = new PdfMembersLabels($this->preferences
);
267 $pdf->drawLabels($members);
269 return $this->sendResponse($response, $pdf);
275 * @param Request $request PSR Request
276 * @param Response $response PSR Response
277 * @param integer $id_adh Member id
281 public function adhesionForm(Request
$request, Response
$response, int $id_adh = null): Response
283 $adh = new Adherent($this->zdb
, $id_adh, ['dynamics' => true]);
285 if ($id_adh !== null && !$adh->canEdit($this->login
)) {
286 $this->flash
->addMessage(
288 _T("You do not have permission for requested URL.")
295 $this->router
->pathFor('me')
299 $form = $this->preferences
->pref_adhesion_form
;
300 $pdf = new $form($adh, $this->zdb
, $this->preferences
);
302 return $this->sendResponse($response, $pdf);
306 * PDF attendance sheet configuration page
308 * @param Request $request PSR Request
309 * @param Response $response PSR Response
313 public function attendanceSheetConfig(Request
$request, Response
$response): Response
315 $post = $request->getParsedBody();
317 if ($this->session
->filter_members
!== null) {
318 $filters = $this->session
->filter_members
;
320 $filters = new MembersList();
323 // check for ajax mode
327 ||
(isset($post['ajax'])
328 && $post['ajax'] == 'true')
332 //retrieve selected members
333 $selection = $post['selection'] ??
array();
335 $filters->selected
= $selection;
336 $this->session
->filter_members
= $filters;
338 $selection = $filters->selected
;
344 'attendance_sheet_details.tpl',
346 'page_title' => _T("Attendance sheet configuration"),
348 'selection' => $selection
355 * PDF attendance sheet
357 * @param Request $request PSR Request
358 * @param Response $response PSR Response
362 public function attendanceSheet(Request
$request, Response
$response): Response
364 $post = $request->getParsedBody();
366 if ($this->session
->filter_members
!== null) {
367 $filters = $this->session
->filter_members
;
369 $filters = new MembersList();
372 //retrieve selected members
373 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
375 $filters->selected
= $selection;
376 $this->session
->filter_members
= $filters;
378 if (count($filters->selected
) == 0) {
379 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
380 $this->flash
->addMessage(
382 _T("No member selected to generate attendance sheet")
387 ->withHeader('Location', $this->router
->pathFor('members'));
391 $members = $m->getArrayList(
393 array('nom_adh', 'prenom_adh'),
397 if (!is_array($members) ||
count($members) < 1) {
398 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
399 $this->flash
->addMessage(
401 _T("No member selected to generate attendance sheet")
406 ->withHeader('Location', $this->router
->pathFor('members'));
409 $doc_title = _T("Attendance sheet");
410 if (isset($post['sheet_type']) && trim($post['sheet_type']) != '') {
411 $doc_title = $post['sheet_type'];
415 'doc_title' => $doc_title,
416 'title' => $post['sheet_title'] ??
null,
417 'subtitle' => $post['sheet_sub_title'] ??
null,
418 'sheet_date' => $post['sheet_date'] ??
null
420 $pdf = new PdfAttendanceSheet($this->zdb
, $this->preferences
, $data);
421 //with or without images?
422 if (isset($post['sheet_photos']) && $post['sheet_photos'] === '1') {
425 $pdf->drawSheet($members);
427 return $this->sendResponse($response, $pdf);
433 * @param Request $request PSR Request
434 * @param Response $response PSR Response
435 * @param integer $id Contribution id
439 public function contribution(Request
$request, Response
$response, int $id): Response
441 $contribution = new Contribution($this->zdb
, $this->login
, $id);
442 if ($contribution->id
== '') {
443 //not possible to load contribution, exit
444 $this->flash
->addMessage(
449 _T("Unable to load contribution #%id!")
454 ->withHeader('Location', $this->router
->pathFor(
456 ['type' => 'contributions']
460 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
461 return $this->sendResponse($response, $pdf);
467 * @param Request $request PSR Request
468 * @param Response $response PSR Response
469 * @param integer $id Group id
473 public function group(Request
$request, Response
$response, int $id = null): Response
475 $groups = new Groups($this->zdb
, $this->login
);
479 $groups_list = $groups->getList(true, $id);
481 $groups_list = $groups->getList();
484 if (!is_array($groups_list) ||
count($groups_list) < 1) {
486 'An error has occurred, unable to get groups list.',
490 $this->flash
->addMessage(
492 _T("Unable to get groups list.")
497 ->withHeader('Location', $this->router
->pathFor('groups'));
500 $pdf = new PdfGroups($this->preferences
);
501 $pdf->draw($groups_list, $this->login
);
503 return $this->sendResponse($response, $pdf);
509 * @param Request $request PSR Request
510 * @param Response $response PSR Response
511 * @param integer $id Model id
515 public function models(Request
$request, Response
$response, int $id = null): Response
518 if (isset($_POST[PdfModel
::PK
])) {
519 $mid = (int)$_POST[PdfModel
::PK
];
520 } elseif ($id !== null) {
525 $ms = new PdfModels($this->zdb
, $this->preferences
, $this->login
);
526 $models = $ms->getList();
529 foreach ($models as $m) {
530 if ($m->id
=== $mid) {
537 $params = ['model' => $model];
539 //Render directly template if we called from ajax,
540 //render in a full page otherwise
543 ||
(isset($request->getQueryParams()['ajax'])
544 && $request->getQueryParams()['ajax'] == 'true')
546 $tpl = 'gestion_pdf_content.tpl';
548 $tpl = 'gestion_pdf.tpl';
550 'page_title' => _T("PDF models"),
567 * @param Request $request PSR Request
568 * @param Response $response PSR Response
572 public function storeModels(Request
$request, Response
$response): Response
574 $post = $request->getParsedBody();
575 $error_detected = [];
577 if (!isset($post['model_type'])) {
578 $error_detected[] = _T("Missing PDF model type!");
580 $type = (int)$post['model_type'];
581 $class = PdfModel
::getTypeClass($type);
582 if (isset($post[PdfModel
::PK
])) {
583 $model = new $class($this->zdb
, $this->preferences
, (int)$post[PdfModel
::PK
]);
585 $model = new $class($this->zdb
, $this->preferences
);
590 'model_header' => 'header',
591 'model_footer' => 'footer',
592 'model_body' => 'body',
593 'model_title' => 'title',
594 'model_subtitle' => 'subtitle',
595 'model_styles' => 'styles'
598 $model->type
= $type;
599 foreach ($fields as $pvar => $prop) {
600 if (isset($post[$pvar])) {
601 $model->$prop = $post[$pvar];
605 $res = $model->store();
607 $this->flash
->addMessage(
609 _T("Model has been successfully stored!")
612 $error_detected[] = _T("Model has not been stored :(");
614 } catch (Throwable
$e) {
615 $error_detected[] = $e->getMessage();
619 if (count($error_detected) > 0) {
620 foreach ($error_detected as $error) {
621 $this->flash
->addMessage(
630 ->withHeader('Location', $this->router
->pathFor('pdfModels', ['id' => $model->id ??
null]));
635 * Get direct document
637 * @param Request $request PSR Request
638 * @param Response $response PSR Response
639 * @param string $hash Hash
643 public function directlinkDocument(Request
$request, Response
$response, string $hash): Response
645 $post = $request->getParsedBody();
646 $email = $post['email'];
648 $links = new Links($this->zdb
);
649 $valid = $links->isHashValid($hash, $email);
651 if ($valid === false) {
652 $this->flash
->addMessage(
657 return $response->withStatus(301)
658 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
662 $id = (int)$valid[1];
664 //get user information (like id...) from DB since its missing
665 $select = $this->zdb
->select(Adherent
::TABLE
, 'a');
666 $select->where(['email_adh' => $post['email']]);
667 $results = $this->zdb
->execute($select);
668 $row = $results->current();
670 //create a new login instance, to not break current session if any
671 //this will be passed directly to Contribution constructor
676 $login->setId((int)$row['id_adh']);
678 if ($target === Links
::TARGET_MEMBERCARD
) {
680 $members = $m->getArrayList(
682 array('nom_adh', 'prenom_adh'),
686 if (!is_array($members) ||
count($members) < 1) {
688 'An error has occurred, unable to get members list.',
692 $this->flash
->addMessage(
694 _T("Unable to get members list.")
699 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
702 $pdf = new PdfMembersCards($this->preferences
);
703 $pdf->drawCards($members);
705 $contribution = new Contribution($this->zdb
, $login, $id);
706 if ($contribution->id
== '') {
707 //not possible to load contribution, exit
708 $this->flash
->addMessage(
713 _T("Unable to load contribution #%id!")
718 ->withHeader('Location', $this->router
->pathFor(
723 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
726 return $this->sendResponse($response, $pdf);