| 1: | <?php
|
| 2: |
|
| 3: | class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCache
|
| 4: | {
|
| 5: |
|
| 6: | |
| 7: | |
| 8: | |
| 9: | |
| 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: | |
| 28: | |
| 29: | |
| 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: | |
| 45: | |
| 46: | |
| 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: | |
| 65: | |
| 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: | |
| 78: | |
| 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: | |
| 91: | |
| 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: |
|
| 101: |
|
| 102: |
|
| 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: | |
| 121: | |
| 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: |
|
| 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: | |
| 152: | |
| 153: | |
| 154: | |
| 155: | |
| 156: |
|
| 157: | public function generateFilePath($config)
|
| 158: | {
|
| 159: | $key = $this->generateKey($config);
|
| 160: | return $this->generateDirectoryPath($config) . '/' . $key . '.ser';
|
| 161: | }
|
| 162: |
|
| 163: | |
| 164: | |
| 165: | |
| 166: | |
| 167: | |
| 168: | |
| 169: |
|
| 170: | public function generateDirectoryPath($config)
|
| 171: | {
|
| 172: | $base = $this->generateBaseDirectoryPath($config);
|
| 173: | return $base . '/' . $this->type;
|
| 174: | }
|
| 175: |
|
| 176: | |
| 177: | |
| 178: | |
| 179: | |
| 180: | |
| 181: | |
| 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: | |
| 192: | |
| 193: | |
| 194: | |
| 195: | |
| 196: |
|
| 197: | private function _write($file, $data, $config)
|
| 198: | {
|
| 199: | $result = file_put_contents($file, $data);
|
| 200: | if ($result !== false) {
|
| 201: |
|
| 202: | $chmod = $config->get('Cache.SerializerPermissions');
|
| 203: | if ($chmod !== null) {
|
| 204: | chmod($file, $chmod & 0666);
|
| 205: | }
|
| 206: | }
|
| 207: | return $result;
|
| 208: | }
|
| 209: |
|
| 210: | |
| 211: | |
| 212: | |
| 213: | |
| 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: | |
| 259: | |
| 260: | |
| 261: | |
| 262: | |
| 263: |
|
| 264: | private function _testPermissions($dir, $chmod)
|
| 265: | {
|
| 266: |
|
| 267: | if (is_writable($dir)) {
|
| 268: | return true;
|
| 269: | }
|
| 270: | if (!is_dir($dir)) {
|
| 271: |
|
| 272: |
|
| 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: |
|
| 281: | if (fileowner($dir) === posix_getuid()) {
|
| 282: |
|
| 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: |
|
| 291: |
|
| 292: | $chmod = $chmod | 0777;
|
| 293: | }
|
| 294: | trigger_error(
|
| 295: | 'Directory ' . $dir . ' not writable, ' .
|
| 296: | 'please chmod to ' . decoct($chmod),
|
| 297: | E_USER_WARNING
|
| 298: | );
|
| 299: | } else {
|
| 300: |
|
| 301: | trigger_error(
|
| 302: | 'Directory ' . $dir . ' not writable, ' .
|
| 303: | 'please alter file permissions',
|
| 304: | E_USER_WARNING
|
| 305: | );
|
| 306: | }
|
| 307: | return false;
|
| 308: | }
|
| 309: | }
|
| 310: |
|
| 311: |
|
| 312: | |