hnhdigital-os/laravel-model-json

View on GitHub
src/JsonColumnValue.php

Summary

Maintainability
A
35 mins
Test Coverage
<?php

namespace Bluora\LaravelModelJson;

class JsonColumnValue
{
    /**
     * Holds the original data provided from the model.
     *
     * @var string
     */
    private $internal_original_value = '';

    /**
     * Holds the original data provided by the model.
     *
     * @var array
     */
    private $internal_original_data = [];

    /**
     * Holds specific defaults.
     *
     * @var array
     */
    private $internal_defaults = [];

    /**
     * Holds specific options to internally deal with values.
     *
     * @var array
     */
    private $internal_options = [];

    /**
     * Add the data to the object.
     *
     * @return array
     */
    public function __construct(&$attribute_value, $defaults, $options)
    {
        $this->internal_original_value = &$attribute_value;
        $this->internal_original_data = (!is_array($attribute_value)) ? json_decode($this->internal_original_value, true) : $this->internal_original_value;

        // Value was double encoded.
        if (is_string($this->internal_original_data)) {
            $this->internal_original_data = json_decode($this->internal_original_data, true);
        }

        $this->internal_defaults = $defaults;
        $this->internal_options = $options;
        foreach ($this->internal_original_data as $key => $value) {
            $this->$key = $value;
            unset($value);
        }
        foreach ($defaults as $key => $value) {
            if (!isset($this->$key)) {
                $this->$key = $value;
            }
        }
    }

    /**
     * Get the json data original values.
     *
     * @param string|null $key
     * @param mixed       $default
     *
     * @return array
     */
    public function getOriginal($key = null, $default = null)
    {
        if ($key === null) {
            return $this->internal_original_data;
        } elseif (array_key_exists($key, $this->internal_original_data)) {
            return $this->internal_original_data[$key];
        }

        return $default;
    }

    /**
     * Get the current data as an array.
     *
     * @return array
     */
    public function getCurrent()
    {
        $data = [];
        foreach (get_object_vars($this) as $key => $value) {
            if (substr($key, 0, 8) !== 'internal') {
                $data[$key] = $value;
            }
        }

        return $data;
    }

    /**
     * Get the current data json encoded.
     *
     * @return string
     */
    public function getJson()
    {
        $dirty = $this->getDirty();
        if (count($dirty)) {
            $this->internal_original_value = $this->__toString();
        }

        return $this->internal_original_value;
    }

    /**
     * Add json data values that have changed.
     *
     * @return array
     */
    public function getDirty()
    {
        $dirty = [];
        foreach ($this->getCurrent() as $key => $value) {

            // Value is a default value and `no_saving_default_values` option has been enabled
            if (array_key_exists('no_saving_default_values', $this->internal_options)
                && $this->internal_options['no_saving_default_values']
                && array_key_exists($key, $this->internal_defaults)
                && $this->internal_defaults[$key] === $value) {
                // Do nothing
            }

            // Existing value has changed
            elseif (array_key_exists($key, $this->internal_original_data)
                && $this->internal_original_data[$key] !== $value) {
                $dirty[$key] = $value;
            }

            // New value that has been assigned
            elseif (!array_key_exists($key, $this->internal_original_data)) {
                $dirty[$key] = $value;
            }
        }

        return $dirty;
    }

    /**
     * Set value.
     *
     * @param array $data
     */
    public function setValue($key, $value)
    {
        $this->$key = $value;
    }

    /**
     * Set values.
     *
     * @param array $data
     */
    public function setValues($data)
    {
        if (!is_array($data)) {
            return $this;
        }

        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
    }

    /**
     * Track new column additions.
     *
     * @param string $key
     * @param mixed  $value
     */
    public function __set($key, $value)
    {
        $this->$key = $value;
    }

    /**
     * Get a value.
     *
     * @param string $key
     * @param mixed  $value
     */
    public function &__get($key)
    {
        if (!isset($this->$key)) {
            $this->$key = null;
        }

        return $this->$key;
    }

    /**
     * Check if key exists.
     *
     * @param string $key
     *
     * @return bool
     */
    public function __isset($key)
    {
        return isset($this->$key);
    }

    /**
     * Remove a key.
     *
     * @param string $key
     */
    public function __unset($key)
    {
        unset($this->$key);
    }

    /**
     * Convert to json encoded string.
     *
     * @return string
     */
    public function __toString()
    {
        return json_encode($this->getCurrent());
    }
}