2016-11-29 22:27:19 +00:00
|
|
|
<?php
|
2025-03-29 10:50:03 +00:00
|
|
|
|
2022-02-14 20:48:15 -08:00
|
|
|
/**
|
|
|
|
|
* Provides static methods for cleansing user input before storing in the database.
|
2016-11-29 22:27:19 +00:00
|
|
|
*
|
2022-02-14 20:48:15 -08:00
|
|
|
* @package NamelessMC\Core
|
|
|
|
|
* @author Samerton
|
|
|
|
|
* @version 2.0.0-pr8
|
|
|
|
|
* @license MIT
|
2018-08-19 13:13:58 +01:00
|
|
|
*/
|
2024-03-09 03:19:55 -08:00
|
|
|
class Output
|
|
|
|
|
{
|
2022-02-14 20:48:15 -08:00
|
|
|
/**
|
|
|
|
|
* @var HTMLPurifier Static purifier instance.
|
|
|
|
|
*/
|
2021-10-09 10:10:56 -07:00
|
|
|
private static HTMLPurifier $_purifier;
|
2018-08-19 13:13:58 +01:00
|
|
|
|
2021-04-12 18:36:34 -07:00
|
|
|
/**
|
|
|
|
|
* Returns a clean version of an inputted string.
|
2021-12-05 08:17:24 -08:00
|
|
|
* Will remove HTML, convert HTML entities, and strip slashes.
|
2021-04-12 18:36:34 -07:00
|
|
|
*
|
2024-03-09 03:19:55 -08:00
|
|
|
* @param ?string $input The string which will be cleaned
|
2022-06-01 19:43:38 +02:00
|
|
|
* @return ?string Cleaned version of string.
|
2021-04-12 18:36:34 -07:00
|
|
|
*/
|
2024-03-09 03:19:55 -08:00
|
|
|
public static function getClean(?string $input): ?string
|
|
|
|
|
{
|
2023-04-14 22:56:53 +02:00
|
|
|
return $input === null ? null : htmlspecialchars($input, ENT_QUOTES);
|
2020-12-13 19:38:04 +01:00
|
|
|
}
|
2020-12-13 20:42:04 -08:00
|
|
|
|
2021-04-12 18:36:34 -07:00
|
|
|
/**
|
|
|
|
|
* Returns a decoded version of a clean string.
|
2021-10-29 22:09:38 -07:00
|
|
|
*
|
2024-03-09 03:19:55 -08:00
|
|
|
* @param ?string $input Contains the clean string which will be decoded.
|
2022-06-01 19:43:38 +02:00
|
|
|
* @return ?string Decoded string.
|
2021-04-12 18:36:34 -07:00
|
|
|
*/
|
2024-03-09 03:19:55 -08:00
|
|
|
public static function getDecoded(?string $input): ?string
|
|
|
|
|
{
|
2022-07-03 20:56:15 +02:00
|
|
|
return $input === null ? null : htmlspecialchars_decode($input, ENT_QUOTES);
|
2020-12-13 19:38:04 +01:00
|
|
|
}
|
2018-08-05 19:47:01 +01:00
|
|
|
|
2021-04-12 18:36:34 -07:00
|
|
|
/**
|
|
|
|
|
* Returns a purified version of an inputted string with HTMLPurifier.
|
2021-12-05 08:17:24 -08:00
|
|
|
* Will not remove any HTML tags.
|
2021-04-12 18:36:34 -07:00
|
|
|
*
|
2024-03-09 03:19:55 -08:00
|
|
|
* @param string|null $input String which will be purified.
|
|
|
|
|
* @param bool $escape_invalid Should invalid HTML be escaped instead of fully removed?
|
2025-07-27 10:00:13 +01:00
|
|
|
* @param bool $for_editor Whether the purification is for use in the WYSIWYG editor or not, default true
|
2021-10-29 22:09:38 -07:00
|
|
|
*
|
2021-04-12 18:36:34 -07:00
|
|
|
* @return string Purified string.
|
|
|
|
|
*/
|
2025-07-27 10:00:13 +01:00
|
|
|
public static function getPurified(?string $input, bool $escape_invalid = false, bool $for_editor = true): string
|
2024-03-09 03:19:55 -08:00
|
|
|
{
|
2021-10-09 10:10:56 -07:00
|
|
|
if (!isset(self::$_purifier)) {
|
2020-12-13 19:38:04 +01:00
|
|
|
$purifierConfig = HTMLPurifier_Config::createDefault();
|
2018-08-19 13:13:58 +01:00
|
|
|
|
2020-12-13 19:38:04 +01:00
|
|
|
// Config settings
|
|
|
|
|
$purifierConfig->set('HTML.Doctype', 'XHTML 1.0 Transitional');
|
|
|
|
|
$purifierConfig->set('URI.DisableExternalResources', false);
|
|
|
|
|
$purifierConfig->set('URI.DisableResources', false);
|
2024-12-01 18:38:31 +00:00
|
|
|
$purifierConfig->set('HTML.Allowed', 'u,a,p,p[style],b,i,small,blockquote,span[style],span[class],p,strong,em,li,ul,ol,div[align],br,img,figure,figcaption');
|
2025-05-21 19:46:01 +01:00
|
|
|
$purifierConfig->set('CSS.AllowedProperties', ['text-align', 'display', 'float', 'color', 'background-color', 'background', 'font-size', 'font-family', 'margin', 'margin-bottom', 'margin-left', 'margin-right', 'margin-top', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'text-decoration', 'font-weight', 'font-style', 'font-size', 'vertical-align', 'width', 'border-color', 'border-style']);
|
2020-12-13 19:38:04 +01:00
|
|
|
$purifierConfig->set('CSS.AllowTricky', true);
|
2024-12-01 18:38:31 +00:00
|
|
|
$purifierConfig->set('HTML.AllowedAttributes', 'target, rel, href, id, src, height, width, alt, class, *.style, dir');
|
2025-03-19 19:39:00 +00:00
|
|
|
$purifierConfig->set('HTML.ForbiddenAttributes', 'iframe@width,iframe@height');
|
2021-10-29 22:00:05 -07:00
|
|
|
$purifierConfig->set('Attr.AllowedFrameTargets', ['_blank', '_self', '_parent', '_top']);
|
|
|
|
|
$purifierConfig->set('Attr.AllowedRel', ['noopener', 'nofollow']);
|
2020-12-13 19:38:04 +01:00
|
|
|
$purifierConfig->set('HTML.SafeIframe', true);
|
|
|
|
|
$purifierConfig->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%');
|
2021-05-24 18:31:27 +01:00
|
|
|
$purifierConfig->set('Core.EscapeInvalidTags', $escape_invalid);
|
2020-12-13 19:38:04 +01:00
|
|
|
$purifierConfig->set('AutoFormat.Linkify', true);
|
2018-08-19 13:13:58 +01:00
|
|
|
|
2020-12-13 19:38:04 +01:00
|
|
|
$purifierConfig->set('HTML.DefinitionID', 'namelessmc');
|
|
|
|
|
$purifierConfig->set('HTML.DefinitionRev', 1);
|
|
|
|
|
$purifierConfig->set('Cache.DefinitionImpl', null);
|
2021-04-12 18:36:34 -07:00
|
|
|
|
2020-12-13 20:42:04 -08:00
|
|
|
if ($def = $purifierConfig->maybeGetRawHTMLDefinition()) {
|
2020-12-13 19:38:04 +01:00
|
|
|
$def->addElement('figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common');
|
|
|
|
|
$def->addElement('figcaption', 'Inline', 'Flow', 'Common');
|
|
|
|
|
}
|
2021-04-12 18:36:34 -07:00
|
|
|
|
2020-12-13 19:38:04 +01:00
|
|
|
self::$_purifier = new HTMLPurifier($purifierConfig);
|
|
|
|
|
}
|
2018-08-19 13:13:58 +01:00
|
|
|
|
2025-07-27 10:00:13 +01:00
|
|
|
$purified = self::$_purifier->purify($input);
|
|
|
|
|
|
|
|
|
|
if ($for_editor) {
|
|
|
|
|
// Double encode < and > to prevent editor from parsing them
|
|
|
|
|
return str_replace(['<', '>'], ['&lt;', '&gt;'], $purified);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $purified;
|
2020-12-13 19:38:04 +01:00
|
|
|
}
|
2022-04-08 08:50:32 +02:00
|
|
|
|
|
|
|
|
/**
|
2024-03-09 03:19:55 -08:00
|
|
|
* urlencode() a string without encoding slashes.
|
2022-04-08 08:50:32 +02:00
|
|
|
*
|
2024-03-09 03:19:55 -08:00
|
|
|
* @param string $input String to encode
|
2022-04-08 08:50:32 +02:00
|
|
|
* @return string Encoded string
|
|
|
|
|
*/
|
2024-03-09 03:19:55 -08:00
|
|
|
public static function urlEncodeAllowSlashes(string $input): string
|
|
|
|
|
{
|
2022-04-08 08:50:32 +02:00
|
|
|
return str_replace('%2F', '/', urlencode($input));
|
|
|
|
|
}
|
2020-12-13 19:38:04 +01:00
|
|
|
}
|