1 <?php 2 3 /** 4 * Parses string hash files. File format is as such: 5 * 6 * DefaultKeyValue 7 * KEY: Value 8 * KEY2: Value2 9 * --MULTILINE-KEY-- 10 * Multiline 11 * value. 12 * 13 * Which would output something similar to: 14 * 15 * array( 16 * 'ID' => 'DefaultKeyValue', 17 * 'KEY' => 'Value', 18 * 'KEY2' => 'Value2', 19 * 'MULTILINE-KEY' => "Multiline\nvalue.\n", 20 * ) 21 * 22 * We use this as an easy to use file-format for configuration schema 23 * files, but the class itself is usage agnostic. 24 * 25 * You can use ---- to forcibly terminate parsing of a single string-hash; 26 * this marker is used in multi string-hashes to delimit boundaries. 27 */ 28 class HTMLPurifier_StringHashParser 29 { 30 31 /** 32 * @type string 33 */ 34 public $default = 'ID'; 35 36 /** 37 * Parses a file that contains a single string-hash. 38 * @param string $file 39 * @return array 40 */ 41 public function parseFile($file) 42 { 43 if (!file_exists($file)) { 44 return false; 45 } 46 $fh = fopen($file, 'r'); 47 if (!$fh) { 48 return false; 49 } 50 $ret = $this->parseHandle($fh); 51 fclose($fh); 52 return $ret; 53 } 54 55 /** 56 * Parses a file that contains multiple string-hashes delimited by '----' 57 * @param string $file 58 * @return array 59 */ 60 public function parseMultiFile($file) 61 { 62 if (!file_exists($file)) { 63 return false; 64 } 65 $ret = array(); 66 $fh = fopen($file, 'r'); 67 if (!$fh) { 68 return false; 69 } 70 while (!feof($fh)) { 71 $ret[] = $this->parseHandle($fh); 72 } 73 fclose($fh); 74 return $ret; 75 } 76 77 /** 78 * Internal parser that acepts a file handle. 79 * @note While it's possible to simulate in-memory parsing by using 80 * custom stream wrappers, if such a use-case arises we should 81 * factor out the file handle into its own class. 82 * @param resource $fh File handle with pointer at start of valid string-hash 83 * block. 84 * @return array 85 */ 86 protected function parseHandle($fh) 87 { 88 $state = false; 89 $single = false; 90 $ret = array(); 91 do { 92 $line = fgets($fh); 93 if ($line === false) { 94 break; 95 } 96 $line = rtrim($line, "\n\r"); 97 if (!$state && $line === '') { 98 continue; 99 } 100 if ($line === '----') { 101 break; 102 } 103 if (strncmp('--#', $line, 3) === 0) { 104 // Comment 105 continue; 106 } elseif (strncmp('--', $line, 2) === 0) { 107 // Multiline declaration 108 $state = trim($line, '- '); 109 if (!isset($ret[$state])) { 110 $ret[$state] = ''; 111 } 112 continue; 113 } elseif (!$state) { 114 $single = true; 115 if (strpos($line, ':') !== false) { 116 // Single-line declaration 117 list($state, $line) = explode(':', $line, 2); 118 $line = trim($line); 119 } else { 120 // Use default declaration 121 $state = $this->default; 122 } 123 } 124 if ($single) { 125 $ret[$state] = $line; 126 $single = false; 127 $state = false; 128 } else { 129 $ret[$state] .= "$line\n"; 130 } 131 } while (!feof($fh)); 132 return $ret; 133 } 134 } 135 136 // vim: et sw=4 sts=4
title
Description
Body
title
Description
Body
title
Description
Body
title
Body