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 $adh = new Adherent($this->zdb
);
109 $adh->enableDep('dynamics');
110 if ($this->login
->id
!= $id_adh) {
111 $adh->disableDep('dues');
115 if (!$adh->canEdit($this->login
)) {
116 $this->flash
->addMessage(
118 _T("You do not have permission for requested URL.")
125 $this->router
->pathFor('me')
129 //check if member is up to date
130 if ($this->login
->id
== $id_adh) {
131 if (!$adh->isUp2Date()) {
133 'Member ' . $id_adh . ' is not up to date; cannot get his PDF member card',
138 ->withHeader('Location', $this->router
->pathFor('slash'));
142 // If we are called from a member's card, get unique id value
145 if (count($filters->selected
) == 0) {
147 'No member selected to generate members cards',
150 $this->flash
->addMessage(
152 _T("No member was selected, please check at least one name.")
157 ->withHeader('Location', $this->router
->pathFor('members'));
161 // Fill array $selected with selected ids
163 if (isset($unique) && $unique) {
164 $selected[] = $unique;
166 $selected = $filters->selected
;
170 $members = $m->getArrayList(
172 array('nom_adh', 'prenom_adh'),
176 if (!is_array($members) ||
count($members) < 1) {
178 'An error has occurred, unable to get members list.',
182 $this->flash
->addMessage(
184 _T("Unable to get members list.")
189 ->withHeader('Location', $this->router
->pathFor('members'));
192 $pdf = new PdfMembersCards($this->preferences
);
193 $pdf->drawCards($members);
195 return $this->sendResponse($response, $pdf);
201 * @param Request $request PSR Request
202 * @param Response $response PSR Response
206 public function membersLabels(Request
$request, Response
$response): Response
208 $post = $request->getParsedBody();
209 $get = $request->getQueryParams();
211 $session_var = $post['session_var'] ??
$get['session_var'] ??
'filter_members';
213 if (isset($this->session
->$session_var)) {
214 $filters = $this->session
->$session_var;
216 $filters = new MembersList();
222 && $get['from'] === 'mailing'
224 //if we're from mailing, we have to retrieve
225 //its unreachables members for labels
226 $mailing = $this->session
->mailing
;
227 $members = $mailing->unreachables
;
229 if (count($filters->selected
) == 0) {
230 Analog
::log('No member selected to generate labels', Analog
::INFO
);
231 $this->flash
->addMessage(
233 _T("No member was selected, please check at least one name.")
238 ->withHeader('Location', $this->router
->pathFor('members'));
242 $members = $m->getArrayList(
244 array('nom_adh', 'prenom_adh')
248 if (!is_array($members) ||
count($members) < 1) {
250 'An error has occurred, unable to get members list.',
254 $this->flash
->addMessage(
256 _T("Unable to get members list.")
261 ->withHeader('Location', $this->router
->pathFor('members'));
264 $pdf = new PdfMembersLabels($this->preferences
);
265 $pdf->drawLabels($members);
267 return $this->sendResponse($response, $pdf);
273 * @param Request $request PSR Request
274 * @param Response $response PSR Response
275 * @param integer $id_adh Member id
279 public function adhesionForm(Request
$request, Response
$response, int $id_adh = null): Response
281 $adh = new Adherent($this->zdb
, $id_adh, ['dynamics' => true]);
283 if ($id_adh !== null && !$adh->canEdit($this->login
)) {
284 $this->flash
->addMessage(
286 _T("You do not have permission for requested URL.")
293 $this->router
->pathFor('me')
297 $form = $this->preferences
->pref_adhesion_form
;
298 $pdf = new $form($adh, $this->zdb
, $this->preferences
);
300 return $this->sendResponse($response, $pdf);
304 * PDF attendance sheet configuration page
306 * @param Request $request PSR Request
307 * @param Response $response PSR Response
311 public function attendanceSheetConfig(Request
$request, Response
$response): Response
313 $post = $request->getParsedBody();
315 if ($this->session
->filter_members
!== null) {
316 $filters = $this->session
->filter_members
;
318 $filters = new MembersList();
321 // check for ajax mode
325 ||
(isset($post['ajax'])
326 && $post['ajax'] == 'true')
330 //retrieve selected members
331 $selection = $post['selection'] ??
array();
333 $filters->selected
= $selection;
334 $this->session
->filter_members
= $filters;
336 $selection = $filters->selected
;
342 'attendance_sheet_details.tpl',
344 'page_title' => _T("Attendance sheet configuration"),
346 'selection' => $selection
353 * PDF attendance sheet
355 * @param Request $request PSR Request
356 * @param Response $response PSR Response
360 public function attendanceSheet(Request
$request, Response
$response): Response
362 $post = $request->getParsedBody();
364 if ($this->session
->filter_members
!== null) {
365 $filters = $this->session
->filter_members
;
367 $filters = new MembersList();
370 //retrieve selected members
371 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
373 $filters->selected
= $selection;
374 $this->session
->filter_members
= $filters;
376 if (count($filters->selected
) == 0) {
377 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
378 $this->flash
->addMessage(
380 _T("No member selected to generate attendance sheet")
385 ->withHeader('Location', $this->router
->pathFor('members'));
389 $members = $m->getArrayList(
391 array('nom_adh', 'prenom_adh'),
395 if (!is_array($members) ||
count($members) < 1) {
396 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
397 $this->flash
->addMessage(
399 _T("No member selected to generate attendance sheet")
404 ->withHeader('Location', $this->router
->pathFor('members'));
407 $doc_title = _T("Attendance sheet");
408 if (isset($post['sheet_type']) && trim($post['sheet_type']) != '') {
409 $doc_title = $post['sheet_type'];
413 'doc_title' => $doc_title,
414 'title' => $post['sheet_title'] ??
null,
415 'subtitle' => $post['sheet_sub_title'] ??
null,
416 'sheet_date' => $post['sheet_date'] ??
null
418 $pdf = new PdfAttendanceSheet($this->zdb
, $this->preferences
, $data);
419 //with or without images?
420 if (isset($post['sheet_photos']) && $post['sheet_photos'] === '1') {
423 $pdf->drawSheet($members);
425 return $this->sendResponse($response, $pdf);
431 * @param Request $request PSR Request
432 * @param Response $response PSR Response
433 * @param integer $id Contribution id
437 public function contribution(Request
$request, Response
$response, int $id): Response
439 $contribution = new Contribution($this->zdb
, $this->login
, $id);
440 if ($contribution->id
== '') {
441 //not possible to load contribution, exit
442 $this->flash
->addMessage(
447 _T("Unable to load contribution #%id!")
452 ->withHeader('Location', $this->router
->pathFor(
454 ['type' => 'contributions']
458 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
459 return $this->sendResponse($response, $pdf);
465 * @param Request $request PSR Request
466 * @param Response $response PSR Response
467 * @param integer $id Group id
471 public function group(Request
$request, Response
$response, int $id = null): Response
473 $groups = new Groups($this->zdb
, $this->login
);
477 $groups_list = $groups->getList(true, $id);
479 $groups_list = $groups->getList();
482 if (!is_array($groups_list) ||
count($groups_list) < 1) {
484 'An error has occurred, unable to get groups list.',
488 $this->flash
->addMessage(
490 _T("Unable to get groups list.")
495 ->withHeader('Location', $this->router
->pathFor('groups'));
498 $pdf = new PdfGroups($this->preferences
);
499 $pdf->draw($groups_list, $this->login
);
501 return $this->sendResponse($response, $pdf);
507 * @param Request $request PSR Request
508 * @param Response $response PSR Response
509 * @param integer $id Model id
513 public function models(Request
$request, Response
$response, int $id = null): Response
516 if (isset($_POST[PdfModel
::PK
])) {
517 $mid = (int)$_POST[PdfModel
::PK
];
518 } elseif ($id !== null) {
523 $ms = new PdfModels($this->zdb
, $this->preferences
, $this->login
);
524 $models = $ms->getList();
527 foreach ($models as $m) {
528 if ($m->id
=== $mid) {
535 $params = ['model' => $model];
537 //Render directly template if we called from ajax,
538 //render in a full page otherwise
541 ||
(isset($request->getQueryParams()['ajax'])
542 && $request->getQueryParams()['ajax'] == 'true')
544 $tpl = 'gestion_pdf_content.tpl';
546 $tpl = 'gestion_pdf.tpl';
548 'page_title' => _T("PDF models"),
565 * @param Request $request PSR Request
566 * @param Response $response PSR Response
570 public function storeModels(Request
$request, Response
$response): Response
572 $post = $request->getParsedBody();
573 $error_detected = [];
575 if (!isset($post['model_type'])) {
576 $error_detected[] = _T("Missing PDF model type!");
578 $type = (int)$post['model_type'];
579 $class = PdfModel
::getTypeClass($type);
580 if (isset($post[PdfModel
::PK
])) {
581 $model = new $class($this->zdb
, $this->preferences
, (int)$post[PdfModel
::PK
]);
583 $model = new $class($this->zdb
, $this->preferences
);
588 'model_header' => 'header',
589 'model_footer' => 'footer',
590 'model_body' => 'body',
591 'model_title' => 'title',
592 'model_subtitle' => 'subtitle',
593 'model_styles' => 'styles'
596 $model->type
= $type;
597 foreach ($fields as $pvar => $prop) {
598 if (isset($post[$pvar])) {
599 $model->$prop = $post[$pvar];
603 $res = $model->store();
605 $this->flash
->addMessage(
607 _T("Model has been successfully stored!")
610 $error_detected[] = _T("Model has not been stored :(");
612 } catch (Throwable
$e) {
613 $error_detected[] = $e->getMessage();
617 if (count($error_detected) > 0) {
618 foreach ($error_detected as $error) {
619 $this->flash
->addMessage(
628 ->withHeader('Location', $this->router
->pathFor('pdfModels', ['id' => $model->id ??
null]));
633 * Get direct document
635 * @param Request $request PSR Request
636 * @param Response $response PSR Response
637 * @param string $hash Hash
641 public function directlinkDocument(Request
$request, Response
$response, string $hash): Response
643 $post = $request->getParsedBody();
644 $email = $post['email'];
646 $links = new Links($this->zdb
);
647 $valid = $links->isHashValid($hash, $email);
649 if ($valid === false) {
650 $this->flash
->addMessage(
655 return $response->withStatus(301)
656 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
660 $id = (int)$valid[1];
662 //get user information (like id...) from DB since its missing
663 $select = $this->zdb
->select(Adherent
::TABLE
, 'a');
664 $select->where(['email_adh' => $post['email']]);
665 $results = $this->zdb
->execute($select);
666 $row = $results->current();
668 //create a new login instance, to not break current session if any
669 //this will be passed directly to Contribution constructor
674 $login->setId((int)$row['id_adh']);
676 if ($target === Links
::TARGET_MEMBERCARD
) {
678 $members = $m->getArrayList(
680 array('nom_adh', 'prenom_adh'),
684 if (!is_array($members) ||
count($members) < 1) {
686 'An error has occurred, unable to get members list.',
690 $this->flash
->addMessage(
692 _T("Unable to get members list.")
697 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
700 $pdf = new PdfMembersCards($this->preferences
);
701 $pdf->drawCards($members);
703 $contribution = new Contribution($this->zdb
, $login, $id);
704 if ($contribution->id
== '') {
705 //not possible to load contribution, exit
706 $this->flash
->addMessage(
711 _T("Unable to load contribution #%id!")
716 ->withHeader('Location', $this->router
->pathFor(
721 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
724 return $this->sendResponse($response, $pdf);