Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCache
4
{
5
 
6
    /**
7
     * @param HTMLPurifier_Definition $def
8
     * @param HTMLPurifier_Config $config
9
     * @return int|bool
10
     */
11
    public function add($def, $config)
12
    {
13
        if (!$this->checkDefType($def)) {
14
            return;
15
        }
16
        $file = $this->generateFilePath($config);
17
        if (file_exists($file)) {
18
            return false;
19
        }
20
        if (!$this->_prepareDir($config)) {
21
            return false;
22
        }
23
        return $this->_write($file, serialize($def), $config);
24
    }
25
 
26
    /**
27
     * @param HTMLPurifier_Definition $def
28
     * @param HTMLPurifier_Config $config
29
     * @return int|bool
30
     */
31
    public function set($def, $config)
32
    {
33
        if (!$this->checkDefType($def)) {
34
            return;
35
        }
36
        $file = $this->generateFilePath($config);
37
        if (!$this->_prepareDir($config)) {
38
            return false;
39
        }
40
        return $this->_write($file, serialize($def), $config);
41
    }
42
 
43
    /**
44
     * @param HTMLPurifier_Definition $def
45
     * @param HTMLPurifier_Config $config
46
     * @return int|bool
47
     */
48
    public function replace($def, $config)
49
    {
50
        if (!$this->checkDefType($def)) {
51
            return;
52
        }
53
        $file = $this->generateFilePath($config);
54
        if (!file_exists($file)) {
55
            return false;
56
        }
57
        if (!$this->_prepareDir($config)) {
58
            return false;
59
        }
60
        return $this->_write($file, serialize($def), $config);
61
    }
62
 
63
    /**
64
     * @param HTMLPurifier_Config $config
65
     * @return bool|HTMLPurifier_Config
66
     */
67
    public function get($config)
68
    {
69
        $file = $this->generateFilePath($config);
70
        if (!file_exists($file)) {
71
            return false;
72
        }
73
        return unserialize(file_get_contents($file));
74
    }
75
 
76
    /**
77
     * @param HTMLPurifier_Config $config
78
     * @return bool
79
     */
80
    public function remove($config)
81
    {
82
        $file = $this->generateFilePath($config);
83
        if (!file_exists($file)) {
84
            return false;
85
        }
86
        return unlink($file);
87
    }
88
 
89
    /**
90
     * @param HTMLPurifier_Config $config
91
     * @return bool
92
     */
93
    public function flush($config)
94
    {
95
        if (!$this->_prepareDir($config)) {
96
            return false;
97
        }
98
        $dir = $this->generateDirectoryPath($config);
99
        $dh = opendir($dir);
100
        // Apparently, on some versions of PHP, readdir will return
101
        // an empty string if you pass an invalid argument to readdir.
102
        // So you need this test.  See #49.
103
        if (false === $dh) {
104
            return false;
105
        }
106
        while (false !== ($filename = readdir($dh))) {
107
            if (empty($filename)) {
108
                continue;
109
            }
110
            if ($filename[0] === '.') {
111
                continue;
112
            }
113
            unlink($dir . '/' . $filename);
114
        }
115
        closedir($dh);
116
        return true;
117
    }
118
 
119
    /**
120
     * @param HTMLPurifier_Config $config
121
     * @return bool
122
     */
123
    public function cleanup($config)
124
    {
125
        if (!$this->_prepareDir($config)) {
126
            return false;
127
        }
128
        $dir = $this->generateDirectoryPath($config);
129
        $dh = opendir($dir);
130
        // See #49 (and above).
131
        if (false === $dh) {
132
            return false;
133
        }
134
        while (false !== ($filename = readdir($dh))) {
135
            if (empty($filename)) {
136
                continue;
137
            }
138
            if ($filename[0] === '.') {
139
                continue;
140
            }
141
            $key = substr($filename, 0, strlen($filename) - 4);
142
            if ($this->isOld($key, $config)) {
143
                unlink($dir . '/' . $filename);
144
            }
145
        }
146
        closedir($dh);
147
        return true;
148
    }
149
 
150
    /**
151
     * Generates the file path to the serial file corresponding to
152
     * the configuration and definition name
153
     * @param HTMLPurifier_Config $config
154
     * @return string
155
     * @todo Make protected
156
     */
157
    public function generateFilePath($config)
158
    {
159
        $key = $this->generateKey($config);
160
        return $this->generateDirectoryPath($config) . '/' . $key . '.ser';
161
    }
162
 
163
    /**
164
     * Generates the path to the directory contain this cache's serial files
165
     * @param HTMLPurifier_Config $config
166
     * @return string
167
     * @note No trailing slash
168
     * @todo Make protected
169
     */
170
    public function generateDirectoryPath($config)
171
    {
172
        $base = $this->generateBaseDirectoryPath($config);
173
        return $base . '/' . $this->type;
174
    }
175
 
176
    /**
177
     * Generates path to base directory that contains all definition type
178
     * serials
179
     * @param HTMLPurifier_Config $config
180
     * @return mixed|string
181
     * @todo Make protected
182
     */
183
    public function generateBaseDirectoryPath($config)
184
    {
185
        $base = $config->get('Cache.SerializerPath');
186
        $base = is_null($base) ? HTMLPURIFIER_PREFIX . '/HTMLPurifier/DefinitionCache/Serializer' : $base;
187
        return $base;
188
    }
189
 
190
    /**
191
     * Convenience wrapper function for file_put_contents
192
     * @param string $file File name to write to
193
     * @param string $data Data to write into file
194
     * @param HTMLPurifier_Config $config
195
     * @return int|bool Number of bytes written if success, or false if failure.
196
     */
197
    private function _write($file, $data, $config)
198
    {
199
        $result = file_put_contents($file, $data);
200
        if ($result !== false) {
201
            // set permissions of the new file (no execute)
202
            $chmod = $config->get('Cache.SerializerPermissions');
203
            if ($chmod !== null) {
204
                chmod($file, $chmod & 0666);
205
            }
206
        }
207
        return $result;
208
    }
209
 
210
    /**
211
     * Prepares the directory that this type stores the serials in
212
     * @param HTMLPurifier_Config $config
213
     * @return bool True if successful
214
     */
215
    private function _prepareDir($config)
216
    {
217
        $directory = $this->generateDirectoryPath($config);
218
        $chmod = $config->get('Cache.SerializerPermissions');
219
        if ($chmod === null) {
220
            if (!@mkdir($directory) && !is_dir($directory)) {
221
                trigger_error(
222
                    'Could not create directory ' . $directory . '',
223
                    E_USER_WARNING
224
                );
225
                return false;
226
            }
227
            return true;
228
        }
229
        if (!is_dir($directory)) {
230
            $base = $this->generateBaseDirectoryPath($config);
231
            if (!is_dir($base)) {
232
                trigger_error(
233
                    'Base directory ' . $base . ' does not exist,
234
                    please create or change using %Cache.SerializerPath',
235
                    E_USER_WARNING
236
                );
237
                return false;
238
            } elseif (!$this->_testPermissions($base, $chmod)) {
239
                return false;
240
            }
241
            if (!@mkdir($directory, $chmod) && !is_dir($directory)) {
242
                trigger_error(
243
                    'Could not create directory ' . $directory . '',
244
                    E_USER_WARNING
245
                );
246
                return false;
247
            }
248
            if (!$this->_testPermissions($directory, $chmod)) {
249
                return false;
250
            }
251
        } elseif (!$this->_testPermissions($directory, $chmod)) {
252
            return false;
253
        }
254
        return true;
255
    }
256
 
257
    /**
258
     * Tests permissions on a directory and throws out friendly
259
     * error messages and attempts to chmod it itself if possible
260
     * @param string $dir Directory path
261
     * @param int $chmod Permissions
262
     * @return bool True if directory is writable
263
     */
264
    private function _testPermissions($dir, $chmod)
265
    {
266
        // early abort, if it is writable, everything is hunky-dory
267
        if (is_writable($dir)) {
268
            return true;
269
        }
270
        if (!is_dir($dir)) {
271
            // generally, you'll want to handle this beforehand
272
            // so a more specific error message can be given
273
            trigger_error(
274
                'Directory ' . $dir . ' does not exist',
275
                E_USER_WARNING
276
            );
277
            return false;
278
        }
279
        if (function_exists('posix_getuid') && $chmod !== null) {
280
            // POSIX system, we can give more specific advice
281
            if (fileowner($dir) === posix_getuid()) {
282
                // we can chmod it ourselves
283
                $chmod = $chmod | 0700;
284
                if (chmod($dir, $chmod)) {
285
                    return true;
286
                }
287
            } elseif (filegroup($dir) === posix_getgid()) {
288
                $chmod = $chmod | 0070;
289
            } else {
290
              // PHP's probably running as nobody, it is
291
              // not obvious how to fix this (777 is probably
292
              // bad if you are multi-user), let the user figure it out
293
                $chmod = null;
294
            }
295
            trigger_error(
296
                'Directory ' . $dir . ' not writable. ' .
297
                ($chmod === null ? '' : 'Please chmod to ' . decoct($chmod)),
298
                E_USER_WARNING
299
            );
300
        } else {
301
            // generic error message
302
            trigger_error(
303
                'Directory ' . $dir . ' not writable, ' .
304
                'please alter file permissions',
305
                E_USER_WARNING
306
            );
307
        }
308
        return false;
309
    }
310
}
311
 
312
// vim: et sw=4 sts=4