briannesbitt / Carbon
1
<?php
2

3
/**
4
 * This file is part of the Carbon package.
5
 *
6
 * (c) Brian Nesbitt <brian@nesbot.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace Carbon\Traits;
12

13
use Carbon\Exceptions\InvalidFormatException;
14
use DateTimeZone;
15

16
/**
17
 * Trait Serialization.
18
 *
19
 * Serialization and JSON stuff.
20
 *
21
 * Depends on the following properties:
22
 *
23
 * @property int $year
24
 * @property int $month
25
 * @property int $daysInMonth
26
 * @property int $quarter
27
 *
28
 * Depends on the following methods:
29
 *
30
 * @method string|static locale(string $locale = null, string ...$fallbackLocales)
31
 * @method string        toJSON()
32
 */
33
trait Serialization
34
{
35
    use ObjectInitialisation;
36

37
    /**
38
     * The custom Carbon JSON serializer.
39
     *
40
     * @var callable|null
41
     */
42
    protected static $serializer;
43

44
    /**
45
     * List of key to use for dump/serialization.
46
     *
47
     * @var string[]
48
     */
49
    protected $dumpProperties = ['date', 'timezone_type', 'timezone'];
50

51
    /**
52
     * Locale to dump comes here before serialization.
53
     *
54
     * @var string|null
55
     */
56
    protected $dumpLocale = null;
57

58
    /**
59
     * Return a serialized string of the instance.
60
     *
61
     * @return string
62
     */
63 1
    public function serialize()
64
    {
65 1
        return serialize($this);
66
    }
67

68
    /**
69
     * Create an instance from a serialized string.
70
     *
71
     * @param string $value
72
     *
73
     * @throws InvalidFormatException
74
     *
75
     * @return static
76
     */
77 1
    public static function fromSerialized($value)
78
    {
79 1
        $instance = @unserialize("$value");
80

81 1
        if (!$instance instanceof static) {
82 1
            throw new InvalidFormatException("Invalid serialized value: $value");
83
        }
84

85 1
        return $instance;
86
    }
87

88
    /**
89
     * The __set_state handler.
90
     *
91
     * @param string|array $dump
92
     *
93
     * @return static
94
     */
95 1
    public static function __set_state($dump)
96
    {
97 1
        if (\is_string($dump)) {
98 1
            return static::parse($dump);
99
        }
100

101
        /** @var \DateTimeInterface $date */
102 1
        $date = get_parent_class(static::class) && method_exists(parent::class, '__set_state')
103 1
            ? parent::__set_state((array) $dump)
104 1
            : (object) $dump;
105

106 1
        return static::instance($date);
107
    }
108

109
    /**
110
     * Returns the list of properties to dump on serialize() called on.
111
     *
112
     * @return array
113
     */
114 1
    public function __sleep()
115
    {
116 1
        $properties = $this->dumpProperties;
117

118 1
        if ($this->localTranslator ?? null) {
119 1
            $properties[] = 'dumpLocale';
120 1
            $this->dumpLocale = $this->locale ?? null;
121
        }
122

123 1
        return $properties;
124
    }
125

126
    /**
127
     * Set locale if specified on unserialize() called.
128
     */
129 1
    public function __wakeup()
130
    {
131
        // FatalError occurs when calling __wakeup method in PHP 7.4 or later.
132
        // @codeCoverageIgnoreStart
133
        if (version_compare(PHP_VERSION, '7.4.0-dev', '>=')) {
134
            parent::__construct($this->{$this->dumpProperties[0]}, $this->timezone !== null ? new DateTimeZone($this->timezone) : null);
135
        } elseif (get_parent_class() && method_exists(parent::class, '__wakeup')) {
136
            parent::__wakeup();
137
        }
138
        // @codeCoverageIgnoreEnd
139

140 1
        $this->constructedObjectId = spl_object_hash($this);
141

142 1
        if (isset($this->dumpLocale)) {
143 1
            $this->locale($this->dumpLocale);
144 1
            $this->dumpLocale = null;
145
        }
146

147 1
        $this->cleanupDumpProperties();
148
    }
149

150
    /**
151
     * Prepare the object for JSON serialization.
152
     *
153
     * @return array|string
154
     */
155 1
    public function jsonSerialize()
156
    {
157 1
        $serializer = $this->localSerializer ?? static::$serializer;
158

159 1
        if ($serializer) {
160 1
            return \is_string($serializer)
161 1
                ? $this->rawFormat($serializer)
162 1
                : $serializer($this);
163
        }
164

165 1
        return $this->toJSON();
166
    }
167

168
    /**
169
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
170
     *             You should rather transform Carbon object before the serialization.
171
     *
172
     * JSON serialize all Carbon instances using the given callback.
173
     *
174
     * @param callable $callback
175
     *
176
     * @return void
177
     */
178 1
    public static function serializeUsing($callback)
179
    {
180 1
        static::$serializer = $callback;
181
    }
182

183
    /**
184
     * Cleanup properties attached to the public scope of DateTime when a dump of the date is requested.
185
     * foreach ($date as $_) {}
186
     * serializer($date)
187
     * var_export($date)
188
     * get_object_vars($date)
189
     */
190 1
    public function cleanupDumpProperties()
191
    {
192 1
        foreach ($this->dumpProperties as $property) {
193 1
            if (isset($this->$property)) {
194 1
                unset($this->$property);
195
            }
196
        }
197

198 1
        return $this;
199
    }
200
}

Read our documentation on viewing source code .

Loading