@@ -1777,15 +1777,11 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
1777
1777
1778
1778
/**
1779
1779
* Executes internal hooks before save a record
1780
- *
1781
- * @param Phalcon\Mvc\Model\MetadataInterface metaData
1782
- * @param boolean exists
1783
- * @param string identityField
1784
- * @return boolean
1785
1780
*/
1786
1781
protected function _preSave (<MetadataInterface> metaData, boolean exists, var identityField ) -> boolean
1787
1782
{
1788
- var notNull, columnMap, dataTypeNumeric, automaticAttributes, defaultValues, field, attributeField, value;
1783
+ var notNull, columnMap, dataTypeNumeric, automaticAttributes, defaultValues,
1784
+ field, attributeField, value, emptyStringValues;
1789
1785
boolean error, isNull;
1790
1786
1791
1787
/**
@@ -1852,6 +1848,11 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
1852
1848
let defaultValues = metaData-> getDefaultValues(this );
1853
1849
}
1854
1850
1851
+ /**
1852
+ * Get string attributes that allow empty strings as defaults
1853
+ */
1854
+ let emptyStringValues = metaData-> getEmptyStringAttributes(this );
1855
+
1855
1856
let error = false ;
1856
1857
for field in notNull {
1857
1858
@@ -1881,15 +1882,22 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
1881
1882
*/
1882
1883
if typeof value != " object" {
1883
1884
if ! isset dataTypeNumeric[field] {
1884
- if value === null || value === " " {
1885
- let isNull = true ;
1885
+ if isset emptyStringValues[field] {
1886
+ if value === null {
1887
+ let isNull = true ;
1888
+ }
1889
+ } else {
1890
+ if value === null || value === " " {
1891
+ let isNull = true ;
1892
+ }
1886
1893
}
1887
1894
} else {
1888
1895
if ! is_numeric(value) {
1889
1896
let isNull = true ;
1890
1897
}
1891
1898
}
1892
1899
}
1900
+
1893
1901
} else {
1894
1902
let isNull = true ;
1895
1903
}
@@ -2026,7 +2034,8 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
2026
2034
table, identityField) -> boolean
2027
2035
{
2028
2036
var bindSkip, fields, values, bindTypes, attributes, bindDataTypes, automaticAttributes,
2029
- field, columnMap, value, attributeField, success, bindType, defaultValue, sequenceName;
2037
+ field, columnMap, value, attributeField, success, bindType,
2038
+ defaultValue, sequenceName, defaultValues;
2030
2039
boolean useExplicitIdentity;
2031
2040
2032
2041
let bindSkip = Column:: BIND_SKIP ;
@@ -2037,7 +2046,8 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
2037
2046
2038
2047
let attributes = metaData-> getAttributes(this ),
2039
2048
bindDataTypes = metaData-> getBindTypes(this ),
2040
- automaticAttributes = metaData-> getAutomaticCreateAttributes(this );
2049
+ automaticAttributes = metaData-> getAutomaticCreateAttributes(this ),
2050
+ defaultValues = metaData-> getDefaultValues(this );
2041
2051
2042
2052
if globals_get(" orm.column_renaming" ) {
2043
2053
let columnMap = metaData-> getColumnMap(this );
@@ -2075,6 +2085,10 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
2075
2085
*/
2076
2086
if fetch value, this -> {attributeField} {
2077
2087
2088
+ if value === null && isset defaultValues[field] {
2089
+ let value = defaultValues[field];
2090
+ }
2091
+
2078
2092
/**
2079
2093
* Every column must have a bind data type defined
2080
2094
*/
@@ -2084,7 +2098,11 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
2084
2098
2085
2099
let values[] = value, bindTypes[] = bindType;
2086
2100
} else {
2087
- let values[] = null , bindTypes[] = bindSkip;
2101
+
2102
+ let bindTypes[] = bindSkip;
2103
+
2104
+ fetch value, defaultValues[field];
2105
+ let values[] = value;
2088
2106
}
2089
2107
}
2090
2108
}
@@ -3160,9 +3178,6 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3160
3178
* <code>
3161
3179
* echo $robot->readAttribute('name');
3162
3180
* </code>
3163
- *
3164
- * @param string attribute
3165
- * @return mixed
3166
3181
*/
3167
3182
public function readAttribute (string! attribute )
3168
3183
{
@@ -3176,14 +3191,11 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3176
3191
/**
3177
3192
* Writes an attribute value by its name
3178
3193
*
3179
- * <code>
3194
+ *<code>
3180
3195
* $robot->writeAttribute('name', 'Rosey');
3181
- * </code>
3182
- *
3183
- * @param string attribute
3184
- * @param mixed value
3196
+ *</code>
3185
3197
*/
3186
- public function writeAttribute (string! attribute, value )
3198
+ public function writeAttribute (string! attribute, var value )
3187
3199
{
3188
3200
let this -> {attribute} = value;
3189
3201
}
@@ -3202,7 +3214,6 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3202
3214
* {
3203
3215
* $this->skipAttributes(array('price'));
3204
3216
* }
3205
- *
3206
3217
*}
3207
3218
*</code>
3208
3219
*/
@@ -3234,7 +3245,6 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3234
3245
* {
3235
3246
* $this->skipAttributesOnCreate(array('created_at'));
3236
3247
* }
3237
- *
3238
3248
*}
3239
3249
*</code>
3240
3250
*/
@@ -3264,7 +3274,6 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3264
3274
* {
3265
3275
* $this->skipAttributesOnUpdate(array('modified_in'));
3266
3276
* }
3267
- *
3268
3277
*}
3269
3278
*</code>
3270
3279
*/
@@ -3280,6 +3289,35 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3280
3289
this -> getModelsMetaData()-> setAutomaticUpdateAttributes(this , keysAttributes);
3281
3290
}
3282
3291
3292
+ /**
3293
+ * Sets a list of attributes that must be skipped from the
3294
+ * generated UPDATE statement
3295
+ *
3296
+ *<code>
3297
+ *<?php
3298
+ *
3299
+ *class Robots extends \Phalcon\Mvc\Model
3300
+ *{
3301
+ *
3302
+ * public function initialize()
3303
+ * {
3304
+ * $this->allowEmptyStringValues(array('name'));
3305
+ * }
3306
+ *}
3307
+ *</code>
3308
+ */
3309
+ protected function allowEmptyStringValues (array! attributes ) -> void
3310
+ {
3311
+ var keysAttributes, attribute;
3312
+
3313
+ let keysAttributes = [];
3314
+ for attribute in attributes {
3315
+ let keysAttributes[attribute] = null ;
3316
+ }
3317
+
3318
+ this -> getModelsMetaData()-> setEmptyStringAttributes(this , keysAttributes);
3319
+ }
3320
+
3283
3321
/**
3284
3322
* Setup a 1-1 relation between two models
3285
3323
*
@@ -3293,15 +3331,8 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3293
3331
* {
3294
3332
* $this->hasOne('id', 'RobotsDescription', 'robots_id');
3295
3333
* }
3296
- *
3297
3334
*}
3298
3335
*</code>
3299
- *
3300
- * @param mixed fields
3301
- * @param string referenceModel
3302
- * @param mixed referencedFields
3303
- * @param array options
3304
- * @return Phalcon\Mvc\Model\Relation
3305
3336
*/
3306
3337
protected function hasOne (var fields, string! referenceModel, var referencedFields, options = null ) -> <Relation>
3307
3338
{
@@ -3324,12 +3355,6 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3324
3355
*
3325
3356
*}
3326
3357
*</code>
3327
- *
3328
- * @param mixed fields
3329
- * @param string referenceModel
3330
- * @param mixed referencedFields
3331
- * @param array options
3332
- * @return Phalcon\Mvc\Model\Relation
3333
3358
*/
3334
3359
protected function belongsTo (var fields, string! referenceModel, var referencedFields, options = null ) -> <Relation>
3335
3360
{
@@ -3349,15 +3374,8 @@ abstract class Model implements ModelInterface, ResultInterface, InjectionAwareI
3349
3374
* {
3350
3375
* $this->hasMany('id', 'RobotsParts', 'robots_id');
3351
3376
* }
3352
- *
3353
3377
*}
3354
3378
*</code>
3355
- *
3356
- * @param mixed fields
3357
- * @param string referenceModel
3358
- * @param mixed referencedFields
3359
- * @param array options
3360
- * @return Phalcon\Mvc\Model\Relation
3361
3379
*/
3362
3380
protected function hasMany (var fields, string! referenceModel, var referencedFields, options = null ) -> <Relation>
3363
3381
{
0 commit comments