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();
107 if (isset($args[Adherent
::PK
])
108 && $args[Adherent
::PK
] > 0
110 $id_adh = $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();
225 if (isset($get['from'])
226 && $get['from'] === 'mailing'
228 //if we're from mailing, we have to retrieve
229 //its unreachables members for labels
230 $mailing = $this->session
->mailing
;
231 $members = $mailing->unreachables
;
233 if (count($filters->selected
) == 0) {
234 Analog
::log('No member selected to generate labels', Analog
::INFO
);
235 $this->flash
->addMessage(
237 _T("No member was selected, please check at least one name.")
242 ->withHeader('Location', $this->router
->pathFor('members'));
246 $members = $m->getArrayList(
248 array('nom_adh', 'prenom_adh')
252 if (!is_array($members) ||
count($members) < 1) {
254 'An error has occurred, unable to get members list.',
258 $this->flash
->addMessage(
260 _T("Unable to get members list.")
265 ->withHeader('Location', $this->router
->pathFor('members'));
268 $pdf = new PdfMembersLabels($this->preferences
);
269 $pdf->drawLabels($members);
271 return $this->sendResponse($response, $pdf);
277 * @param Request $request PSR Request
278 * @param Response $response PSR Response
279 * @param array $args Request arguments
283 public function adhesionForm(Request
$request, Response
$response, array $args = []) :Response
285 $id_adh = isset($args[Adherent
::PK
]) ?
(int)$args[Adherent
::PK
] : null;
286 $adh = new Adherent($this->zdb
, $id_adh, ['dynamics' => true]);
288 if ($id_adh !== null && !$adh->canEdit($this->login
)) {
289 $this->flash
->addMessage(
291 _T("You do not have permission for requested URL.")
298 $this->router
->pathFor('me')
302 $form = $this->preferences
->pref_adhesion_form
;
303 $pdf = new $form($adh, $this->zdb
, $this->preferences
);
305 return $this->sendResponse($response, $pdf);
309 * PDF attendance sheet configuration page
311 * @param Request $request PSR Request
312 * @param Response $response PSR Response
313 * @param array $args Request arguments
317 public function attendanceSheetConfig(Request
$request, Response
$response, array $args = []) :Response
319 $post = $request->getParsedBody();
321 if ($this->session
->filter_members
!== null) {
322 $filters = $this->session
->filter_members
;
324 $filters = new MembersList();
327 // check for ajax mode
329 if ($request->isXhr()
330 ||
isset($post['ajax'])
331 && $post['ajax'] == 'true'
335 //retrieve selected members
336 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
338 $filters->selected
= $selection;
339 $this->session
->filter_members
= $filters;
341 $selection = $filters->selected
;
347 'attendance_sheet_details.tpl',
349 'page_title' => _T("Attendance sheet configuration"),
351 'selection' => $selection
358 * PDF attendance sheet
360 * @param Request $request PSR Request
361 * @param Response $response PSR Response
365 public function attendanceSheet(Request
$request, Response
$response) :Response
367 $post = $request->getParsedBody();
369 if ($this->session
->filter_members
!== null) {
370 $filters = $this->session
->filter_members
;
372 $filters = new MembersList();
375 //retrieve selected members
376 $selection = (isset($post['selection'])) ?
$post['selection'] : array();
378 $filters->selected
= $selection;
379 $this->session
->filter_members
= $filters;
381 if (count($filters->selected
) == 0) {
382 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
383 $this->flash
->addMessage(
385 _T("No member selected to generate attendance sheet")
390 ->withHeader('Location', $this->router
->pathFor('members'));
394 $members = $m->getArrayList(
396 array('nom_adh', 'prenom_adh'),
400 if (!is_array($members) ||
count($members) < 1) {
401 Analog
::log('No member selected to generate attendance sheet', Analog
::INFO
);
402 $this->flash
->addMessage(
404 _T("No member selected to generate attendance sheet")
409 ->withHeader('Location', $this->router
->pathFor('members'));
412 $doc_title = _T("Attendance sheet");
413 if (isset($post['sheet_type']) && trim($post['sheet_type']) != '') {
414 $doc_title = $post['sheet_type'];
418 'doc_title' => $doc_title,
419 'title' => $post['sheet_title'] ??
null,
420 'subtitle' => $post['sheet_sub_title'] ??
null,
421 'sheet_date'=> $post['sheet_date'] ??
null
423 $pdf = new PdfAttendanceSheet($this->zdb
, $this->preferences
, $data);
424 //with or without images?
425 if (isset($post['sheet_photos']) && $post['sheet_photos'] === '1') {
428 $pdf->drawSheet($members);
430 return $this->sendResponse($response, $pdf);
436 * @param Request $request PSR Request
437 * @param Response $response PSR Response
438 * @param array $args Request arguments
442 public function contribution(Request
$request, Response
$response, array $args = []) :Response
444 $contribution = new Contribution($this->zdb
, $this->login
, (int)$args['id']);
445 if ($contribution->id
== '') {
446 //not possible to load contribution, exit
447 $this->flash
->addMessage(
452 _T("Unable to load contribution #%id!")
457 ->withHeader('Location', $this->router
->pathFor(
459 ['type' => 'contributions']
462 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
463 return $this->sendResponse($response, $pdf);
470 * @param Request $request PSR Request
471 * @param Response $response PSR Response
472 * @param array $args Request arguments
476 public function group(Request
$request, Response
$response, array $args = []) :Response
478 $groups = new Groups($this->zdb
, $this->login
);
481 if (isset($args['id'])) {
482 $groups_list = $groups->getList(true, $args['id']);
484 $groups_list = $groups->getList();
487 if (!is_array($groups_list) ||
count($groups_list) < 1) {
489 'An error has occurred, unable to get groups list.',
493 $this->flash
->addMessage(
495 _T("Unable to get groups list.")
500 ->withHeader('Location', $this->router
->pathFor('groups'));
503 $pdf = new PdfGroups($this->preferences
);
504 $pdf->draw($groups_list, $this->login
);
506 return $this->sendResponse($response, $pdf);
512 * @param Request $request PSR Request
513 * @param Response $response PSR Response
514 * @param array $args Request arguments
518 public function models(Request
$request, Response
$response, array $args = []) :Response
521 if (isset($_POST[PdfModel
::PK
])) {
522 $id = (int)$_POST[PdfModel
::PK
];
523 } elseif (isset($args['id'])) {
524 $id = (int)$args['id'];
528 $ms = new PdfModels($this->zdb
, $this->preferences
, $this->login
);
529 $models = $ms->getList();
532 foreach ($models as $m) {
533 if ($m->id
=== $id) {
542 //Render directly template if we called from ajax,
543 //render in a full page otherwise
544 if ($request->isXhr()
545 ||
isset($request->getQueryParams()['ajax'])
546 && $request->getQueryParams()['ajax'] == 'true'
548 $tpl = 'gestion_pdf_content.tpl';
549 $params['model'] = $model;
551 $tpl = 'gestion_pdf.tpl';
553 'page_title' => _T("PDF models"),
571 * @param Request $request PSR Request
572 * @param Response $response PSR Response
573 * @param array $args Request arguments
577 public function storeModels(Request
$request, Response
$response, array $args = []) :Response
579 $post = $request->getParsedBody();
581 if (isset($post['model_type'])) {
582 $type = (int)$post['model_type'];
585 if ($type === null) {
586 $this->flash
->addMessage(
588 _T("Missing PDF model type!")
591 $class = PdfModel
::getTypeClass($type);
592 if (isset($post[PdfModel
::PK
])) {
593 $model = new $class($this->zdb
, $this->preferences
, (int)$_POST[PdfModel
::PK
]);
595 $model = new $class($this->zdb
, $this->preferences
);
599 $model->header
= $post['model_header'];
600 $model->footer
= $post['model_footer'];
601 $model->type
= $type;
602 if (isset($post['model_body'])) {
603 $model->body
= $post['model_body'];
605 if (isset($post['model_title'])) {
606 $model->title
= $post['model_title'];
608 if (isset($post['model_body'])) {
609 $model->subtitle
= $post['model_subtitle'];
611 if (isset($post['model_styles'])) {
612 $model->styles
= $post['model_styles'];
614 $res = $model->store();
616 $this->flash
->addMessage(
618 _T("Model has been successfully stored!")
621 $this->flash
->addMessage(
623 _T("Model has not been stored :(")
626 } catch (\Exception
$e) {
627 $error_detected[] = $e->getMessage();
633 ->withHeader('Location', $this->router
->pathFor('pdfModels', ['id' => $model->id
]));
638 * Get direct document
640 * @param Request $request PSR Request
641 * @param Response $response PSR Response
642 * @param array $args Request arguments
646 public function directlinkDocument(Request
$request, Response
$response, array $args = []) :Response
648 $hash = $args['hash'];
649 $post = $request->getParsedBody();
650 $email = $post['email'];
652 $links = new Links($this->zdb
);
653 $valid = $links->isHashValid($hash, $email);
655 if ($valid === false) {
656 $this->flash
->addMessage(
661 return $response->withStatus(301)
662 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
668 if ($target === Links
::TARGET_MEMBERCARD
) {
670 $members = $m->getArrayList(
672 array('nom_adh', 'prenom_adh'),
676 if (!is_array($members) ||
count($members) < 1) {
678 'An error has occurred, unable to get members list.',
682 $this->flash
->addMessage(
684 _T("Unable to get members list.")
689 ->withHeader('Location', $this->router
->pathFor('directlink', ['hash' => $hash]));
692 $pdf = new PdfMembersCards($this->preferences
);
693 $pdf->drawCards($members);
695 $contribution = new Contribution($this->zdb
, $this->login
, $id);
696 if ($contribution->id
== '') {
697 //not possible to load contribution, exit
698 $this->flash
->addMessage(
703 _T("Unable to load contribution #%id!")
708 ->withHeader('Location', $this->router
->pathFor(
713 $pdf = new PdfContribution($contribution, $this->zdb
, $this->preferences
);
717 return $this->sendResponse($response, $pdf);