Elgg  Version 3.0
HtmlFormatter.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Views;
4 
5 use Elgg\Loggable;
9 
14 
15  use Loggable;
16 
20  protected $views;
21 
25  protected $hooks;
26 
30  protected $autop;
31 
40  public function __construct(
41  LoggerInterface $logger,
45  ) {
46  $this->logger = $logger;
47  $this->views = $views;
48  $this->hooks = $hooks;
49  $this->autop = $autop;
50 
51  }
52 
66  public function formatBlock($html, array $options = []) {
67  if (!is_string($html)) {
68  return '';
69  }
70 
71  $options = array_merge([
72  'parse_urls' => true,
73  'parse_emails' => true,
74  'sanitize' => true,
75  'autop' => true,
76  ], $options);
77 
78  $params = [
79  'options' => $options,
80  'html' => $html,
81  ];
82 
83  $params = $this->hooks->trigger('prepare', 'html', null, $params);
84 
85  $html = elgg_extract('html', $params);
86  $options = elgg_extract('options', $params);
87 
88  if (elgg_extract('parse_urls', $options)) {
89  $html = $this->parseUrls($html);
90  }
91 
92  if (elgg_extract('parse_emails', $options)) {
93  $html = $this->parseEmails($html);
94  }
95 
96  if (elgg_extract('sanitize', $options)) {
98  }
99 
100  if (elgg_extract('autop', $options)) {
101  $html = $this->addParagaraphs($html);
102  }
103 
104  return $html;
105  }
106 
114  public function parseUrls($text) {
115 
116  $linkify = new \Misd\Linkify\Linkify();
117 
118  return $linkify->processUrls($text, ['attr' => ['rel' => 'nofollow']]);
119  }
120 
130  public function parseEmails($text) {
131  $linkify = new \Misd\Linkify\Linkify();
132 
133  return $linkify->processEmails($text, ['attr' => ['rel' => 'nofollow']]);
134  }
135 
143  public function addParagaraphs($string) {
144  try {
145  $result = $this->autop->process($string);
146  if ($result !== false) {
147  return $result;
148  }
149  } catch (\RuntimeException $e) {
150  $this->logger->warning('ElggAutoP failed to process the string: ' . $e->getMessage());
151  }
152 
153  return $string;
154  }
155 
179  public function formatAttributes(array $attrs = []) {
180  if (empty($attrs)) {
181  return '';
182  }
183 
184  $attributes = [];
185 
186  foreach ($attrs as $attr => $val) {
187  if (0 !== strpos($attr, 'data-') && false !== strpos($attr, '_')) {
188  // this is probably a view $vars variable not meant for output
189  continue;
190  }
191 
192  $attr = strtolower($attr);
193 
194  if (!isset($val) || $val === false) {
195  continue;
196  }
197 
198  if ($val === true) {
199  $val = $attr; //e.g. checked => true ==> checked="checked"
200  }
201 
202  if (is_array($val) && empty($val)) {
203  //e.g. ['class' => []]
204  continue;
205  }
206 
207  if (is_scalar($val)) {
208  $val = [$val];
209  }
210 
211  if (!is_array($val)) {
212  continue;
213  }
214 
215  // Check if array contains non-scalar values and bail if so
216  $filtered_val = array_filter($val, function($e) {
217  return is_scalar($e);
218  });
219 
220  if (count($val) != count($filtered_val)) {
221  continue;
222  }
223 
224  $val = implode(' ', $val);
225 
226  $val = htmlspecialchars($val, ENT_QUOTES, 'UTF-8', false);
227  $attributes[] = "$attr=\"$val\"";
228  }
229 
230  return implode(' ', $attributes);
231  }
232 
262  public function formatElement($tag_name, array $attributes = [], $text = '', array $options = []) {
263  if (is_array($tag_name)) {
264  $args = $tag_name;
265 
266  if ($attributes !== [] || $text !== '' || $options !== []) {
267  throw new \InvalidArgumentException('If $tag_name is an array, the other arguments must not be set');
268  }
269 
270  if (isset($args['#tag_name'])) {
271  $tag_name = $args['#tag_name'];
272  }
273  if (isset($args['#text'])) {
274  $text = $args['#text'];
275  }
276  if (isset($args['#options'])) {
277  $options = $args['#options'];
278  }
279 
280  unset($args['#tag_name'], $args['#text'], $args['#options']);
281  $attributes = $args;
282  }
283 
284  if (!is_string($tag_name) || $tag_name === '') {
285  throw new \InvalidArgumentException('$tag_name is required');
286  }
287 
288  if (isset($options['is_void'])) {
289  $is_void = $options['is_void'];
290  } else {
291  // from http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
292  $is_void = in_array(strtolower($tag_name), [
293  'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem',
294  'meta', 'param', 'source', 'track', 'wbr'
295  ]);
296  }
297 
298  if (!empty($options['encode_text'])) {
299  $double_encode = empty($options['double_encode']) ? false : true;
300  $text = htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', $double_encode);
301  }
302 
303  $attrs = '';
304  if (!empty($attributes)) {
306  if ($attrs !== '') {
307  $attrs = " $attrs";
308  }
309  }
310 
311  if ($is_void) {
312  return empty($options['is_xml']) ? "<{$tag_name}{$attrs}>" : "<{$tag_name}{$attrs} />";
313  }
314 
315  return "<{$tag_name}{$attrs}>$text</$tag_name>";
316  }
317 
328  public function stripTags($string, $allowable_tags = null) {
329  $params = [
330  'original_string' => $string,
331  'allowable_tags' => $allowable_tags,
332  ];
333 
334  $string = strip_tags($string, $allowable_tags);
335  $string = $this->hooks->trigger('format', 'strip_tags', $params, $string);
336 
337  return $string;
338  }
339 
367  public function decode($string) {
368  $string = str_replace(
369  ['&gt;', '&lt;', '&amp;', '&quot;', '&#039;'],
370  ['&amp;gt;', '&amp;lt;', '&amp;amp;', '&amp;quot;', '&amp;#039;'],
371  $string
372  );
373  $string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8');
374  $string = str_replace(
375  ['&amp;gt;', '&amp;lt;', '&amp;amp;', '&amp;quot;', '&amp;#039;'],
376  ['&gt;', '&lt;', '&amp;', '&quot;', '&#039;'],
377  $string
378  );
379  return $string;
380  }
381 }
$params
Saves global plugin settings.
Definition: save.php:13
formatAttributes(array $attrs=[])
Converts an associative array into a string of well-formed HTML/XML attributes Returns a concatenated...
stripTags($string, $allowable_tags=null)
Strip tags and offer plugins the chance.
trait Loggable
Enables adding a logger.
Definition: Loggable.php:12
$args
Some servers don&#39;t allow PHP to check the rewrite, so try via AJAX.
filter_tags($var)
Filter tags from a given string based on registered hooks.
Definition: input.php:82
formatElement($tag_name, array $attributes=[], $text= '', array $options=[])
Format an HTML element.
$options
Elgg admin footer.
Definition: footer.php:6
$html
Definition: section.php:10
decode($string)
Decode HTML markup into a raw text string.
$text
Definition: default.php:28
parseEmails($text)
Takes a string and turns any email addresses into formatted links.
parseUrls($text)
Takes a string and turns any URLs into formatted links.
WARNING: API IN FLUX.
Various helper method for formatting and sanitizing output.
__construct(LoggerInterface $logger, ViewsService $views, PluginHooksService $hooks,\ElggAutoP $autop)
Output constructor.
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1131
if(elgg_extract('hidden', $vars, true)) $attrs
Definition: ajax_loader.php:25
formatBlock($html, array $options=[])
Prepare HTML output.
$attributes
Definition: ajax_loader.php:13
addParagaraphs($string)
Create paragraphs from text with line spacing.