Serialization.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. /**
  3. * This file is part of the Carbon package.
  4. *
  5. * (c) Brian Nesbitt <brian@nesbot.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Carbon\Traits;
  11. use InvalidArgumentException;
  12. /**
  13. * Trait Serialization.
  14. *
  15. * Serialization and JSON stuff.
  16. *
  17. * Depends on the following properties:
  18. *
  19. * @property int $year
  20. * @property int $month
  21. * @property int $daysInMonth
  22. * @property int $quarter
  23. *
  24. * Depends on the following methods:
  25. *
  26. * @method string|static locale(string $locale = null)
  27. * @method string toJSON()
  28. */
  29. trait Serialization
  30. {
  31. use ObjectInitialisation;
  32. /**
  33. * The custom Carbon JSON serializer.
  34. *
  35. * @var callable|null
  36. */
  37. protected static $serializer;
  38. /**
  39. * List of key to use for dump/serialization.
  40. *
  41. * @var string[]
  42. */
  43. protected $dumpProperties = ['date', 'timezone_type', 'timezone'];
  44. /**
  45. * Locale to dump comes here before serialization.
  46. *
  47. * @var string|null
  48. */
  49. protected $dumpLocale = null;
  50. /**
  51. * Return a serialized string of the instance.
  52. *
  53. * @return string
  54. */
  55. public function serialize()
  56. {
  57. return serialize($this);
  58. }
  59. /**
  60. * Create an instance from a serialized string.
  61. *
  62. * @param string $value
  63. *
  64. * @throws \InvalidArgumentException
  65. *
  66. * @return static
  67. */
  68. public static function fromSerialized($value)
  69. {
  70. $instance = @unserialize("$value");
  71. if (!$instance instanceof static) {
  72. throw new InvalidArgumentException('Invalid serialized value.');
  73. }
  74. return $instance;
  75. }
  76. /**
  77. * The __set_state handler.
  78. *
  79. * @param string|array $dump
  80. *
  81. * @return static
  82. */
  83. public static function __set_state($dump)
  84. {
  85. if (is_string($dump)) {
  86. return static::parse($dump);
  87. }
  88. /** @var \DateTimeInterface $date */
  89. $date = get_parent_class(static::class) && method_exists(parent::class, '__set_state')
  90. ? parent::__set_state((array) $dump)
  91. : (object) $dump;
  92. return static::instance($date);
  93. }
  94. /**
  95. * Returns the list of properties to dump on serialize() called on.
  96. *
  97. * @return array
  98. */
  99. public function __sleep()
  100. {
  101. $properties = $this->dumpProperties;
  102. if ($this->localTranslator ?? null) {
  103. $properties[] = 'dumpLocale';
  104. $this->dumpLocale = $this->locale ?? null;
  105. }
  106. return $properties;
  107. }
  108. /**
  109. * Set locale if specified on unserialize() called.
  110. */
  111. public function __wakeup()
  112. {
  113. if (get_parent_class() && method_exists(parent::class, '__wakeup')) {
  114. parent::__wakeup();
  115. }
  116. $this->constructedObjectId = spl_object_hash($this);
  117. if (isset($this->dumpLocale)) {
  118. $this->locale($this->dumpLocale);
  119. $this->dumpLocale = null;
  120. }
  121. $this->cleanupDumpProperties();
  122. }
  123. /**
  124. * Prepare the object for JSON serialization.
  125. *
  126. * @return array|string
  127. */
  128. public function jsonSerialize()
  129. {
  130. $serializer = $this->localSerializer ?? static::$serializer;
  131. if ($serializer) {
  132. return is_string($serializer)
  133. ? $this->rawFormat($serializer)
  134. : call_user_func($serializer, $this);
  135. }
  136. return $this->toJSON();
  137. }
  138. /**
  139. * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
  140. * You should rather transform Carbon object before the serialization.
  141. *
  142. * JSON serialize all Carbon instances using the given callback.
  143. *
  144. * @param callable $callback
  145. *
  146. * @return void
  147. */
  148. public static function serializeUsing($callback)
  149. {
  150. static::$serializer = $callback;
  151. }
  152. /**
  153. * Cleanup properties attached to the public scope of DateTime when a dump of the date is requested.
  154. * foreach ($date as $_) {}
  155. * serializer($date)
  156. * var_export($date)
  157. * get_object_vars($date)
  158. */
  159. public function cleanupDumpProperties()
  160. {
  161. foreach ($this->dumpProperties as $property) {
  162. if (isset($this->$property)) {
  163. unset($this->$property);
  164. }
  165. }
  166. return $this;
  167. }
  168. }