1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 
<?php
namespace MvcCore\Model;
trait DataMethods {
    
    public function GetValues ($propsFlags = 0, $getNullValues = FALSE) {
        
        $metaData = static::getMetaData($propsFlags);
        
        $phpWithTypes = PHP_VERSION_ID >= 70400;
        $keyConversionsMethod = NULL;
        $caseSensitiveKeysMap = '';
        $stringKeyConversions = $propsFlags > 127;
        if ($stringKeyConversions) {
            $keyConversionsMethod = static::getKeyConversionMethod($propsFlags);
            $toolsClass = \MvcCore\Application::GetInstance()->GetToolClass();
            if ($propsFlags > 8191)
                $caseSensitiveKeysMap = ','.implode(',', array_keys($metaData)).',';
        };
        $result = [];
        
        foreach ($metaData as $propertyName => $propData) {
            $propValue = NULL;
            
            if ($propData[0]) {
                $prop = new \ReflectionProperty($this, $propertyName);
                $prop->setAccessible(TRUE);
                if ($phpWithTypes) {
                    if ($prop->isInitialized($this))
                        $propValue = $prop->getValue($this);
                } else {
                    $propValue = $prop->getValue($this);
                }
            } else if (isset($this->{$propertyName})) {
                $propValue = $this->{$propertyName};
            }
            if (!$getNullValues && $propValue === NULL)
                continue;
            $resultKey = $propertyName;
            if ($stringKeyConversions) 
                $resultKey = static::{$keyConversionsMethod}(
                    $resultKey, $toolsClass, $caseSensitiveKeysMap
                );
            $result[$resultKey] = $propValue;
        }
        return $result;
    }
    
    public function SetValues ($data = [], $propsFlags = 0) {
        
        $completeInitialValues = ($propsFlags & \MvcCore\IModel::PROPS_INITIAL_VALUES) != 0;
        $metaData = static::getMetaData($propsFlags);
        $keyConversionsMethod = NULL;
        $caseSensitiveKeysMap = '';
        $stringKeyConversions = $propsFlags > 127;
        if ($stringKeyConversions) {
            $keyConversionsMethod = static::getKeyConversionMethod($propsFlags);
            $toolsClass = \MvcCore\Application::GetInstance()->GetToolClass();
            if ($propsFlags > 8191)
                $caseSensitiveKeysMap = ','.implode(',', array_keys($metaData)).',';
        };
        foreach ($data as $dbKey => $dbValue) {
            $propertyName = $dbKey;
            if ($stringKeyConversions) 
                $propertyName = static::{$keyConversionsMethod}(
                    $propertyName, $toolsClass, $caseSensitiveKeysMap
                );
            $isNull = $dbValue === NULL;
            $propIsPrivate = NULL;
            if (isset($metaData[$propertyName])) {
                list (
                    $propIsPrivate, $propAllowNulls, $propTypes
                ) = $metaData[$propertyName];
                if (!$propAllowNulls && $isNull) continue;
                if ($isNull) {
                    $value = $dbValue;
                } else {
                    $value = static::parseToTypes($dbValue, $propTypes);    
                }
            } else {
                $value = $dbValue;
            }
            if ($propIsPrivate) {
                $prop = new \ReflectionProperty($this, $propertyName);
                $prop->setAccessible(TRUE);
                $prop->setValue($this, $value);
            } else {
                $this->{$propertyName} = $value;
            }
            if ($completeInitialValues)
                $this->initialValues[$propertyName] = $value;
        }
        return $this;
    }
    
    public function GetTouched ($propsFlags = 0) {
        
        $metaData = static::getMetaData($propsFlags);
        
        $phpWithTypes = PHP_VERSION_ID >= 70400;
        $keyConversionsMethod = NULL;
        $caseSensitiveKeysMap = '';
        $stringKeyConversions = $propsFlags > 127;
        if ($stringKeyConversions) {
            $keyConversionsMethod = static::getKeyConversionMethod($propsFlags);
            $toolsClass = \MvcCore\Application::GetInstance()->GetToolClass();
            if ($propsFlags > 8191)
                $caseSensitiveKeysMap = ','.implode(',', array_keys($metaData)).',';
        };
        $result = [];
        foreach ($metaData as $propertyName => $propData) {
            $initialValue = NULL;
            $currentValue = NULL;
            if (array_key_exists($propertyName, $this->initialValues))
                $initialValue = $this->initialValues[$propertyName];
            
            if ($propData[0]) {
                $prop = new \ReflectionProperty($this, $propertyName);
                $prop->setAccessible(TRUE);
                if ($phpWithTypes) {
                    if ($prop->isInitialized($this))
                        $currentValue = $prop->getValue($this);
                } else {
                    $currentValue = $prop->getValue($this);
                }
            } else if (isset($this->{$propertyName})) {
                $currentValue = $this->{$propertyName};
            }
            if (static::isEqual($initialValue, $currentValue)) continue;
            
            $resultKey = $propertyName;
            if ($stringKeyConversions) 
                $resultKey = static::{$keyConversionsMethod}(
                    $resultKey, $toolsClass, $caseSensitiveKeysMap
                );
            
            $result[$resultKey] = $currentValue;
        }
        return $result;
    }
}