diff --git a/composer.json b/composer.json index 746ab326d2f..ecfd7f7eb71 100644 --- a/composer.json +++ b/composer.json @@ -53,6 +53,7 @@ "composer/package-versions-deprecated": "1.11.99.5", "composer/semver": "3.4.3", "endroid/qr-code": "5.1.0", + "ezyang/htmlpurifier": "4.17.0", "guzzlehttp/guzzle": "7.9.2", "jaybizzle/crawler-detect": "^1.2", "laminas/laminas-cache": "3.12.2", diff --git a/composer.lock b/composer.lock index 3ca06deea52..57a72c735af 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "540c871f9b843a7da019964d94455bf4", + "content-hash": "1bb2a6857e13815b065e34b819acb716", "packages": [ { "name": "ahand/mobileesp", @@ -1214,6 +1214,67 @@ ], "time": "2024-09-08T08:52:55+00:00" }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.17.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c", + "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c", + "shasum": "" + }, + "require": { + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" + }, + "require-dev": { + "cerdic/css-tidy": "^1.7 || ^2.0", + "simpletest/simpletest": "dev-master" + }, + "suggest": { + "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.", + "ext-bcmath": "Used for unit conversion and imagecrash protection", + "ext-iconv": "Converts text to and from non-UTF-8 encodings", + "ext-tidy": "Used for pretty-printing HTML" + }, + "type": "library", + "autoload": { + "files": [ + "library/HTMLPurifier.composer.php" + ], + "psr-0": { + "HTMLPurifier": "library/" + }, + "exclude-from-classmap": [ + "/library/HTMLPurifier/Language/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.17.0" + }, + "time": "2023-11-17T15:01:25+00:00" + }, { "name": "filp/whoops", "version": "2.16.0", @@ -14408,7 +14469,7 @@ "platform": { "php": ">=8.1" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { "php": "8.1" }, diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 068680c25c0..ba64c91d2f7 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -2641,3 +2641,10 @@ description = "The REST API provides access to search functions and records cont ; By default, VuFind sorts text in a locale-agnostic way; if this setting is ; turned on, the current user-selected locale will impact sort order. ;use_locale_sorting = true + +; By default HTML is not allowed in record fields, but support for sanitized HTML +; can be enabled per field type. +[HTML_Fields] +;title = false +;title-alt = false +;summary = false diff --git a/module/VuFind/src/VuFind/Content/Summaries/Demo.php b/module/VuFind/src/VuFind/Content/Summaries/Demo.php index 2e7d91deacc..c3a22f191c9 100644 --- a/module/VuFind/src/VuFind/Content/Summaries/Demo.php +++ b/module/VuFind/src/VuFind/Content/Summaries/Demo.php @@ -29,6 +29,8 @@ namespace VuFind\Content\Summaries; +use VuFind\String\PropertyString; + /** * Demo (fake data) summaries content loader. * @@ -56,6 +58,8 @@ public function loadByIsbn($key, \VuFindCode\ISBN $isbnObj) return [ 'Demo summary key: ' . $key, 'Demo summary ISBN: ' . $isbnObj->get13(), + (new PropertyString('Demo non-HTML summary')) + ->setHtml('Demo HTML Summary:
=$this->truncate($summary, 300)?>
+ + truncate($summary, 300); ?> +=$this->escapeOrCleanHtml($shortSummary, $summary, 'summary')?>
- 300): ?> +=$this->transEsc('Full description')?>
@@ -86,7 +88,7 @@ = - $this->record($this->driver)->renderTemplate( + $recordHelper->renderTemplate( 'core-fields.phtml', [ 'driver' => $this->driver, diff --git a/themes/bootstrap3/templates/RecordDriver/DefaultRecord/data-summary.phtml b/themes/bootstrap3/templates/RecordDriver/DefaultRecord/data-summary.phtml index bd4333cb4e5..99b13a9bc1c 100644 --- a/themes/bootstrap3/templates/RecordDriver/DefaultRecord/data-summary.phtml +++ b/themes/bootstrap3/templates/RecordDriver/DefaultRecord/data-summary.phtml @@ -1,10 +1,17 @@ driver->getSummary() as $summary): ?> - =$this->escapeHtml($summary) ?>=$this->truncate($summary, 300)?>
+ + truncate($summary, 300); ?> +=$this->escapeOrCleanHtml($shortSummary, $summary, 'summary')?>
- 300): ?> +=$this->transEsc('Full description')?>
@@ -86,7 +88,7 @@ = - $this->record($this->driver)->renderTemplate( + $recordHelper->renderTemplate( 'core-fields.phtml', [ 'driver' => $this->driver, diff --git a/themes/bootstrap5/templates/RecordDriver/DefaultRecord/data-summary.phtml b/themes/bootstrap5/templates/RecordDriver/DefaultRecord/data-summary.phtml index bd4333cb4e5..99b13a9bc1c 100644 --- a/themes/bootstrap5/templates/RecordDriver/DefaultRecord/data-summary.phtml +++ b/themes/bootstrap5/templates/RecordDriver/DefaultRecord/data-summary.phtml @@ -1,10 +1,17 @@ driver->getSummary() as $summary): ?> - =$this->escapeHtml($summary) ?>