SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/SproutExtension.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16. use DateTimeImmutable;
  17. use Twig\Extension\AbstractExtension;
  18. use Twig\Extension\GlobalsInterface;
  19. use Twig\TwigFilter;
  20. use Twig\TwigFunction;
  21.  
  22. /**
  23.  *
  24.  */
  25. final class SproutExtension
  26. extends AbstractExtension
  27. implements GlobalsInterface
  28. {
  29.  
  30. /** @inheritdoc */
  31. public function getGlobals(): array
  32. {
  33. return [
  34. 'IN_PRODUCTION' => IN_PRODUCTION,
  35. 'DOCROOT' => DOCROOT,
  36.  
  37. 'sprout' => new SproutVariable(),
  38. 'now' => new DateTimeImmutable(null),
  39. ];
  40. }
  41.  
  42.  
  43. /** @inheritdoc */
  44. public function getFilters() {
  45. return [
  46. new TwigFilter('cc2kc', [$this, 'cc2kc']),
  47. new TwigFilter('kc2cc', [$this, 'kc2cc']),
  48. new TwigFilter('truncate', [$this, 'truncate']),
  49. new TwigFilter('jsdate', [$this, 'jsdate']),
  50. new TwigFilter('json_pretty', [$this, 'jsonPretty']),
  51. new TwigFilter('json_encode', 'json_encode'),
  52. ];
  53. }
  54.  
  55.  
  56. /** @inheritdoc */
  57. public function getFunctions() {
  58. return [
  59. new TwigFunction('redirect', [Web::class, 'redirect']),
  60. new TwigFunction('attr', [$this, 'attr'], [
  61. 'is_safe' => ['html'],
  62. ]),
  63. new TwigFunction('url', [$this, 'url'], [
  64. 'is_safe' => ['html'],
  65. ]),
  66. new TwigFunction('options', [$this, 'options'], [
  67. 'is_safe' => ['html'],
  68. ]),
  69. new TwigFunction('jquery', [Jquery::class, 'script'], [
  70. 'is_safe' => ['html'],
  71. ]),
  72. ];
  73. }
  74.  
  75.  
  76. /**
  77.   *
  78.   * @param array $options
  79.   * @return string
  80.   */
  81. public function options(array $options)
  82. {
  83. $out = [];
  84. foreach ($options as $key => $value) {
  85. if (!$value) continue;
  86. $out[] = Enc::html($key);
  87. }
  88. return implode(' ', $out);
  89. }
  90.  
  91.  
  92. /**
  93.   *
  94.   * @param array $config
  95.   * @return string
  96.   */
  97. public function attr(array $config)
  98. {
  99. $out = '';
  100. foreach ($config as $name => $value) {
  101. if ($value === null or $value === false) continue;
  102.  
  103. $out .= Enc::html($name);
  104.  
  105. if (
  106. $value !== true and
  107. (is_numeric($value) or !empty($value))
  108. ) {
  109. $value = Enc::html($value);
  110. $out .= "=\"{$value}\"";
  111. }
  112. $out .= " \n";
  113. }
  114. return trim($out);
  115. }
  116.  
  117.  
  118. /**
  119.   *
  120.   * @param string|null $path
  121.   * @param array|null $params
  122.   * @return string
  123.   */
  124. public function url(string $path = null, array $params = null)
  125. {
  126. $out = Sprout::absRoot();
  127. if ($path) {
  128. $out .= '/' . ltrim(Enc::url($path), '/');
  129. }
  130. else {
  131. $out .= Router::$current_uri;
  132. }
  133.  
  134. if ($params) {
  135. $out .= '?' . http_build_query($params);
  136. }
  137.  
  138. return $out;
  139. }
  140.  
  141.  
  142. /**
  143.   * Trim a string if it's too long. Adds a ... ellipsis character.
  144.   *
  145.   * @param null|string $text
  146.   * @param int $length
  147.   * @return string
  148.   */
  149. public function truncate(?string $text, int $length): string
  150. {
  151. if (empty($text)) {
  152. return '';
  153. }
  154. else if (mb_strlen($text) > $length) {
  155. return mb_substr($text, 0, $length - 1) . '…';
  156. }
  157. else {
  158. return $text;
  159. }
  160. }
  161.  
  162.  
  163. /**
  164.   * Shorthand pretty print JSON.
  165.   *
  166.   * @param mixed $data
  167.   * @return string
  168.   */
  169. public function jsonPretty($data): string
  170. {
  171. return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  172. }
  173.  
  174.  
  175. /**
  176.   * Changes camelCase to kebab-case
  177.   *
  178.   * @param string $var
  179.   * @return string
  180.   */
  181. public function cc2kc(?string $var)
  182. {
  183. if (is_string($var) && strlen($var))
  184. {
  185. $var = preg_replace_callback('/(^|[a-z])([A-Z])/', function($matches) {
  186. return strtolower(strlen("\\1") ? "$matches[1]-$matches[2]" : "\\2");
  187. },
  188. $var);
  189. }
  190.  
  191. return $var;
  192. }
  193.  
  194.  
  195. /**
  196.   * Changes kebab-case to camelCase
  197.   *
  198.   * @param string $var
  199.   * @return string
  200.   */
  201. public function kc2cc(?string $var)
  202. {
  203. if (is_string($var) && strlen($var))
  204. {
  205. $var = preg_replace_callback('/(^|[a-z])([-])([a-z])/', function($matches) {
  206. return strlen("\\1") ? "$matches[1]" . ucfirst("$matches[3]") : "\\3";
  207. },
  208. $var);
  209. }
  210.  
  211. return $var;
  212. }
  213.  
  214.  
  215. /**
  216.   * A wrapper around strtotime. Pretty handy.
  217.   *
  218.   * @param mixed $value
  219.   * @return string
  220.   */
  221. public function jsdate($value): string
  222. {
  223. $date = strtotime($value) * 1000;
  224. return $date ? "new Date({$date})" : 'null';
  225. }
  226. }
  227.