3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
10 * Copyright © 2013-2023 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 2013-2023 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.7.5dev - 2013-02-19
37 namespace Galette\Entity
;
40 use Slim\Routing\RouteParser
;
43 use Galette\Core\Preferences
;
44 use Galette\Features\Replacements
;
45 use Galette\Repository\PdfModels
;
47 use Laminas\Db\Sql\Expression
;
55 * @author Johan Cwiklinski <johan@x-tnd.be>
56 * @copyright 2013-2023 The Galette Team
57 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
58 * @link http://galette.tuxfamily.org
59 * @since Available since 0.7.5dev - 2013-02-19
61 * @property integer $id
62 * @property string $name
63 * @property integer $type
64 * @property string $header
65 * @property-read string $hheader
66 * @property string $footer
67 * @property-read string $hfooter
68 * @property string $title
69 * @property-read string $htitle
70 * @property string $subtitle
71 * @property-read string $hsubtitle
72 * @property string $body
73 * @property-read string $hbody
74 * @property string $styles
75 * @property PdfMain $parent
78 abstract class PdfModel
82 public const TABLE
= 'pdfmodels';
83 public const PK
= 'model_id';
85 public const MAIN_MODEL
= 1;
86 public const INVOICE_MODEL
= 2;
87 public const RECEIPT_MODEL
= 3;
88 public const ADHESION_FORM_MODEL
= 4;
104 * @param Db $zdb Database instance
105 * @param Preferences $preferences Galette preferences
106 * @param int $type Model type
107 * @param mixed $args Arguments
109 public function __construct(Db
$zdb, Preferences
$preferences, $type, $args = null)
111 global $container, $login;
112 $this->routeparser
= $container->get(RouteParser
::class);
113 $this->preferences
= $preferences;
121 } elseif ($args !== null && is_object($args)) {
122 $this->loadFromRs($args);
127 $this->setPatterns($this->getMainPatterns());
132 * Load a Model from its identifier
134 * @param int $id Identifier
135 * @param boolean $init Init data if required model is missing
139 protected function load($id, $init = true)
144 $select = $this->zdb
->select(self
::TABLE
);
146 ->where([self
::PK
=> $id]);
148 $results = $this->zdb
->execute($select);
150 $count = $results->count();
152 if ($init === true) {
153 $models = new PdfModels($this->zdb
, $this->preferences
, $login);
154 $models->installInit();
155 $this->load($id, false);
157 throw new \
RuntimeException('Model not found!');
160 /** @var ArrayObject $result */
161 $result = $results->current();
162 $this->loadFromRs($result);
164 } catch (Throwable
$e) {
166 'An error occurred loading model #' . $id . "Message:\n" .
175 * Load model from a db ResultSet
177 * @param ArrayObject $rs ResultSet
181 protected function loadFromRs(ArrayObject
$rs)
184 $this->id
= (int)$rs->$pk;
186 $callback = function ($matches) {
187 return _T($matches[1]);
189 $this->name
= preg_replace_callback(
190 '/_T\("([^\"]+)"\)/',
195 $this->title
= $rs->model_title
;
196 $this->subtitle
= $rs->model_subtitle
;
197 $this->header
= $rs->model_header
;
198 $this->footer
= $rs->model_footer
;
199 $this->body
= $rs->model_body
;
200 $this->styles
.= $rs->model_styles
;
202 if ($this->id
> self
::MAIN_MODEL
) {
203 //FIXME: for now, parent will always be a PdfMain
204 $this->parent
= new PdfMain(
207 (int)$rs->model_parent
213 * Store model in database
217 public function store()
219 $title = $this->title
;
220 if ($title === null ||
trim($title) === '') {
221 $title = new Expression('NULL');
224 $subtitle = $this->subtitle
;
225 if ($subtitle === null ||
trim($subtitle) === '') {
226 $subtitle = new Expression('NULL');
230 'model_header' => $this->header
,
231 'model_footer' => $this->footer
,
232 'model_type' => $this->type
,
233 'model_title' => $title,
234 'model_subtitle' => $subtitle,
235 'model_body' => $this->body
,
236 'model_styles' => $this->styles
240 if ($this->id
!== null) {
241 $update = $this->zdb
->update(self
::TABLE
);
242 $update->set($data)->where(
243 [self
::PK
=> $this->id
]
245 $this->zdb
->execute($update);
247 $data['model_name'] = $this->name
;
248 $insert = $this->zdb
->insert(self
::TABLE
);
249 $insert->values($data);
250 $add = $this->zdb
->execute($insert);
251 if (!($add->count() > 0)) {
252 Analog
::log('Not stored!', Analog
::ERROR
);
257 } catch (Throwable
$e) {
259 'An error occurred storing model: ' . $e->getMessage() .
260 "\n" . print_r($data, true),
268 * Get object class for specified type
270 * @param int $type Type
274 public static function getTypeClass(int $type)
278 case self
::INVOICE_MODEL
:
279 $class = 'PdfInvoice';
281 case self
::RECEIPT_MODEL
:
282 $class = 'PdfReceipt';
284 case self
::ADHESION_FORM_MODEL
:
285 $class = 'PdfAdhesionFormModel';
291 $class = 'Galette\\Entity\\' . $class;
298 * @param string $value The value
299 * @param int $chars Length
300 * @param string $field Field name
301 * @param boolean $empty Can value be empty
305 protected function checkChars($value, $chars, $field, $empty = false)
307 if ($value !== null && trim($value) !== '') {
308 if (mb_strlen($value) > $chars) {
309 throw new \
LengthException(
311 array('%field', '%chars'),
312 array($field, $chars),
313 _T("%field should be less than %chars characters long.")
318 if ($empty === false) {
319 throw new \
UnexpectedValueException(
323 _T("%field should not be empty!")
333 * @param string $name Property name
337 public function __get($name)
343 return (int)$this->$name;
354 return $this->$name ??
'';
358 //get header and footer from parent if not defined in current model
360 $this->id
> self
::MAIN_MODEL
361 && $this->parent
!== null
363 $value = $this->parent
->styles
;
366 $value .= $this->styles
;
373 $pname = substr($name, 1);
374 $prop_value = $this->$pname ??
'';
376 //get header and footer from parent if not defined in current model
378 $this->id
> self
::MAIN_MODEL
379 && $this->parent
!== null
380 && ($pname === 'footer'
381 ||
$pname === 'header')
382 && trim($prop_value) === ''
384 $prop_value = $this->parent
->$pname;
387 $value = $this->proceedReplacements($prop_value);
391 'Unable to get PdfModel property ' . $name,
400 * Required for twig to access properties via __get
402 * @param string $name Property name
406 public function __isset($name)
435 * @param string $name Property name
436 * @param mixed $value Property value
440 public function __set($name, $value)
445 $value === self
::MAIN_MODEL
446 ||
$value === self
::INVOICE_MODEL
447 ||
$value === self
::RECEIPT_MODEL
448 ||
$value === self
::ADHESION_FORM_MODEL
450 $this->$name = $value;
452 throw new \
UnexpectedValueException(
456 _T("Unknown type %type!")
463 $this->checkChars($value, 50, _T("Name"));
464 $this->$name = $value;
465 } catch (Throwable
$e) {
471 if ($name == 'title') {
472 $field = _T("Title");
474 $field = _T("Subtitle");
477 $this->checkChars($value, 100, $field, true);
478 $this->$name = $value;
479 } catch (Throwable
$e) {
486 if ($value === null ||
trim($value) === '') {
487 if ($name !== 'body' && get_class($this) === PdfMain
::class) {
488 throw new \
UnexpectedValueException(
489 _T("header and footer should not be empty!")
491 } elseif ($name === 'body' && get_class($this) !== PdfMain
::class) {
492 throw new \
UnexpectedValueException(
493 _T("body should not be empty!")
498 $this->$name = $value;
501 $this->styles
= $value;
505 'Unable to set PdfModel property ' . $name,