Completed
Push — master ( dff3a1...c429b4 )
by Axel
05:10
created

PurifierHelper::ensureCacheDirectoryExists()   A

Complexity

Conditions 4
Paths 9

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 2
b 0
f 0
nc 9
nop 1
dl 0
loc 21
rs 9.8333
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\SecurityCenterModule\Helper;
15
16
use HTMLPurifier;
17
use HTMLPurifier_Config;
18
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
19
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
20
21
class PurifierHelper
22
{
23
    /**
24
     * @var ZikulaHttpKernelInterface
25
     */
26
    private $kernel;
27
28
    /**
29
     * @var VariableApiInterface
30
     */
31
    private $variableApi;
32
33
    /**
34
     * @var CacheDirHelper
35
     */
36
    private $cacheDirHelper;
37
38
    public function __construct(
39
        ZikulaHttpKernelInterface $kernel,
40
        VariableApiInterface $variableApi,
41
        CacheDirHelper $cacheDirHelper
42
    ) {
43
        $this->kernel = $kernel;
44
        $this->variableApi = $variableApi;
45
        $this->cacheDirHelper = $cacheDirHelper;
46
    }
47
48
    /**
49
     * Retrieves configuration array for HTML Purifier.
50
     */
51
    public function getPurifierConfig(array $args = []): HTMLPurifier_Config
52
    {
53
        $config = $this->getPurifierDefaultConfig();
54
        if (!isset($args['forcedefault']) || true !== $args['forcedefault']) {
55
            $savedConfigSerialised = $this->variableApi->get('ZikulaSecurityCenterModule', 'htmlpurifierConfig');
56
            if (null !== $savedConfigSerialised && false !== $savedConfigSerialised) {
57
                $savedConfigArray = [];
58
                /** @var HTMLPurifier_Config $savedConfig */
59
                $savedConfig = unserialize($savedConfigSerialised);
60
                if (!is_object($savedConfig) && is_array($savedConfig)) {
61
                    // this case may happen for old installations
62
                    $savedConfigArray = $savedConfig;
63
                } elseif (is_object($savedConfig) && $savedConfig instanceof HTMLPurifier_Config) {
64
                    // this is the normal case for newer installations
65
                    $savedConfigArray = $savedConfig->getAll();
66
                }
67
                $savedNamespaces = array_keys($savedConfigArray);
68
                foreach ($savedNamespaces as $savedNamespace) {
69
                    foreach ($savedConfigArray[$savedNamespace] as $key => $value) {
70
                        $config->set($savedNamespace . '.' . $key, $value);
71
                    }
72
                }
73
            }
74
        }
75
76
        $def = $config->getHTMLDefinition(true);
77
        $def->addAttribute('iframe', 'allowfullscreen', 'Bool');
78
79
        $this->cacheDirHelper->ensureCacheDirectoryExists($config->get('Cache.SerializerPath'), true);
80
81
        return $config;
82
    }
83
84
    /**
85
     * Retrieves an instance of HTMLPurifier.
86
     *
87
     * The instance returned is either a newly created instance, or previously created instance
88
     * that has been cached in a static variable.
89
     */
90
    public function getPurifier(array $args = []): HTMLPurifier
91
    {
92
        $force = $args['force'] ?? false;
93
94
        // prepare htmlpurifier class
95
        static $purifier;
96
97
        if (!isset($purifier) || $force) {
98
            $config = $this->getPurifierConfig(['forcedefault' => false]);
99
100
            $purifier = new HTMLPurifier($config);
101
        }
102
103
        return $purifier;
104
    }
105
106
    /**
107
     * Retrieves default configuration array for HTML Purifier.
108
     */
109
    private function getPurifierDefaultConfig(): HTMLPurifier_Config
110
    {
111
        $config = HTMLPurifier_Config::createDefault();
112
113
        $charset = $this->kernel->getCharset();
114
        if ('utf-8' !== mb_strtolower($charset)) {
115
            // set a different character encoding with iconv
116
            $config->set('Core.Encoding', $charset);
117
            // Note that HTML Purifier's support for non-Unicode encodings is crippled by the
118
            // fact that any character not supported by that encoding will be silently
119
            // dropped, EVEN if it is ampersand escaped.  If you want to work around
120
            // this, you are welcome to read docs/enduser-utf8.html in the full package for a fix,
121
            // but please be cognizant of the issues the "solution" creates (for this
122
            // reason, I do not include the solution in this document).
123
        }
124
125
        // allow nofollow and imageviewer to be used as document relationships in the rel attribute
126
        // see http://htmlpurifier.org/live/configdoc/plain.html#Attr.AllowedRel
127
        $config->set('Attr.AllowedRel', [
128
            'nofollow' => true,
129
            'imageviewer' => true,
130
            'lightbox' => true
131
        ]);
132
133
        // general enable for embeds and objects
134
        $config->set('HTML.SafeObject', true);
135
        $config->set('Output.FlashCompat', true);
136
        $config->set('HTML.SafeEmbed', true);
137
138
        $cacheDirectory = $this->kernel->getCacheDir() . '/purifier';
139
        $config->set('Cache.SerializerPath', $cacheDirectory);
140
141
        return $config;
142
    }
143
}
144