TextHelper.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace Tools\View\Helper;
  3. use Cake\Core\App;
  4. use Cake\Core\Exception\CakeException;
  5. use Cake\Utility\Hash;
  6. use Cake\View\Helper\TextHelper as CakeTextHelper;
  7. use Cake\View\View;
  8. use Tools\Utility\Number;
  9. use Tools\Utility\Utility;
  10. if (!defined('CHAR_HELLIP')) {
  11. define('CHAR_HELLIP', '&#8230;'); # � (horizontal ellipsis = three dot leader)
  12. }
  13. /**
  14. * This helper extends the core Text helper and adds some improvements.
  15. *
  16. * autoLinkEmails
  17. * - obfuscate (defaults to FALSE right now)
  18. * (- maxLength?)
  19. * - escape (defaults to TRUE for security reasons regarding plain text)
  20. *
  21. * autoLinkUrls
  22. * - stripProtocol (defaults To FALSE right now)
  23. * - maxLength (to shorten links in order to not mess up the layout in some cases - appends ...)
  24. * - escape (defaults to TRUE for security reasons regarding plain text)
  25. *
  26. * @mixin \Tools\Utility\Text
  27. * @property \Cake\View\Helper\HtmlHelper $Html
  28. */
  29. class TextHelper extends CakeTextHelper {
  30. /**
  31. * Cake Utility Text instance
  32. *
  33. * @var \Cake\Utility\Text
  34. */
  35. protected $_engine;
  36. /**
  37. * ### Settings:
  38. *
  39. * - `engine` Class name to use to replace Text functionality.
  40. * The class needs to be placed in the `Utility` directory.
  41. *
  42. * @param \Cake\View\View $View the view object the helper is attached to.
  43. * @param array<string, mixed> $config Settings array Settings array
  44. */
  45. public function __construct(View $View, array $config = []) {
  46. $config += ['engine' => 'Tools.Text'];
  47. parent::__construct($View, $config);
  48. /** @psalm-var class-string<\Cake\Utility\Text>|null $engineClass */
  49. $engineClass = App::className($config['engine'], 'Utility');
  50. if ($engineClass === null) {
  51. throw new CakeException(sprintf('Class for `%s` could not be found', $config['engine']));
  52. }
  53. $this->_engine = new $engineClass($config);
  54. }
  55. /**
  56. * Call methods from String utility class
  57. *
  58. * @param string $method Method to invoke
  59. * @param array $params Array of params for the method.
  60. * @return mixed Whatever is returned by called method, or false on failure
  61. */
  62. public function __call(string $method, array $params): mixed {
  63. return $this->_engine->{$method}(...$params);
  64. }
  65. /**
  66. * Minimizes the given URL to a maximum length
  67. *
  68. * @param string $url the url
  69. * @param int|null $max the maximum length
  70. * @param array<string, mixed> $options
  71. * - placeholder
  72. * @return string the manipulated url (+ eventuell ...)
  73. */
  74. public function minimizeUrl(string $url, ?int $max = null, array $options = []): string {
  75. // check if there is nothing to do
  76. if (!$url || mb_strlen($url) <= (int)$max) {
  77. return $url;
  78. }
  79. // http:// etc has not to be displayed, so
  80. $url = Utility::stripProtocol($url);
  81. // cut the parameters
  82. if (mb_strpos($url, '/') !== false) {
  83. /** @var string $url */
  84. $url = strtok($url, '/');
  85. }
  86. // return if the url is short enough
  87. if (mb_strlen($url) <= (int)$max) {
  88. return $url;
  89. }
  90. // otherwise cut a part in the middle (but only if long enough!)
  91. // TODO: more dynamically
  92. $placeholder = CHAR_HELLIP;
  93. if (!empty($options['placeholder'])) {
  94. $placeholder = $options['placeholder'];
  95. }
  96. $end = mb_substr($url, -5, 5);
  97. $front = mb_substr($url, 0, (int)$max - 8);
  98. return $front . $placeholder . $end;
  99. }
  100. /**
  101. * Removes http:// or other protocols from the link.
  102. *
  103. * @param string $url
  104. * @param array<string> $protocols Defaults to http and https. Pass empty array for all.
  105. * @return string strippedUrl
  106. */
  107. public function stripProtocol(string $url, array $protocols = ['http', 'https']): string {
  108. return Utility::stripProtocol($url, $protocols);
  109. }
  110. /**
  111. * Transforming int values into ordinal numbers (1st, 3rd, ...).
  112. * When using HTML, you can use <sup>, as well.
  113. *
  114. * @param int $num The number to be suffixed.
  115. * @param bool $sup Whether to wrap the suffix in a superscript (<sup>) tag on output.
  116. * @return string ordinal
  117. */
  118. public function ordinalNumber(int $num = 0, bool $sup = false): string {
  119. $ordinal = Number::ordinal($num);
  120. return ($sup) ? $num . '<sup>' . $ordinal . '</sup>' : $num . $ordinal;
  121. }
  122. /**
  123. * Syntax highlighting using php internal highlighting
  124. *
  125. * @param string $file Filename
  126. * @return string
  127. */
  128. public function highlightFile(string $file): string {
  129. return highlight_file($file, true);
  130. }
  131. /**
  132. * Syntax highlighting using php internal highlighting
  133. *
  134. * @param string $string Content
  135. * @return string
  136. */
  137. public function highlightString(string $string): string {
  138. return highlight_string($string, true);
  139. }
  140. }