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 8.0KB

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