PHPExcel
10 years ago
PHPExcel.php
10 years ago
api.php
10 years ago
arraytoxml.php
10 years ago
chunk.php
10 years ago
config.php
10 years ago
download.php
10 years ago
handler.php
10 years ago
helper.php
10 years ago
input.php
10 years ago
render.php
10 years ago
session.php
10 years ago
upload.php
10 years ago
chunk.php
252 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Chunk |
| 4 | * |
| 5 | * Reads a large file in as chunks for easier parsing. |
| 6 | * |
| 7 | * |
| 8 | * @package default |
| 9 | * @author Max Tsiplyakov |
| 10 | */ |
| 11 | class PMXI_Chunk { |
| 12 | /** |
| 13 | * options |
| 14 | * |
| 15 | * @var array Contains all major options |
| 16 | * @access public |
| 17 | */ |
| 18 | public $options = array( |
| 19 | 'path' => './', // string The path to check for $file in |
| 20 | 'element' => '', // string The XML element to return |
| 21 | 'type' => 'upload', |
| 22 | 'encoding' => 'UTF-8', |
| 23 | 'pointer' => 1, |
| 24 | 'chunkSize' => 1024, |
| 25 | 'filter' => true, |
| 26 | 'get_cloud' => false |
| 27 | ); |
| 28 | |
| 29 | /** |
| 30 | * file |
| 31 | * |
| 32 | * @var string The filename being read |
| 33 | * @access public |
| 34 | */ |
| 35 | public $file = ''; |
| 36 | /** |
| 37 | * pointer |
| 38 | * |
| 39 | * @var integer The current position the file is being read from |
| 40 | * @access public |
| 41 | */ |
| 42 | public $reader; |
| 43 | public $cloud = array(); |
| 44 | public $loop = 1; |
| 45 | |
| 46 | /** |
| 47 | * handle |
| 48 | * |
| 49 | * @var resource The fopen() resource |
| 50 | * @access private |
| 51 | */ |
| 52 | private $handle = null; |
| 53 | /** |
| 54 | * reading |
| 55 | * |
| 56 | * @var boolean Whether the script is currently reading the file |
| 57 | * @access private |
| 58 | */ |
| 59 | |
| 60 | /** |
| 61 | * __construct |
| 62 | * |
| 63 | * Builds the Chunk object |
| 64 | * |
| 65 | * @param string $file The filename to work with |
| 66 | * @param array $options The options with which to parse the file |
| 67 | * @author Dom Hastings |
| 68 | * @access public |
| 69 | */ |
| 70 | public function __construct($file, $options = array()) { |
| 71 | |
| 72 | // merge the options together |
| 73 | $this->options = array_merge($this->options, (is_array($options) ? $options : array())); |
| 74 | |
| 75 | $this->options['chunkSize'] *= PMXI_Plugin::getInstance()->getOption('chunk_size'); |
| 76 | |
| 77 | // set the filename |
| 78 | $this->file = $file; |
| 79 | |
| 80 | $is_html = false; |
| 81 | $f = @fopen($file, "rb"); |
| 82 | while (!@feof($f)) { |
| 83 | $chunk = @fread($f, 1024); |
| 84 | if (strpos($chunk, "<!DOCTYPE") === 0) $is_html = true; |
| 85 | break; |
| 86 | } |
| 87 | @fclose($f); |
| 88 | |
| 89 | if ($is_html) return; |
| 90 | |
| 91 | if (empty($this->options['element']) or $this->options['get_cloud']) |
| 92 | { |
| 93 | if (function_exists('stream_filter_register') and $this->options['filter']){ |
| 94 | stream_filter_register('preprocessxml', 'preprocessXml_filter'); |
| 95 | $path = 'php://filter/read=preprocessxml/resource=' . $this->file; |
| 96 | } |
| 97 | else $path = $this->file; |
| 98 | |
| 99 | $reader = new XMLReader(); |
| 100 | $reader->open($path); |
| 101 | $reader->setParserProperty(XMLReader::VALIDATE, false); |
| 102 | while ( @$reader->read()) { |
| 103 | switch ($reader->nodeType) { |
| 104 | case (XMLREADER::ELEMENT): |
| 105 | if (array_key_exists(str_replace(":", "_", $reader->localName), $this->cloud)) |
| 106 | $this->cloud[str_replace(":", "_", $reader->localName)]++; |
| 107 | else |
| 108 | $this->cloud[str_replace(":", "_", $reader->localName)] = 1; |
| 109 | break; |
| 110 | default: |
| 111 | |
| 112 | break; |
| 113 | } |
| 114 | } |
| 115 | unset($reader); |
| 116 | |
| 117 | if ( ! empty($this->cloud) and empty($this->options['element']) ){ |
| 118 | |
| 119 | arsort($this->cloud); |
| 120 | |
| 121 | $main_elements = array('node', 'product', 'job', 'deal', 'entry', 'item', 'property', 'listing', 'hotel', 'record', 'article', 'post', 'book'); |
| 122 | |
| 123 | foreach ($this->cloud as $element_name => $value) { |
| 124 | if ( in_array(strtolower($element_name), $main_elements) ){ |
| 125 | $this->options['element'] = $element_name; |
| 126 | break; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | if (empty($this->options['element'])){ |
| 131 | foreach ($this->cloud as $el => $count) { |
| 132 | $this->options['element'] = $el; |
| 133 | break; |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | if (function_exists('stream_filter_register') and $this->options['filter']){ |
| 140 | stream_filter_register('preprocessxml', 'preprocessXml_filter'); |
| 141 | $path = 'php://filter/read=preprocessxml/resource=' . $this->file; |
| 142 | } |
| 143 | else $path = $this->file; |
| 144 | |
| 145 | $this->reader = new XMLReader(); |
| 146 | @$this->reader->open($path); |
| 147 | @$this->reader->setParserProperty(XMLReader::VALIDATE, false); |
| 148 | |
| 149 | |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * __destruct |
| 154 | * |
| 155 | * Cleans up |
| 156 | * |
| 157 | * @return void |
| 158 | * @author Dom Hastings |
| 159 | * @access public |
| 160 | */ |
| 161 | public function __destruct() { |
| 162 | // close the file resource |
| 163 | unset($this->reader); |
| 164 | } |
| 165 | |
| 166 | /** |
| 167 | * read |
| 168 | * |
| 169 | * Reads the first available occurence of the XML element $this->options['element'] |
| 170 | * |
| 171 | * @return string The XML string from $this->file |
| 172 | * @author Dom Hastings |
| 173 | * @access public |
| 174 | */ |
| 175 | public function read($debug = false) { |
| 176 | |
| 177 | // trim it |
| 178 | $element = trim($this->options['element']); |
| 179 | |
| 180 | $xml = ''; |
| 181 | |
| 182 | try { |
| 183 | while ( @$this->reader->read() ) { |
| 184 | switch ($this->reader->nodeType) { |
| 185 | case (XMLREADER::ELEMENT): |
| 186 | if ( strtolower(str_replace(":", "_", $this->reader->localName)) == strtolower($element) ) { |
| 187 | |
| 188 | if ($this->loop < $this->options['pointer']){ |
| 189 | $this->loop++; |
| 190 | continue; |
| 191 | } |
| 192 | |
| 193 | $xml = @$this->reader->readOuterXML(); |
| 194 | |
| 195 | break(2); |
| 196 | } |
| 197 | break; |
| 198 | default: |
| 199 | // code ... |
| 200 | break; |
| 201 | } |
| 202 | } |
| 203 | } catch (XmlImportException $e) { |
| 204 | $xml = false; |
| 205 | } |
| 206 | |
| 207 | return ( ! empty($xml) ) ? $this->removeColonsFromRSS(preg_replace('%xmlns.*=\s*([\'""]).*\1%sU', '', $xml)) : false; |
| 208 | |
| 209 | } |
| 210 | |
| 211 | function removeColonsFromRSS($feed) { |
| 212 | |
| 213 | // pull out colons from start tags |
| 214 | // (<\w+):(\w+>) |
| 215 | $pattern = '/(<\w+):(\w+[ |>]{1})/i'; |
| 216 | $replacement = '<$2'; |
| 217 | $feed = preg_replace($pattern, $replacement, $feed); |
| 218 | // pull out colons from end tags |
| 219 | // (<\/\w+):(\w+>) |
| 220 | $pattern = '/(<\/\w+):(\w+>)/i'; |
| 221 | $replacement = '</$2'; |
| 222 | $feed = preg_replace($pattern, $replacement, $feed); |
| 223 | // pull out colons from attributes |
| 224 | $pattern = '/(\s+\w+):(\w+[=]{1})/i'; |
| 225 | $replacement = '$1_$2'; |
| 226 | $feed = preg_replace($pattern, $replacement, $feed); |
| 227 | // pull colons from single element |
| 228 | // (<\w+):(\w+\/>) |
| 229 | $pattern = '/(<\w+):(\w+\/>)/i'; |
| 230 | $replacement = '<$2'; |
| 231 | $feed = preg_replace($pattern, $replacement, $feed); |
| 232 | |
| 233 | return $feed; |
| 234 | |
| 235 | } |
| 236 | |
| 237 | } |
| 238 | |
| 239 | class preprocessXml_filter extends php_user_filter { |
| 240 | |
| 241 | function filter($in, $out, &$consumed, $closing) |
| 242 | { |
| 243 | while ($bucket = stream_bucket_make_writeable($in)) { |
| 244 | PMXI_Import_Record::preprocessXml($bucket->data); |
| 245 | $consumed += $bucket->datalen; |
| 246 | stream_bucket_append($out, $bucket); |
| 247 | } |
| 248 | return PSFS_PASS_ON; |
| 249 | } |
| 250 | |
| 251 | } |
| 252 |