Boundaries.php
4 years ago
Cast.php
4 years ago
Comparison.php
2 years ago
Converter.php
2 years ago
Creator.php
2 years ago
Date.php
9 months ago
DeprecatedProperties.php
4 years ago
Difference.php
2 years ago
IntervalRounding.php
2 years ago
IntervalStep.php
4 years ago
Localization.php
9 months ago
Macro.php
4 years ago
MagicParameter.php
2 years ago
Mixin.php
2 years ago
Modifiers.php
4 years ago
Mutability.php
4 years ago
ObjectInitialisation.php
4 years ago
Options.php
2 years ago
Rounding.php
2 years ago
Serialization.php
2 years ago
Test.php
9 months ago
Timestamp.php
1 year ago
ToStringFormat.php
3 years ago
Units.php
2 years ago
Week.php
4 years ago
index.php
3 years ago
Creator.php
406 lines
| 1 | <?php |
| 2 | namespace MailPoetVendor\Carbon\Traits; |
| 3 | if (!defined('ABSPATH')) exit; |
| 4 | use MailPoetVendor\Carbon\Carbon; |
| 5 | use MailPoetVendor\Carbon\CarbonImmutable; |
| 6 | use MailPoetVendor\Carbon\CarbonInterface; |
| 7 | use MailPoetVendor\Carbon\Exceptions\InvalidDateException; |
| 8 | use MailPoetVendor\Carbon\Exceptions\InvalidFormatException; |
| 9 | use MailPoetVendor\Carbon\Exceptions\OutOfRangeException; |
| 10 | use MailPoetVendor\Carbon\Translator; |
| 11 | use Closure; |
| 12 | use MailPoetVendor\DateMalformedStringException; |
| 13 | use DateTimeImmutable; |
| 14 | use DateTimeInterface; |
| 15 | use DateTimeZone; |
| 16 | use Exception; |
| 17 | use ReturnTypeWillChange; |
| 18 | trait Creator |
| 19 | { |
| 20 | use ObjectInitialisation; |
| 21 | protected static $lastErrors; |
| 22 | public function __construct($time = null, $tz = null) |
| 23 | { |
| 24 | if ($time instanceof DateTimeInterface) { |
| 25 | $time = $this->constructTimezoneFromDateTime($time, $tz)->format('Y-m-d H:i:s.u'); |
| 26 | } |
| 27 | if (\is_numeric($time) && (!\is_string($time) || !\preg_match('/^\\d{1,14}$/', $time))) { |
| 28 | $time = static::createFromTimestampUTC($time)->format('Y-m-d\\TH:i:s.uP'); |
| 29 | } |
| 30 | // If the class has a test now set and we are trying to create a now() |
| 31 | // instance then override as required |
| 32 | $isNow = empty($time) || $time === 'now'; |
| 33 | if (\method_exists(static::class, 'hasTestNow') && \method_exists(static::class, 'getTestNow') && static::hasTestNow() && ($isNow || static::hasRelativeKeywords($time))) { |
| 34 | static::mockConstructorParameters($time, $tz); |
| 35 | } |
| 36 | // Work-around for PHP bug https://bugs.php.net/bug.php?id=67127 |
| 37 | if (!\str_contains((string) 0.1, '.')) { |
| 38 | $locale = \setlocale(\LC_NUMERIC, '0'); |
| 39 | // @codeCoverageIgnore |
| 40 | \setlocale(\LC_NUMERIC, 'C'); |
| 41 | // @codeCoverageIgnore |
| 42 | } |
| 43 | try { |
| 44 | parent::__construct($time ?: 'now', static::safeCreateDateTimeZone($tz) ?: null); |
| 45 | } catch (Exception $exception) { |
| 46 | throw new InvalidFormatException($exception->getMessage(), 0, $exception); |
| 47 | } |
| 48 | $this->constructedObjectId = \spl_object_hash($this); |
| 49 | if (isset($locale)) { |
| 50 | \setlocale(\LC_NUMERIC, $locale); |
| 51 | // @codeCoverageIgnore |
| 52 | } |
| 53 | self::setLastErrors(parent::getLastErrors()); |
| 54 | } |
| 55 | private function constructTimezoneFromDateTime(DateTimeInterface $date, &$tz) |
| 56 | { |
| 57 | if ($tz !== null) { |
| 58 | $safeTz = static::safeCreateDateTimeZone($tz); |
| 59 | if ($safeTz) { |
| 60 | return ($date instanceof DateTimeImmutable ? $date : clone $date)->setTimezone($safeTz); |
| 61 | } |
| 62 | return $date; |
| 63 | } |
| 64 | $tz = $date->getTimezone(); |
| 65 | return $date; |
| 66 | } |
| 67 | public function __clone() |
| 68 | { |
| 69 | $this->constructedObjectId = \spl_object_hash($this); |
| 70 | } |
| 71 | public static function instance($date) |
| 72 | { |
| 73 | if ($date instanceof static) { |
| 74 | return clone $date; |
| 75 | } |
| 76 | static::expectDateTime($date); |
| 77 | $instance = new static($date->format('Y-m-d H:i:s.u'), $date->getTimezone()); |
| 78 | if ($date instanceof CarbonInterface) { |
| 79 | $settings = $date->getSettings(); |
| 80 | if (!$date->hasLocalTranslator()) { |
| 81 | unset($settings['locale']); |
| 82 | } |
| 83 | $instance->settings($settings); |
| 84 | } |
| 85 | return $instance; |
| 86 | } |
| 87 | public static function rawParse($time = null, $tz = null) |
| 88 | { |
| 89 | if ($time instanceof DateTimeInterface) { |
| 90 | return static::instance($time); |
| 91 | } |
| 92 | try { |
| 93 | return new static($time, $tz); |
| 94 | } catch (Exception $exception) { |
| 95 | // @codeCoverageIgnoreStart |
| 96 | try { |
| 97 | $date = @static::now($tz)->change($time); |
| 98 | } catch (DateMalformedStringException $ignoredException) { |
| 99 | $date = null; |
| 100 | } |
| 101 | // @codeCoverageIgnoreEnd |
| 102 | if (!$date) { |
| 103 | throw new InvalidFormatException("Could not parse '{$time}': " . $exception->getMessage(), 0, $exception); |
| 104 | } |
| 105 | return $date; |
| 106 | } |
| 107 | } |
| 108 | public static function parse($time = null, $tz = null) |
| 109 | { |
| 110 | $function = static::$parseFunction; |
| 111 | if (!$function) { |
| 112 | return static::rawParse($time, $tz); |
| 113 | } |
| 114 | if (\is_string($function) && \method_exists(static::class, $function)) { |
| 115 | $function = [static::class, $function]; |
| 116 | } |
| 117 | return $function(...\func_get_args()); |
| 118 | } |
| 119 | public static function parseFromLocale($time, $locale = null, $tz = null) |
| 120 | { |
| 121 | return static::rawParse(static::translateTimeString($time, $locale, 'en'), $tz); |
| 122 | } |
| 123 | public static function now($tz = null) |
| 124 | { |
| 125 | return new static(null, $tz); |
| 126 | } |
| 127 | public static function today($tz = null) |
| 128 | { |
| 129 | return static::rawParse('today', $tz); |
| 130 | } |
| 131 | public static function tomorrow($tz = null) |
| 132 | { |
| 133 | return static::rawParse('tomorrow', $tz); |
| 134 | } |
| 135 | public static function yesterday($tz = null) |
| 136 | { |
| 137 | return static::rawParse('yesterday', $tz); |
| 138 | } |
| 139 | public static function maxValue() |
| 140 | { |
| 141 | if (self::$PHPIntSize === 4) { |
| 142 | // 32 bit |
| 143 | return static::createFromTimestamp(\PHP_INT_MAX); |
| 144 | // @codeCoverageIgnore |
| 145 | } |
| 146 | // 64 bit |
| 147 | return static::create(9999, 12, 31, 23, 59, 59); |
| 148 | } |
| 149 | public static function minValue() |
| 150 | { |
| 151 | if (self::$PHPIntSize === 4) { |
| 152 | // 32 bit |
| 153 | return static::createFromTimestamp(~\PHP_INT_MAX); |
| 154 | // @codeCoverageIgnore |
| 155 | } |
| 156 | // 64 bit |
| 157 | return static::create(1, 1, 1, 0, 0, 0); |
| 158 | } |
| 159 | private static function assertBetween($unit, $value, $min, $max) |
| 160 | { |
| 161 | if (static::isStrictModeEnabled() && ($value < $min || $value > $max)) { |
| 162 | throw new OutOfRangeException($unit, $min, $max, $value); |
| 163 | } |
| 164 | } |
| 165 | private static function createNowInstance($tz) |
| 166 | { |
| 167 | if (!static::hasTestNow()) { |
| 168 | return static::now($tz); |
| 169 | } |
| 170 | $now = static::getTestNow(); |
| 171 | if ($now instanceof Closure) { |
| 172 | return $now(static::now($tz)); |
| 173 | } |
| 174 | return $now->avoidMutation()->tz($tz); |
| 175 | } |
| 176 | public static function create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $tz = null) |
| 177 | { |
| 178 | if (\is_string($year) && !\is_numeric($year) || $year instanceof DateTimeInterface) { |
| 179 | return static::parse($year, $tz ?: (\is_string($month) || $month instanceof DateTimeZone ? $month : null)); |
| 180 | } |
| 181 | $defaults = null; |
| 182 | $getDefault = function ($unit) use($tz, &$defaults) { |
| 183 | if ($defaults === null) { |
| 184 | $now = self::createNowInstance($tz); |
| 185 | $defaults = \array_combine(['year', 'month', 'day', 'hour', 'minute', 'second'], \explode('-', $now->rawFormat('Y-n-j-G-i-s.u'))); |
| 186 | } |
| 187 | return $defaults[$unit]; |
| 188 | }; |
| 189 | $year = $year ?? $getDefault('year'); |
| 190 | $month = $month ?? $getDefault('month'); |
| 191 | $day = $day ?? $getDefault('day'); |
| 192 | $hour = $hour ?? $getDefault('hour'); |
| 193 | $minute = $minute ?? $getDefault('minute'); |
| 194 | $second = (float) ($second ?? $getDefault('second')); |
| 195 | self::assertBetween('month', $month, 0, 99); |
| 196 | self::assertBetween('day', $day, 0, 99); |
| 197 | self::assertBetween('hour', $hour, 0, 99); |
| 198 | self::assertBetween('minute', $minute, 0, 99); |
| 199 | self::assertBetween('second', $second, 0, 99); |
| 200 | $fixYear = null; |
| 201 | if ($year < 0) { |
| 202 | $fixYear = $year; |
| 203 | $year = 0; |
| 204 | } elseif ($year > 9999) { |
| 205 | $fixYear = $year - 9999; |
| 206 | $year = 9999; |
| 207 | } |
| 208 | $second = ($second < 10 ? '0' : '') . \number_format($second, 6); |
| 209 | $instance = static::rawCreateFromFormat('!Y-n-j G:i:s.u', \sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $tz); |
| 210 | if ($fixYear !== null) { |
| 211 | $instance = $instance->addYears($fixYear); |
| 212 | } |
| 213 | return $instance; |
| 214 | } |
| 215 | public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null) |
| 216 | { |
| 217 | $fields = static::getRangesByUnit(); |
| 218 | foreach ($fields as $field => $range) { |
| 219 | if (${$field} !== null && (!\is_int(${$field}) || ${$field} < $range[0] || ${$field} > $range[1])) { |
| 220 | if (static::isStrictModeEnabled()) { |
| 221 | throw new InvalidDateException($field, ${$field}); |
| 222 | } |
| 223 | return \false; |
| 224 | } |
| 225 | } |
| 226 | $instance = static::create($year, $month, $day, $hour, $minute, $second, $tz); |
| 227 | foreach (\array_reverse($fields) as $field => $range) { |
| 228 | if (${$field} !== null && (!\is_int(${$field}) || ${$field} !== $instance->{$field})) { |
| 229 | if (static::isStrictModeEnabled()) { |
| 230 | throw new InvalidDateException($field, ${$field}); |
| 231 | } |
| 232 | return \false; |
| 233 | } |
| 234 | } |
| 235 | return $instance; |
| 236 | } |
| 237 | public static function createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $tz = null) : self |
| 238 | { |
| 239 | $initialStrictMode = static::isStrictModeEnabled(); |
| 240 | static::useStrictMode(\true); |
| 241 | try { |
| 242 | $date = static::create($year, $month, $day, $hour, $minute, $second, $tz); |
| 243 | } finally { |
| 244 | static::useStrictMode($initialStrictMode); |
| 245 | } |
| 246 | return $date; |
| 247 | } |
| 248 | public static function createFromDate($year = null, $month = null, $day = null, $tz = null) |
| 249 | { |
| 250 | return static::create($year, $month, $day, null, null, null, $tz); |
| 251 | } |
| 252 | public static function createMidnightDate($year = null, $month = null, $day = null, $tz = null) |
| 253 | { |
| 254 | return static::create($year, $month, $day, 0, 0, 0, $tz); |
| 255 | } |
| 256 | public static function createFromTime($hour = 0, $minute = 0, $second = 0, $tz = null) |
| 257 | { |
| 258 | return static::create(null, null, null, $hour, $minute, $second, $tz); |
| 259 | } |
| 260 | public static function createFromTimeString($time, $tz = null) |
| 261 | { |
| 262 | return static::today($tz)->setTimeFromTimeString($time); |
| 263 | } |
| 264 | private static function createFromFormatAndTimezone($format, $time, $originalTz) |
| 265 | { |
| 266 | // Work-around for https://bugs.php.net/bug.php?id=75577 |
| 267 | // @codeCoverageIgnoreStart |
| 268 | if (\version_compare(\PHP_VERSION, '7.3.0-dev', '<')) { |
| 269 | $format = \str_replace('.v', '.u', $format); |
| 270 | } |
| 271 | // @codeCoverageIgnoreEnd |
| 272 | if ($originalTz === null) { |
| 273 | return parent::createFromFormat($format, (string) $time); |
| 274 | } |
| 275 | $tz = \is_int($originalTz) ? @\timezone_name_from_abbr('', (int) ($originalTz * static::MINUTES_PER_HOUR * static::SECONDS_PER_MINUTE), 1) : $originalTz; |
| 276 | $tz = static::safeCreateDateTimeZone($tz, $originalTz); |
| 277 | if ($tz === \false) { |
| 278 | return \false; |
| 279 | } |
| 280 | return parent::createFromFormat($format, (string) $time, $tz); |
| 281 | } |
| 282 | public static function rawCreateFromFormat($format, $time, $tz = null) |
| 283 | { |
| 284 | // Work-around for https://bugs.php.net/bug.php?id=80141 |
| 285 | $format = \preg_replace('/(?<!\\\\)((?:\\\\{2})*)c/', '$1Y-m-d\\TH:i:sP', $format); |
| 286 | if (\preg_match('/(?<!\\\\)(?:\\\\{2})*(a|A)/', $format, $aMatches, \PREG_OFFSET_CAPTURE) && \preg_match('/(?<!\\\\)(?:\\\\{2})*(h|g|H|G)/', $format, $hMatches, \PREG_OFFSET_CAPTURE) && $aMatches[1][1] < $hMatches[1][1] && \preg_match('/(am|pm|AM|PM)/', $time)) { |
| 287 | $format = \preg_replace('/^(.*)(?<!\\\\)((?:\\\\{2})*)(a|A)(.*)$/U', '$1$2$4 $3', $format); |
| 288 | $time = \preg_replace('/^(.*)(am|pm|AM|PM)(.*)$/U', '$1$3 $2', $time); |
| 289 | } |
| 290 | if ($tz === \false) { |
| 291 | $tz = null; |
| 292 | } |
| 293 | // First attempt to create an instance, so that error messages are based on the unmodified format. |
| 294 | $date = self::createFromFormatAndTimezone($format, $time, $tz); |
| 295 | $lastErrors = parent::getLastErrors(); |
| 296 | $mock = static::getMockedTestNow($tz); |
| 297 | if ($mock && $date instanceof DateTimeInterface) { |
| 298 | // Set timezone from mock if custom timezone was neither given directly nor as a part of format. |
| 299 | // First let's skip the part that will be ignored by the parser. |
| 300 | $nonEscaped = '(?<!\\\\)(\\\\{2})*'; |
| 301 | $nonIgnored = \preg_replace("/^.*{$nonEscaped}!/s", '', $format); |
| 302 | if ($tz === null && !\preg_match("/{$nonEscaped}[eOPT]/", $nonIgnored)) { |
| 303 | $tz = clone $mock->getTimezone(); |
| 304 | } |
| 305 | $mock = $mock->copy(); |
| 306 | // Prepend mock datetime only if the format does not contain non escaped unix epoch reset flag. |
| 307 | if (!\preg_match("/{$nonEscaped}[!|]/", $format)) { |
| 308 | if (\preg_match('/[HhGgisvuB]/', $format)) { |
| 309 | $mock = $mock->setTime(0, 0); |
| 310 | } |
| 311 | $format = static::MOCK_DATETIME_FORMAT . ' ' . $format; |
| 312 | $time = ($mock instanceof self ? $mock->rawFormat(static::MOCK_DATETIME_FORMAT) : $mock->format(static::MOCK_DATETIME_FORMAT)) . ' ' . $time; |
| 313 | } |
| 314 | // Regenerate date from the modified format to base result on the mocked instance instead of now. |
| 315 | $date = self::createFromFormatAndTimezone($format, $time, $tz); |
| 316 | } |
| 317 | if ($date instanceof DateTimeInterface) { |
| 318 | $instance = static::instance($date); |
| 319 | $instance::setLastErrors($lastErrors); |
| 320 | return $instance; |
| 321 | } |
| 322 | if (static::isStrictModeEnabled()) { |
| 323 | throw new InvalidFormatException(\implode(\PHP_EOL, $lastErrors['errors'])); |
| 324 | } |
| 325 | return \false; |
| 326 | } |
| 327 | #[\ReturnTypeWillChange] |
| 328 | public static function createFromFormat($format, $time, $tz = null) |
| 329 | { |
| 330 | $function = static::$createFromFormatFunction; |
| 331 | if (!$function) { |
| 332 | return static::rawCreateFromFormat($format, $time, $tz); |
| 333 | } |
| 334 | if (\is_string($function) && \method_exists(static::class, $function)) { |
| 335 | $function = [static::class, $function]; |
| 336 | } |
| 337 | return $function(...\func_get_args()); |
| 338 | } |
| 339 | public static function createFromIsoFormat($format, $time, $tz = null, $locale = 'en', $translator = null) |
| 340 | { |
| 341 | $format = \preg_replace_callback('/(?<!\\\\)(\\\\{2})*(LTS|LT|[Ll]{1,4})/', function ($match) use($locale, $translator) { |
| 342 | [$code] = $match; |
| 343 | static $formats = null; |
| 344 | if ($formats === null) { |
| 345 | $translator = $translator ?: Translator::get($locale); |
| 346 | $formats = ['LT' => static::getTranslationMessageWith($translator, 'formats.LT', $locale, 'h:mm A'), 'LTS' => static::getTranslationMessageWith($translator, 'formats.LTS', $locale, 'h:mm:ss A'), 'L' => static::getTranslationMessageWith($translator, 'formats.L', $locale, 'MM/DD/YYYY'), 'LL' => static::getTranslationMessageWith($translator, 'formats.LL', $locale, 'MMMM D, YYYY'), 'LLL' => static::getTranslationMessageWith($translator, 'formats.LLL', $locale, 'MMMM D, YYYY h:mm A'), 'LLLL' => static::getTranslationMessageWith($translator, 'formats.LLLL', $locale, 'dddd, MMMM D, YYYY h:mm A')]; |
| 347 | } |
| 348 | return $formats[$code] ?? \preg_replace_callback('/MMMM|MM|DD|dddd/', function ($code) { |
| 349 | return \mb_substr($code[0], 1); |
| 350 | }, $formats[\strtoupper($code)] ?? ''); |
| 351 | }, $format); |
| 352 | $format = \preg_replace_callback('/(?<!\\\\)(\\\\{2})*(' . CarbonInterface::ISO_FORMAT_REGEXP . '|[A-Za-z])/', function ($match) { |
| 353 | [$code] = $match; |
| 354 | static $replacements = null; |
| 355 | if ($replacements === null) { |
| 356 | $replacements = ['OD' => 'd', 'OM' => 'M', 'OY' => 'Y', 'OH' => 'G', 'Oh' => 'g', 'Om' => 'i', 'Os' => 's', 'D' => 'd', 'DD' => 'd', 'Do' => 'd', 'd' => '!', 'dd' => '!', 'ddd' => 'D', 'dddd' => 'D', 'DDD' => 'z', 'DDDD' => 'z', 'DDDo' => 'z', 'e' => '!', 'E' => '!', 'H' => 'G', 'HH' => 'H', 'h' => 'g', 'hh' => 'h', 'k' => 'G', 'kk' => 'G', 'hmm' => 'gi', 'hmmss' => 'gis', 'Hmm' => 'Gi', 'Hmmss' => 'Gis', 'm' => 'i', 'mm' => 'i', 'a' => 'a', 'A' => 'a', 's' => 's', 'ss' => 's', 'S' => '*', 'SS' => '*', 'SSS' => '*', 'SSSS' => '*', 'SSSSS' => '*', 'SSSSSS' => 'u', 'SSSSSSS' => 'u*', 'SSSSSSSS' => 'u*', 'SSSSSSSSS' => 'u*', 'M' => 'm', 'MM' => 'm', 'MMM' => 'M', 'MMMM' => 'M', 'Mo' => 'm', 'Q' => '!', 'Qo' => '!', 'G' => '!', 'GG' => '!', 'GGG' => '!', 'GGGG' => '!', 'GGGGG' => '!', 'g' => '!', 'gg' => '!', 'ggg' => '!', 'gggg' => '!', 'ggggg' => '!', 'W' => '!', 'WW' => '!', 'Wo' => '!', 'w' => '!', 'ww' => '!', 'wo' => '!', 'x' => 'U???', 'X' => 'U', 'Y' => 'Y', 'YY' => 'y', 'YYYY' => 'Y', 'YYYYY' => 'Y', 'YYYYYY' => 'Y', 'z' => 'e', 'zz' => 'e', 'Z' => 'e', 'ZZ' => 'e']; |
| 357 | } |
| 358 | $format = $replacements[$code] ?? '?'; |
| 359 | if ($format === '!') { |
| 360 | throw new InvalidFormatException("Format {$code} not supported for creation."); |
| 361 | } |
| 362 | return $format; |
| 363 | }, $format); |
| 364 | return static::rawCreateFromFormat($format, $time, $tz); |
| 365 | } |
| 366 | public static function createFromLocaleFormat($format, $locale, $time, $tz = null) |
| 367 | { |
| 368 | $format = \preg_replace_callback('/(?:\\\\[a-zA-Z]|[bfkqCEJKQRV]){2,}/', static function (array $match) use($locale) : string { |
| 369 | $word = \str_replace('\\', '', $match[0]); |
| 370 | $translatedWord = static::translateTimeString($word, $locale, 'en'); |
| 371 | return $word === $translatedWord ? $match[0] : \preg_replace('/[a-zA-Z]/', '\\\\$0', $translatedWord); |
| 372 | }, $format); |
| 373 | return static::rawCreateFromFormat($format, static::translateTimeString($time, $locale, 'en'), $tz); |
| 374 | } |
| 375 | public static function createFromLocaleIsoFormat($format, $locale, $time, $tz = null) |
| 376 | { |
| 377 | $time = static::translateTimeString($time, $locale, 'en', CarbonInterface::TRANSLATE_MONTHS | CarbonInterface::TRANSLATE_DAYS | CarbonInterface::TRANSLATE_MERIDIEM); |
| 378 | return static::createFromIsoFormat($format, $time, $tz, $locale); |
| 379 | } |
| 380 | public static function make($var) |
| 381 | { |
| 382 | if ($var instanceof DateTimeInterface) { |
| 383 | return static::instance($var); |
| 384 | } |
| 385 | $date = null; |
| 386 | if (\is_string($var)) { |
| 387 | $var = \trim($var); |
| 388 | if (!\preg_match('/^P[\\dT]/', $var) && !\preg_match('/^R\\d/', $var) && \preg_match('/[a-z\\d]/i', $var)) { |
| 389 | $date = static::parse($var); |
| 390 | } |
| 391 | } |
| 392 | return $date; |
| 393 | } |
| 394 | private static function setLastErrors($lastErrors) |
| 395 | { |
| 396 | if (\is_array($lastErrors) || $lastErrors === \false) { |
| 397 | static::$lastErrors = \is_array($lastErrors) ? $lastErrors : ['warning_count' => 0, 'warnings' => [], 'error_count' => 0, 'errors' => []]; |
| 398 | } |
| 399 | } |
| 400 | #[\ReturnTypeWillChange] |
| 401 | public static function getLastErrors() |
| 402 | { |
| 403 | return static::$lastErrors; |
| 404 | } |
| 405 | } |
| 406 |