<commit_before><?php
/**
 * Webiny Framework (http://www.webiny.com/framework)
 *
 * @copyright Copyright Webiny LTD
 */

namespace Webiny\Component\Entity\Attribute;

use JsonSerializable;
use Webiny\Component\Entity\Attribute\Validation\ValidationException;
use Webiny\Component\Entity\Entity;
use Webiny\Component\Entity\AbstractEntity;
use Webiny\Component\Entity\EntityAttributeBuilder;
use Webiny\Component\StdLib\StdLibTrait;


/**
 * AbstractAttribute
 * @package Webiny\Component\Entity\AttributeType
 */
abstract class AbstractAttribute implements JsonSerializable
{
    use StdLibTrait;

    /**
     * Entity this attribute belongs to
     *
     * @var AbstractEntity
     */
    protected $parent;

    /**
     * Attribute name
     * @var null|string
     */
    protected $attribute = '';

    /**
     * Default value
     * @var null
     */
    protected $defaultValue = null;

    /**
     * Actual value
     * @var null
     */
    protected $value = null;

    /**
     * Is this attribute required
     * @var bool
     */
    protected $required = false;

    /**
     * If true - updating will be disabled
     * @var bool
     */
    protected $once = false;

    /**
     * If true - mass populate will skip this attribute
     * @var bool
     */
    protected $skipOnPopulate = false;

    /**
     * Attribute validators
     * @var array
     */
    protected $validators = [];

    /**
     * Validation messages
     * @var array
     */
    protected $validationMessages = [];

    /**
     * If true - will store this attribute to database
     * @var bool
     */
    protected $storeToDb = true;

    /**
     * If true - will wait until mass populate is finished and assign the value afterwards
     * @var bool
     */
    protected $setAfterPopulate = false;

    /**
     * Value to trigger $onSetCallback
     * @var null
     */
    protected $onSetValue = null;

    /**
     * Callback to execute before setting a new value.
     * The value returned from the callback will be set as a new attribute value.
     * @var null
     */
    protected $onSetCallback = null;

    /**
     * Callback to execute when attribute value is being accessed.
     * The value returned from the callback will be returned as attribute value.
     * @var null
     */
    protected $onGetCallback = null;

    /**
     * Callback to execute when toArray() is called on Entity.
     * The value returned from the callback will be returned as attribute value.
     * @var null
     */
    protected $onToArrayCallback = null;

    /**
     * If true - this attribute will be included in the output of entity's toArray method
     * @var null
     */
    protected $toArrayDefault = null;

    /**
     * Callback to execute when attribute is being stored to database.
     * The value returned from the callback will be returned as attribute value for database.
     * @var null
     */
    protected $onToDbCallback = null;

    /**
     * Callback to execute when attribute is being loaded from database.
     * The value returned from the callback will be set as attribute value
     * @var null
     */
    protected $onFromDbCallback = null;

    /**
     * @var string
     */
    protected $validatorInterface = '\Webiny\Component\Entity\Attribute\Validation\ValidatorInterface';

    /**
     * @param string         $name
     * @param AbstractEntity $parent
     */
    public function __construct($name = null, AbstractEntity $parent = null)
    {
        $this->attribute = $name;
        $this->parent = $parent;
    }

    /**
     * Get attribute value as string
     *
     * @return string
     */
    public function __toString()
    {
        $defaultValue = $this->getDefaultValue();
        if ($this->isNull($this->value) && !$this->isNull($defaultValue)) {
            return (string)$defaultValue;
        }

        return $this->isNull($this->value) ? '' : (string)$this->value;
    }

    /**
     * Get attribute name
     * @return string
     */
    public function getName()
    {
        return $this->attribute;
    }

    /**
     * Set attribute name
     *
     * @param string $attribute
     *
     * @return $this
     */
    public function setName($attribute)
    {
        $this->attribute = $attribute;

        return $this;
    }

    public function setParent(AbstractEntity $entity)
    {
        $this->parent = $entity;

        return $this;
    }

    public function hasValue()
    {
        if ($this->value !== null) {
            return true;
        }

        return false;
    }

    /**
     * Get entity instance this attribute belongs to
     *
     * @return AbstractEntity
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Get value that will be stored to database<br>
     *
     * If no value is set, default value will be used, and that value will also be assigned as a new attribute value.
     *
     * @return string
     */
    public function getDbValue()
    {
        $value = $this->getValue();
        if ($this->isNull($this->value)) {
            $this->value = $value;
        }

        $value = $this->processToDbValue($value);

        return $this->value = $value;
    }

