Skip to content

Commit

Permalink
Refactor for code clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
hparadiz committed Jul 27, 2023
1 parent 12f61e0 commit ee754cb
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 122 deletions.
167 changes: 65 additions & 102 deletions src/Models/ActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
use Divergence\IO\Database\Query\Delete;
use Divergence\IO\Database\Query\Insert;
use Divergence\IO\Database\Query\Update;
use Divergence\Models\Interfaces\FieldSetMapper;
use Divergence\Models\SetMappers\DefaultSetMapper;
use Divergence\Models\Mapping\DefaultGetMapper;
use Divergence\Models\Mapping\DefaultSetMapper;

/**
* ActiveRecord
Expand Down Expand Up @@ -290,9 +290,9 @@ class ActiveRecord implements JsonSerializable
*/
protected $_isUpdated;

/** Field Mapper */
protected ?FieldSetMapper $fieldSetMapper;

public const defaultSetMapper = DefaultSetMapper::class;
public const defaultGetMapper = DefaultGetMapper::class;
/**
* __construct Instantiates a Model and returns.
*
Expand Down Expand Up @@ -1118,7 +1118,7 @@ public static function _definedAttributeFields(): array
// skip these because they are built in
if (in_array($property->getName(), [
'_classFields','_classRelationships','_classBeforeSave','_classAfterSave','_fieldsDefined','_relationshipsDefined','_eventsDefined','_record','_validator'
,'_validationErrors','_isDirty','_isValid','fieldSetMapper','_convertedValues','_originalValues','_isPhantom','_wasPhantom','_isNew','_isUpdated','_relatedObjects'
,'_validationErrors','_isDirty','_isValid','_convertedValues','_originalValues','_isPhantom','_wasPhantom','_isNew','_isUpdated','_relatedObjects'
])) {
continue;
}
Expand Down Expand Up @@ -1245,8 +1245,21 @@ protected static function _cn($field)
}


private function applyNewValue($type, $field, $value)
{
if (!isset($this->_convertedValues[$field])) {
if (is_null($value) && !in_array($type, ['set','list'])) {
unset($this->_convertedValues[$field]);
return null;
}
$this->_convertedValues[$field] = $value;
}
return $this->_convertedValues[$field];
}

/**
* Retrieves given field's value
* Applies type-dependent transformations to the value in $this->_record[$fieldOptions['columnName']]
* Caches to $this->_convertedValues[$field] and returns the value in there.
* @param string $field Name of field
* @return mixed value
*/
Expand All @@ -1257,81 +1270,34 @@ protected function _getFieldValue($field, $useDefault = true)
if (isset($this->_record[$fieldOptions['columnName']])) {
$value = $this->_record[$fieldOptions['columnName']];

$defaultGetMapper = static::defaultGetMapper;

// apply type-dependent transformations
switch ($fieldOptions['type']) {
case 'password':
{
return $value;
}

case 'timestamp':
{
if (!isset($this->_convertedValues[$field])) {
if ($value && is_string($value) && $value != '0000-00-00 00:00:00') {
$this->_convertedValues[$field] = strtotime($value);
} elseif (is_integer($value)) {
$this->_convertedValues[$field] = $value;
} else {
unset($this->_convertedValues[$field]);
}
}
return $this->applyNewValue($fieldOptions['type'], $field, $defaultGetMapper::getTimestampValue($value));

return $this->_convertedValues[$field];
}
case 'serialized':
{
if (!isset($this->_convertedValues[$field])) {
$this->_convertedValues[$field] = is_string($value) ? unserialize($value) : $value;
}
return $this->applyNewValue($fieldOptions['type'], $field, $defaultGetMapper::getSerializedValue($value));

return $this->_convertedValues[$field];
}
case 'set':
case 'list':
{
if (!isset($this->_convertedValues[$field])) {
$delim = empty($fieldOptions['delimiter']) ? ',' : $fieldOptions['delimiter'];
$this->_convertedValues[$field] = array_filter(preg_split('/\s*'.$delim.'\s*/', $value));
}

return $this->_convertedValues[$field];
}
return $this->applyNewValue($fieldOptions['type'], $field, $defaultGetMapper::getListValue($value, $fieldOptions['delimiter']));

case 'int':
case 'integer':
case 'uint':
if (!isset($this->_convertedValues[$field])) {
if (!$fieldOptions['notnull'] && is_null($value)) {
$this->_convertedValues[$field] = $value;
} else {
$this->_convertedValues[$field] = intval($value);
}
}
return $this->_convertedValues[$field];
return $this->applyNewValue($fieldOptions['type'], $field, $defaultGetMapper::getIntegerValue($value));

case 'boolean':
{
if (!isset($this->_convertedValues[$field])) {
$this->_convertedValues[$field] = (bool)$value;
}

return $this->_convertedValues[$field];
}
return $this->applyNewValue($fieldOptions['type'], $field, $defaultGetMapper::getBooleanValue($value));

case 'decimal':
if (!isset($this->_convertedValues[$field])) {
if (!$fieldOptions['notnull'] && is_null($value)) {
$this->_convertedValues[$field] = $value;
} else {
$this->_convertedValues[$field] = floatval($value);
}
}
return $this->_convertedValues[$field];
return $this->applyNewValue($fieldOptions['type'], $field, $defaultGetMapper::getDecimalValue($value));

case 'password':
default:
{
return $value;
}
return $value;
}
} elseif ($useDefault && isset($fieldOptions['default'])) {
// return default
Expand All @@ -1340,13 +1306,9 @@ protected function _getFieldValue($field, $useDefault = true)
switch ($fieldOptions['type']) {
case 'set':
case 'list':
{
return [];
}
return [];
default:
{
return null;
}
return null;
}
}
}
Expand Down Expand Up @@ -1376,17 +1338,15 @@ protected function _setFieldValue($field, $value)
return false;
}

