summaryrefslogtreecommitdiff
path: root/inc/lib/twig
diff options
context:
space:
mode:
authorAppleman1234 <applemansigloo@gmail.com>2022-09-25 13:22:40 +1000
committerAppleman1234 <applemansigloo@gmail.com>2022-09-25 13:22:40 +1000
commit92561d7f36508b7e0271926e417adf0e2e53916b (patch)
treea8588b4f70af276c5acf58836e33b1f6ff5c61e8 /inc/lib/twig
parent6f1083e4b51fc9c4c594f6c72cf3d84ef4d0298b (diff)
Initial attempt a switch to composer and PHP-8.1 compatibility
Diffstat (limited to 'inc/lib/twig')
-rw-r--r--inc/lib/twig/extensions/Extension/I18n.php45
-rw-r--r--inc/lib/twig/extensions/Extension/Tinyboard.php298
-rw-r--r--inc/lib/twig/extensions/Node/Trans.php133
-rw-r--r--inc/lib/twig/extensions/TokenParser/Trans.php80
4 files changed, 556 insertions, 0 deletions
diff --git a/inc/lib/twig/extensions/Extension/I18n.php b/inc/lib/twig/extensions/Extension/I18n.php
new file mode 100644
index 00000000..bc6a05bd
--- /dev/null
+++ b/inc/lib/twig/extensions/Extension/I18n.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extensions_Extension_I18n extends Twig_Extension
+{
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
+ */
+ public function getTokenParsers()
+ {
+ return array(new Twig_Extensions_TokenParser_Trans());
+ }
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters()
+ {
+ return array(
+ new Twig_SimpleFilter('trans', 'gettext'),
+ );
+ }
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'i18n';
+ }
+}
+
diff --git a/inc/lib/twig/extensions/Extension/Tinyboard.php b/inc/lib/twig/extensions/Extension/Tinyboard.php
new file mode 100644
index 00000000..da75ee75
--- /dev/null
+++ b/inc/lib/twig/extensions/Extension/Tinyboard.php
@@ -0,0 +1,298 @@
+<?php
+
+class Twig_Extensions_Extension_Tinyboard extends Twig_Extension
+{
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters()
+ {
+ return array(
+ new Twig_SimpleFilter('filesize', 'format_bytes'),
+ new Twig_SimpleFilter('truncate', 'twig_truncate_filter'),
+ new Twig_SimpleFilter('truncate_body', 'truncate'),
+ new Twig_SimpleFilter('truncate_filename', 'twig_filename_truncate_filter'),
+ new Twig_SimpleFilter('extension', 'twig_extension_filter'),
+ new Twig_SimpleFilter('sprintf', 'sprintf'),
+ new Twig_SimpleFilter('capcode', 'capcode'),
+ new Twig_SimpleFilter('remove_modifiers', 'remove_modifiers'),
+ new Twig_SimpleFilter('hasPermission', 'twig_hasPermission_filter'),
+ new Twig_SimpleFilter('date', 'twig_date_filter'),
+ new Twig_SimpleFilter('poster_id', 'poster_id'),
+ new Twig_SimpleFilter('remove_whitespace', 'twig_remove_whitespace_filter'),
+ new Twig_SimpleFilter('count', 'count'),
+ new Twig_SimpleFilter('ago', 'ago'),
+ new Twig_SimpleFilter('until', 'until'),
+ new Twig_SimpleFilter('push', 'twig_push_filter'),
+ new Twig_SimpleFilter('bidi_cleanup', 'bidi_cleanup'),
+ new Twig_SimpleFilter('addslashes', 'addslashes'),
+ );
+ }
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFunctions()
+ {
+ return array(
+ new Twig_SimpleFunction('time', 'time'),
+ new Twig_SimpleFunction('floor', 'floor'),
+ new Twig_SimpleFunction('timezone', 'twig_timezone_function'),
+ new Twig_SimpleFunction('hiddenInputs', 'hiddenInputs'),
+ new Twig_SimpleFunction('hiddenInputsHash', 'hiddenInputsHash'),
+ new Twig_SimpleFunction('ratio', 'twig_ratio_function'),
+ new Twig_SimpleFunction('secure_link_confirm', 'twig_secure_link_confirm'),
+ new Twig_SimpleFunction('secure_link', 'twig_secure_link'),
+ new Twig_SimpleFunction('link_for', 'link_for')
+ );
+ }
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'tinyboard';
+ }
+}
+
+function twig_timezone_function() {
+ return 'Z';
+}
+
+function twig_push_filter($array, $value) {
+ array_push($array, $value);
+ return $array;
+}
+
+function twig_remove_whitespace_filter($data) {
+ return preg_replace('/[\t\r\n]/', '', $data);
+}
+
+function custom_strftime(string $format, $timestamp = null, ?string $locale = null): string
+{
+ if (null === $timestamp) {
+ $timestamp = new \DateTime;
+ }
+ elseif (is_numeric($timestamp)) {
+ $timestamp = date_create('@' . $timestamp);
+
+ if ($timestamp) {
+ $timestamp->setTimezone(new \DateTimezone(date_default_timezone_get()));
+ }
+ }
+ elseif (is_string($timestamp)) {
+ $timestamp = date_create($timestamp);
+ }
+
+ if (!($timestamp instanceof \DateTimeInterface)) {
+ throw new \InvalidArgumentException('$timestamp argument is neither a valid UNIX timestamp, a valid date-time string or a DateTime object.');
+ }
+
+ $locale = substr((string) $locale, 0, 5);
+
+ $intl_formats = [
+ '%a' => 'EEE', // An abbreviated textual representation of the day Sun through Sat
+ '%A' => 'EEEE', // A full textual representation of the day Sunday through Saturday
+ '%b' => 'MMM', // Abbreviated month name, based on the locale Jan through Dec
+ '%B' => 'MMMM', // Full month name, based on the locale January through December
+ '%h' => 'MMM', // Abbreviated month name, based on the locale (an alias of %b) Jan through Dec
+ ];
+
+ $intl_formatter = function (\DateTimeInterface $timestamp, string $format) use ($intl_formats, $locale) {
+ $tz = $timestamp->getTimezone();
+ $date_type = \IntlDateFormatter::FULL;
+ $time_type = \IntlDateFormatter::FULL;
+ $pattern = '';
+
+ // %c = Preferred date and time stamp based on locale
+ // Example: Tue Feb 5 00:45:10 2009 for February 5, 2009 at 12:45:10 AM
+ if ($format == '%c') {
+ $date_type = \IntlDateFormatter::LONG;
+ $time_type = \IntlDateFormatter::SHORT;
+ }
+ // %x = Preferred date representation based on locale, without the time
+ // Example: 02/05/09 for February 5, 2009
+ elseif ($format == '%x') {
+ $date_type = \IntlDateFormatter::SHORT;
+ $time_type = \IntlDateFormatter::NONE;
+ }
+ // Localized time format
+ elseif ($format == '%X') {
+ $date_type = \IntlDateFormatter::NONE;
+ $time_type = \IntlDateFormatter::MEDIUM;
+ }
+ else {
+ $pattern = $intl_formats[$format];
+ }
+
+ return (new \IntlDateFormatter($locale, $date_type, $time_type, $tz, null, $pattern))->format($timestamp);
+ };
+
+ // Same order as https://www.php.net/manual/en/function.strftime.php
+ $translation_table = [
+ // Day
+ '%a' => $intl_formatter,
+ '%A' => $intl_formatter,
+ '%d' => 'd',
+ '%e' => function ($timestamp) {
+ return sprintf('% 2u', $timestamp->format('j'));
+ },
+ '%j' => function ($timestamp) {
+ // Day number in year, 001 to 366
+ return sprintf('%03d', $timestamp->format('z')+1);
+ },
+ '%u' => 'N',
+ '%w' => 'w',
+
+ // Week
+ '%U' => function ($timestamp) {
+ // Number of weeks between date and first Sunday of year
+ $day = new \DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y')));
+ return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
+ },
+ '%V' => 'W',
+ '%W' => function ($timestamp) {
+ // Number of weeks between date and first Monday of year
+ $day = new \DateTime(sprintf('%d-01 Monday', $timestamp->format('Y')));
+ return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
+ },
+
+ // Month
+ '%b' => $intl_formatter,
+ '%B' => $intl_formatter,
+ '%h' => $intl_formatter,
+ '%m' => 'm',
+
+ // Year
+ '%C' => function ($timestamp) {
+ // Century (-1): 19 for 20th century
+ return floor($timestamp->format('Y') / 100);
+ },
+ '%g' => function ($timestamp) {
+ return substr($timestamp->format('o'), -2);
+ },
+ '%G' => 'o',
+ '%y' => 'y',
+ '%Y' => 'Y',
+
+ // Time
+ '%H' => 'H',
+ '%k' => function ($timestamp) {
+ return sprintf('% 2u', $timestamp->format('G'));
+ },
+ '%I' => 'h',
+ '%l' => function ($timestamp) {
+ return sprintf('% 2u', $timestamp->format('g'));
+ },
+ '%M' => 'i',
+ '%p' => 'A', // AM PM (this is reversed on purpose!)
+ '%P' => 'a', // am pm
+ '%r' => 'h:i:s A', // %I:%M:%S %p
+ '%R' => 'H:i', // %H:%M
+ '%S' => 's',
+ '%T' => 'H:i:s', // %H:%M:%S
+ '%X' => $intl_formatter, // Preferred time representation based on locale, without the date
+
+ // Timezone
+ '%z' => 'O',
+ '%Z' => 'T',
+
+ // Time and Date Stamps
+ '%c' => $intl_formatter,
+ '%D' => 'm/d/Y',
+ '%F' => 'Y-m-d',
+ '%s' => 'U',
+ '%x' => $intl_formatter,
+ ];
+
+ $out = preg_replace_callback('/(?<!%)(%[a-zA-Z])/', function ($match) use ($translation_table, $timestamp) {
+ if ($match[1] == '%n') {
+ return "\n";
+ }
+ elseif ($match[1] == '%t') {
+ return "\t";
+ }
+
+ if (!isset($translation_table[$match[1]])) {
+ throw new \InvalidArgumentException(sprintf('Format "%s" is unknown in time format', $match[1]));
+ }
+
+ $replace = $translation_table[$match[1]];
+
+ if (is_string($replace)) {
+ return $timestamp->format($replace);
+ }
+ else {
+ return $replace($timestamp, $match[1]);
+ }
+ }, $format);
+
+ $out = str_replace('%%', '%', $out);
+ return $out;
+}
+
+function twig_date_filter($date, $format) {
+ return custom_strftime($format, $date);
+}
+
+function twig_hasPermission_filter($mod, $permission, $board = null) {
+ return hasPermission($permission, $board, $mod);
+}
+
+function twig_extension_filter($value, $case_insensitive = true) {
+ $ext = mb_substr($value, mb_strrpos($value, '.') + 1);
+ if($case_insensitive)
+ $ext = mb_strtolower($ext);
+ return $ext;
+}
+
+function twig_sprintf_filter( $value, $var) {
+ return sprintf($value, $var);
+}
+
+function twig_truncate_filter($value, $length = 30, $preserve = false, $separator = '…') {
+ if (mb_strlen($value) > $length) {
+ if ($preserve) {
+ if (false !== ($breakpoint = mb_strpos($value, ' ', $length))) {
+ $length = $breakpoint;
+ }
+ }
+ return mb_substr($value, 0, $length) . $separator;
+ }
+ return $value;
+}
+
+function twig_filename_truncate_filter($value, $length = 30, $separator = '…') {
+ if (mb_strlen($value) > $length) {
+ $value = strrev($value);
+ $array = array_reverse(explode(".", $value, 2));
+ $array = array_map("strrev", $array);
+
+ $filename = &$array[0];
+ $extension = isset($array[1]) ? $array[1] : false;
+
+ $filename = mb_substr($filename, 0, $length - ($extension ? mb_strlen($extension) + 1 : 0)) . $separator;
+
+ return implode(".", $array);
+ }
+ return $value;
+}
+
+function twig_ratio_function($w, $h) {
+ return fraction($w, $h, ':');
+}
+function twig_secure_link_confirm($text, $title, $confirm_message, $href) {
+ global $config;
+
+ return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes($confirm_message)) . '\')) document.location=\'?/' . htmlspecialchars(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>';
+}
+function twig_secure_link($href) {
+ return $href . '/' . make_secure_link_token($href);
+}
diff --git a/inc/lib/twig/extensions/Node/Trans.php b/inc/lib/twig/extensions/Node/Trans.php
new file mode 100644
index 00000000..e7dc1ca8
--- /dev/null
+++ b/inc/lib/twig/extensions/Node/Trans.php
@@ -0,0 +1,133 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a trans node.
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+class Twig_Extensions_Node_Trans extends Twig_Node
+{
+ public function __construct(Twig_NodeInterface $body, Twig_NodeInterface $plural = null, Twig_Node_Expression $count = null, $lineno, $tag = null)
+ {
+ parent::__construct(array('count' => $count, 'body' => $body, 'plural' => $plural), array(), $lineno, $tag);
+ }
+
+ /**
+ * Compiles the node to PHP.
+ *
+ * @param Twig_Compiler A Twig_Compiler instance
+ */
+ public function compile(Twig_Compiler $compiler)
+ {
+ $compiler->addDebugInfo($this);
+
+ list($msg, $vars) = $this->compileString($this->getNode('body'));
+
+ if (null !== $this->getNode('plural')) {
+ list($msg1, $vars1) = $this->compileString($this->getNode('plural'));
+
+ $vars = array_merge($vars, $vars1);
+ }
+
+ $function = null === $this->getNode('plural') ? 'gettext' : 'ngettext';
+
+ if ($vars) {
+ $compiler
+ ->write('echo strtr('.$function.'(')
+ ->subcompile($msg)
+ ;
+
+ if (null !== $this->getNode('plural')) {
+ $compiler
+ ->raw(', ')
+ ->subcompile($msg1)
+ ->raw(', abs(')
+ ->subcompile($this->getNode('count'))
+ ->raw(')')
+ ;
+ }
+
+ $compiler->raw('), array(');
+
+ foreach ($vars as $var) {
+ if ('count' === $var->getAttribute('name')) {
+ $compiler
+ ->string('%count%')
+ ->raw(' => abs(')
+ ->subcompile($this->getNode('count'))
+ ->raw('), ')
+ ;
+ } else {
+ $compiler
+ ->string('%'.$var->getAttribute('name').'%')
+ ->raw(' => ')
+ ->subcompile($var)
+ ->raw(', ')
+ ;
+ }
+ }
+
+ $compiler->raw("));\n");
+ } else {
+ $compiler
+ ->write('echo '.$function.'(')
+ ->subcompile($msg)
+ ;
+
+ if (null !== $this->getNode('plural')) {
+ $compiler
+ ->raw(', ')
+ ->subcompile($msg1)
+ ->raw(', abs(')
+ ->subcompile($this->getNode('count'))
+ ->raw(')')
+ ;
+ }
+
+ $compiler->raw(");\n");
+ }
+ }
+
+ protected function compileString(Twig_NodeInterface $body)
+ {
+ if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant || $body instanceof Twig_Node_Expression_TempName) {
+ return array($body, array());
+ }
+
+ $vars = array();
+ if (count($body)) {
+ $msg = '';
+
+ foreach ($body as $node) {
+ if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof Twig_Node_SetTemp) {
+ $node = $node->getNode(1);
+ }
+
+ if ($node instanceof Twig_Node_Print) {
+ $n = $node->getNode('expr');
+ while ($n instanceof Twig_Node_Expression_Filter) {
+ $n = $n->getNode('node');
+ }
+ $msg .= sprintf('%%%s%%', $n->getAttribute('name'));
+ $vars[] = new Twig_Node_Expression_Name($n->getAttribute('name'), $n->getLine());
+ } else {
+ $msg .= $node->getAttribute('data');
+ }
+ }
+ } else {
+ $msg = $body->getAttribute('data');
+ }
+
+ return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $body->getLine()))), $vars);
+ }
+} \ No newline at end of file
diff --git a/inc/lib/twig/extensions/TokenParser/Trans.php b/inc/lib/twig/extensions/TokenParser/Trans.php
new file mode 100644
index 00000000..4a0fad41
--- /dev/null
+++ b/inc/lib/twig/extensions/TokenParser/Trans.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Extensions_TokenParser_Trans extends Twig_TokenParser
+{
+ /**
+ * Parses a token and returns a node.
+ *
+ * @param Twig_Token $token A Twig_Token instance
+ *
+ * @return Twig_NodeInterface A Twig_NodeInterface instance
+ */
+ public function parse(Twig_Token $token)
+ {
+ $lineno = $token->getLine();
+ $stream = $this->parser->getStream();
+ $count = null;
+ $plural = null;
+
+ if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) {
+ $body = $this->parser->getExpressionParser()->parseExpression();
+ } else {
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideForFork'));
+ if ('plural' === $stream->next()->getValue()) {
+ $count = $this->parser->getExpressionParser()->parseExpression();
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ $plural = $this->parser->subparse(array($this, 'decideForEnd'), true);
+ }
+ }
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+ $this->checkTransString($body, $lineno);
+
+ return new Twig_Extensions_Node_Trans($body, $plural, $count, $lineno, $this->getTag());
+ }
+
+ public function decideForFork(Twig_Token $token)
+ {
+ return $token->test(array('plural', 'endtrans'));
+ }
+
+ public function decideForEnd(Twig_Token $token)
+ {
+ return $token->test('endtrans');
+ }
+
+ /**
+ * Gets the tag name associated with this token parser.
+ *
+ * @param string The tag name
+ */
+ public function getTag()
+ {
+ return 'trans';
+ }
+
+ protected function checkTransString(Twig_NodeInterface $body, $lineno)
+ {
+ foreach ($body as $i => $node) {
+ if (
+ $node instanceof Twig_Node_Text
+ ||
+ ($node instanceof Twig_Node_Print && $node->getNode('expr') instanceof Twig_Node_Expression_Name)
+ ) {
+ continue;
+ }
+
+ throw new Twig_Error_Syntax(sprintf('The text to be translated with "trans" can only contain references to simple variables'), $lineno);
+ }
+ }
+} \ No newline at end of file