    /**
     * Should this attribute value be stored to DB
     *
     * @return bool
     */
    public function getStoreToDb()
    {
        return $this->storeToDb;
    }

    /**
     * Get value that will be used to represent this attribute when converting AbstractEntity to array
     *
     * @param array $params
     *
     * @return string
     */
    public function toArray($params = [])
    {
        return $this->processToArrayValue($this->getValue($params));
    }

    /**
     * Set callback that will be used to process getToArrayValue() call
     *
     * @param $callback
     *
     * @return $this
     */
    public function onToArray($callback)
    {
        $this->onToArrayCallback = $callback;

        return $this;
    }

    /**
     * Get toArrayDefault flag
     *
     * @return bool
     */
    public function getToArrayDefault()
    {
        return $this->toArrayDefault;
    }

    /**
     * Set if this attribute will be by default included in the output of entity's toArray method
     *
     * @param boolean $flag
     *
     * @return $this
     */
    public function setToArrayDefault($flag = true)
    {
        $this->toArrayDefault = $flag;

        return $this;
    }

    /**
     * Set callback that will be used to process getDbValue() call
     *
     * @param $callback
     *
     * @return $this
     */
    public function onToDb($callback)
    {
        $this->onToDbCallback = $callback;

        return $this;
    }

    /**
     * Set callback that will be used to process value when data is loaded from DB
     *
     * @param $callback
     *
     * @return $this
     */
    public function onFromDb($callback)
    {
        $this->onFromDbCallback = $callback;

        return $this;
    }

    public function hasToArrayCallback()
    {
        return $this->onToArrayCallback !== null;
    }

    /**
     * Create new attribute or get name of current attribute
     *
     * @param null|string $attribute
     *
     * @return EntityAttributeBuilder|string
     */
    public function attr($attribute = null)
    {
        if ($this->isNull($attribute)) {
            return $this->attribute;
        }

        return $this->parent->attr($attribute);
    }

    /**
     * Set required flag
     *
     * @param boolean $flag
     *
     * @return $this
     */
    public function setRequired($flag = true)
    {
        $this->required = $flag;

        return $this;
    }

