Merge branch 'master_MDL-57324' of git://github.com/danmarsden/moodle
[moodle.git] / lib / xmldb / xmldb_field.php
blob0a5062adadecd1d1144467a6227a4e46736bc2b5
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * This class represent one XMLDB Field
20 * @package core_xmldb
21 * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
22 * 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
29 class xmldb_field extends xmldb_object {
31 /** @var int XMLDB_TYPE_ constants */
32 protected $type;
34 /** @var int size of field */
35 protected $length;
37 /** @var bool is null forbidden? XMLDB_NOTNULL */
38 protected $notnull;
40 /** @var mixed default value */
41 protected $default;
43 /** @var bool use automatic counter */
44 protected $sequence;
46 /** @var int number of decimals */
47 protected $decimals;
49 /**
50 * Note:
51 * - Oracle: VARCHAR2 has a limit of 4000 bytes
52 * - SQL Server: NVARCHAR has a limit of 40000 chars
53 * - MySQL: VARCHAR 65,535 chars
54 * - PostgreSQL: no limit
56 * @const maximum length of text field
58 const CHAR_MAX_LENGTH = 1333;
61 /**
62 * @const maximum number of digits of integers
64 const INTEGER_MAX_LENGTH = 20;
66 /**
67 * @const max length of decimals
69 const NUMBER_MAX_LENGTH = 20;
71 /**
72 * @const max length of floats
74 const FLOAT_MAX_LENGTH = 20;
76 /**
77 * Note:
78 * - Oracle has 30 chars limit for all names
80 * @const maximumn length of field names
82 const NAME_MAX_LENGTH = 30;
84 /**
85 * Creates one new xmldb_field
86 * @param string $name of field
87 * @param int $type XMLDB_TYPE_INTEGER, XMLDB_TYPE_NUMBER, XMLDB_TYPE_CHAR, XMLDB_TYPE_TEXT, XMLDB_TYPE_BINARY
88 * @param string $precision length for integers and chars, two-comma separated numbers for numbers
89 * @param bool $unsigned XMLDB_UNSIGNED or null (or false)
90 * @param bool $notnull XMLDB_NOTNULL or null (or false)
91 * @param bool $sequence XMLDB_SEQUENCE or null (or false)
92 * @param mixed $default meaningful default o null (or false)
93 * @param xmldb_object $previous
95 public function __construct($name, $type=null, $precision=null, $unsigned=null, $notnull=null, $sequence=null, $default=null, $previous=null) {
96 $this->type = null;
97 $this->length = null;
98 $this->notnull = false;
99 $this->default = null;
100 $this->sequence = false;
101 $this->decimals = null;
102 parent::__construct($name);
103 $this->set_attributes($type, $precision, $unsigned, $notnull, $sequence, $default, $previous);
107 * Set all the attributes of one xmldb_field
109 * @param int $type XMLDB_TYPE_INTEGER, XMLDB_TYPE_NUMBER, XMLDB_TYPE_CHAR, XMLDB_TYPE_TEXT, XMLDB_TYPE_BINARY
110 * @param string $precision length for integers and chars, two-comma separated numbers for numbers
111 * @param bool $unsigned XMLDB_UNSIGNED or null (or false)
112 * @param bool $notnull XMLDB_NOTNULL or null (or false)
113 * @param bool $sequence XMLDB_SEQUENCE or null (or false)
114 * @param mixed $default meaningful default o null (or false)
115 * @param xmldb_object $previous
117 public function set_attributes($type, $precision=null, $unsigned=null, $notnull=null, $sequence=null, $default=null, $previous=null) {
118 $this->type = $type;
119 /// Try to split the precision into length and decimals and apply
120 /// each one as needed
121 $precisionarr = explode(',', $precision);
122 if (isset($precisionarr[0])) {
123 $this->length = trim($precisionarr[0]);
125 if (isset($precisionarr[1])) {
126 $this->decimals = trim($precisionarr[1]);
128 $this->precision = $type;
129 $this->notnull = !empty($notnull) ? true : false;
130 $this->sequence = !empty($sequence) ? true : false;
131 $this->setDefault($default);
133 if ($this->type == XMLDB_TYPE_BINARY || $this->type == XMLDB_TYPE_TEXT) {
134 $this->length = null;
135 $this->decimals = null;
138 $this->previous = $previous;
142 * Get the type
143 * @return int
145 public function getType() {
146 return $this->type;
150 * Get the length
151 * @return int
153 public function getLength() {
154 return $this->length;
158 * Get the decimals
159 * @return string
161 public function getDecimals() {
162 return $this->decimals;
166 * Get the notnull
167 * @return bool
169 public function getNotNull() {
170 return $this->notnull;
174 * Get the unsigned
175 * @deprecated since moodle 2.3
176 * @return bool
178 public function getUnsigned() {
179 return false;
183 * Get the sequence
184 * @return bool
186 public function getSequence() {
187 return $this->sequence;
191 * Get the default
192 * @return mixed
194 public function getDefault() {
195 return $this->default;
199 * Set the field type
200 * @param int $type
202 public function setType($type) {
203 $this->type = $type;
207 * Set the field length
208 * @param int $length
210 public function setLength($length) {
211 $this->length = $length;
215 * Set the field decimals
216 * @param string
218 public function setDecimals($decimals) {
219 $this->decimals = $decimals;
223 * Set the field unsigned
224 * @deprecated since moodle 2.3
225 * @param bool $unsigned
227 public function setUnsigned($unsigned=true) {
231 * Set the field notnull
232 * @param bool $notnull
234 public function setNotNull($notnull=true) {
235 $this->notnull = $notnull;
239 * Set the field sequence
240 * @param bool $sequence
242 public function setSequence($sequence=true) {
243 $this->sequence = $sequence;
247 * Set the field default
248 * @param mixed $default
250 public function setDefault($default) {
251 // Check, warn and auto-fix '' (empty) defaults for CHAR NOT NULL columns, changing them
252 // to NULL so XMLDB will apply the proper default
253 if ($this->type == XMLDB_TYPE_CHAR && $this->notnull && $default === '') {
254 $this->errormsg = 'XMLDB has detected one CHAR NOT NULL column (' . $this->name . ") with '' (empty string) as DEFAULT value. This type of columns must have one meaningful DEFAULT declared or none (NULL). XMLDB have fixed it automatically changing it to none (NULL). The process will continue ok and proper defaults will be created accordingly with each DB requirements. Please fix it in source (XML and/or upgrade script) to avoid this message to be displayed.";
255 $this->debug($this->errormsg);
256 $default = null;
258 // Check, warn and autofix TEXT|BINARY columns having a default clause (only null is allowed)
259 if (($this->type == XMLDB_TYPE_TEXT || $this->type == XMLDB_TYPE_BINARY) && $default !== null) {
260 $this->errormsg = 'XMLDB has detected one TEXT/BINARY column (' . $this->name . ") with some DEFAULT defined. This type of columns cannot have any default value. Please fix it in source (XML and/or upgrade script) to avoid this message to be displayed.";
261 $this->debug($this->errormsg);
262 $default = null;
264 $this->default = $default;
268 * Load data from XML to the table
269 * @param array $xmlarr
270 * @return mixed
272 public function arr2xmldb_field($xmlarr) {
274 $result = true;
276 // Debug the table
277 // traverse_xmlize($xmlarr); //Debug
278 // print_object ($GLOBALS['traverse_array']); //Debug
279 // $GLOBALS['traverse_array']=""; //Debug
281 // Process table attributes (name, type, length
282 // notnull, sequence, decimals, comment, previous, next)
283 if (isset($xmlarr['@']['NAME'])) {
284 $this->name = trim($xmlarr['@']['NAME']);
285 } else {
286 $this->errormsg = 'Missing NAME attribute';
287 $this->debug($this->errormsg);
288 $result = false;
291 if (isset($xmlarr['@']['TYPE'])) {
292 // Check for valid type
293 $type = $this->getXMLDBFieldType(trim($xmlarr['@']['TYPE']));
294 if ($type) {
295 $this->type = $type;
296 } else {
297 $this->errormsg = 'Invalid TYPE attribute';
298 $this->debug($this->errormsg);
299 $result = false;
301 } else {
302 $this->errormsg = 'Missing TYPE attribute';
303 $this->debug($this->errormsg);
304 $result = false;
307 if (isset($xmlarr['@']['LENGTH'])) {
308 $length = trim($xmlarr['@']['LENGTH']);
309 // Check for integer values
310 if ($this->type == XMLDB_TYPE_INTEGER ||
311 $this->type == XMLDB_TYPE_NUMBER ||
312 $this->type == XMLDB_TYPE_CHAR) {
313 if (!(is_numeric($length)&&(intval($length)==floatval($length)))) {
314 $this->errormsg = 'Incorrect LENGTH attribute for int, number or char fields';
315 $this->debug($this->errormsg);
316 $result = false;
317 } else if (!$length) {
318 $this->errormsg = 'Zero LENGTH attribute';
319 $this->debug($this->errormsg);
320 $result = false;
323 // Remove length from text and binary
324 if ($this->type == XMLDB_TYPE_TEXT ||
325 $this->type == XMLDB_TYPE_BINARY) {
326 $length = null;
328 // Finally, set the length
329 $this->length = $length;
332 if (isset($xmlarr['@']['NOTNULL'])) {
333 $notnull = strtolower(trim($xmlarr['@']['NOTNULL']));
334 if ($notnull == 'true') {
335 $this->notnull = true;
336 } else if ($notnull == 'false') {
337 $this->notnull = false;
338 } else {
339 $this->errormsg = 'Incorrect NOTNULL attribute (true/false allowed)';
340 $this->debug($this->errormsg);
341 $result = false;
345 if (isset($xmlarr['@']['SEQUENCE'])) {
346 $sequence = strtolower(trim($xmlarr['@']['SEQUENCE']));
347 if ($sequence == 'true') {
348 $this->sequence = true;
349 } else if ($sequence == 'false') {
350 $this->sequence = false;
351 } else {
352 $this->errormsg = 'Incorrect SEQUENCE attribute (true/false allowed)';
353 $this->debug($this->errormsg);
354 $result = false;
358 if (isset($xmlarr['@']['DEFAULT'])) {
359 $this->setDefault(trim($xmlarr['@']['DEFAULT']));
362 $decimals = null;
363 if (isset($xmlarr['@']['DECIMALS'])) {
364 $decimals = trim($xmlarr['@']['DECIMALS']);
365 // Check for integer values
366 if ($this->type == XMLDB_TYPE_NUMBER ||
367 $this->type == XMLDB_TYPE_FLOAT) {
368 if (!(is_numeric($decimals)&&(intval($decimals)==floatval($decimals)))) {
369 $this->errormsg = 'Incorrect DECIMALS attribute for number field';
370 $this->debug($this->errormsg);
371 $result = false;
372 } else if ($this->length <= $decimals){
373 $this->errormsg = 'Incorrect DECIMALS attribute (bigget than length)';
374 $this->debug($this->errormsg);
375 $result = false;
377 } else {
378 $this->errormsg = 'Incorrect DECIMALS attribute for non-number field';
379 $this->debug($this->errormsg);
380 $result = false;
382 } else {
383 if ($this->type == XMLDB_TYPE_NUMBER) {
384 $decimals = 0;
387 // Finally, set the decimals
388 if ($this->type == XMLDB_TYPE_NUMBER ||
389 $this->type == XMLDB_TYPE_FLOAT) {
390 $this->decimals = $decimals;
393 if (isset($xmlarr['@']['COMMENT'])) {
394 $this->comment = trim($xmlarr['@']['COMMENT']);
397 // Set some attributes
398 if ($result) {
399 $this->loaded = true;
401 $this->calculateHash();
402 return $result;
406 * This function returns the correct XMLDB_TYPE_XXX value for the
407 * string passed as argument
408 * @param string $type
409 * @return int
411 public function getXMLDBFieldType($type) {
413 $result = XMLDB_TYPE_INCORRECT;
415 switch (strtolower($type)) {
416 case 'int':
417 $result = XMLDB_TYPE_INTEGER;
418 break;
419 case 'number':
420 $result = XMLDB_TYPE_NUMBER;
421 break;
422 case 'float':
423 $result = XMLDB_TYPE_FLOAT;
424 break;
425 case 'char':
426 $result = XMLDB_TYPE_CHAR;
427 break;
428 case 'text':
429 $result = XMLDB_TYPE_TEXT;
430 break;
431 case 'binary':
432 $result = XMLDB_TYPE_BINARY;
433 break;
434 case 'datetime':
435 $result = XMLDB_TYPE_DATETIME;
436 break;
438 // Return the normalized XMLDB_TYPE
439 return $result;
443 * This function returns the correct name value for the
444 * XMLDB_TYPE_XXX passed as argument
445 * @param int $type
446 * @return string
448 public function getXMLDBTypeName($type) {
450 $result = "";
452 switch (strtolower($type)) {
453 case XMLDB_TYPE_INTEGER:
454 $result = 'int';
455 break;
456 case XMLDB_TYPE_NUMBER:
457 $result = 'number';
458 break;
459 case XMLDB_TYPE_FLOAT:
460 $result = 'float';
461 break;
462 case XMLDB_TYPE_CHAR:
463 $result = 'char';
464 break;
465 case XMLDB_TYPE_TEXT:
466 $result = 'text';
467 break;
468 case XMLDB_TYPE_BINARY:
469 $result = 'binary';
470 break;
471 case XMLDB_TYPE_DATETIME:
472 $result = 'datetime';
473 break;
475 // Return the normalized name
476 return $result;
480 * This function calculate and set the hash of one xmldb_field
481 * @param bool $recursive
482 * @return void, modifies $this->hash
484 public function calculateHash($recursive = false) {
485 if (!$this->loaded) {
486 $this->hash = null;
487 } else {
488 $defaulthash = is_null($this->default) ? '' : sha1($this->default);
489 $key = $this->name . $this->type . $this->length .
490 $this->notnull . $this->sequence .
491 $this->decimals . $this->comment . $defaulthash;
492 $this->hash = md5($key);
497 * This function will output the XML text for one field
498 * @return string
500 public function xmlOutput() {
501 $o = '';
502 $o.= ' <FIELD NAME="' . $this->name . '"';
503 $o.= ' TYPE="' . $this->getXMLDBTypeName($this->type) . '"';
504 if ($this->length) {
505 $o.= ' LENGTH="' . $this->length . '"';
507 if ($this->notnull) {
508 $notnull = 'true';
509 } else {
510 $notnull = 'false';
512 $o.= ' NOTNULL="' . $notnull . '"';
513 if (!$this->sequence && $this->default !== null) {
514 $o.= ' DEFAULT="' . $this->default . '"';
516 if ($this->sequence) {
517 $sequence = 'true';
518 } else {
519 $sequence = 'false';
521 $o.= ' SEQUENCE="' . $sequence . '"';
522 if ($this->decimals !== null) {
523 $o.= ' DECIMALS="' . $this->decimals . '"';
525 if ($this->comment) {
526 $o.= ' COMMENT="' . htmlspecialchars($this->comment) . '"';
528 $o.= '/>' . "\n";
530 return $o;
534 * This function will set all the attributes of the xmldb_field object
535 * based on information passed in one ADOField
536 * @param string $adofield
537 * @return void, sets $this->type
539 public function setFromADOField($adofield) {
541 // Calculate the XMLDB_TYPE
542 switch (strtolower($adofield->type)) {
543 case 'int':
544 case 'tinyint':
545 case 'smallint':
546 case 'bigint':
547 case 'integer':
548 $this->type = XMLDB_TYPE_INTEGER;
549 break;
550 case 'number':
551 case 'decimal':
552 case 'dec':
553 case 'numeric':
554 $this->type = XMLDB_TYPE_NUMBER;
555 break;
556 case 'float':
557 case 'double':
558 $this->type = XMLDB_TYPE_FLOAT;
559 break;
560 case 'char':
561 case 'varchar':
562 case 'enum':
563 $this->type = XMLDB_TYPE_CHAR;
564 break;
565 case 'text':
566 case 'tinytext':
567 case 'mediumtext':
568 case 'longtext':
569 $this->type = XMLDB_TYPE_TEXT;
570 break;
571 case 'blob':
572 case 'tinyblob':
573 case 'mediumblob':
574 case 'longblob':
575 $this->type = XMLDB_TYPE_BINARY;
576 break;
577 case 'datetime':
578 case 'timestamp':
579 $this->type = XMLDB_TYPE_DATETIME;
580 break;
581 default:
582 $this->type = XMLDB_TYPE_TEXT;
584 // Calculate the length of the field
585 if ($adofield->max_length > 0 &&
586 ($this->type == XMLDB_TYPE_INTEGER ||
587 $this->type == XMLDB_TYPE_NUMBER ||
588 $this->type == XMLDB_TYPE_FLOAT ||
589 $this->type == XMLDB_TYPE_CHAR)) {
590 $this->length = $adofield->max_length;
592 if ($this->type == XMLDB_TYPE_TEXT) {
593 $this->length = null;
595 if ($this->type == XMLDB_TYPE_BINARY) {
596 $this->length = null;
598 // Calculate the decimals of the field
599 if ($adofield->max_length > 0 &&
600 $adofield->scale &&
601 ($this->type == XMLDB_TYPE_NUMBER ||
602 $this->type == XMLDB_TYPE_FLOAT)) {
603 $this->decimals = $adofield->scale;
605 // Calculate the notnull field
606 if ($adofield->not_null) {
607 $this->notnull = true;
609 // Calculate the default field
610 if ($adofield->has_default) {
611 $this->default = $adofield->default_value;
613 // Calculate the sequence field
614 if ($adofield->auto_increment) {
615 $this->sequence = true;
617 // Some more fields
618 $this->loaded = true;
619 $this->changed = true;
623 * Returns the PHP code needed to define one xmldb_field
624 * @param bool $includeprevious
625 * @return string
627 public function getPHP($includeprevious=true) {
629 $result = '';
631 // The XMLDBTYPE
632 switch ($this->getType()) {
633 case XMLDB_TYPE_INTEGER:
634 $result .= 'XMLDB_TYPE_INTEGER' . ', ';
635 break;
636 case XMLDB_TYPE_NUMBER:
637 $result .= 'XMLDB_TYPE_NUMBER' . ', ';
638 break;
639 case XMLDB_TYPE_FLOAT:
640 $result .= 'XMLDB_TYPE_FLOAT' . ', ';
641 break;
642 case XMLDB_TYPE_CHAR:
643 $result .= 'XMLDB_TYPE_CHAR' . ', ';
644 break;
645 case XMLDB_TYPE_TEXT:
646 $result .= 'XMLDB_TYPE_TEXT' . ', ';
647 break;
648 case XMLDB_TYPE_BINARY:
649 $result .= 'XMLDB_TYPE_BINARY' . ', ';
650 break;
651 case XMLDB_TYPE_DATETIME:
652 $result .= 'XMLDB_TYPE_DATETIME' . ', ';
653 break;
654 case XMLDB_TYPE_TIMESTAMP:
655 $result .= 'XMLDB_TYPE_TIMESTAMP' . ', ';
656 break;
658 // The length
659 $length = $this->getLength();
660 $decimals = $this->getDecimals();
661 if (!empty($length)) {
662 $result .= "'" . $length;
663 if (!empty($decimals)) {
664 $result .= ', ' . $decimals;
666 $result .= "', ";
667 } else {
668 $result .= 'null, ';
670 // Unsigned is not used any more since Moodle 2.3
671 $result .= 'null, ';
672 // Not Null
673 $notnull = $this->getNotnull();
674 if (!empty($notnull)) {
675 $result .= 'XMLDB_NOTNULL' . ', ';
676 } else {
677 $result .= 'null, ';
679 // Sequence
680 $sequence = $this->getSequence();
681 if (!empty($sequence)) {
682 $result .= 'XMLDB_SEQUENCE' . ', ';
683 } else {
684 $result .= 'null, ';
686 // Default
687 $default = $this->getDefault();
688 if ($default !== null && !$this->getSequence()) {
689 $result .= "'" . $default . "'";
690 } else {
691 $result .= 'null';
693 // Previous (decided by parameter)
694 if ($includeprevious) {
695 $previous = $this->getPrevious();
696 if (!empty($previous)) {
697 $result .= ", '" . $previous . "'";
698 } else {
699 $result .= ', null';
702 // Return result
703 return $result;
707 * Shows info in a readable format
708 * @return string
710 public function readableInfo() {
711 $o = '';
712 // type
713 $o .= $this->getXMLDBTypeName($this->type);
714 // length
715 if ($this->type == XMLDB_TYPE_INTEGER ||
716 $this->type == XMLDB_TYPE_NUMBER ||
717 $this->type == XMLDB_TYPE_FLOAT ||
718 $this->type == XMLDB_TYPE_CHAR) {
719 if ($this->length) {
720 $o .= ' (' . $this->length;
721 if ($this->type == XMLDB_TYPE_NUMBER ||
722 $this->type == XMLDB_TYPE_FLOAT) {
723 if ($this->decimals !== null) {
724 $o .= ', ' . $this->decimals;
727 $o .= ')';
730 // not null
731 if ($this->notnull) {
732 $o .= ' not null';
734 // default
735 if ($this->default !== null) {
736 $o .= ' default ';
737 if ($this->type == XMLDB_TYPE_CHAR ||
738 $this->type == XMLDB_TYPE_TEXT) {
739 $o .= "'" . $this->default . "'";
740 } else {
741 $o .= $this->default;
744 // sequence
745 if ($this->sequence) {
746 $o .= ' auto-numbered';
749 return $o;
753 * Validates the field restrictions.
755 * The error message should not be localised because it is intended for developers,
756 * end users and admins should never see these problems!
758 * @param xmldb_table $xmldb_table optional when object is table
759 * @return string null if ok, error message if problem found
761 public function validateDefinition(xmldb_table $xmldb_table=null) {
762 if (!$xmldb_table) {
763 return 'Invalid xmldb_field->validateDefinition() call, $xmldb_table is required.';
766 $name = $this->getName();
767 if (strlen($name) > self::NAME_MAX_LENGTH) {
768 return 'Invalid field name in table {'.$xmldb_table->getName().'}: field "'.$this->getName().'" name is too long.'
769 .' Limit is '.self::NAME_MAX_LENGTH.' chars.';
771 if (!preg_match('/^[a-z][a-z0-9_]*$/', $name)) {
772 return 'Invalid field name in table {'.$xmldb_table->getName().'}: field "'.$this->getName().'" name includes invalid characters.';
775 switch ($this->getType()) {
776 case XMLDB_TYPE_INTEGER:
777 $length = $this->getLength();
778 if (!is_number($length) or $length <= 0 or $length > self::INTEGER_MAX_LENGTH) {
779 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_INTEGER field "'.$this->getName().'" has invalid length';
781 $default = $this->getDefault();
782 if (!empty($default) and !is_number($default)) {
783 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_INTEGER field "'.$this->getName().'" has invalid default';
785 break;
787 case XMLDB_TYPE_NUMBER:
788 $maxlength = self::NUMBER_MAX_LENGTH;
789 if ($xmldb_table->getName() === 'question_numerical_units' and $name === 'multiplier') {
790 //TODO: remove after MDL-32113 is resolved
791 $maxlength = 40;
793 $length = $this->getLength();
794 if (!is_number($length) or $length <= 0 or $length > $maxlength) {
795 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_NUMBER field "'.$this->getName().'" has invalid length';
797 $decimals = $this->getDecimals();
798 $decimals = empty($decimals) ? 0 : $decimals; // fix missing decimals
799 if (!is_number($decimals) or $decimals < 0 or $decimals > $length) {
800 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_NUMBER field "'.$this->getName().'" has invalid decimals';
802 $default = $this->getDefault();
803 if (!empty($default) and !is_numeric($default)) {
804 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_NUMBER field "'.$this->getName().'" has invalid default';
806 break;
808 case XMLDB_TYPE_FLOAT:
809 $length = $this->getLength();
810 $length = empty($length) ? 6 : $length; // weird, it might be better to require something here...
811 if (!is_number($length) or $length <= 0 or $length > self::FLOAT_MAX_LENGTH) {
812 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_FLOAT field "'.$this->getName().'" has invalid length';
814 $decimals = $this->getDecimals();
815 $decimals = empty($decimals) ? 0 : $decimals; // fix missing decimals
816 if (!is_number($decimals) or $decimals < 0 or $decimals > $length) {
817 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_FLOAT field "'.$this->getName().'" has invalid decimals';
819 $default = $this->getDefault();
820 if (!empty($default) and !is_numeric($default)) {
821 return 'Invalid field definition in table {'.$xmldb_table->getName().'}: XMLDB_TYPE_FLOAT field "'.$this->getName().'" has invalid default';
823 break;
825 case XMLDB_TYPE_CHAR:
826 if ($this->getLength() > self::CHAR_MAX_LENGTH) {
827 return 'Invalid field definition in table {'.$xmldb_table->getName(). '}: XMLDB_TYPE_CHAR field "'.$this->getName().'" is too long.'
828 .' Limit is '.self::CHAR_MAX_LENGTH.' chars.';
830 break;
832 case XMLDB_TYPE_TEXT:
833 break;
835 case XMLDB_TYPE_BINARY:
836 break;
838 case XMLDB_TYPE_DATETIME:
839 break;
841 case XMLDB_TYPE_TIMESTAMP:
842 break;
845 return null;