Skip to content

Commit

Permalink
Nullable support for __set.
Browse files Browse the repository at this point in the history
I wrote it and works like a charm. Slightly more efficient, because I  some of  array_key_exists don't exist anymore ;). 
But... I noticed an issue when I am trying to save this entity. Property which is set to null is excluded from INSERT what should cause problem if default column value is not set to null but different value - in that case we cannot save null during insert.

In my case should be:
```
INSERT INTO `t_table_search` (`dcs_identifier`, `dcs_conditions`, `dcs_dsc_id`) VALUES ('e77d630b7be1484cb4b7b4f8dbc15c45', '{\"v-school\":[\"1\"],\"v-center\":[\"44\"]}', NULL) // dcs_dsc_id = null;
```
it is:
```
INSERT INTO `t_table_search` (`dcs_identifier`, `dcs_conditions`) VALUES ('e77d630b7be1484cb4b7b4f8dbc15c45', '{\"v-school\":[\"1\"],\"v-center\":[\"44\"]}')// no null for dcs_dsc_id
```

 I think it is because of entity value of property in _original is the same as actual value of property (i.e.: dcs_dsc_id == null)


```object(App\Entities\entityname)codeigniter4#40 (7) {
  ["dcs_identifier":protected]=>
  string(32) "e77d630b7be1484cb4b7b4f8dbc15c45"
  ["dcs_conditions":protected]=>
  string(52) "{"driving-school":["1"],"examination-center":["44"]}"
  ["dcs_dsc_id":protected]=>
  NULL
  ["dcs_updated_at":protected]=>
  NULL
  ["_options":protected]=>
  array(3) {
    ["casts"]=>
    array(3) {
      ["dcs_identifier"]=>
      string(6) "string"
      ["dcs_conditions"]=>
      string(10) "json-array"
      ["dcs_dsc_id"]=>
      string(11) "?json-array"
    }
    ["dates"]=>
    array(2) {
      [0]=>
      NULL
      [1]=>
      string(14) "dcs_updated_at"
    }
    ["datamap"]=>
    array(0) {
    }
  }
  ["_original":protected]=>
  array(4) {
    ["dcs_identifier"]=>
    NULL
    ["dcs_conditions"]=>
    NULL
    ["dcs_dsc_id"]=>
    NULL
    ["dcs_updated_at"]=>
    NULL
  }
  ["_cast":"CodeIgniter\Entity":private]=>
  bool(true)```


I saw PR month or two ago which was changing entity saving but IMHO it should be turned ON for update or replace but should NOT work for INSERT.
  • Loading branch information
nowackipawel authored Dec 22, 2018
1 parent 3a4ade9 commit 79d4fd2
Showing 1 changed file with 25 additions and 10 deletions.
35 changes: 25 additions & 10 deletions system/Entity.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,24 +267,38 @@ public function __set(string $key, $value = null)
$value = $this->mutateDate($value);
}

// Array casting requires that we serialize the value
// when setting it so that it can easily be stored
// back to the database.
if (array_key_exists($key, $this->_options['casts']) && $this->_options['casts'][$key] === 'array')
$is_nullable = false;
$cast_to = false;

if(array_key_exists($key, $this->_options['casts']))
{
$value = serialize($value);
$is_nullable = substr($this->_options['casts'][$key],0,1) === '?';
$cast_to = $is_nullable ? substr($this->_options['casts'][$key], 1) : $this->_options['casts'][$key];
}

// JSON casting requires that we JSONize the value
// when setting it so that it can easily be stored
// back to the database.
if (function_exists('json_encode') && array_key_exists($key, $this->_options['casts']) && ($this->_options['casts'][$key] === 'json' || $this->_options['casts'][$key] === 'json-array'))
if(!$is_nullable || !is_null($value))
{
$value = json_encode($value);
// Array casting requires that we serialize the value
// when setting it so that it can easily be stored
// back to the database.
if ($cast_to === 'array')
{
$value = serialize($value);
}

// JSON casting requires that we JSONize the value
// when setting it so that it can easily be stored
// back to the database.
if (($cast_to === 'json' || $cast_to === 'json-array') && function_exists('json_encode'))
{
$value = json_encode($value);
}

}

// if a set* method exists for this key,
// use that method to insert this value.
// *) should be outside $is_nullable check - SO maybe wants to do sth with null value automatically
$method = 'set' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $key)));
if (method_exists($this, $method))
{
Expand All @@ -304,6 +318,7 @@ public function __set(string $key, $value = null)
return $this;
}


//--------------------------------------------------------------------

/**
Expand Down

0 comments on commit 79d4fd2

Please sign in to comment.