BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

twig.class.php 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * Twig class
  5. *
  6. * Converted to a singleton class like $ENV.
  7. * One instance should only ever exist,
  8. * because of its separate disk cache system.
  9. *
  10. * Based on OPS's useful rule set:
  11. * https://github.com/OPSnet/Gazelle/blob/master/app/Util/Twig.php
  12. */
  13. class Twig
  14. {
  15. /**
  16. * Singleton stuff
  17. */
  18. private static $Twig = null;
  19. private function __construct()
  20. {
  21. return;
  22. }
  23. public function __clone()
  24. {
  25. return trigger_error(
  26. 'clone() not allowed',
  27. E_USER_ERROR
  28. );
  29. }
  30. public static function go()
  31. {
  32. return (self::$Twig === null)
  33. ? self::$Twig = Twig::factory()
  34. : self::$Twig;
  35. }
  36. /**
  37. * factory
  38. */
  39. private static function factory(): \Twig\Environment
  40. {
  41. $ENV = ENV::go();
  42. $twig = new \Twig\Environment(
  43. new \Twig\Loader\FilesystemLoader("$ENV->SERVER_ROOT/templates"),
  44. [
  45. 'auto_reload' => true,
  46. 'autoescape' => 'html',
  47. 'cache' => "$ENV->WEB_ROOT/cache/twig"
  48. #'debug' => DEBUG_MODE,
  49. ]
  50. );
  51. $twig->addFilter(new \Twig\TwigFilter(
  52. 'article',
  53. function ($word) {
  54. return preg_match('/^[aeiou]/i', $word) ? 'an' : 'a';
  55. }
  56. ));
  57. $twig->addFilter(new \Twig\TwigFilter(
  58. 'b64',
  59. function (string $binary) {
  60. return base64_encode($binary);
  61. }
  62. ));
  63. $twig->addFilter(new \Twig\TwigFilter(
  64. 'bb_format',
  65. function ($text) {
  66. return new \Twig\Markup(\Text::full_format($text), 'UTF-8');
  67. }
  68. ));
  69. $twig->addFilter(new \Twig\TwigFilter(
  70. 'checked',
  71. function ($isChecked) {
  72. return $isChecked ? ' checked="checked"' : '';
  73. }
  74. ));
  75. $twig->addFilter(new \Twig\TwigFilter(
  76. 'image',
  77. function ($i) {
  78. return new \Twig\Markup(\ImageTools::process($i, true), 'UTF-8');
  79. }
  80. ));
  81. $twig->addFilter(new \Twig\TwigFilter(
  82. 'ipaddr',
  83. function ($ipaddr) {
  84. return new \Twig\Markup(\Tools::display_ip($ipaddr), 'UTF-8');
  85. }
  86. ));
  87. $twig->addFilter(new \Twig\TwigFilter(
  88. 'octet_size',
  89. function ($size, array $option = []) {
  90. return \Format::get_size($size, empty($option) ? 2 : $option[0]);
  91. },
  92. ['is_variadic' => true]
  93. ));
  94. $twig->addFilter(new \Twig\TwigFilter(
  95. 'plural',
  96. function ($number) {
  97. return plural($number);
  98. }
  99. ));
  100. $twig->addFilter(new \Twig\TwigFilter(
  101. 'selected',
  102. function ($isSelected) {
  103. return $isSelected ? ' selected="selected"' : '';
  104. }
  105. ));
  106. $twig->addFilter(new \Twig\TwigFilter(
  107. 'shorten',
  108. function (string $text, int $length) {
  109. return shortenString($text, $length);
  110. }
  111. ));
  112. $twig->addFilter(new \Twig\TwigFilter(
  113. 'time_diff',
  114. function ($time) {
  115. return new \Twig\Markup(time_diff($time), 'UTF-8');
  116. }
  117. ));
  118. $twig->addFilter(new \Twig\TwigFilter(
  119. 'ucfirst',
  120. function ($text) {
  121. return ucfirst($text);
  122. }
  123. ));
  124. $twig->addFilter(new \Twig\TwigFilter(
  125. 'ucfirstall',
  126. function ($text) {
  127. return implode(' ', array_map(function ($w) {
  128. return ucfirst($w);
  129. }, explode(' ', $text)));
  130. }
  131. ));
  132. $twig->addFilter(new \Twig\TwigFilter(
  133. 'user_url',
  134. function ($userId) {
  135. return new \Twig\Markup(\Users::format_username($userId, false, false, false), 'UTF-8');
  136. }
  137. ));
  138. $twig->addFilter(new \Twig\TwigFilter(
  139. 'user_full',
  140. function ($userId) {
  141. return new \Twig\Markup(\Users::format_username($userId, true, true, true, true), 'UTF-8');
  142. }
  143. ));
  144. $twig->addFunction(new \Twig\TwigFunction('donor_icon', function ($icon, $userId) {
  145. return new \Twig\Markup(
  146. \ImageTools::process($icon, false, 'donoricon', $userId),
  147. 'UTF-8'
  148. );
  149. }));
  150. $twig->addFunction(new \Twig\TwigFunction('privilege', function ($default, $config, $key) {
  151. return new \Twig\Markup(
  152. (
  153. $default
  154. ? sprintf(
  155. '<input id="%s" type="checkbox" disabled="disabled"%s />&nbsp;',
  156. "default_$key",
  157. (isset($default[$key]) && $default[$key] ? ' checked="checked"' : '')
  158. )
  159. : ''
  160. )
  161. . sprintf(
  162. '<input type="checkbox" name="%s" id="%s" value="1"%s />&nbsp;<label title="%s" for="%s">%s</label><br />',
  163. "perm_$key",
  164. $key,
  165. (empty($config[$key]) ? '' : ' checked="checked"'),
  166. $key,
  167. $key,
  168. \Permissions::list()[$key] ?? "!unknown($key)!"
  169. ),
  170. 'UTF-8'
  171. );
  172. }));
  173. $twig->addFunction(new \Twig\TwigFunction('ratio', function ($up, $down) {
  174. return new \Twig\Markup(
  175. \Format::get_ratio_html($up, $down),
  176. 'UTF-8'
  177. );
  178. }));
  179. $twig->addFunction(new \Twig\TwigFunction('resolveCountryIpv4', function ($addr) {
  180. return new \Twig\Markup(
  181. (function ($ip) {
  182. static $cache = [];
  183. if (!isset($cache[$ip])) {
  184. $Class = strtr($ip, '.', '-');
  185. $cache[$ip] = '<span class="cc_'.$Class.'">Resolving CC...'
  186. . '<script type="text/javascript">'
  187. . '$(document).ready(function() {'
  188. . '$.get(\'tools.php?action=get_cc&ip='.$ip.'\', function(cc) {'
  189. . '$(\'.cc_'.$Class.'\').html(cc);'
  190. . '});'
  191. . '});'
  192. . '</script></span>';
  193. }
  194. return $cache[$ip];
  195. })($addr),
  196. 'UTF-8'
  197. );
  198. }));
  199. $twig->addFunction(new \Twig\TwigFunction('resolveIpv4', function ($addr) {
  200. return new \Twig\Markup(
  201. (function ($ip) {
  202. if (!$ip) {
  203. $ip = '127.0.0.1';
  204. }
  205. static $cache = [];
  206. if (!isset($cache[$ip])) {
  207. $class = strtr($ip, '.', '-');
  208. $cache[$ip] = '<span class="host_' . $class
  209. . '">Resolving host' . "\xE2\x80\xA6" . '<script type="text/javascript">$(document).ready(function() {'
  210. . "\$.get('tools.php?action=get_host&ip=$ip', function(host) {\$('.host_$class').html(host)})})</script></span>";
  211. }
  212. return $cache[$ip];
  213. })($addr),
  214. 'UTF-8'
  215. );
  216. }));
  217. $twig->addFunction(new \Twig\TwigFunction('shorten', function ($text, $length) {
  218. return new \Twig\Markup(
  219. shortenString($text, $length),
  220. 'UTF-8'
  221. );
  222. }));
  223. $twig->addTest(
  224. new \Twig\TwigTest('numeric', function ($value) {
  225. return is_numeric($value);
  226. })
  227. );
  228. return $twig;
  229. }
  230. }