/** * @param string $picture * @throws InvalidArgumentException */ public function __construct($picture) { $matches = preg_match_all('/([YMDdWwFHhmsfZzPCE])\\s*(.*)/', $picture, $groups); if ($matches === 0) { $exception = new InvalidArgumentException('No valid components found'); $exception->setErrorCode('XTDE1340'); throw $exception; } $this->componentSpecifier = $groups[1][0]; $modifier = $groups[2][0]; if (($comma = strpos($modifier, ',')) !== false) { $this->presentationModifier = substr($modifier, 0, $comma); if (($dash = strpos($modifier, '-')) !== false) { $widthModifier = substr($modifier, $comma + 1); list($this->minWidth, $this->maxWidth) = explode('-', $widthModifier); if ($this->maxWidth === '*') { $this->maxWidth = null; } if ($this->minWidth === '*') { $this->minWidth = null; } } else { $this->minWidth = (int) substr($modifier, $comma + 1); } } else { $this->presentationModifier = $modifier; } }
/** * @param DOMAttr $attribute * @throws InvalidArgumentException * @credits https://github.com/Saxonica/Saxon-CE/ https://github.com/Saxonica/Saxon-CE/blob/master/notices/MOZILLA.txt */ public function transform(DOMAttr $attribute) { $expression = $attribute->nodeValue; $components = []; $length = strlen($expression); $last = 0; while ($last < $length) { $i0 = strpos($expression, "{", $last); $i1 = strpos($expression, "{{", $last); $i8 = strpos($expression, "}", $last); $i9 = strpos($expression, "}}", $last); if (($i0 === false || $length < $i0) && ($i8 === false || $length < $i8)) { // found end of string $components[] = substr($expression, $last); break; } elseif ($i8 >= 0 && ($i0 === false || $i8 < $i0)) { // found a "}" if ($i8 !== $i9) { // a "}" that isn't a "}}" $exception = new InvalidArgumentException("Closing curly brace in attribute value template \"" . $expression . "\" must be doubled"); $exception->setErrorCode("XTSE0370"); throw $exception; } $components[] = substr($expression, $last, $i8 + 2 - $last); $last = $i8 + 2; } elseif ($i1 >= 0 && $i1 === $i0) { // found a doubled "{{" $components[] = substr($expression, $last, $i1 + 2 - $last); $last = $i1 + 2; } elseif ($i0 >= 0) { // found a single "{" if ($i0 > $last) { $components[] = substr($expression, $last, $i0 - $last); } if ($i8 === false) { $exception = new InvalidArgumentException("Curly brace in attribute value template \"" . $expression . "\" must be closed"); $exception->setErrorCode("XTSE0370"); throw $exception; } $compileFrom = $i0 + 1; $compileUntil = $i8 - $compileFrom; $components[] = '{'; $components[] = $this->xpathCompiler->compile(substr($expression, $compileFrom, $compileUntil), $attribute); $components[] = '}'; $last = $i8 + 1; } else { // @codeCoverageIgnoreStart throw new RuntimeException("Internal error parsing Attribute Value Template"); // @codeCoverageIgnoreEnd } } $attribute->nodeValue = htmlentities(implode('', $components), ENT_XML1); }
/** * @param DateTimeInterface $date * @param string $picture * @param $locale * @param $calendar * @return string * @throws InvalidArgumentException * @credits https://github.com/Saxonica/Saxon-CE/ https://github.com/Saxonica/Saxon-CE/blob/master/notices/MOZILLA.txt */ public function format(DateTimeInterface $date, $picture, $locale, $calendar) { if ($date->format('Y-m-d') === '2017-01-01') { if ($this->flagsDate && $this->flagsTime) { return DateTimeFormatter::createWithFlagDateTime()->format($date, $picture, $locale, $calendar); } if ($this->flagsDate) { return DateTimeFormatter::createWithFlagDate()->format($date, $picture, $locale, $calendar); } if ($this->flagsTime) { return DateTimeFormatter::createWithFlagTime()->format($date, $picture, $locale, $calendar); } } $result = []; $i = 0; $escaped = false; while (true) { while ($i < strlen($picture) && substr($picture, $i, 1) !== '[') { if ($escaped === false) { $result[] = self::ESCAPE; $escaped = true; } $result[] = substr($picture, $i, 1); if (substr($picture, $i, 1) === ']') { $i++; if ($i == strlen($picture) || substr($picture, $i, 1) != ']') { $exception = new InvalidArgumentException('Wrong formatted date, escape by doubling [[ and ]]'); $exception->setErrorCode('XTDE1340'); throw $exception; } } $i++; } if ($i === strlen($picture)) { break; } // look for '[[' $i++; if ($i < strlen($picture) && substr($picture, $i, 1) === '[') { $result[] = '['; $i++; } else { $close = $i < strlen($picture) ? strpos($picture, "]", $i) : -1; if ($close === -1 || $close === false) { $exception = new InvalidArgumentException('Wrong formatted date, missing ]'); $exception->setErrorCode('XTDE1340'); throw $exception; } $pictureString = new PictureString(substr($picture, $i, $close - $i)); $specifier = $pictureString->getComponentSpecifier(); if (isset($this->components[$specifier])) { if ($pictureString->getPresentationModifier() === 'N') { if ($escaped === false) { $result[] = self::ESCAPE; $escaped = true; } $result[] = strtoupper($this->formatPattern($date, $locale, $this->components[$specifier]->format($pictureString, $date))); } elseif ($pictureString->getPresentationModifier() === 'n') { if ($escaped === false) { $result[] = self::ESCAPE; $escaped = true; } $result[] = strtolower($this->formatPattern($date, $locale, $this->components[$specifier]->format($pictureString, $date))); } else { if ($escaped) { $result[] = self::ESCAPE; $escaped = false; } $result[] = $this->components[$specifier]->format($pictureString, $date); } } else { $exception = new InvalidArgumentException("Component [{$specifier}] is not supported"); $exception->setErrorCode('XTDE1340'); throw $exception; } $i = $close + 1; } } if ($escaped) { $result[] = self::ESCAPE; } return $this->formatPattern($date, $locale, implode('', $result)); }
/** * @param DateTimeImmutable $date * @param string $componentFormat * @param int $flags * @return string * @throws InvalidArgumentException * * @credits https://github.com/Saxonica/Saxon-CE/ https://github.com/Saxonica/Saxon-CE/blob/master/notices/MOZILLA.txt */ private static function formatDateComponent(DateTimeImmutable $date, $componentFormat, $flags) { $matches = preg_match_all('/([YMDdWwFHhmsfZzPCE])\\s*(.*)/', $componentFormat, $groups); if ($matches === 0) { $exception = new InvalidArgumentException('No valid components found'); $exception->setErrorCode('XTDE1340'); throw $exception; } $ignoreDate = ($flags & self::FLAG_DATE) === 0; $ignoreTime = ($flags & self::FLAG_TIME) === 0; $component = $groups[1][0]; switch (substr($component, 0, 1)) { case 'Y': // year if ($ignoreDate) { $exception = new InvalidArgumentException('Cannot use date context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('Y'); case 'M': // month if ($ignoreDate) { $exception = new InvalidArgumentException('Cannot use date context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('m'); case 'D': // day in month if ($ignoreDate) { $exception = new InvalidArgumentException('Cannot use date context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('d'); case 'd': // day in year if ($ignoreDate) { $exception = new InvalidArgumentException('Cannot use date context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('z'); case 'W': // week of year if ($ignoreDate) { $exception = new InvalidArgumentException('Cannot use date context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('W'); case 'H': // hour in day if ($ignoreTime) { $exception = new InvalidArgumentException('Cannot use time context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('H'); case 'h': // hour in half-day (12 hour clock) if ($ignoreTime) { $exception = new InvalidArgumentException('Cannot use time context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('h'); case 'm': // minutes if ($ignoreTime) { $exception = new InvalidArgumentException('Cannot use time context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('i'); case 's': // seconds if ($ignoreTime) { $exception = new InvalidArgumentException('Cannot use time context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('s'); case 'Z': // timezone in +hh:mm format, unless format=N in which case use timezone name return $date->format('P'); case 'z': // timezone return $date->format('O'); case 'F': // day of week if ($ignoreDate) { $exception = new InvalidArgumentException('Cannot use date context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('O'); case 'P': // am/pm marker if ($ignoreTime) { $exception = new InvalidArgumentException('Cannot use time context'); $exception->setErrorCode('XTDE1350'); throw $exception; } return $date->format('A'); } $exception = new InvalidArgumentException("Component [{$component}] is not supported"); $exception->setErrorCode('XTDE1340'); throw $exception; }
/** * @param DateTimeInterface $date * @param string $picture * @param $locale * @param $calendar * @return string * @throws InvalidArgumentException * @credits https://github.com/Saxonica/Saxon-CE/ https://github.com/Saxonica/Saxon-CE/blob/master/notices/MOZILLA.txt */ public function format(DateTimeInterface $date, $picture, $locale, $calendar) { $result = []; $i = 0; while (true) { while ($i < strlen($picture) && substr($picture, $i, 1) != '[') { $result[] = $this->escape(substr($picture, $i, 1)); if (substr($picture, $i, 1) == ']') { $i++; if ($i == strlen($picture) || substr($picture, $i, 1) != ']') { $exception = new InvalidArgumentException('Wrong formatted date, escape by doubling [[ and ]]'); $exception->setErrorCode('XTDE1340'); throw $exception; } } $i++; } if ($i == strlen($picture)) { break; } // look for '[[' $i++; if ($i < strlen($picture) && substr($picture, $i, 1) == '[') { $result[] = '['; $i++; } else { $close = $i < strlen($picture) ? strpos($picture, "]", $i) : -1; if ($close === -1 || $close === false) { $exception = new InvalidArgumentException('Wrong formatted date, missing ]'); $exception->setErrorCode('XTDE1340'); throw $exception; } $pictureString = new PictureString(substr($picture, $i, $close - $i)); $specifier = $pictureString->getComponentSpecifier(); if (isset($this->components[$specifier])) { $result[] = $this->components[$specifier]->format($pictureString, $date); } else { $exception = new InvalidArgumentException("Component [{$specifier}] is not supported"); $exception->setErrorCode('XTDE1340'); throw $exception; } $i = $close + 1; } } return $date->format(implode('', $result)); }