3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
10 * Copyright © 2007-2021 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 John Perr <johnperr@abul.org>
31 * @author Johan Cwiklinski <joahn@x-tnd.be>
32 * @copyright 2007-2021 The Galette Team
33 * @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 Avaialble since 0.7dev - 2007-07-16
38 namespace Galette\Entity
;
40 use Galette\Core\I18n
;
41 use Galette\Features\Replacements
;
44 use Laminas\Db\Sql\Expression
;
45 use Galette\Core\Password
;
46 use Galette\Core\Preferences
;
50 * Texts class for galette
55 * @author John Perr <johnperr@abul.org>
56 * @author Johan Cwiklinski <joahn@x-tnd.be>
57 * @copyright 2007-2021 The Galette Team
58 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
59 * @link http://galette.tuxfamily.org
60 * @since Avaialble since 0.7dev - 2007-07-16
65 getLegend
as protected trait_getLegend
;
69 public const TABLE
= "texts";
70 public const PK
= 'tid';
71 public const DEFAULT_REF
= 'sub';
79 * @param Preferences $preferences Galette's preferences
80 * @param Router|null $router Router instance
82 public function __construct(Preferences
$preferences, Router
$router = null)
84 global $zdb, $login, $container;
85 $this->preferences
= $preferences;
86 if ($router === null) {
87 $router = $container->get('router');
89 if ($login === null) {
90 $login = $container->get('login');
92 $this->router
= $router;
98 $this->getMainPatterns()
99 +
$this->getMailPatterns()
100 +
$this->getMemberPatterns()
101 +
$this->getContributionPatterns()
104 if (GALETTE_MODE
!== 'INSTALL') {
112 * Get patterns for mails
114 * @param boolean $legacy Whether to load legacy patterns
118 protected function getMailPatterns($legacy = true): array
122 'title' => _T('Insert a carriage return'),
123 'pattern' => '/{BR}/',
126 'title' => _T('Insert a new blank line'),
127 'pattern' => '/{NEWLINE}/',
130 'title' => _T('Link validity'),
131 'pattern' => '/{LINK_VALIDITY}/',
132 'onlyfor' => ['sub', 'pwd']
134 'link_membercard' => [
135 'title' => _T('Direct link for member card download'),
136 'pattern' => '/{LINK_MEMBERCARD}/',
137 'onlyfor' => ['contrib', 'donation']
139 'link_contribpdf' => [
140 'title' => _T('Direct link for invoice/receipt download'),
141 'pattern' => '/{LINK_CONTRIBPDF}/',
142 'onlyfor' => ['contrib', 'donation']
144 'change_pass_uri' => [
145 'title' => _T("Galette's change password URI"),
146 'pattern' => '/{CHG_PWD_URI}/',
147 'onlyfor' => ['sub', 'pwd']
151 //clean based on current ref and onlyfor
152 if ($this->current
!== null) {
153 foreach ($m_patterns as $key => $m_pattern) {
155 isset($m_pattern['onlyfor'])
156 && !in_array($this->current
, $m_pattern['onlyfor'])
158 unset($m_patterns[$key]);
167 * Set emails replacements
171 public function setMail(): self
173 $this->setReplacements([
174 'link_validity' => null,
175 'breakline' => "\r\n",
176 'newline' => "\r\n\r\n",
177 'link_membercard' => null,
178 'link_contribpdf' => null,
179 'change_pass_uri' => null
185 * Set change password URL
187 * @param Password $password Password instance
191 public function setChangePasswordURI(Password
$password): Texts
193 $this->setReplacements([
194 'change_pass_uri' => $this->preferences
->getURL() .
195 $this->router
->pathFor(
197 ['hash' => base64_encode($password->getHash())]
208 public function setLinkValidity(): Texts
210 $link_validity = new \
DateTime();
211 $link_validity->add(new \
DateInterval('PT24H'));
212 $this->setReplacements(['link_validity' => $link_validity->format(_T("Y-m-d H:i:s"))]);
217 * Set member card PDF link
219 * @param string $link Link
223 public function setMemberCardLink(string $link): Texts
225 $this->setReplacements(['link_membercard' => $link]);
230 * Set contribution PDF link
232 * @param string $link Link
236 public function setContribLink(string $link): Texts
238 $this->setReplacements(['link_contribpdf' => $link]);
245 * @param string $ref Reference of text to get
246 * @param string $lang Language texts to get
248 * @return array of all text fields for one language.
250 public function getTexts($ref, $lang)
254 //check if language is set and exists
255 $langs = $i18n->getList();
257 foreach ($langs as $l) {
258 if ($lang === $l->getID()) {
264 if ($is_lang_ok !== true) {
266 'Language ' . $lang .
267 ' does not exists. Falling back to default Galette lang.',
270 $lang = $i18n->getID();
274 $select = $this->zdb
->select(self
::TABLE
);
281 $results = $this->zdb
->execute($select);
282 $result = $results->current();
284 $this->all_texts
= $result;
286 //hum... no result... That means text do not exist in the
287 //database, let's add it
289 $this->defaults
= $this->getAllDefaults(); //load defaults
290 foreach ($this->defaults
as $d) {
291 if ($d['tref'] == $ref && $d['tlang'] == $lang) {
296 if ($default !== null) {
298 'tref' => $default['tref'],
299 'tsubject' => $default['tsubject'],
300 'tbody' => $default['tbody'],
301 'tlang' => $default['tlang'],
302 'tcomment' => $default['tcomment']
306 $this->insert([$values]);
307 return $this->getTexts($ref, $lang);
308 } catch (Throwable
$e) {
310 'Unable to add missing requested text "' . $ref .
311 ' (' . $lang . ') | ' . $e->getMessage(),
317 'Unable to find missing requested text "' . $ref .
323 return $this->all_texts
;
324 } catch (Throwable
$e) {
326 'Cannot get text `' . $ref . '` for lang `' . $lang . '` | ' .
337 * @param string $ref Texte ref to locate
338 * @param string $lang Texte language to locate
339 * @param string $subject Subject to set
340 * @param string $body Body text to set
342 * @return integer|false affected rows (0 if record did not change)
345 public function setTexts($ref, $lang, $subject, $body)
349 'tsubject' => $subject,
353 $update = $this->zdb
->update(self
::TABLE
);
354 $update->set($values)->where(
360 $this->zdb
->execute($update);
363 } catch (Throwable
$e) {
365 'An error has occurred while storing email text. | ' .
376 * @param string $lang Requested language
378 * @return array: list of references used for texts
380 public function getRefs(string $lang = I18n
::DEFAULT_LANG
)
383 $select = $this->zdb
->select(self
::TABLE
);
385 array('tref', 'tcomment')
386 )->where(array('tlang' => $lang));
389 $results = $this->zdb
->execute($select);
390 foreach ($results as $result) {
394 } catch (Throwable
$e) {
396 'Cannot get refs for lang `' . $lang . '` | ' .
405 * Initialize texts at install time
407 * @param boolean $check_first Check first if it seem initialized
409 * @return boolean|Exception false if no need to initialize, true if data
410 * has been initialized, Exception if error
412 public function installInit($check_first = true)
415 //first of all, let's check if data seem to have already
417 $this->defaults
= $this->getAllDefaults(); //load defaults
419 if ($check_first === true) {
420 $select = $this->zdb
->select(self
::TABLE
);
423 'counter' => new Expression('COUNT(' . self
::PK
. ')')
427 $results = $this->zdb
->execute($select);
428 $result = $results->current();
429 $count = $result->counter
;
431 //if we got no values in texts table, let's proceed
434 if ($count < count($this->defaults
)) {
435 return $this->checkUpdate();
443 if ($proceed === true) {
444 //first, we drop all values
445 $delete = $this->zdb
->delete(self
::TABLE
);
446 $this->zdb
->execute($delete);
448 $this->zdb
->handleSequence(
450 count($this->defaults
)
453 $this->insert($this->defaults
);
456 'Default texts were successfully stored into database.',
461 } catch (Throwable
$e) {
463 'Unable to initialize default texts.' . $e->getMessage(),
471 * Checks for missing texts in the database
475 private function checkUpdate()
478 $select = $this->zdb
->select(self
::TABLE
);
479 $dblist = $this->zdb
->execute($select);
482 foreach ($dblist as $dbentry) {
487 foreach ($this->defaults
as $default) {
489 foreach ($list as $text) {
491 $text->tref
== $default['tref']
492 && $text->tlang
== $default['tlang']
499 if ($exists === false) {
500 //text does not exists in database, insert it.
501 $missing[] = $default;
505 if (count($missing) > 0) {
506 $this->insert($missing);
509 'Missing texts were successfully stored into database.',
514 } catch (Throwable
$e) {
516 'An error occurred checking missing texts.' . $e->getMessage(),
524 * Get the subject, with all replacements done
528 public function getSubject()
530 return $this->proceedReplacements($this->all_texts
->tsubject
);
534 * Get the body, with all replacements done
538 public function getBody()
540 return $this->proceedReplacements($this->all_texts
->tbody
);
544 * Insert values in database
546 * @param array $values Values to insert
550 private function insert(array $values)
552 $insert = $this->zdb
->insert(self
::TABLE
);
556 'tsubject' => ':tsubject',
559 'tcomment' => ':tcomment'
562 $stmt = $this->zdb
->sql
->prepareStatementForSqlObject($insert);
564 foreach ($values as $value) {
565 $stmt->execute($value);
570 * Get default mail texts for all languages
574 public function getAllDefaults()
579 foreach (array_keys($i18n->getArrayList()) as $lang) {
580 $all = array_merge($all, $this->getDefaultTexts($lang));
587 * Get default texts for specified language
589 * @param string $lang Requested lang. Defaults to en_US
593 public function getDefaultTexts($lang = 'en_US')
597 $current_lang = $i18n->getID();
599 $i18n->changeLanguage($lang);
602 include GALETTE_ROOT
. 'includes/fields_defs/texts_fields.php';
605 foreach ($texts_fields as $text_field) {
606 unset($text_field['tid']);
607 $text_field['tlang'] = $lang;
608 $texts[] = $text_field;
611 //reset to current lang
612 $i18n->changeLanguage($current_lang);
621 public function getLegend(): array
623 $legend = $this->trait_getLegend();
625 $contribs = ['contrib', 'newcont', 'donation', 'newdonation'];
626 if ($this->current
!== null && in_array($this->current
, $contribs)) {
627 $patterns = $this->getContributionPatterns(false);
628 $legend['contribution'] = [
629 'title' => _T('Contribution information'),
630 'patterns' => $patterns
634 $patterns = $this->getMailPatterns(false);
636 'title' => _T('Mail specific'),
637 'patterns' => $patterns
644 * Set current text reference
646 * @param string $ref Reference
650 public function setCurrent(string $ref): self
652 $this->current
= $ref;