<commit_before><?php
namespace PSFS\base\dto;

use Propel\Runtime\ActiveRecord\ActiveRecordInterface;
use PSFS\base\Logger;
use PSFS\base\Request;
use PSFS\base\Singleton;
use PSFS\base\types\helpers\InjectorHelper;

/**
 * Class Dto
 * @package PSFS\base\dto
 */
class Dto extends Singleton
{

    public function __construct($hydrate = true)
    {
        parent::__construct();
        if($hydrate) {
            $this->fromArray(Request::getInstance()->getData());
        }
    }

    /**
     * ToArray wrapper
     * @return array
     */
    public function toArray()
    {
        return $this->__toArray();
    }

    /**
     * Convert dto to array representation
     * @return array
     */
    public function __toArray()
    {
        $dto = array();
        try {
            $reflectionClass = new \ReflectionClass($this);
            $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC);
            if (count($properties) > 0) {
                /** @var \ReflectionProperty $property */
                foreach ($properties as $property) {
                    $value = $property->getValue($this);
                    if(is_object($value) && method_exists($value, 'toArray')) {
                        $dto[$property->getName()] = $value->toArray();
                    } else {
                        $dto[$property->getName()] = $property->getValue($this);
                    }
                }
            }
        } catch (\Exception $e) {
            Logger::log(get_class($this) . ': ' . $e->getMessage(), LOG_ERR);
        }
        return $dto;
    }

    /**
     * Convert to string representation
     * @return string
     */
    public function __toString()
    {
        return get_class($this);
    }

    /**
     * @param array $properties
     * @param string $key
     * @param mixed $value
     */
    protected function parseDtoField(array $properties, $key, $value = null) {
        $type = 'string';
        $is_array = false;
        if(array_key_exists($key, $properties)) {
            $type = $properties[$key];
            if(preg_match('/(\[\]|Array)/i', $type)) {
                $type = preg_replace('/(\[\]|Array)/i', '', $type);
                $is_array = true;
            }
        }
        $reflector = (class_exists($type)) ? new \ReflectionClass($type) : null;
        if(null !== $reflector && $reflector->isSubclassOf(Dto::class)) {
            if($is_array) {
                $this->$key = [];
                foreach($value as $data) {
                    $dto = new $type(false);
                    $dto->fromArray($data);
                    array_push($this->$key, $dto);
                }
            } else {
                $this->$key = new $type(false);
                $this->$key->fromArray($value);
            }
        } else {
            switch($type) {
                default:
                case 'string':
                    $this->$key = $value;
                    break;
                case 'integer':
                    $this->$key = (integer)$value;
                    break;<commit_msg>Improved Dto creation<commit_after><?php
namespace PSFS\base\dto;

use Propel\Runtime\ActiveRecord\ActiveRecordInterface;
use PSFS\base\config\Config;
use PSFS\base\Logger;
use PSFS\base\Request;
use PSFS\base\Singleton;
use PSFS\base\types\helpers\InjectorHelper;

/**
 * Class Dto
 * @package PSFS\base\dto
 */
class Dto extends Singleton
{

    public function __construct($hydrate = true)
    {
        parent::__construct();
        if($hydrate) {
            $this->fromArray(Request::getInstance()->getData());
        }
    }

    /**
     * ToArray wrapper
     * @return array
     */
    public function toArray()
    {
        return $this->__toArray();
    }

    /**
     * Convert dto to array representation
     * @return array
     */
    public function __toArray()
    {
        $dto = array();
        try {
            $reflectionClass = new \ReflectionClass($this);
            $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PUBLIC);
            if (count($properties) > 0) {
                /** @var \ReflectionProperty $property */
                foreach ($properties as $property) {
                    $value = $property->getValue($this);
                    if(is_object($value) && method_exists($value, 'toArray')) {
                        $dto[$property->getName()] = $value->toArray();
                    } else {
                        $dto[$property->getName()] = $property->getValue($this);
                    }
                }
            }
        } catch (\Exception $e) {
            Logger::log(get_class($this) . ': ' . $e->getMessage(), LOG_ERR);
        }
        return $dto;
    }

    /**
     * Convert to string representation
     * @return string
     */
    public function __toString()
    {
        return get_class($this);
    }

    /**
     * @param array $properties
     * @param string $key
     * @param mixed $value
     */
    protected function parseDtoField(array $properties, $key, $value = null) {
        $type = 'string';
        $is_array = false;
        if(array_key_exists($key, $properties)) {
            $type = $properties[$key];
            if(preg_match('/(\[\]|Array)/i', $type)) {
                $type = preg_replace('/(\[\]|Array)/i', '', $type);
                $is_array = true;
            }
        }
        $reflector = (class_exists($type)) ? new \ReflectionClass($type) : null;
        if(null !== $reflector && $reflector->isSubclassOf(Dto::class)) {
            if($is_array) {
                $this->$key = [];
                foreach($value as $data) {
                    if(null !== $data) {
                        $dto = new $type(false);
                        $dto->fromArray($data);
                        array_push($this->$key, $dto);
                    }
                }
            } else {
                if(null !== $value) {
                    $this->$key = new $type(false);
                    $this->$key->fromArray($value);
                } elseif(Config::getParam('api.default.null', true)) {
                    $this->$key = null;
                }
            }
        } else {
            switch($type) {
                default:
                case 'string':
                    $this->$key = $value;
                    break;
                case 'integer':
                    $this->$key = (integer)$value;
                    break;
{'fraction_non_alphanumeric': 0.14659283187201969, 'fraction_numerical': 0.00030764497769573913, 'mean_word_length': 1.4911877394636015, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3584367', 'n_tokens_mistral': 1840, 'n_tokens_neox': 1774, 'n_words': 335}