]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Entity/Texts.php
be07f0ebe3646b7e772e78c5d0f3f6873499cc7d
[galette.git] / galette / lib / Galette / Entity / Texts.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Texts handling
7 *
8 * PHP version 5
9 *
10 * Copyright © 2007-2014 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
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.
18 *
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.
23 *
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/>.
26 *
27 * @category Entity
28 * @package Galette
29 *
30 * @author John Perr <johnperr@abul.org>
31 * @author Johan Cwiklinski <joahn@x-tnd.be>
32 * @copyright 2007-2014 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
36 */
37
38 namespace Galette\Entity;
39
40 use Analog\Analog;
41 use Laminas\Db\Sql\Expression;
42 use Galette\Core\Preferences;
43 use Slim\Router;
44
45 /**
46 * Texts class for galette
47 *
48 * @category Entity
49 * @name Texts
50 * @package Galette
51 * @author John Perr <johnperr@abul.org>
52 * @author Johan Cwiklinski <joahn@x-tnd.be>
53 * @copyright 2007-2014 The Galette Team
54 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
55 * @link http://galette.tuxfamily.org
56 * @since Avaialble since 0.7dev - 2007-07-16
57 */
58 class Texts
59 {
60 private $all_texts;
61 const TABLE = "texts";
62 const PK = 'tid';
63 const DEFAULT_REF = 'sub';
64
65 private $patterns;
66 private $replaces;
67 private $defaults;
68
69 /**
70 * Main constructor
71 *
72 * @param Preferences $preferences Galette's preferences
73 * @param Router $router Router instance
74 * @param array $replaces Data that will be used as replacments
75 */
76 public function __construct(Preferences $preferences, Router $router = null, $replaces = null)
77 {
78 $this->patterns = array(
79 'asso_name' => '/{ASSO_NAME}/',
80 'asso_slogan' => '/{ASSO_SLOGAN}/',
81 'id_adh' => '/{ID_ADH}/',
82 'name_adh' => '/{NAME_ADH}/',
83 'lastname_adh' => '/{LASTNAME_ADH}/',
84 'firstname_adh' => '/{FIRSTNAME_ADH}/',
85 'login_adh' => '/{LOGIN}/',
86 'mail_adh' => '/{MAIL_ADH}/',
87 'login_uri' => '/{LOGIN_URI}/',
88 'change_pass_uri' => '/{CHG_PWD_URI}/',
89 'link_validity' => '/{LINK_VALIDITY}/',
90 'deadline' => '/{DEADLINE}/',
91 'contrib_info' => '/{CONTRIB_INFO}/',
92 'days_remaining' => '/{DAYS_REMAINING}/',
93 'days_expired' => '/{DAYS_EXPIRED}/',
94 'contrib_amount' => '/{CONTRIB_AMOUNT}/',
95 'contrib_type' => '/{CONTRIB_TYPE}/',
96 'breakline' => '/{BR}/',
97 'newline' => '/{NEWLINE}/',
98 'link_membercard' => '/{LINK_MEMBERCARD}/',
99 'link_contribpdf' => '/{LINK_CONTRIBPDF}/'
100 );
101
102 $login_uri = '';
103 if ($router !== null) {
104 $login_uri = $preferences->getURL() . $router->pathFor('login');
105 }
106
107 $this->replaces = array(
108 'asso_name' => $preferences->pref_nom,
109 'asso_slogan' => $preferences->pref_slogan,
110 'id_adh' => null,
111 'name_adh' => null,
112 'lastname_adh' => null,
113 'firstname_adh' => null,
114 'login_adh' => null,
115 'mail_adh' => null,
116 'login_uri' => $login_uri,
117 'change_pass_uri' => null,
118 'link_validity' => null,
119 'deadline' => null,
120 'contrib_info' => null,
121 'days_remaining' => null,
122 'days_expired' => null,
123 'contrib_amount' => null,
124 'contrib_type' => null,
125 'breakline' => "\r\n",
126 'newline' => "\r\n\r\n",
127 'link_membercard' => null,
128 'link_contribpdf' => null
129 );
130
131 if ($replaces != null && is_array($replaces)) {
132 $this->setReplaces($replaces);
133 }
134 }
135
136 /**
137 * Set replacements values
138 *
139 * @param array $replaces Replacements values
140 *
141 * @return void
142 */
143 public function setReplaces($replaces)
144 {
145 //let's populate replacement array with values provided
146 foreach ($replaces as $k => $v) {
147 $this->replaces[$k] = $v;
148 }
149 }
150
151 /**
152 * Get specific text
153 *
154 * @param string $ref Reference of text to get
155 * @param string $lang Language texts to get
156 *
157 * @return array of all text fields for one language.
158 */
159 public function getTexts($ref, $lang)
160 {
161 global $zdb, $i18n;
162
163 //check if language is set and exists
164 $langs = $i18n->getList();
165 $is_lang_ok = false;
166 foreach ($langs as $l) {
167 if ($lang === $l->getID()) {
168 $is_lang_ok = true;
169 break;
170 }
171 }
172
173 if ($is_lang_ok !== true) {
174 Analog::log(
175 'Language ' . $lang .
176 ' does not exists. Falling back to default Galette lang.',
177 Analog::ERROR
178 );
179 $lang = $i18n->getID();
180 }
181
182 try {
183 $select = $zdb->select(self::TABLE);
184 $select->where(
185 array(
186 'tref' => $ref,
187 'tlang' => $lang
188 )
189 );
190 $results = $zdb->execute($select);
191 $result = $results->current();
192 if ($result) {
193 $this->all_texts = $result;
194 } else {
195 //hum... no result... That means text do not exist in the
196 //database, let's add it
197 $default = null;
198 $this->defaults = $this->getAllDefaults(); //load defaults
199 foreach ($this->defaults as $d) {
200 if ($d['tref'] == $ref && $d['tlang'] == $lang) {
201 $default = $d;
202 break;
203 }
204 }
205 if ($default !== null) {
206 $values = array(
207 'tref' => $default['tref'],
208 'tsubject' => $default['tsubject'],
209 'tbody' => $default['tbody'],
210 'tlang' => $default['tlang'],
211 'tcomment' => $default['tcomment']
212 );
213
214 try {
215 $this->insert($zdb, [$values]);
216 return $this->getTexts($ref, $lang);
217 } catch (\Exception $e) {
218 Analog::log(
219 'Unable to add missing requested text "' . $ref .
220 ' (' . $lang . ') | ' . $e->getMessage(),
221 Analog::WARNING
222 );
223 }
224 } else {
225 Analog::log(
226 'Unable to find missing requested text "' . $ref .
227 ' (' . $lang . ')',
228 Analog::WARNING
229 );
230 }
231 }
232 return $this->all_texts;
233 } catch (\Exception $e) {
234 Analog::log(
235 'Cannot get text `' . $ref . '` for lang `' . $lang . '` | ' .
236 $e->getMessage(),
237 Analog::WARNING
238 );
239 return false;
240 }
241 }
242
243 /**
244 * Set text
245 *
246 * @param string $ref Texte ref to locate
247 * @param string $lang Texte language to locate
248 * @param string $subject Subject to set
249 * @param string $body Body text to set
250 *
251 * @return integer|false affected rows (0 if record did not change)
252 * or false on error
253 */
254 public function setTexts($ref, $lang, $subject, $body)
255 {
256 global $zdb;
257 //set texts
258
259 try {
260 $values = array(
261 'tsubject' => $subject,
262 'tbody' => $body,
263 );
264
265 $update = $zdb->update(self::TABLE);
266 $update->set($values)->where(
267 array(
268 'tref' => $ref,
269 'tlang' => $lang
270 )
271 );
272 $zdb->execute($update);
273
274 return true;
275 } catch (\Exception $e) {
276 Analog::log(
277 'An error has occurred while storing email text. | ' .
278 $e->getMessage(),
279 Analog::ERROR
280 );
281 return false;
282 }
283 }
284
285 /**
286 * Ref List
287 *
288 * @param string $lang Requested language
289 *
290 * @return array: list of references used for texts
291 */
292 public function getRefs($lang)
293 {
294 global $zdb;
295
296 try {
297 $select = $zdb->select(self::TABLE);
298 $select->columns(
299 array('tref', 'tcomment')
300 )->where(array('tlang' => $lang));
301
302 $refs = [];
303 $results = $zdb->execute($select);
304 foreach ($results as $result) {
305 $refs[] = $result;
306 }
307 return $refs;
308 } catch (\Exception $e) {
309 Analog::log(
310 'Cannot get refs for lang `' . $lang . '` | ' .
311 $e->getMessage(),
312 Analog::WARNING
313 );
314 return false;
315 }
316 }
317
318 /**
319 * Retrieve fields from database
320 *
321 * @deprecated Do not seem to be used as of 2013-07-16
322 *
323 * @return array
324 */
325 public static function getDbFields()
326 {
327 global $zdb;
328 $columns = $zdb->getColumns(self::TABLE);
329 $fields = array();
330 foreach ($columns as $col) {
331 $fields[] = $col->getName();
332 }
333 return $fields;
334 }
335
336 /**
337 * Initialize texts at install time
338 *
339 * @param boolean $check_first Check first if it seem initialized
340 *
341 * @return boolean|Exception false if no need to initialize, true if data
342 * has been initialized, Exception if error
343 */
344 public function installInit($check_first = true)
345 {
346 global $zdb;
347
348 try {
349 //first of all, let's check if data seem to have already
350 //been initialized
351 $this->defaults = $this->getAllDefaults(); //load defaults
352 $proceed = false;
353 if ($check_first === true) {
354 $select = $zdb->select(self::TABLE);
355 $select->columns(
356 array(
357 'counter' => new Expression('COUNT(' . self::PK . ')')
358 )
359 );
360
361 $results = $zdb->execute($select);
362 $result = $results->current();
363 $count = $result->counter;
364 if ($count == 0) {
365 //if we got no values in texts table, let's proceed
366 $proceed = true;
367 } else {
368 if ($count < count($this->defaults)) {
369 return $this->checkUpdate();
370 }
371 return false;
372 }
373 } else {
374 $proceed = true;
375 }
376
377 if ($proceed === true) {
378 //first, we drop all values
379 $delete = $zdb->delete(self::TABLE);
380 $zdb->execute($delete);
381
382 $zdb->handleSequence(
383 self::TABLE,
384 count($this->defaults)
385 );
386
387 $this->insert($zdb, $this->defaults);
388
389 Analog::log(
390 'Default texts were successfully stored into database.',
391 Analog::INFO
392 );
393 return true;
394 }
395 } catch (\Exception $e) {
396 Analog::log(
397 'Unable to initialize default texts.' . $e->getMessage(),
398 Analog::WARNING
399 );
400 return $e;
401 }
402 }
403
404 /**
405 * Checks for missing texts in the database
406 *
407 * @return boolean
408 */
409 private function checkUpdate()
410 {
411 global $zdb;
412
413 try {
414 $select = $zdb->select(self::TABLE);
415 $dblist = $zdb->execute($select);
416
417 $list = [];
418 foreach ($dblist as $dbentry) {
419 $list[] = $dbentry;
420 }
421
422 $missing = array();
423 foreach ($this->defaults as $default) {
424 $exists = false;
425 foreach ($list as $text) {
426 if (
427 $text->tref == $default['tref']
428 && $text->tlang == $default['tlang']
429 ) {
430 $exists = true;
431 continue;
432 }
433 }
434
435 if ($exists === false) {
436 //text does not exists in database, insert it.
437 $missing[] = $default;
438 }
439 }
440
441 if (count($missing) > 0) {
442 $this->insert($zdb, $missing);
443
444 Analog::log(
445 'Missing texts were successfully stored into database.',
446 Analog::INFO
447 );
448 return true;
449 }
450 } catch (\Exception $e) {
451 Analog::log(
452 'An error occurred checking missing texts.' . $e->getMessage(),
453 Analog::WARNING
454 );
455 throw $e;
456 }
457 }
458
459 /**
460 * Get the subject, with all replacements done
461 *
462 * @return string
463 */
464 public function getSubject()
465 {
466 return preg_replace(
467 $this->patterns,
468 $this->replaces,
469 $this->all_texts->tsubject
470 );
471 }
472
473 /**
474 * Get the body, with all replacements done
475 *
476 * @return string
477 */
478 public function getBody()
479 {
480 return preg_replace(
481 $this->patterns,
482 $this->replaces,
483 $this->all_texts->tbody
484 );
485 }
486
487 /**
488 * Insert values in database
489 *
490 * @param Db $zdb Database instance
491 * @param array $values Values to insert
492 *
493 * @return void
494 */
495 private function insert($zdb, $values)
496 {
497 $insert = $zdb->insert(self::TABLE);
498 $insert->values(
499 array(
500 'tref' => ':tref',
501 'tsubject' => ':tsubject',
502 'tbody' => ':tbody',
503 'tlang' => ':tlang',
504 'tcomment' => ':tcomment'
505 )
506 );
507 $stmt = $zdb->sql->prepareStatementForSqlObject($insert);
508
509 foreach ($values as $value) {
510 $stmt->execute($value);
511 }
512 }
513
514 /**
515 * Get default mail texts for all languages
516 *
517 * @return array
518 */
519 public function getAllDefaults()
520 {
521 global $i18n;
522
523 $all = [];
524 foreach (array_keys($i18n->getArrayList()) as $lang) {
525 $all = array_merge($all, $this->getDefaultTexts($lang));
526 }
527
528 return $all;
529 }
530
531 /**
532 * Get default texts for specified language
533 *
534 * @param string $lang Requested lang. Defaults to en_US
535 *
536 * @return array
537 */
538 public function getDefaultTexts($lang = 'en_US')
539 {
540 global $i18n;
541
542 $current_lang = $i18n->getID();
543
544 $i18n->changeLanguage($lang);
545
546 //do the magic!
547 include GALETTE_ROOT . 'includes/fields_defs/texts_fields.php';
548 $texts = [];
549
550 foreach ($texts_fields as $text_field) {
551 unset($text_field['tid']);
552 $text_field['tlang'] = $lang;
553 $texts[] = $text_field;
554 }
555
556 //reset to current lang
557 $i18n->changeLanguage($current_lang);
558 return $texts;
559 }
560 }