    /**
     * Get required flag
     *
     * @return $this
     */
    public function isRequired()
    {
        return $this->required;<commit_msg>Fixed wrong type hint in return value<commit_after><?php
/**
 * Webiny Framework (http://www.webiny.com/framework)
 *
 * @copyright Copyright Webiny LTD
 */

namespace Webiny\Component\Entity\Attribute;

use JsonSerializable;
use Webiny\Component\Entity\Attribute\Validation\ValidationException;
use Webiny\Component\Entity\Entity;
use Webiny\Component\Entity\AbstractEntity;
use Webiny\Component\Entity\EntityAttributeBuilder;
use Webiny\Component\StdLib\StdLibTrait;


/**
 * AbstractAttribute
 * @package Webiny\Component\Entity\AttributeType
 */
abstract class AbstractAttribute implements JsonSerializable
{
    use StdLibTrait;

    /**
     * Entity this attribute belongs to
     *
     * @var AbstractEntity
     */
    protected $parent;

    /**
     * Attribute name
     * @var null|string
     */
    protected $attribute = '';

    /**
     * Default value
     * @var null
     */
    protected $defaultValue = null;

    /**
     * Actual value
     * @var null
     */
    protected $value = null;

    /**
     * Is this attribute required
     * @var bool
     */
    protected $required = false;

    /**
     * If true - updating will be disabled
     * @var bool
     */
    protected $once = false;

    /**
     * If true - mass populate will skip this attribute
     * @var bool
     */
    protected $skipOnPopulate = false;

    /**
     * Attribute validators
     * @var array
     */
    protected $validators = [];

    /**
     * Validation messages
     * @var array
     */
    protected $validationMessages = [];

    /**
     * If true - will store this attribute to database
     * @var bool
     */
    protected $storeToDb = true;

    /**
     * If true - will wait until mass populate is finished and assign the value afterwards
     * @var bool
     */
    protected $setAfterPopulate = false;

    /**
     * Value to trigger $onSetCallback
     * @var null
     */
    protected $onSetValue = null;

    /**
     * Callback to execute before setting a new value.
     * The value returned from the callback will be set as a new attribute value.
     * @var null
     */
    protected $onSetCallback = null;

    /**
     * Callback to execute when attribute value is being accessed.
     * The value returned from the callback will be returned as attribute value.
     * @var null
     */
    protected $onGetCallback = null;

    /**
     * Callback to execute when toArray() is called on Entity.
     * The value returned from the callback will be returned as attribute value.
     * @var null
     */
    protected $onToArrayCallback = null;

    /**
     * If true - this attribute will be included in the output of entity's toArray method
     * @var null
     */
    protected $toArrayDefault = null;

    /**
     * Callback to execute when attribute is being stored to database.
     * The value returned from the callback will be returned as attribute value for database.
     * @var null
     */
    protected $onToDbCallback = null;

    /**
     * Callback to execute when attribute is being loaded from database.
     * The value returned from the callback will be set as attribute value
     * @var null
     */
    protected $onFromDbCallback = null;

    /**
     * @var string
     */
    protected $validatorInterface = '\Webiny\Component\Entity\Attribute\Validation\ValidatorInterface';

    /**
     * @param string         $name
     * @param AbstractEntity $parent
     */
    public function __construct($name = null, AbstractEntity $parent = null)
    {
        $this->attribute = $name;
        $this->parent = $parent;
    }

    /**
     * Get attribute value as string
     *
     * @return string
     */
    public function __toString()
    {
        $defaultValue = $this->getDefaultValue();
        if ($this->isNull($this->value) && !$this->isNull($defaultValue)) {
            return (string)$defaultValue;
        }

        return $this->isNull($this->value) ? '' : (string)$this->value;
    }

    /**
     * Get attribute name
     * @return string
     */
    public function getName()
    {
        return $this->attribute;
    }

    /**
     * Set attribute name
     *
     * @param string $attribute
     *
     * @return $this
     */
    public function setName($attribute)
    {
        $this->attribute = $attribute;

        return $this;
    }

    public function setParent(AbstractEntity $entity)
    {
        $this->parent = $entity;

        return $this;
    }

    public function hasValue()
    {
        if ($this->value !== null) {
            return true;
        }

        return false;
    }

    /**
     * Get entity instance this attribute belongs to
     *
     * @return AbstractEntity
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * Get value that will be stored to database<br>
     *
     * If no value is set, default value will be used, and that value will also be assigned as a new attribute value.
     *
     * @return string
     */
    public function getDbValue()
    {
        $value = $this->getValue();
        if ($this->isNull($this->value)) {
            $this->value = $value;
        }

        $value = $this->processToDbValue($value);

        return $this->value = $value;
    }

    /**
     * Should this attribute value be stored to DB
     *
     * @return bool
     */
    public function getStoreToDb()
    {
        return $this->storeToDb;
    }

    /**
     * Get value that will be used to represent this attribute when converting AbstractEntity to array
     *
     * @param array $params
     *
     * @return string
     */
    public function toArray($params = [])
    {
        return $this->processToArrayValue($this->getValue($params));
    }

    /**
     * Set callback that will be used to process getToArrayValue() call
     *
     * @param $callback
     *
     * @return $this
     */
    public function onToArray($callback)
    {
        $this->onToArrayCallback = $callback;

        return $this;
    }

    /**
     * Get toArrayDefault flag
     *
     * @return bool
     */
    public function getToArrayDefault()
    {
        return $this->toArrayDefault;
    }

    /**
     * Set if this attribute will be by default included in the output of entity's toArray method
     *
     * @param boolean $flag
     *
     * @return $this
     */
    public function setToArrayDefault($flag = true)
    {
        $this->toArrayDefault = $flag;

        return $this;
    }

    /**
     * Set callback that will be used to process getDbValue() call
     *
     * @param $callback
     *
     * @return $this
     */
    public function onToDb($callback)
    {
        $this->onToDbCallback = $callback;

        return $this;
    }

    /**
     * Set callback that will be used to process value when data is loaded from DB
     *
     * @param $callback
     *
     * @return $this
     */
    public function onFromDb($callback)
    {
        $this->onFromDbCallback = $callback;

        return $this;
    }

    public function hasToArrayCallback()
    {
        return $this->onToArrayCallback !== null;
    }

    /**
     * Create new attribute or get name of current attribute
     *
     * @param null|string $attribute
     *
     * @return EntityAttributeBuilder|string
     */
    public function attr($attribute = null)
    {
        if ($this->isNull($attribute)) {
            return $this->attribute;
        }

        return $this->parent->attr($attribute);
    }

    /**
     * Set required flag
     *
     * @param boolean $flag
     *
     * @return $this
     */
    public function setRequired($flag = true)
    {
        $this->required = $flag;

        return $this;
    }

    /**
     * Get required flag
     *
     * @return bool
     */
    public function isRequired()
    {
        return $this->required;
{'fraction_non_alphanumeric': 0.10642096537652235, 'fraction_numerical': 0.0, 'mean_word_length': 1.937628769432478, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '7247638', 'n_tokens_mistral': 4386, 'n_tokens_neox': 4296, 'n_words': 1303}