saeven/zf3-purifier

Zend Framework 3 的 HTML Purifier 集成模块

1.1.0 2022-01-31 15:07 UTC

README

Mantainer Build Status Latest Stable Version License Total Downloads

Soflomo\Purifier 是 Zend Framework 2 的 HTMLPurifier 集成。

它提供了一个 Laminas\Filter\FilterInterface 实现,以便您可以在您的 Laminas\InputFilter 类中使用 HTMLPurifier。此外,还提供了一个视图助手,帮助在视图脚本中即时净化 HTML。

安装

您可以通过 Composer 安装 Soflomo\Purifier

$: composer require soflomo/purifier

要启用 ZF2 应用程序中的模块,请在 config/application.config.php 中将 Soflomo\Purifier 添加到已启用模块列表中。

使用方法

在您的输入过滤器配置中,使用 htmlpurifier 作为 name 在过滤器规范中使用。

示例 Form

class MyForm extends Laminas\Form\Form implements Laminas\InputFilter\InputFilterProviderInterface
{
    public function init()
    {
        $this->add([
            'name'    => 'text',
            'options' => [
                'label' => 'Text'
            ],
            'attributes' => [
                'type' => 'textarea',
            ],
        ]);
    }

    public function getInputFilterSpecification()
    {
        return [
            'text'  => [
                'required' => true,
                'filters'  => [
                    [ 'name' => 'stringtrim' ],
                    [ 'name' => 'htmlpurifier' ],
                ],
            ],
        ];
    }
}

InputFilter

class MyInputFilter extends Laminas\InputFilter\InputFilter
{
    public function init()
    {
        $this->add([
            'name'     => 'text',
            'required' => true,
            'filters'  => [
                [ 'name' => 'stringtrim' ],
                [ 'name' => 'htmlpurifier' ],
            ],
        ]);
    }
}

或者,您可以使用 FQCN Soflomo\Purifier\PurifierFilter 代替 htmlpurifier 别名。

如果您从各自的插件管理器中获取消费者,这将按原样工作。如果不这样做,请阅读 如何注入过滤器插件管理器

如果您出于某种原因想在视图模板中使用过滤器,您还可以使用视图助手。请注意,HTMLPurifier 不是一个非常快的库,因此,在每个请求上过滤可能会成为一个重大的性能瓶颈。建议使用缓存机制来缓存过滤后的 HTML 输出。视图助手在 htmlPurifier 键下可用

<?php echo $this->htmlPurifier()->purify($foo->getText()) ?>

还有一个简写可用

<?php echo $this->htmlPurifier($foo->getText()) ?>

配置 HTMLPurifier

HTMLPurifier 使用类 HTMLPurifier_Config 来配置其规则。大多数配置规则基于键/值对:$config->set('HTML.Doctype', 'HTML 4.01 Transitional')

全局配置

HTMLPurifier_Config 键/值存储由 Soflomo\Purifier 暴露为 ZF2 配置中的关联数组,因此您可以像这样自定义默认的 HTMLPurifier_Config 实例:

return [
    'soflomo_purifier' => [
        'config' => [
            'HTML.Doctype' => 'HTML 4.01 Transitional'
        ],
    ],
];

配置工厂还处理一个 definitions 子数组,用于向净化器添加自定义定义,如 此处所述

例如

return [
    'soflomo_purifier' => [
        'config' => [
            'HTML.DefinitionID' => 'my custom definitions',
        ], 
        'definitions' => [
            'HTML' => [
                'addAttribute' => [
                    [ 'a', 'target', 'Enum#_blank,_self,_target,_top' ]
                ],
            ],
        ],
    ],
];

这将添加一个 HTMLPurifier_AttrDef_Enum 定义用于 a 元素的 target 属性。请注意,需要一个任意值作为 HTML.DefinitionID 配置键才能正确加载定义。

定义也可以在配置数组中的 definitions 键下设置。这些将覆盖 soflomo_purifier 数组中的键。

每个实例的配置

您还可以使用通常的 options 键使用规格添加过滤器时设置不同的配置。

class MyInputFilter extends Laminas\InputFilter\InputFilter
{
    public function init()
    {
        $this->add([
            'name'     => 'text',
            'required' => true,
            'filters'  => [
                [ 'name' => 'stringtrim' ],
                [
                    'name' => 'htmlpurifier',
                    'options' => [
                        'purifier_config' => [
                            'HTML.AllowedElements' => 'a, span'
                        ],
                    ],
                ],
            ],
        ]);
    }
}

注入 FilterManager

如果您使用 new 关键字手动实例化表单或输入过滤器,而不是从各自的插件管理器(即 FormElementManagerInputFilterManager)中获取,则 FilterManager 不会自动注入到它们的工厂中,这些将回退到使用默认的一个。

因此,您会得到一个 ServiceNotFoundException: Laminas\Filter\FilterPluginManager::get was unable to fetch or create an instance for htmlpurifier。这意味着过滤器插件管理器是延迟实例化的,并且不知道关于 htmlpurifier 插件的任何信息。

您可以通过手动执行初始化器来解决这个问题。

$form = new MyForm();
$formElementManager = $serviceManager->get('FormElementManager');
$formElementManager->injectFactory($form);

// same goes for input filters
$inputFilter = new MyInputFilter();
$inputFilterManager = $serviceManager->get('InputFilterManager');
$inputFilterManager->populateFactory($inputFilter);

然而,强烈建议从相应的插件管理器中拉取表单和输入过滤器,并在适用的情况下使用 init() 方法(该方法将在所有工厂注入后调用)。

性能优化

HTMLPurifier 并不是最快的库。它使用了大量的类和文件,因此自动加载可能会很麻烦。

幸运的是,您可以为 HTMLPurifier 类 创建一个独立版本,其中单个文件包含大多数类。

位于 vendor/bin/purifier-generate-standalone 的脚本为您生成此文件。独立文件创建在 vendor/ezyang/htmlpurifier/library 内,因此请确保您可以在该目录中写入。

Soflomo\Purifier 通过配置选项 soflomo_purifier.standalone 帮助您使用此独立版本。

例如,您可以在您的 config/autoload/local.php 中添加以下内容:

return [
    'soflomo_purifier' => [
        'standalone' => true,
    ],
];

如果您想将独立文件放置在其他位置,也可以设置其路径。

return [
    'soflomo_purifier' => [
        'standalone'      => true,
        'standalone_path' => 'path/to/HTMLPurifier.standalone.php',
    ],
];

注意: 独立生成脚本要求 HTMLPurifier 必须使用版本 <4.7.0 或使用 Composer 的 --prefer-source 标志安装,因为从该版本开始,维护工具已被从存档中移除(参见 htmlpurifier #65)。