Skip to content
لیافام شیمی لوگو
$characterMask = " \t\n\r\0\v"; } switch ($side) { case 'both': return \trim($string, $characterMask); case 'left': return \ltrim($string, $characterMask); case 'right': return \rtrim($string, $characterMask); default: throw new \WPML\Core\Twig\Error\RuntimeError('Trimming side must be "left", "right" or "both".'); } } /** * Removes whitespaces between HTML tags. * * @return string */ function twig_spaceless($content) { return \trim(\preg_replace('/>\\s+<', $content)); } /** * Escapes a string. * * @param mixed $string The value to be escaped * @param string $strategy The escaping strategy * @param string $charset The charset * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) * * @return string */ function twig_escape_filter(\WPML\Core\Twig\Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = \false) { if ($autoescape && $string instanceof \WPML\Core\Twig\Markup) { return $string; } if (!\is_string($string)) { if (\is_object($string) && \method_exists($string, '__toString')) { $string = (string) $string; } elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) { return $string; } } if ('' === $string) { return ''; } if (null === $charset) { $charset = $env->getCharset(); } switch ($strategy) { case 'html': // see https://secure.php.net/htmlspecialchars // Using a static variable to avoid initializing the array // each time the function is called. Moving the declaration on the // top of the function slow downs other escaping strategies. static $htmlspecialcharsCharsets = ['ISO-8859-1' => \true, 'ISO8859-1' => \true, 'ISO-8859-15' => \true, 'ISO8859-15' => \true, 'utf-8' => \true, 'UTF-8' => \true, 'CP866' => \true, 'IBM866' => \true, '866' => \true, 'CP1251' => \true, 'WINDOWS-1251' => \true, 'WIN-1251' => \true, '1251' => \true, 'CP1252' => \true, 'WINDOWS-1252' => \true, '1252' => \true, 'KOI8-R' => \true, 'KOI8-RU' => \true, 'KOI8R' => \true, 'BIG5' => \true, '950' => \true, 'GB2312' => \true, '936' => \true, 'BIG5-HKSCS' => \true, 'SHIFT_JIS' => \true, 'SJIS' => \true, '932' => \true, 'EUC-JP' => \true, 'EUCJP' => \true, 'ISO8859-5' => \true, 'ISO-8859-5' => \true, 'MACROMAN' => \true]; if (isset($htmlspecialcharsCharsets[$charset])) { return \htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset); } if (isset($htmlspecialcharsCharsets[\strtoupper($charset)])) { // cache the lowercase variant for future iterations $htmlspecialcharsCharsets[$charset] = \true; return \htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset); } $string = \WPML\Core\twig_convert_encoding($string, 'UTF-8', $charset); $string = \htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8'); return \WPML\Core\twig_convert_encoding($string, $charset, 'UTF-8'); case 'js': // escape all non-alphanumeric characters // into their \x or \uHHHH representations if ('UTF-8' !== $charset) { $string = \WPML\Core\twig_convert_encoding($string, 'UTF-8', $charset); } if (!\preg_match('//u', $string)) { throw new \WPML\Core\Twig\Error\RuntimeError('The string to escape is not a valid UTF-8 string.'); } $string = \preg_replace_callback('#[^a-zA-Z0-9,\\._]#Su', '\\WPML\\Core\\_twig_escape_js_callback', $string); if ('UTF-8' !== $charset) { $string = \WPML\Core\twig_convert_encoding($string, $charset, 'UTF-8'); } return $string; case 'css': if ('UTF-8' !== $charset) { $string = \WPML\Core\twig_convert_encoding($string, 'UTF-8', $charset); } if (!\preg_match('//u', $string)) { throw new \WPML\Core\Twig\Error\RuntimeError('The string to escape is not a valid UTF-8 string.'); } $string = \preg_replace_callback('#[^a-zA-Z0-9]#Su', '\\WPML\\Core\\_twig_escape_css_callback', $string); if ('UTF-8' !== $charset) { $string = \WPML\Core\twig_convert_encoding($string, $charset, 'UTF-8'); } return $string; case 'html_attr': if ('UTF-8' !== $charset) { $string = \WPML\Core\twig_convert_encoding($string, 'UTF-8', $charset); } if (!\preg_match('//u', $string)) { throw new \WPML\Core\Twig\Error\RuntimeError('The string to escape is not a valid UTF-8 string.'); } $string = \preg_replace_callback('#[^a-zA-Z0-9,\\.\\-_]#Su', '\\WPML\\Core\\_twig_escape_html_attr_callback', $string); if ('UTF-8' !== $charset) { $string = \WPML\Core\twig_convert_encoding($string, $charset, 'UTF-8'); } return $string; case 'url': return \rawurlencode($string); default: static $escapers; if (null === $escapers) { $escapers = $env->getExtension('WPML\\Core\\Twig\\Extension\\CoreExtension')->getEscapers(); } if (isset($escapers[$strategy])) { return \call_user_func($escapers[$strategy], $env, $string, $charset); } $validStrategies = \implode(', ', \array_merge(['html', 'js', 'url', 'css', 'html_attr'], \array_keys($escapers))); throw new \WPML\Core\Twig\Error\RuntimeError(\sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies)); } } /** * @internal */ function twig_escape_filter_is_safe(\WPML\Core\Twig\Node\Node $filterArgs) { foreach ($filterArgs as $arg) { if ($arg instanceof \WPML\Core\Twig\Node\Expression\ConstantExpression) { return [$arg->getAttribute('value')]; } return []; } return ['html']; } if (\function_exists('mb_convert_encoding')) { function twig_convert_encoding($string, $to, $from) { return \mb_convert_encoding($string, $to, $from); } } elseif (\function_exists('iconv')) { function twig_convert_encoding($string, $to, $from) { return \iconv($from, $to, $string); } } else { function twig_convert_encoding($string, $to, $from) { throw new \WPML\Core\Twig\Error\RuntimeError('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).'); } } if (\function_exists('mb_ord')) { function twig_ord($string) { return \mb_ord($string, 'UTF-8'); } } else { function twig_ord($string) { $code = ($string = \unpack('C*', \substr($string, 0, 4))) ? $string[1] : 0; if (0xf0 <= $code) { return ($code - 0xf0 << 18) + ($string[2] - 0x80 << 12) + ($string[3] - 0x80 << 6) + $string[4] - 0x80; } if (0xe0 <= $code) { return ($code - 0xe0 << 12) + ($string[2] - 0x80 << 6) + $string[3] - 0x80; } if (0xc0 <= $code) { return ($code - 0xc0 << 6) + $string[2] - 0x80; } return $code; } } function _twig_escape_js_callback($matches) { $char = $matches[0]; /* * A few characters have short escape sequences in JSON and JavaScript. * Escape sequences supported only by JavaScript, not JSON, are ommitted. * \" is also supported but omitted, because the resulting string is not HTML safe. */ static $shortMap = ['\\' => '\\\\', '/' => '\\/', "\10" => '\\b', "\f" => '\\f', "\n" => '\\n', "\r" => '\\r', "\t" => '\\t']; if (isset($shortMap[$char])) { return $shortMap[$char]; } // \uHHHH $char = \WPML\Core\twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); $char = \strtoupper(\bin2hex($char)); if (4 >= \strlen($char)) { return \sprintf('\\u%04s', $char); } return \sprintf('\\u%04s\\u%04s', \substr($char, 0, -4), \substr($char, -4)); } function _twig_escape_css_callback($matches) { $char = $matches[0]; return \sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : \WPML\Core\twig_ord($char)); } /** * This function is adapted from code coming from Zend Framework. * * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (https://www.zend.com) * @license https://framework.zend.com/license/new-bsd New BSD License */ function _twig_escape_html_attr_callback($matches) { $chr = $matches[0]; $ord = \ord($chr); /* * The following replaces characters undefined in HTML with the * hex entity for the Unicode replacement character. */ if ($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr || $ord >= 0x7f && $ord <= 0x9f) { return '�'; } /* * Check if the current character to escape has a name entity we should * replace it with while grabbing the hex value of the character. */ if (1 == \strlen($chr)) { /* * While HTML supports far more named entities, the lowest common denominator * has become HTML5's XML Serialisation which is restricted to the those named * entities that XML supports. Using HTML entities would result in this error: * XML Parsing Error: undefined entity */ static $entityMap = [ 34 => '"', /* quotation mark */ 38 => '&', /* ampersand */ 60 => '<', /* less-than sign */ 62 => '>', ]; if (isset($entityMap[$ord])) { return $entityMap[$ord]; } return \sprintf('&#x%02X;', $ord); } /* * Per OWASP recommendations, we'll use hex entities for any other * characters where a named entity does not exist. */ return \sprintf('&#x%04X;', \WPML\Core\twig_ord($chr)); } // add multibyte extensions if possible if (\function_exists('mb_get_info')) { /** * Returns the length of a variable. * * @param mixed $thing A variable * * @return int The length of the value */ function twig_length_filter(\WPML\Core\Twig\Environment $env, $thing) { if (null === $thing) { return 0; } if (\is_scalar($thing)) { return \mb_strlen($thing, $env->getCharset()); } if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) { return \count($thing); } if ($thing instanceof \Traversable) { return \iterator_count($thing); } if (\is_object($thing) && \method_exists($thing, '__toString')) { return \mb_strlen((string) $thing, $env->getCharset()); } return 1; } /** * Converts a string to uppercase. * * @param string $string A string * * @return string The uppercased string */ function twig_upper_filter(\WPML\Core\Twig\Environment $env, $string) { if (null !== ($charset = $env->getCharset())) { return \mb_strtoupper($string, $charset); } return \strtoupper($string); } /** * Converts a string to lowercase. * * @param string $string A string * * @return string The lowercased string */ function twig_lower_filter(\WPML\Core\Twig\Environment $env, $string) { if (null !== ($charset = $env->getCharset())) { return \mb_strtolower($string, $charset); } return \strtolower($string); } /** * Returns a titlecased string. * * @param string $string A string * * @return string The titlecased string */ function twig_title_string_filter(\WPML\Core\Twig\Environment $env, $string) { if (null !== ($charset = $env->getCharset())) { return \mb_convert_case($string, \MB_CASE_TITLE, $charset); } return \ucwords(\strtolower($string)); } /** * Returns a capitalized string. * * @param string $string A string * * @return string The capitalized string */ function twig_capitalize_string_filter(\WPML\Core\Twig\Environment $env, $string) { if (null !== ($charset = $env->getCharset())) { return \mb_strtoupper(\mb_substr($string, 0, 1, $charset), $charset) . \mb_strtolower(\mb_substr($string, 1, \mb_strlen($string, $charset), $charset), $charset); } return \ucfirst(\strtolower($string)); } } else { /** * Returns the length of a variable. * * @param mixed $thing A variable * * @return int The length of the value */ function twig_length_filter(\WPML\Core\Twig\Environment $env, $thing) { if (null === $thing) { return 0; } if (\is_scalar($thing)) { return \strlen($thing); } if ($thing instanceof \SimpleXMLElement) { return \count($thing); } if (\is_object($thing) && \method_exists($thing, '__toString') && !$thing instanceof \Countable) { return \strlen((string) $thing); } if ($thing instanceof \Countable || \is_array($thing)) { return \count($thing); } if ($thing instanceof \IteratorAggregate) { return \iterator_count($thing); } return 1; } /** * Returns a titlecased string. * * @param string $string A string * * @return string The titlecased string */ function twig_title_string_filter(\WPML\Core\Twig\Environment $env, $string) { return \ucwords(\strtolower($string)); } /** * Returns a capitalized string. * * @param string $string A string * * @return string The capitalized string */ function twig_capitalize_string_filter(\WPML\Core\Twig\Environment $env, $string) { return \ucfirst(\strtolower($string)); } } /** * @internal */ function twig_ensure_traversable($seq) { if ($seq instanceof \Traversable || \is_array($seq)) { return $seq; } return []; } /** * @internal */ function twig_to_array($seq, $preserveKeys = \true) { if ($seq instanceof \Traversable) { return \iterator_to_array($seq, $preserveKeys); } if (!\is_array($seq)) { return $seq; } return $preserveKeys ? $seq : \array_values($seq); } /** * Checks if a variable is empty. * * {# evaluates to true if the foo variable is null, false, or the empty string #} * {% if foo is empty %} * {# ... #} * {% endif %} * * @param mixed $value A variable * * @return bool true if the value is empty, false otherwise */ function twig_test_empty($value) { if ($value instanceof \Countable) { return 0 == \count($value); } if ($value instanceof \Traversable) { return !\iterator_count($value); } if (\is_object($value) && \method_exists($value, '__toString')) { return '' === (string) $value; } return '' === $value || \false === $value || null === $value || [] === $value; } /** * Checks if a variable is traversable. * * {# evaluates to true if the foo variable is an array or a traversable object #} * {% if foo is iterable %} * {# ... #} * {% endif %} * * @param mixed $value A variable * * @return bool true if the value is traversable */ function twig_test_iterable($value) { return $value instanceof \Traversable || \is_array($value); } /** * Renders a template. * * @param array $context * @param string|array $template The template to render or an array of templates to try consecutively * @param array $variables The variables to pass to the template * @param bool $withContext * @param bool $ignoreMissing Whether to ignore missing templates or not * @param bool $sandboxed Whether to sandbox the template or not * * @return string The rendered template */ function twig_include(\WPML\Core\Twig\Environment $env, $context, $template, $variables = [], $withContext = \true, $ignoreMissing = \false, $sandboxed = \false) { $alreadySandboxed = \false; $sandbox = null; if ($withContext) { $variables = \array_merge($context, $variables); } if ($isSandboxed = $sandboxed && $env->hasExtension('WPML\\Core\\Twig\\Extension\\SandboxExtension')) { $sandbox = $env->getExtension('WPML\\Core\\Twig\\Extension\\SandboxExtension'); if (!($alreadySandboxed = $sandbox->isSandboxed())) { $sandbox->enableSandbox(); } } $loaded = null; try { $loaded = $env->resolveTemplate($template); } catch (\WPML\Core\Twig\Error\LoaderError $e) { if (!$ignoreMissing) { if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } throw $e; } } catch (\Throwable $e) { if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } throw $e; } catch (\Exception $e) { if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } throw $e; } try { $ret = $loaded ? $loaded->render($variables) : ''; } catch (\Exception $e) { if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } throw $e; } if ($isSandboxed && !$alreadySandboxed) { $sandbox->disableSandbox(); } return $ret; } /** * Returns a template content without rendering it. * * @param string $name The template name * @param bool $ignoreMissing Whether to ignore missing templates or not * * @return string The template source */ function twig_source(\WPML\Core\Twig\Environment $env, $name, $ignoreMissing = \false) { $loader = $env->getLoader(); try { if (!$loader instanceof \WPML\Core\Twig\Loader\SourceContextLoaderInterface) { return $loader->getSource($name); } else { return $loader->getSourceContext($name)->getCode(); } } catch (\WPML\Core\Twig\Error\LoaderError $e) { if (!$ignoreMissing) { throw $e; } } } /** * Provides the ability to get constants from instances as well as class/global constants. * * @param string $constant The name of the constant * @param object|null $object The object to get the constant from * * @return string */ function twig_constant($constant, $object = null) { if (null !== $object) { $constant = \get_class($object) . '::' . $constant; } return \constant($constant); } /** * Checks if a constant exists. * * @param string $constant The name of the constant * @param object|null $object The object to get the constant from * * @return bool */ function twig_constant_is_defined($constant, $object = null) { if (null !== $object) { $constant = \get_class($object) . '::' . $constant; } return \defined($constant); } /** * Batches item. * * @param array $items An array of items * @param int $size The size of the batch * @param mixed $fill A value used to fill missing items * * @return array */ function twig_array_batch($items, $size, $fill = null, $preserveKeys = \true) { if (!\WPML\Core\twig_test_iterable($items)) { throw new \WPML\Core\Twig\Error\RuntimeError(\sprintf('The "batch" filter expects an array or "Traversable", got "%s".', \is_object($items) ? \get_class($items) : \gettype($items))); } $size = \ceil($size); $result = \array_chunk(\WPML\Core\twig_to_array($items, $preserveKeys), $size, $preserveKeys); if (null !== $fill && $result) { $last = \count($result) - 1; if ($fillCount = $size - \count($result[$last])) { for ($i = 0; $i < $fillCount; ++$i) { $result[$last][] = $fill; } } } return $result; } function twig_array_filter($array, $arrow) { if (\is_array($array)) { if (\PHP_VERSION_ID >= 50600) { return \array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH); } return \array_filter($array, $arrow); } // the IteratorIterator wrapping is needed as some internal PHP classes are \Traversable but do not implement \Iterator return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow); } function twig_array_map($array, $arrow) { $r = []; foreach ($array as $k => $v) { $r[$k] = $arrow($v, $k); } return $r; } function twig_array_reduce($array, $arrow, $initial = null) { if (!\is_array($array)) { $array = \iterator_to_array($array); } return \array_reduce($array, $arrow, $initial); }