if (!isset($this->fieldSetMapper)) {
$this->fieldSetMapper = new DefaultSetMapper();
}
$setMapper = static::defaultSetMapper;

// pre-process value
$forceDirty = false;
switch ($fieldOptions['type']) {
case 'clob':
case 'string':
{
$value = $this->fieldSetMapper->setStringValue($value);
$value = $setMapper::setStringValue($value);
if (!$fieldOptions['notnull'] && $fieldOptions['blankisnull'] && ($value === '' || $value === null)) {
$value = null;
}
Expand All @@ -1395,21 +1355,21 @@ protected function _setFieldValue($field, $value)

case 'boolean':
{
$value = $this->fieldSetMapper->setBooleanValue($value);
$value = $setMapper::setBooleanValue($value);
break;
}

case 'decimal':
{
$value = $this->fieldSetMapper->setDecimalValue($value);
$value = $setMapper::setDecimalValue($value);
break;
}

case 'int':
case 'uint':
case 'integer':
{
$value = $this->fieldSetMapper->setIntegerValue($value);
$value = $setMapper::setIntegerValue($value);
if (!$fieldOptions['notnull'] && ($value === '' || is_null($value))) {
$value = null;
}
Expand All @@ -1419,67 +1379,70 @@ protected function _setFieldValue($field, $value)
case 'timestamp':
{
unset($this->_convertedValues[$field]);
$value = $this->fieldSetMapper->setTimestampValue($value);
$value = $setMapper::setTimestampValue($value);
break;
}

case 'date':
{
unset($this->_convertedValues[$field]);
$value = $this->fieldSetMapper->setDateValue($value);
$value = $setMapper::setDateValue($value);
break;
}

// these types are converted to strings from another PHP type on save
case 'serialized':
{
// if the value is a string we assume it's already serialized data
if (!is_string($value)) {
$value = $this->fieldSetMapper->setSerializedValue($value);
$value = $setMapper::setSerializedValue($value);
}
break;
}
case 'enum':
{
$value = $this->fieldSetMapper->setEnumValue($fieldOptions['values'], $value);
$value = $setMapper::setEnumValue($fieldOptions['values'], $value);
break;
}
case 'set':
case 'list':
{
$value = $this->fieldSetMapper->setListValue($value, isset($fieldOptions['delimiter']) ? $fieldOptions['delimiter'] : null);
$value = $setMapper::setListValue($value, isset($fieldOptions['delimiter']) ? $fieldOptions['delimiter'] : null);
$this->_convertedValues[$field] = $value;
$forceDirty = true;
break;
}
}

if ($forceDirty || (empty($this->_record[$field]) && isset($value)) || ($this->_record[$field] !== $value)) {
$columnName = static::_cn($field);
if (isset($this->_record[$columnName])) {
$this->_originalValues[$field] = $this->_record[$columnName];
}
$this->_record[$columnName] = $value;
// only set value if this is an attribute mapped field
if (isset($this->_classFields[get_called_class()][$columnName]['attributeField'])) {
$this->$columnName = $value;
}
$this->_isDirty = true;

// unset invalidated relationships
if (!empty($fieldOptions['relationships']) && static::isRelational()) {
foreach ($fieldOptions['relationships'] as $relationship => $isCached) {
if ($isCached) {
unset($this->_relatedObjects[$relationship]);
}
}
}
$this->_setDirtyValue($field, $value);
return true;
} else {
return false;
}
}

protected function _setDirtyValue($field, $value)
{
$columnName = static::_cn($field);
if (isset($this->_record[$columnName])) {
$this->_originalValues[$field] = $this->_record[$columnName];
}
$this->_record[$columnName] = $value;
// only set value if this is an attribute mapped field
if (isset($this->_classFields[get_called_class()][$columnName]['attributeField'])) {
$this->$columnName = $value;
}
$this->_isDirty = true;

// unset invalidated relationships
if (!empty($fieldOptions['relationships']) && static::isRelational()) {
foreach ($fieldOptions['relationships'] as $relationship => $isCached) {
if ($isCached) {
unset($this->_relatedObjects[$relationship]);
}
}
}
}

protected function _prepareRecordValues()
{
$record = [];
Expand Down
32 changes: 32 additions & 0 deletions src/Models/Interfaces/FieldGetMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* This file is part of the Divergence package.
*
* (c) Henry Paradiz <henry.paradiz@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Divergence\Models\Interfaces;

/**
* Field Get Mapper interface
*
* This is how each Model field type is processed.
*
* @package Divergence
* @author Henry Paradiz <henry.paradiz@gmail.com>
*
*/
interface FieldGetMapper
{
public static function getStringValue($value): ?string;
public static function getBooleanValue($value): bool;
public static function getDecimalValue($value): ?float;
public static function getIntegerValue($value): ?int;
public static function getDateValue($value);
public static function getTimestampValue($value): ?int;
public static function getSerializedValue($value);
public static function getListValue($value, ?string $delimiter): array;
}
18 changes: 9 additions & 9 deletions src/Models/Interfaces/FieldSetMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
*/
interface FieldSetMapper
{
public function setStringValue($value): ?string;
public function setBooleanValue($value): bool;
public function setDecimalValue($value): ?float;
public function setIntegerValue($value): ?int;
public function setDateValue($value): ?string;
public function setTimestampValue($value): ?string;
public function setSerializedValue($value): string;
public function setEnumValue(array $values, $value);
public function setListValue($value, ?string $delimiter): array;
public static function setStringValue($value): ?string;
public static function setBooleanValue($value): bool;
public static function setDecimalValue($value): ?float;
public static function setIntegerValue($value): ?int;
public static function setDateValue($value): ?string;
public static function setTimestampValue($value): ?string;
public static function setSerializedValue($value): string;
public static function setEnumValue(array $values, $value);
public static function setListValue($value, ?string $delimiter): array;
}

0 comments on commit ee754cb

Please sign in to comment.