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