Index: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.css |
— | — | @@ -80,8 +80,9 @@ |
81 | 81 | cursor: pointer; |
82 | 82 | } |
83 | 83 | |
84 | | -.formbuilder-field-list { |
| 84 | +.formbuilder-list-items { |
85 | 85 | border: 1px solid #888; |
| 86 | + border-bottom: none; |
86 | 87 | } |
87 | 88 | |
88 | 89 | .formbuilder-list-item-container { |
Index: branches/salvatoreingala/Gadgets/ui/resources/jquery.formBuilder.js |
— | — | @@ -198,7 +198,7 @@ |
199 | 199 | }, mw.msg( 'gadgets-formbuilder-scalar' ) ); |
200 | 200 | |
201 | 201 | /* Functions used by the preferences editor */ |
202 | | - function createFieldDialog( params, options ) { |
| 202 | + function createFieldDialog( params, options ) { |
203 | 203 | var self = this; |
204 | 204 | |
205 | 205 | if ( !$.isFunction( params.callback ) ) { |
— | — | @@ -365,7 +365,7 @@ |
366 | 366 | } ); |
367 | 367 | } |
368 | 368 | |
369 | | - function showEditFieldDialog( fieldDesc, options, callback ) { |
| 369 | + function showEditFieldDialog( fieldDesc, listParams, options, callback ) { |
370 | 370 | $( { "fields": [ fieldDesc ] } ) |
371 | 371 | .formBuilder( { |
372 | 372 | editable: true, |
— | — | @@ -400,11 +400,14 @@ |
401 | 401 | $( this ).dialog( "close" ); |
402 | 402 | |
403 | 403 | var ListField = validFieldTypes.list; |
404 | | - callback( new ListField( { |
405 | | - type: 'list', |
406 | | - name: name, |
407 | | - field: fieldDesc |
408 | | - }, options ) ); |
| 404 | + |
| 405 | + $.extend( listParams, { |
| 406 | + type: 'list', |
| 407 | + name: name, |
| 408 | + field: fieldDesc |
| 409 | + } ); |
| 410 | + |
| 411 | + callback( new ListField( listParams, options ) ); |
409 | 412 | } |
410 | 413 | }, |
411 | 414 | { |
— | — | @@ -1722,9 +1725,26 @@ |
1723 | 1726 | self._createItem( true ); |
1724 | 1727 | } ) |
1725 | 1728 | .appendTo( this.$div ); |
| 1729 | + |
| 1730 | + //Add a hidden input to attach validation rules on the number of items |
| 1731 | + //We set its value to "" if there are no elements, or to the number of items otherwise |
| 1732 | + this._$hiddenInput = $( '<input/>').attr( { |
| 1733 | + type: 'hidden', |
| 1734 | + name: this.options.idPrefix + this.desc.name, |
| 1735 | + id: this.options.idPrefix + this.desc.name |
| 1736 | + } ) |
| 1737 | + .hide() |
| 1738 | + .appendTo( this.$div ); |
| 1739 | + |
| 1740 | + this._refreshHiddenField(); |
1726 | 1741 | } |
1727 | 1742 | inherit( ListField, EmptyField ); |
1728 | 1743 | |
| 1744 | + ListField.prototype._refreshHiddenField = function() { |
| 1745 | + var nItems = this._$divItems.children().length; |
| 1746 | + this._$hiddenInput.val( nItems ? nItems : "" ); |
| 1747 | + }; |
| 1748 | + |
1729 | 1749 | ListField.prototype._createItem = function( afterInit, itemValue ) { |
1730 | 1750 | var itemDesc = $.extend( {}, this.desc.field, { |
1731 | 1751 | "name": this.desc.name |
— | — | @@ -1763,7 +1783,7 @@ |
1764 | 1784 | var $itemButtons = $( '<div/>' ) |
1765 | 1785 | .addClass( 'formbuilder-list-item-buttons' ); |
1766 | 1786 | |
1767 | | - |
| 1787 | + var self = this; |
1768 | 1788 | $( '<span/>' ) |
1769 | 1789 | .addClass( 'formbuilder-button formbuilder-list-button-delete ui-icon ui-icon-trash' ) |
1770 | 1790 | .attr( 'title', mw.msg( 'gadgets-formbuilder-editor-delete' ) ) |
— | — | @@ -1771,6 +1791,8 @@ |
1772 | 1792 | $itemDiv.slideUp( function() { |
1773 | 1793 | deleteFieldRules( itemField ); |
1774 | 1794 | $itemDiv.remove(); |
| 1795 | + self._refreshHiddenField(); |
| 1796 | + self._$hiddenInput.valid(); //force revalidation of the number of items |
1775 | 1797 | } ); |
1776 | 1798 | } ) |
1777 | 1799 | .appendTo( $itemButtons ); |
— | — | @@ -1791,6 +1813,9 @@ |
1792 | 1814 | .slideDown(); |
1793 | 1815 | |
1794 | 1816 | addFieldRules( itemField ); |
| 1817 | + |
| 1818 | + this._refreshHiddenField(); |
| 1819 | + this._$hiddenInput.valid(); //force revalidation of the number of items |
1795 | 1820 | } else { |
1796 | 1821 | $itemDiv.appendTo( this._$divItems ); |
1797 | 1822 | } |
— | — | @@ -1817,7 +1842,28 @@ |
1818 | 1843 | }; |
1819 | 1844 | |
1820 | 1845 | ListField.prototype.getValidationSettings = function() { |
1821 | | - var validationSettings = {}; |
| 1846 | + var validationSettings = EmptyField.prototype.getValidationSettings.call( this ); |
| 1847 | + hiddenFieldRules = {}, hiddenFieldMessages = {}; |
| 1848 | + |
| 1849 | + if ( typeof this.desc.required != 'undefined' ) { |
| 1850 | + hiddenFieldRules.required = this.desc.required; |
| 1851 | + hiddenFieldMessages.required = mw.msg( 'gadgets-formbuilder-list-required' ); |
| 1852 | + } |
| 1853 | + |
| 1854 | + if ( typeof this.desc.minlength != 'undefined' ) { |
| 1855 | + hiddenFieldRules.min = this.desc.minlength; |
| 1856 | + hiddenFieldMessages.min = mw.msg( 'gadgets-formbuilder-list-minlength', this.desc.minlength ); |
| 1857 | + } |
| 1858 | + |
| 1859 | + if ( typeof this.desc.maxlength == 'undefined' ) { |
| 1860 | + this.desc.maxlength = 1024; |
| 1861 | + } |
| 1862 | + hiddenFieldRules.max = this.desc.maxlength; |
| 1863 | + hiddenFieldMessages.max = mw.msg( 'gadgets-formbuilder-list-maxlength', this.desc.maxlength ); |
| 1864 | + |
| 1865 | + validationSettings.rules[this.options.idPrefix + this.desc.name] = hiddenFieldRules; |
| 1866 | + validationSettings.messages[this.options.idPrefix + this.desc.name] = hiddenFieldMessages; |
| 1867 | + |
1822 | 1868 | this._$divItems.children().each( function( index, divItem ) { |
1823 | 1869 | var field = $( divItem ).data( 'field' ); |
1824 | 1870 | $.extend( true, validationSettings, field.getValidationSettings() ); |
— | — | @@ -1931,9 +1977,23 @@ |
1932 | 1978 | "builder": simpleFields.concat( [ |
1933 | 1979 | { |
1934 | 1980 | "name": "required", |
1935 | | - "type": "boolean", |
| 1981 | + "type": "select", |
1936 | 1982 | "label": "required", |
1937 | | - "default": false |
| 1983 | + "default": null, |
| 1984 | + "options": [ |
| 1985 | + { |
| 1986 | + "name": "not specified", |
| 1987 | + "value": null |
| 1988 | + }, |
| 1989 | + { |
| 1990 | + "name": "true", |
| 1991 | + "value": true |
| 1992 | + }, |
| 1993 | + { |
| 1994 | + "name": "false", |
| 1995 | + "value": false |
| 1996 | + } |
| 1997 | + ] |
1938 | 1998 | }, |
1939 | 1999 | { |
1940 | 2000 | "name": "minlength", |
— | — | @@ -2088,23 +2148,64 @@ |
2089 | 2149 | } |
2090 | 2150 | } ); |
2091 | 2151 | |
2092 | | - //Create the dialog to chose the field type |
2093 | | - var $form = $( { |
2094 | | - fields: [ { |
2095 | | - "name": "name", |
2096 | | - "type": "string", |
2097 | | - "label": "name", |
2098 | | - "required": true, |
2099 | | - "maxlength": 40, |
2100 | | - "default": "" |
2101 | | - }, |
2102 | | - { |
2103 | | - "name": "type", |
2104 | | - "type": "select", |
2105 | | - "label": "type", |
2106 | | - "options": selectOptions |
2107 | | - } ] |
2108 | | - } ).formBuilder( { idPrefix: 'list-chose-type-' } ) |
| 2152 | + //Create the dialog to chose the field type and set list properties |
| 2153 | + var description = { |
| 2154 | + "fields": [ |
| 2155 | + { |
| 2156 | + "name": "name", |
| 2157 | + "type": "string", |
| 2158 | + "label": "name", |
| 2159 | + "required": true, |
| 2160 | + "maxlength": 40, |
| 2161 | + "default": "" |
| 2162 | + }, |
| 2163 | + { |
| 2164 | + "name": "required", |
| 2165 | + "type": "select", |
| 2166 | + "label": "required", |
| 2167 | + "default": null, |
| 2168 | + "options": [ |
| 2169 | + { |
| 2170 | + "name": "not specified", |
| 2171 | + "value": null |
| 2172 | + }, |
| 2173 | + { |
| 2174 | + "name": "true", |
| 2175 | + "value": true |
| 2176 | + }, |
| 2177 | + { |
| 2178 | + "name": "false", |
| 2179 | + "value": false |
| 2180 | + } |
| 2181 | + ] |
| 2182 | + }, |
| 2183 | + { |
| 2184 | + "name": "minlength", |
| 2185 | + "type": "number", |
| 2186 | + "label": "minlength", |
| 2187 | + "integer": true, |
| 2188 | + "min": 0, |
| 2189 | + "required": false, |
| 2190 | + "default": null |
| 2191 | + }, |
| 2192 | + { |
| 2193 | + "name": "maxlength", |
| 2194 | + "type": "number", |
| 2195 | + "label": "maxlength", |
| 2196 | + "integer": true, |
| 2197 | + "min": 1, |
| 2198 | + "required": false, |
| 2199 | + "default": null |
| 2200 | + }, |
| 2201 | + { |
| 2202 | + "name": "type", |
| 2203 | + "type": "select", |
| 2204 | + "label": "type", |
| 2205 | + "options": selectOptions |
| 2206 | + } |
| 2207 | + ] |
| 2208 | + }; |
| 2209 | + var $form = $( description ).formBuilder( { idPrefix: 'list-chose-type-' } ) |
2109 | 2210 | .submit( function() { |
2110 | 2211 | return false; //prevent form submission |
2111 | 2212 | } ); |
— | — | @@ -2123,6 +2224,14 @@ |
2124 | 2225 | click: function() { |
2125 | 2226 | var values = $( this ).formBuilder( 'getValues' ); |
2126 | 2227 | $( this ).dialog( "close" ); |
| 2228 | + |
| 2229 | + //Remove properties that equal their default |
| 2230 | + $.each( description.fields, function( index, fieldSpec ) { |
| 2231 | + var property = fieldSpec.name; |
| 2232 | + if ( values[property] === fieldSpec['default'] ) { |
| 2233 | + delete values[property]; |
| 2234 | + } |
| 2235 | + } ); |
2127 | 2236 | |
2128 | 2237 | var $dialog = $( this ); |
2129 | 2238 | createFieldDialog( { |
— | — | @@ -2132,7 +2241,7 @@ |
2133 | 2242 | }, |
2134 | 2243 | callback: function( field ) { |
2135 | 2244 | $dialog.dialog( 'close' ); |
2136 | | - showEditFieldDialog( field.getDesc(), options, callback ); |
| 2245 | + showEditFieldDialog( field.getDesc(), values, options, callback ); |
2137 | 2246 | return true; |
2138 | 2247 | } |
2139 | 2248 | }, { editable: true } ); |
Index: branches/salvatoreingala/Gadgets/Gadgets.i18n.php |
— | — | @@ -63,6 +63,9 @@ |
64 | 64 | 'gadgets-formbuilder-date' => 'Please enter a valid date.', |
65 | 65 | 'gadgets-formbuilder-color' => 'Please enter a valid color.', |
66 | 66 | 'gadgets-formbuilder-scalar' => 'Valid values are true, false, null, a floating point number or a double quoted string.', |
| 67 | + 'gadgets-formbuilder-list-required' => 'Please create at least one item.', |
| 68 | + 'gadgets-formbuilder-list-minlength' => 'Please insert at least $1 items.', |
| 69 | + 'gadgets-formbuilder-list-maxlength' => 'Please insert no more than $1 items.', |
67 | 70 | 'gadgets-formbuilder-editor-ok' => 'OK', |
68 | 71 | 'gadgets-formbuilder-editor-cancel' => 'Cancel', |
69 | 72 | 'gadgets-formbuilder-editor-move-field' => 'Move this field', |
Index: branches/salvatoreingala/Gadgets/Gadgets.php |
— | — | @@ -92,7 +92,8 @@ |
93 | 93 | 'messages' => array( |
94 | 94 | 'gadgets-formbuilder-required', 'gadgets-formbuilder-minlength', 'gadgets-formbuilder-maxlength', |
95 | 95 | 'gadgets-formbuilder-min', 'gadgets-formbuilder-max', 'gadgets-formbuilder-integer', 'gadgets-formbuilder-date', |
96 | | - 'gadgets-formbuilder-color', 'gadgets-formbuilder-scalar', |
| 96 | + 'gadgets-formbuilder-color', 'gadgets-formbuilder-list-required', 'gadgets-formbuilder-list-minlength', |
| 97 | + 'gadgets-formbuilder-list-maxlength', 'gadgets-formbuilder-scalar', |
97 | 98 | 'gadgets-formbuilder-editor-ok', 'gadgets-formbuilder-editor-cancel', 'gadgets-formbuilder-editor-move-field', |
98 | 99 | 'gadgets-formbuilder-editor-delete-field', 'gadgets-formbuilder-editor-edit-field', 'gadgets-formbuilder-editor-edit-field-title', 'gadgets-formbuilder-editor-insert-field', |
99 | 100 | 'gadgets-formbuilder-editor-chose-field', 'gadgets-formbuilder-editor-chose-field-title', 'gadgets-formbuilder-editor-create-field-title', |
Index: branches/salvatoreingala/Gadgets/Gadgets_tests.php |
— | — | @@ -274,7 +274,6 @@ |
275 | 275 | 'label' => 'some label', |
276 | 276 | 'minlength' => 6, |
277 | 277 | 'maxlength' => 10, |
278 | | - 'required' => false, |
279 | 278 | 'default' => 'default' |
280 | 279 | ) |
281 | 280 | ) |
— | — | @@ -282,8 +281,23 @@ |
283 | 282 | |
284 | 283 | $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct ) ); |
285 | 284 | |
286 | | - //Tests with wrong default values |
| 285 | + //Tests with wrong default values (when 'required' is not given) |
287 | 286 | $wrong = $correct; |
| 287 | + foreach ( array( null, '', true, false, 0, 1, array(), 'short', 'veryverylongstring' ) as $def ) { |
| 288 | + $wrong['fields'][0]['default'] = $def; |
| 289 | + $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) ); |
| 290 | + } |
| 291 | + |
| 292 | + //Tests with correct default values (when required is not given) |
| 293 | + $correct2 = $correct; |
| 294 | + foreach ( array( '6chars', '1234567890' ) as $def ) { |
| 295 | + $correct2['fields'][0]['default'] = $def; |
| 296 | + $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct2 ) ); |
| 297 | + } |
| 298 | + |
| 299 | + //Tests with wrong default values (when 'required' is false) |
| 300 | + $wrong = $correct; |
| 301 | + $wrong['fields'][0]['required'] = false; |
288 | 302 | foreach ( array( null, true, false, 0, 1, array(), 'short', 'veryverylongstring' ) as $def ) { |
289 | 303 | $wrong['fields'][0]['default'] = $def; |
290 | 304 | $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) ); |
— | — | @@ -291,16 +305,36 @@ |
292 | 306 | |
293 | 307 | //Tests with correct default values (when required is false) |
294 | 308 | $correct2 = $correct; |
| 309 | + $correct2['fields'][0]['required'] = false; |
295 | 310 | foreach ( array( '', '6chars', '1234567890' ) as $def ) { |
296 | 311 | $correct2['fields'][0]['default'] = $def; |
297 | 312 | $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct2 ) ); |
298 | 313 | } |
299 | 314 | |
| 315 | + $correct = array( |
| 316 | + 'fields' => array( |
| 317 | + array( |
| 318 | + 'name' => 'testString', |
| 319 | + 'type' => 'string', |
| 320 | + 'label' => 'some label', |
| 321 | + 'default' => '' |
| 322 | + ) |
| 323 | + ) |
| 324 | + ); |
| 325 | + |
300 | 326 | //Test with empty default when "required" is true |
| 327 | + $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct ) ); |
| 328 | + |
| 329 | + //Test with empty default when "required" is true |
301 | 330 | $wrong = $correct; |
302 | | - $wrong['fields']['testString']['required'] = true; |
303 | | - $wrong['fields']['testString']['default'] = ''; |
| 331 | + $wrong['fields'][0]['required'] = true; |
304 | 332 | $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) ); |
| 333 | + |
| 334 | + //Test with empty default when "required" is false and minlength is given |
| 335 | + $correct2 = $correct; |
| 336 | + $correct2['fields'][0]['required'] = false; |
| 337 | + $correct2['fields'][0]['minlength'] = 3; |
| 338 | + $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct2 ) ); |
305 | 339 | } |
306 | 340 | |
307 | 341 | //Tests for 'number' type preferences |
— | — | @@ -707,6 +741,54 @@ |
708 | 742 | ) |
709 | 743 | ) ); |
710 | 744 | |
| 745 | + |
| 746 | + //Tests with 'minlength' and 'maxlength' options |
| 747 | + $wrong = $correct; |
| 748 | + $wrong['fields'][0]['minlength'] = 4; |
| 749 | + $wrong['fields'][0]['maxlength'] = 3; //maxlength < minlength, wrong |
| 750 | + $this->assertFalse( GadgetPrefs::isPrefsDescriptionValid( $wrong ) ); |
| 751 | + |
| 752 | + $correct2 = $correct; |
| 753 | + $correct2['fields'][0]['minlength'] = 2; |
| 754 | + $correct2['fields'][0]['maxlength'] = 3; |
| 755 | + $correct2['fields'][0]['default'] = array( |
| 756 | + array( 'bar' => true, 'car' => '#115599' ), |
| 757 | + array( 'bar' => false, 'car' => '#123456' ) |
| 758 | + ); |
| 759 | + $this->assertTrue( GadgetPrefs::isPrefsDescriptionValid( $correct2 ) ); |
| 760 | + |
| 761 | + $this->assertFalse( GadgetPrefs::checkPrefsAgainstDescription( |
| 762 | + $correct2, |
| 763 | + array( 'foo' => array( //less than minlength items |
| 764 | + array( 'bar' => true, 'car' => '#115599' ) |
| 765 | + ) |
| 766 | + ) |
| 767 | + ) ); |
| 768 | + |
| 769 | + $this->assertFalse( GadgetPrefs::checkPrefsAgainstDescription( |
| 770 | + $correct2, |
| 771 | + array( 'foo' => array() ) //empty array, must fail because "required" is not false |
| 772 | + ) ); |
| 773 | + |
| 774 | + $this->assertFalse( GadgetPrefs::checkPrefsAgainstDescription( |
| 775 | + $correct2, |
| 776 | + array( 'foo' => array( //more than minlength items |
| 777 | + array( 'bar' => true, 'car' => '#115599' ), |
| 778 | + array( 'bar' => false, 'car' => '#123456' ), |
| 779 | + array( 'bar' => true, 'car' => '#ffffff' ), |
| 780 | + array( 'bar' => false, 'car' => '#2357bd' ) |
| 781 | + ) |
| 782 | + ) |
| 783 | + ) ); |
| 784 | + |
| 785 | + //Test with 'required' |
| 786 | + $correct2['fields'][0]['required'] = false; |
| 787 | + $this->assertTrue( GadgetPrefs::checkPrefsAgainstDescription( |
| 788 | + $correct2, |
| 789 | + array( 'foo' => array() ) //empty array, must be accepted because "required" is false |
| 790 | + ) ); |
| 791 | + |
| 792 | + //Tests matchPrefsWithDescription |
711 | 793 | $prefs = array( 'foo' => array( |
712 | 794 | array( |
713 | 795 | 'bar' => null, |
— | — | @@ -723,6 +805,7 @@ |
724 | 806 | ) |
725 | 807 | ); |
726 | 808 | |
| 809 | + |
727 | 810 | GadgetPrefs::matchPrefsWithDescription( $correct, $prefs ); |
728 | 811 | $this->assertTrue( GadgetPrefs::checkPrefsAgainstDescription( $correct, $prefs ) ); |
729 | 812 | } |
Index: branches/salvatoreingala/Gadgets/backend/GadgetPrefs.php |
— | — | @@ -254,6 +254,18 @@ |
255 | 255 | ), |
256 | 256 | 'default' => array( |
257 | 257 | 'isMandatory' => true |
| 258 | + ), |
| 259 | + 'required' => array( |
| 260 | + 'isMandatory' => false, |
| 261 | + 'validator' => 'is_bool' |
| 262 | + ), |
| 263 | + 'minlength' => array( |
| 264 | + 'isMandatory' => false, |
| 265 | + 'validator' => 'is_integer' |
| 266 | + ), |
| 267 | + 'maxlength' => array( |
| 268 | + 'isMandatory' => false, |
| 269 | + 'validator' => 'is_integer' |
258 | 270 | ) |
259 | 271 | ), |
260 | 272 | 'validator' => 'GadgetPrefs::validateListPrefDefinition', |
— | — | @@ -406,6 +418,13 @@ |
407 | 419 | return false; |
408 | 420 | } |
409 | 421 | |
| 422 | + //Validate minlength and maxlength |
| 423 | + $minlength = isset( $prefDefinition['minlength'] ) ? $prefDefinition['minlength'] : 0; |
| 424 | + $maxlength = isset( $prefDefinition['maxlength'] ) ? $prefDefinition['maxlength'] : 1024; |
| 425 | + if ( $minlength < 0 || $maxlength <= 0 || $minlength > $maxlength ) { |
| 426 | + return false; |
| 427 | + } |
| 428 | + |
410 | 429 | //Check if the field definition is valid, apart from missing the name |
411 | 430 | $itemDescription = $prefDefinition['field']; |
412 | 431 | $itemDescription['name'] = 'dummy'; |
— | — | @@ -654,11 +673,13 @@ |
655 | 674 | $len = strlen( $value ); |
656 | 675 | |
657 | 676 | //Checks the "required" option, if present |
658 | | - $required = isset( $prefDescription['required'] ) ? $prefDescription['required'] : true; |
659 | | - if ( $required === true && $len == 0 ) { |
660 | | - return false; |
661 | | - } elseif ( $required === false && $len == 0 ) { |
662 | | - return true; //overriding 'minlength' |
| 677 | + if ( isset( $prefDescription['required'] ) ) { |
| 678 | + $required = isset( $prefDescription['required'] ) ? $prefDescription['required'] : true; |
| 679 | + if ( $required === true && $len == 0 ) { |
| 680 | + return false; |
| 681 | + } elseif ( $required === false && $len == 0 ) { |
| 682 | + return true; //overriding 'minlength', if given |
| 683 | + } |
663 | 684 | } |
664 | 685 | |
665 | 686 | //Checks the "minlength" option, if present |
— | — | @@ -803,6 +824,24 @@ |
804 | 825 | return false; |
805 | 826 | } |
806 | 827 | |
| 828 | + $nItems = count( $value ); |
| 829 | + |
| 830 | + //Checks the "required" option, if present |
| 831 | + if ( isset( $prefDescription['required'] ) ) { |
| 832 | + $required = $prefDescription['required']; |
| 833 | + if ( $required === true && $nItems == 0 ) { |
| 834 | + return false; |
| 835 | + } elseif ( $required === false && $nItems == 0 ) { |
| 836 | + return true; //overriding 'minlength' |
| 837 | + } |
| 838 | + } |
| 839 | + |
| 840 | + $minlength = isset( $prefDescription['minlength'] ) ? $prefDescription['minlength'] : 0; |
| 841 | + $maxlength = isset( $prefDescription['maxlength'] ) ? $prefDescription['maxlength'] : 1024; |
| 842 | + if ( $nItems < $minlength || $nItems > $maxlength ) { |
| 843 | + return false; |
| 844 | + } |
| 845 | + |
807 | 846 | $itemDescription = $prefDescription['field']; |
808 | 847 | foreach ( $value as $item ) { |
809 | 848 | if ( !self::checkSinglePref( $itemDescription, array( 'dummy' => $item ), 'dummy' ) ) { |