]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/DynamicFields/DynamicField.php
888c4fdea93a4ed29413b7d646b8ae93ba5e0bab
[galette.git] / galette / lib / Galette / DynamicFields / DynamicField.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Abstract dynamic field
7 *
8 * PHP version 5
9 *
10 * Copyright © 2012-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 DynamicFields
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2012-2014 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.1dev - 2012-07-28
35 */
36
37 namespace Galette\DynamicFields;
38
39 use Analog\Analog;
40 use Galette\Core\Db;
41 use Galette\Entity\DynamicFieldsHandle;
42 use Galette\Entity\TranslatableTrait;
43 use Galette\Entity\I18nTrait;
44 use Laminas\Db\Sql\Expression;
45 use Laminas\Db\Sql\Predicate\Expression as PredicateExpression;
46
47 /**
48 * Abstract dynamic field
49 *
50 * @name DynamicField
51 * @category DynamicFields
52 * @package Galette
53 *
54 * @author Johan Cwiklinski <johan@x-tnd.be>
55 * @copyright 2012-2014 The Galette Team
56 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
57 * @link http://galette.tuxfamily.org
58 */
59
60 abstract class DynamicField
61 {
62 use TranslatableTrait;
63 use I18nTrait;
64
65 public const TABLE = 'field_types';
66 public const PK = 'field_id';
67
68 /** Separator field */
69 public const SEPARATOR = 0;
70 /** Simple text field */
71 public const TEXT = 1;
72 /** Line field */
73 public const LINE = 2;
74 /** Choice field (listbox) */
75 public const CHOICE = 3;
76 /** Date field */
77 public const DATE = 4;
78 /** Boolean field (checkbox) */
79 public const BOOLEAN = 5;
80 /** File field (upload) */
81 public const FILE = 6;
82
83 public const PERM_USER_WRITE = 0;
84 public const PERM_ADMIN = 1;
85 public const PERM_STAFF = 2;
86 public const PERM_MANAGER = 3;
87 public const PERM_USER_READ = 4;
88
89 public const DEFAULT_MAX_FILE_SIZE = 1024;
90 public const VALUES_FIELD_LENGTH = 100;
91
92 protected $has_data = false;
93 protected $has_width = false;
94 protected $has_height = false;
95 protected $has_size = false;
96 protected $multi_valued = false;
97 protected $fixed_values = false;
98 protected $has_permissions = true;
99
100 protected $id;
101 protected $index;
102 protected $perm;
103 protected $required;
104 protected $width;
105 protected $height;
106 protected $repeat;
107 protected $size;
108 protected $old_size;
109 protected $values;
110 protected $form;
111
112 protected $errors;
113
114 protected $zdb;
115
116 /**
117 * Default constructor
118 *
119 * @param Db $zdb Database instance
120 * @param mixed $args Arguments
121 */
122 public function __construct(Db $zdb, $args = null)
123 {
124 $this->zdb = $zdb;
125
126 if (is_int($args)) {
127 $this->load($args);
128 } elseif ($args !== null && is_object($args)) {
129 $this->loadFromRs($args);
130 }
131 }
132
133 /**
134 * Load field from its id
135 *
136 * @param Db $zdb Database instance
137 * @param int $id Field id
138 *
139 * @return DynamicField|false
140 */
141 public static function loadFieldType(Db $zdb, $id)
142 {
143 try {
144 $select = $zdb->select(self::TABLE);
145 $select->where('field_id = ' . $id);
146
147 $results = $zdb->execute($select);
148 $result = $results->current();
149 if ($result) {
150 $field_type = $result->field_type;
151 $field_type = self::getFieldType($zdb, $field_type);
152 $field_type->loadFromRs($result);
153 return $field_type;
154 }
155 } catch (\Exception $e) {
156 Analog::log(
157 __METHOD__ . ' | Unable to retrieve field `' . $id .
158 '` information | ' . $e->getMessage(),
159 Analog::ERROR
160 );
161 return false;
162 }
163 return false;
164 }
165
166 /**
167 * Get correct field type instance
168 *
169 * @param Db $zdb Database instance
170 * @param int $t Field type
171 * @param int $id Optional dynamic field id (to load data)
172 *
173 * @return DynamicField
174 */
175 public static function getFieldType(Db $zdb, $t, $id = null)
176 {
177 $df = null;
178 switch ($t) {
179 case self::SEPARATOR:
180 $df = new Separator($zdb, $id);
181 break;
182 case self::TEXT:
183 $df = new Text($zdb, $id);
184 break;
185 case self::LINE:
186 $df = new Line($zdb, $id);
187 break;
188 case self::CHOICE:
189 $df = new Choice($zdb, $id);
190 break;
191 case self::DATE:
192 $df = new Date($zdb, $id);
193 break;
194 case self::BOOLEAN:
195 $df = new Boolean($zdb, $id);
196 break;
197 case self::FILE:
198 $df = new File($zdb, $id);
199 break;
200 default:
201 throw new \Exception('Unknown field type ' . $t . '!');
202 break;
203 }
204 return $df;
205 }
206
207 /**
208 * Load field
209 *
210 * @param integer $id Id
211 *
212 * @return void
213 */
214 public function load($id)
215 {
216 try {
217 $select = $this->zdb->select(self::TABLE);
218 $select->where(self::PK . ' = ' . $id);
219
220 $results = $this->zdb->execute($select);
221 $result = $results->current();
222
223 if ($result) {
224 $this->loadFromRs($result);
225 }
226 } catch (\Exception $e) {
227 Analog::log(
228 'Unable to retrieve field type for field ' . $id . ' | ' .
229 $e->getMessage(),
230 Analog::ERROR
231 );
232 }
233 }
234
235 /**
236 * Load field type from a db ResultSet
237 *
238 * @param ResultSet $rs ResultSet
239 * @param boolean $values Whether to load values. Defaults to true
240 *
241 * @return void
242 */
243 public function loadFromRs($rs, $values = true)
244 {
245 $this->id = (int)$rs->field_id;
246 $this->name = $rs->field_name;
247 $this->index = (int)$rs->field_index;
248 $this->perm = (int)$rs->field_perm;
249 $this->required = ($rs->field_required == 1 ? true : false);
250 $this->width = $rs->field_width;
251 $this->height = $rs->field_height;
252 $this->repeat = $rs->field_repeat;
253 $this->size = $rs->field_size;
254 $this->form = $rs->field_form;
255 if ($values && $this->hasFixedValues()) {
256 $this->loadFixedValues();
257 }
258 }
259
260 /**
261 * Retrieve fixed values table name
262 *
263 * @param integer $id Field ID
264 * @param boolean $prefixed Whether table name should be prefixed
265 *
266 * @return string
267 */
268 public static function getFixedValuesTableName($id, $prefixed = false)
269 {
270 $name = 'field_contents_' . $id;
271 if ($prefixed === true) {
272 $name = PREFIX_DB . $name;
273 }
274 return $name;
275 }
276
277 /**
278 * Returns an array of fixed valued for a field of type 'choice'.
279 *
280 * @return void
281 */
282 private function loadFixedValues()
283 {
284 try {
285 $val_select = $this->zdb->select(
286 self::getFixedValuesTableName($this->id)
287 );
288
289 $val_select->columns(
290 array(
291 'val'
292 )
293 )->order('id');
294
295 $results = $this->zdb->execute($val_select);
296 $this->values = array();
297 if ($results) {
298 foreach ($results as $val) {
299 $this->values[] = $val->val;
300 }
301 }
302 } catch (\Exception $e) {
303 Analog::log(
304 __METHOD__ . ' | ' . $e->getMessage(),
305 Analog::WARNING
306 );
307 }
308 }
309
310 /**
311 * Get field type
312 *
313 * @return integer
314 */
315 abstract public function getType();
316
317 /**
318 * Get field type name
319 *
320 * @return String
321 */
322 public function getTypeName()
323 {
324 $types = $this->getFieldsTypesNames();
325 if (isset($types[$this->getType()])) {
326 return $types[$this->getType()];
327 } else {
328 throw new \RuntimeException(
329 'Unknow type ' . $this->getType()
330 );
331 }
332 }
333
334 /**
335 * Does the field handle data?
336 *
337 * @return boolean
338 */
339 public function hasData()
340 {
341 return $this->has_data;
342 }
343
344 /**
345 * Does the field has width?
346 *
347 * @return boolean
348 */
349 public function hasWidth()
350 {
351 return $this->has_width;
352 }
353
354 /**
355 * Does the field has height?
356 *
357 * @return boolean
358 */
359 public function hasHeight()
360 {
361 return $this->has_height;
362 }
363
364 /**
365 * Does the field has a size?
366 *
367 * @return boolean
368 */
369 public function hasSize()
370 {
371 return $this->has_size;
372 }
373
374 /**
375 * Is the field multi valued?
376 *
377 * @return boolean
378 */
379 public function isMultiValued()
380 {
381 return $this->multi_valued;
382 }
383
384 /**
385 * Does the field has fixed values?
386 *
387 * @return boolean
388 */
389 public function hasFixedValues()
390 {
391 return $this->fixed_values;
392 }
393
394 /**
395 * Does the field require permissions?
396 *
397 * @return boolean
398 */
399 public function hasPermissions()
400 {
401 return $this->has_permissions;
402 }
403
404
405 /**
406 * Get field id
407 *
408 * @return integer
409 */
410 public function getId()
411 {
412 return $this->id;
413 }
414
415 /**
416 * Get field Permissions
417 *
418 * @return integer
419 */
420 public function getPerm()
421 {
422 return $this->perm;
423 }
424
425
426 /**
427 * Is field required?
428 *
429 * @return boolean
430 */
431 public function isRequired()
432 {
433 return $this->required;
434 }
435
436 /**
437 * Get field width
438 *
439 * @return integer
440 */
441 public function getWidth()
442 {
443 return $this->width;
444 }
445
446 /**
447 * Get field height
448 *
449 * @return integer
450 */
451 public function getHeight()
452 {
453 return $this->height;
454 }
455
456 /**
457 * Is current field repeatable?
458 *
459 * @return boolean
460 */
461 public function isRepeatable()
462 {
463 return $this->repeat != null && trim($this->repeat) != '' && (int)$this->repeat > 1;
464 }
465
466 /**
467 * Get fields repetitions
468 *
469 * @return integer|boolean
470 */
471 public function getRepeat()
472 {
473 return $this->repeat;
474 }
475
476 /**
477 * Get field size
478 *
479 * @return integer
480 */
481 public function getSize()
482 {
483 return $this->size;
484 }
485
486 /**
487 * Get field index
488 *
489 * @return integer
490 */
491 public function getIndex()
492 {
493 return $this->index;
494 }
495
496 /**
497 * Retrieve permissions names for display
498 *
499 * @return array
500 */
501 public static function getPermsNames()
502 {
503 return [
504 self::PERM_USER_WRITE => _T("User, read/write"),
505 self::PERM_STAFF => _T("Staff member"),
506 self::PERM_ADMIN => _T("Administrator"),
507 self::PERM_MANAGER => _T("Group manager"),
508 self::PERM_USER_READ => _T("User, read only")
509 ];
510 }
511
512 /**
513 * Retrieve forms names
514 *
515 * @return array
516 */
517 public static function getFormsNames()
518 {
519 return [
520 'adh' => _T("Members"),
521 'contrib' => _T("Contributions"),
522 'trans' => _T("Transactions")
523 ];
524 }
525
526 /**
527 * Retrieve form name
528 *
529 * @param string $form_name Form name
530 *
531 * @return string
532 */
533 public static function getFormTitle($form_name)
534 {
535 $names = self::getFormsNames();
536 return $names[$form_name];
537 }
538
539 /**
540 * Get permission name
541 *
542 * @return string
543 */
544 public function getPermName()
545 {
546 $perms = self::getPermsNames();
547 return $perms[$this->getPerm()];
548 }
549
550 /**
551 * Get form
552 *
553 * @return string
554 */
555 public function getForm()
556 {
557 return $this->form;
558 }
559
560 /**
561 * Get field values
562 *
563 * @param boolean $imploded Whether to implode values
564 *
565 * @return array
566 */
567 public function getValues($imploded = false)
568 {
569 if (!is_array($this->values)) {
570 return false;
571 }
572 if ($imploded === true) {
573 return implode("\n", $this->values);
574 } else {
575 return $this->values;
576 }
577 }
578
579 /**
580 * Check posted values validity
581 *
582 * @param array $values All values to check, basically the $_POST array
583 * after sending the form
584 *
585 * @return true|array
586 */
587 public function check($values)
588 {
589 $this->errors = [];
590 $this->warnings = [];
591
592 if (
593 (!isset($values['field_name']) || $values['field_name'] == '')
594 && get_class($this) != '\Galette\DynamicField\Separator'
595 ) {
596 $this->errors[] = _T('Missing required field name!');
597 } else {
598 if ($this->old_name === null && $this->name !== null && $this->name != $values['field_name']) {
599 $this->old_name = $this->name;
600 }
601 $this->name = $values['field_name'];
602 }
603
604 if (!isset($values['field_perm']) || $values['field_perm'] === '') {
605 $this->errors[] = _T('Missing required field permissions!');
606 } else {
607 if (in_array($values['field_perm'], array_keys(self::getPermsNames()))) {
608 $this->perm = $values['field_perm'];
609 } else {
610 $this->errors[] = _T('Unknown permission!');
611 }
612 }
613
614 if ($this->id === null) {
615 if (!isset($values['form']) || $values['form'] == '') {
616 $this->errors[] = _T('Missing required form!');
617 } else {
618 if (in_array($values['form'], array_keys(self::getFormsNames()))) {
619 $this->form = $values['form'];
620 } else {
621 $this->errors[] = _T('Unknown form!');
622 }
623 }
624 }
625
626 $this->required = $values['field_required'];
627
628 if (count($this->errors) === 0 && $this->isDuplicate($values['form'], $this->name, $this->id)) {
629 $this->errors[] = _T("- Field name already used.");
630 }
631
632 if ($this->hasWidth() && isset($values['field_width']) && trim($values['field_width']) != '') {
633 $this->width = $values['field_width'];
634 }
635
636 if ($this->hasHeight() && isset($values['field_height']) && trim($values['field_height']) != '') {
637 $this->height = $values['field_height'];
638 }
639
640 if ($this->hasSize() && isset($values['field_size']) && trim($values['field_size']) != '') {
641 $this->size = $values['field_size'];
642 }
643
644 if (isset($values['field_repeat']) && trim($values['field_repeat']) != '') {
645 $this->repeat = $values['field_repeat'];
646 }
647
648 if ($this->hasFixedValues() && isset($values['fixed_values'])) {
649 $fixed_values = [];
650 foreach (explode("\n", $values['fixed_values']) as $val) {
651 $val = trim($val);
652 $len = mb_strlen($val);
653 if ($len > 0) {
654 $fixed_values[] = $val;
655 if ($len > $this->size) {
656 if ($this->old_size === null) {
657 $this->old_size = $this->size;
658 }
659 $this->size = $len;
660 }
661 }
662 }
663
664 $this->values = $fixed_values;
665 }
666
667 if ($this->id == null) {
668 $this->index = $this->getNewIndex();
669 }
670
671 if (count($this->errors) === 0) {
672 return true;
673 } else {
674 return false;
675 }
676 }
677
678 /**
679 * Store the field type
680 *
681 * @param array $values All values to check, basically the $_POST array
682 * after sending the form
683 *
684 * @return boolean
685 */
686 public function store($values)
687 {
688 if (!$this->check($values)) {
689 return false;
690 }
691
692 $isnew = ($this->id === null);
693 if ($this->old_name !== null) {
694 $this->deleteTranslation($this->old_name);
695 $this->addTranslation($this->name);
696 }
697
698 try {
699 $values = array(
700 'field_name' => $this->name,
701 'field_perm' => $this->perm,
702 'field_required' => $this->required,
703 'field_width' => ($this->width === null ? new Expression('NULL') : $this->width),
704 'field_height' => ($this->height === null ? new Expression('NULL') : $this->height),
705 'field_size' => ($this->size === null ? new Expression('NULL') : $this->size),
706 'field_repeat' => ($this->repeat === null ? new Expression('NULL') : $this->repeat),
707 'field_form' => $this->form,
708 'field_index' => $this->index
709 );
710
711 if ($this->required === false) {
712 //Handle booleans for postgres ; bugs #18899 and #19354
713 $values['field_required'] = $this->zdb->isPostgres() ? 'false' : 0;
714 }
715
716 if (!$isnew) {
717 $update = $this->zdb->update(self::TABLE);
718 $update->set($values)->where(
719 self::PK . ' = ' . $this->id
720 );
721 $this->zdb->execute($update);
722 } else {
723 $values['field_type'] = $this->getType();
724 $insert = $this->zdb->insert(self::TABLE);
725 $insert->values($values);
726 $this->zdb->execute($insert);
727
728 if ($this->zdb->isPostgres()) {
729 $this->id = $this->zdb->driver->getLastGeneratedValue(
730 PREFIX_DB . 'field_types_id_seq'
731 );
732 } else {
733 $this->id = $this->zdb->driver->getLastGeneratedValue();
734 }
735
736 if ($this->name != '') {
737 $this->addTranslation($this->name);
738 }
739 }
740 } catch (\Exception $e) {
741 Analog::log(
742 'An error occurred storing field | ' . $e->getMessage(),
743 Analog::ERROR
744 );
745 $this->errors[] = _T("An error occurred storing the field.");
746 }
747
748 if (count($this->errors) === 0 && $this->hasFixedValues()) {
749 $contents_table = self::getFixedValuesTableName($this->id, true);
750
751 try {
752 $this->zdb->drop($contents_table, true);
753 $this->zdb->connection->beginTransaction();
754 $field_size = ((int)$this->size > 0) ? $this->size : 1;
755 $this->zdb->db->query(
756 'CREATE TABLE ' . $contents_table .
757 ' (id INTEGER NOT NULL,val varchar(' . $field_size .
758 ') NOT NULL)',
759 \Laminas\Db\Adapter\Adapter::QUERY_MODE_EXECUTE
760 );
761 $this->zdb->connection->commit();
762 } catch (\Exception $e) {
763 if ($this->zdb->connection->inTransaction()) {
764 //because of DROP autocommit on mysql...
765 $this->zdb->connection->rollBack();
766 }
767 Analog::log(
768 'Unable to manage fields values table ' .
769 $contents_table . ' | ' . $e->getMessage(),
770 Analog::ERROR
771 );
772 $this->errors[] = _T("An error occurred creating field values table");
773 }
774
775 if (count($this->errors) == 0 && is_array($this->values)) {
776 $contents_table = self::getFixedValuesTableName($this->id);
777 try {
778 $this->zdb->connection->beginTransaction();
779
780 $insert = $this->zdb->insert($contents_table);
781 $insert->values(
782 array(
783 'id' => ':id',
784 'val' => ':val'
785 )
786 );
787 $stmt = $this->zdb->sql->prepareStatementForSqlObject($insert);
788
789 $cnt_values = count($this->values);
790 for ($i = 0; $i < $cnt_values; $i++) {
791 $stmt->execute(
792 array(
793 'id' => $i,
794 'val' => $this->values[$i]
795 )
796 );
797 }
798 $this->zdb->connection->commit();
799 } catch (\Exception $e) {
800 $this->zdb->connection->rollBack();
801 Analog::log(
802 'Unable to store field ' . $this->id . ' values (' .
803 $e->getMessage() . ')',
804 Analog::ERROR
805 );
806 $this->warnings[] = _T('An error occurred storing dynamic field values :(');
807 }
808 }
809 }
810
811 if (count($this->errors) === 0) {
812 return true;
813 } else {
814 return false;
815 }
816 }
817
818 /**
819 * Get new index
820 *
821 * @return integer
822 */
823 protected function getNewIndex()
824 {
825 $select = $this->zdb->select(self::TABLE);
826 $select->columns(
827 array(
828 'idx' => new \Laminas\Db\Sql\Expression('COUNT(*) + 1')
829 )
830 );
831 $select->where(['field_form' => $this->form]);
832 $results = $this->zdb->execute($select);
833 $result = $results->current();
834 $idx = $result->idx;
835 return $idx;
836 }
837
838 /**
839 * Is field duplicated?
840 *
841 * @return boolean
842 */
843 public function isDuplicate()
844 {
845 //let's consider field is duplicated, in case of future errors
846 $duplicated = true;
847 try {
848 $select = $this->zdb->select(self::TABLE);
849 $select->columns(
850 array(
851 'cnt' => new \Laminas\Db\Sql\Expression('COUNT(' . self::PK . ')')
852 )
853 )->where(
854 array(
855 'field_form' => $this->form,
856 'field_name' => $this->name
857 )
858 );
859
860 if ($this->id !== null) {
861 $select->where->addPredicate(
862 new PredicateExpression(
863 'field_id NOT IN (?)',
864 array($this->id)
865 )
866 );
867 }
868
869 $results = $this->zdb->execute($select);
870 $result = $results->current();
871 $dup = $result->cnt;
872 if (!$dup > 0) {
873 $duplicated = false;
874 }
875 } catch (\Exception $e) {
876 Analog::log(
877 'An error occurred checking field duplicity' . $e->getMessage(),
878 Analog::ERROR
879 );
880 }
881 return $duplicated;
882 }
883 /**
884 * Move a dynamic field
885 *
886 * @param string $action What to do (either 'up' or 'down' localized)
887 *
888 * @return boolean
889 */
890 public function move($action)
891 {
892 try {
893 $this->zdb->connection->beginTransaction();
894
895 $old_rank = $this->index;
896
897 $direction = $action == 'up' ? -1 : 1;
898 $new_rank = $old_rank + $direction;
899 $update = $this->zdb->update(self::TABLE);
900 $update->set([
901 'field_index' => $old_rank
902 ])->where([
903 'field_index' => $new_rank,
904 'field_form' => $this->form
905 ]);
906 $this->zdb->execute($update);
907
908 $update = $this->zdb->update(self::TABLE);
909 $update->set(
910 array(
911 'field_index' => $new_rank
912 )
913 )->where(
914 array(
915 self::PK => $this->id
916 )
917 );
918 $this->zdb->execute($update);
919 $this->zdb->connection->commit();
920
921 return true;
922 } catch (\Exception $e) {
923 $this->zdb->connection->rollBack();
924 Analog::log(
925 'Unable to change field ' . $this->id . ' rank | ' .
926 $e->getMessage(),
927 Analog::ERROR
928 );
929 return false;
930 }
931 }
932
933 /**
934 * Delete a dynamic field
935 *
936 * @return boolean
937 */
938 public function remove()
939 {
940 try {
941 if ($this->hasFixedValues()) {
942 $contents_table = self::getFixedValuesTableName($this->id);
943 $this->zdb->drop($contents_table);
944 }
945
946 $this->zdb->connection->beginTransaction();
947 $old_rank = $this->index;
948
949 $update = $this->zdb->update(self::TABLE);
950 $update->set(
951 array(
952 'field_index' => new \Laminas\Db\Sql\Expression('field_index-1')
953 )
954 )->where
955 ->greaterThan('field_index', $old_rank)
956 ->equalTo('field_form', $this->form);
957 $this->zdb->execute($update);
958
959 //remove associated values
960 $delete = $this->zdb->delete(DynamicFieldsHandle::TABLE);
961 $delete->where(
962 array(
963 'field_id' => $this->id,
964 'field_form' => $this->form
965 )
966 );
967 $result = $this->zdb->execute($delete);
968 if (!$result) {
969 throw new \RuntimeException('Unable to remove associated values for field ' . $this->id . '!');
970 }
971
972 //remove field type
973 $delete = $this->zdb->delete(self::TABLE);
974 $delete->where(
975 array(
976 'field_id' => $this->id,
977 'field_form' => $this->form
978 )
979 );
980 $result = $this->zdb->execute($delete);
981 if (!$result) {
982 throw new \RuntimeException('Unable to remove field ' . $this->id . '!');
983 }
984
985 $this->deleteTranslation($this->name);
986
987 $this->zdb->connection->commit();
988
989 return true;
990 } catch (\Exception $e) {
991 if ($this->zdb->connection->inTransaction()) {
992 //because of DROP autocommit on mysql...
993 $this->zdb->connection->rollBack();
994 }
995 Analog::log(
996 'An error occurred deleting field | ' . $e->getMessage(),
997 Analog::ERROR
998 );
999 return false;
1000 }
1001 }
1002
1003 /**
1004 * Retrieve fields types names
1005 *
1006 * @return array
1007 */
1008 public static function getFieldsTypesNames()
1009 {
1010 $names = [
1011 self::SEPARATOR => _T("separator"),
1012 self::TEXT => _T("free text"),
1013 self::LINE => _T("single line"),
1014 self::CHOICE => _T("choice"),
1015 self::DATE => _T("date"),
1016 self::BOOLEAN => _T("boolean"),
1017 self::FILE => _T("file")
1018 ];
1019 return $names;
1020 }
1021
1022 /**
1023 * Get errors
1024 *
1025 * @return array
1026 */
1027 public function getErrors()
1028 {
1029 return $this->errors;
1030 }
1031
1032 /**
1033 * Get warnings
1034 *
1035 * @return array
1036 */
1037 public function getWarnings()
1038 {
1039 return $this->warnings;
1040 }
1041 }