Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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
 
12
namespace Carbon\Traits;
13
 
14
use Carbon\Exceptions\InvalidFormatException;
15
use ReturnTypeWillChange;
16
use Throwable;
17
 
18
/**
19
 * Trait Serialization.
20
 *
21
 * Serialization and JSON stuff.
22
 *
23
 * Depends on the following properties:
24
 *
25
 * @property int $year
26
 * @property int $month
27
 * @property int $daysInMonth
28
 * @property int $quarter
29
 *
30
 * Depends on the following methods:
31
 *
32
 * @method string|static locale(string $locale = null, string ...$fallbackLocales)
33
 * @method string        toJSON()
34
 */
35
trait Serialization
36
{
37
    use ObjectInitialisation;
38
 
39
    /**
40
     * The custom Carbon JSON serializer.
41
     *
42
     * @var callable|null
43
     */
44
    protected static $serializer;
45
 
46
    /**
47
     * List of key to use for dump/serialization.
48
     *
49
     * @var string[]
50
     */
51
    protected $dumpProperties = ['date', 'timezone_type', 'timezone'];
52
 
53
    /**
54
     * Locale to dump comes here before serialization.
55
     *
56
     * @var string|null
57
     */
58
    protected $dumpLocale;
59
 
60
    /**
61
     * Embed date properties to dump in a dedicated variables so it won't overlap native
62
     * DateTime ones.
63
     *
64
     * @var array|null
65
     */
66
    protected $dumpDateProperties;
67
 
68
    /**
69
     * Return a serialized string of the instance.
70
     *
71
     * @return string
72
     */
73
    public function serialize()
74
    {
75
        return serialize($this);
76
    }
77
 
78
    /**
79
     * Create an instance from a serialized string.
80
     *
81
     * @param string $value
82
     *
83
     * @throws InvalidFormatException
84
     *
85
     * @return static
86
     */
87
    public static function fromSerialized($value)
88
    {
89
        $instance = @unserialize((string) $value);
90
 
91
        if (!$instance instanceof static) {
92
            throw new InvalidFormatException("Invalid serialized value: $value");
93
        }
94
 
95
        return $instance;
96
    }
97
 
98
    /**
99
     * The __set_state handler.
100
     *
101
     * @param string|array $dump
102
     *
103
     * @return static
104
     */
105
    #[ReturnTypeWillChange]
106
    public static function __set_state($dump)
107
    {
108
        if (\is_string($dump)) {
109
            return static::parse($dump);
110
        }
111
 
112
        /** @var \DateTimeInterface $date */
113
        $date = get_parent_class(static::class) && method_exists(parent::class, '__set_state')
114
            ? parent::__set_state((array) $dump)
115
            : (object) $dump;
116
 
117
        return static::instance($date);
118
    }
119
 
120
    /**
121
     * Returns the list of properties to dump on serialize() called on.
122
     *
123
     * Only used by PHP < 7.4.
124
     *
125
     * @return array
126
     */
127
    public function __sleep()
128
    {
129
        $properties = $this->getSleepProperties();
130
 
131
        if ($this->localTranslator ?? null) {
132
            $properties[] = 'dumpLocale';
133
            $this->dumpLocale = $this->locale ?? null;
134
        }
135
 
136
        return $properties;
137
    }
138
 
139
    /**
140
     * Returns the values to dump on serialize() called on.
141
     *
142
     * Only used by PHP >= 7.4.
143
     *
144
     * @return array
145
     */
146
    public function __serialize(): array
147
    {
148
        // @codeCoverageIgnoreStart
149
        if (isset($this->timezone_type)) {
150
            return [
151
                'date' => $this->date ?? null,
152
                'timezone_type' => $this->timezone_type,
153
                'timezone' => $this->timezone ?? null,
154
            ];
155
        }
156
        // @codeCoverageIgnoreEnd
157
 
158
        $timezone = $this->getTimezone();
159
        $export = [
160
            'date' => $this->format('Y-m-d H:i:s.u'),
161
            'timezone_type' => $timezone->getType(),
162
            'timezone' => $timezone->getName(),
163
        ];
164
 
165
        // @codeCoverageIgnoreStart
166
        if (\extension_loaded('msgpack') && isset($this->constructedObjectId)) {
167
            $export['dumpDateProperties'] = [
168
                'date' => $this->format('Y-m-d H:i:s.u'),
169
                'timezone' => serialize($this->timezone ?? null),
170
            ];
171
        }
172
        // @codeCoverageIgnoreEnd
173
 
174
        if ($this->localTranslator ?? null) {
175
            $export['dumpLocale'] = $this->locale ?? null;
176
        }
177
 
178
        return $export;
179
    }
180
 
181
    /**
182
     * Set locale if specified on unserialize() called.
183
     *
184
     * Only used by PHP < 7.4.
185
     *
186
     * @return void
187
     */
188
    #[ReturnTypeWillChange]
189
    public function __wakeup()
190
    {
191
        if (parent::class && method_exists(parent::class, '__wakeup')) {
192
            // @codeCoverageIgnoreStart
193
            try {
194
                parent::__wakeup();
195
            } catch (Throwable $exception) {
196
                try {
197
                    // FatalError occurs when calling msgpack_unpack() in PHP 7.4 or later.
198
                    ['date' => $date, 'timezone' => $timezone] = $this->dumpDateProperties;
199
                    parent::__construct($date, unserialize($timezone));
200
                } catch (Throwable $ignoredException) {
201
                    throw $exception;
202
                }
203
            }
204
            // @codeCoverageIgnoreEnd
205
        }
206
 
207
        $this->constructedObjectId = spl_object_hash($this);
208
 
209
        if (isset($this->dumpLocale)) {
210
            $this->locale($this->dumpLocale);
211
            $this->dumpLocale = null;
212
        }
213
 
214
        $this->cleanupDumpProperties();
215
    }
216
 
217
    /**
218
     * Set locale if specified on unserialize() called.
219
     *
220
     * Only used by PHP >= 7.4.
221
     *
222
     * @return void
223
     */
224
    public function __unserialize(array $data): void
225
    {
226
        // @codeCoverageIgnoreStart
227
        try {
228
            $this->__construct($data['date'] ?? null, $data['timezone'] ?? null);
229
        } catch (Throwable $exception) {
230
            if (!isset($data['dumpDateProperties']['date'], $data['dumpDateProperties']['timezone'])) {
231
                throw $exception;
232
            }
233
 
234
            try {
235
                // FatalError occurs when calling msgpack_unpack() in PHP 7.4 or later.
236
                ['date' => $date, 'timezone' => $timezone] = $data['dumpDateProperties'];
237
                $this->__construct($date, unserialize($timezone));
238
            } catch (Throwable $ignoredException) {
239
                throw $exception;
240
            }
241
        }
242
        // @codeCoverageIgnoreEnd
243
 
244
        if (isset($data['dumpLocale'])) {
245
            $this->locale($data['dumpLocale']);
246
        }
247
    }
248
 
249
    /**
250
     * Prepare the object for JSON serialization.
251
     *
252
     * @return array|string
253
     */
254
    #[ReturnTypeWillChange]
255
    public function jsonSerialize()
256
    {
257
        $serializer = $this->localSerializer ?? static::$serializer;
258
 
259
        if ($serializer) {
260
            return \is_string($serializer)
261
                ? $this->rawFormat($serializer)
262
                : $serializer($this);
263
        }
264
 
265
        return $this->toJSON();
266
    }
267
 
268
    /**
269
     * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
270
     *             You should rather transform Carbon object before the serialization.
271
     *
272
     * JSON serialize all Carbon instances using the given callback.
273
     *
274
     * @param callable $callback
275
     *
276
     * @return void
277
     */
278
    public static function serializeUsing($callback)
279
    {
280
        static::$serializer = $callback;
281
    }
282
 
283
    /**
284
     * Cleanup properties attached to the public scope of DateTime when a dump of the date is requested.
285
     * foreach ($date as $_) {}
286
     * serializer($date)
287
     * var_export($date)
288
     * get_object_vars($date)
289
     */
290
    public function cleanupDumpProperties()
291
    {
292
        // @codeCoverageIgnoreStart
293
        if (PHP_VERSION < 8.2) {
294
            foreach ($this->dumpProperties as $property) {
295
                if (isset($this->$property)) {
296
                    unset($this->$property);
297
                }
298
            }
299
        }
300
        // @codeCoverageIgnoreEnd
301
 
302
        return $this;
303
    }
304
 
305
    private function getSleepProperties(): array
306
    {
307
        $properties = $this->dumpProperties;
308
 
309
        // @codeCoverageIgnoreStart
310
        if (!\extension_loaded('msgpack')) {
311
            return $properties;
312
        }
313
 
314
        if (isset($this->constructedObjectId)) {
315
            $this->dumpDateProperties = [
316
                'date' => $this->format('Y-m-d H:i:s.u'),
317
                'timezone' => serialize($this->timezone ?? null),
318
            ];
319
 
320
            $properties[] = 'dumpDateProperties';
321
        }
322
 
323
        return $properties;
324
        // @codeCoverageIgnoreEnd
325
    }
326
}