1 | <?php |
---|
2 | /** |
---|
3 | * PHPExcel |
---|
4 | * |
---|
5 | * Copyright (c) 2006 - 2014 PHPExcel |
---|
6 | * |
---|
7 | * This library is free software; you can redistribute it and/or |
---|
8 | * modify it under the terms of the GNU Lesser General Public |
---|
9 | * License as published by the Free Software Foundation; either |
---|
10 | * version 2.1 of the License, or (at your option) any later version. |
---|
11 | * |
---|
12 | * This library is distributed in the hope that it will be useful, |
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
15 | * Lesser General Public License for more details. |
---|
16 | * |
---|
17 | * You should have received a copy of the GNU Lesser General Public |
---|
18 | * License along with this library; if not, write to the Free Software |
---|
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
---|
20 | * |
---|
21 | * @category PHPExcel |
---|
22 | * @package PHPExcel_Writer_Excel5 |
---|
23 | * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) |
---|
24 | * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
---|
25 | * @version 1.8.0, 2014-03-02 |
---|
26 | */ |
---|
27 | |
---|
28 | |
---|
29 | /** |
---|
30 | * PHPExcel_Writer_Excel5 |
---|
31 | * |
---|
32 | * @category PHPExcel |
---|
33 | * @package PHPExcel_Writer_Excel5 |
---|
34 | * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) |
---|
35 | */ |
---|
36 | class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter |
---|
37 | { |
---|
38 | /** |
---|
39 | * PHPExcel object |
---|
40 | * |
---|
41 | * @var PHPExcel |
---|
42 | */ |
---|
43 | private $_phpExcel; |
---|
44 | |
---|
45 | /** |
---|
46 | * Total number of shared strings in workbook |
---|
47 | * |
---|
48 | * @var int |
---|
49 | */ |
---|
50 | private $_str_total = 0; |
---|
51 | |
---|
52 | /** |
---|
53 | * Number of unique shared strings in workbook |
---|
54 | * |
---|
55 | * @var int |
---|
56 | */ |
---|
57 | private $_str_unique = 0; |
---|
58 | |
---|
59 | /** |
---|
60 | * Array of unique shared strings in workbook |
---|
61 | * |
---|
62 | * @var array |
---|
63 | */ |
---|
64 | private $_str_table = array(); |
---|
65 | |
---|
66 | /** |
---|
67 | * Color cache. Mapping between RGB value and color index. |
---|
68 | * |
---|
69 | * @var array |
---|
70 | */ |
---|
71 | private $_colors; |
---|
72 | |
---|
73 | /** |
---|
74 | * Formula parser |
---|
75 | * |
---|
76 | * @var PHPExcel_Writer_Excel5_Parser |
---|
77 | */ |
---|
78 | private $_parser; |
---|
79 | |
---|
80 | /** |
---|
81 | * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. |
---|
82 | * |
---|
83 | * @var array |
---|
84 | */ |
---|
85 | private $_IDCLs; |
---|
86 | |
---|
87 | /** |
---|
88 | * Basic OLE object summary information |
---|
89 | * |
---|
90 | * @var array |
---|
91 | */ |
---|
92 | private $_summaryInformation; |
---|
93 | |
---|
94 | /** |
---|
95 | * Extended OLE object document summary information |
---|
96 | * |
---|
97 | * @var array |
---|
98 | */ |
---|
99 | private $_documentSummaryInformation; |
---|
100 | |
---|
101 | /** |
---|
102 | * Create a new PHPExcel_Writer_Excel5 |
---|
103 | * |
---|
104 | * @param PHPExcel $phpExcel PHPExcel object |
---|
105 | */ |
---|
106 | public function __construct(PHPExcel $phpExcel) { |
---|
107 | $this->_phpExcel = $phpExcel; |
---|
108 | |
---|
109 | $this->_parser = new PHPExcel_Writer_Excel5_Parser(); |
---|
110 | } |
---|
111 | |
---|
112 | /** |
---|
113 | * Save PHPExcel to file |
---|
114 | * |
---|
115 | * @param string $pFilename |
---|
116 | * @throws PHPExcel_Writer_Exception |
---|
117 | */ |
---|
118 | public function save($pFilename = null) { |
---|
119 | |
---|
120 | // garbage collect |
---|
121 | $this->_phpExcel->garbageCollect(); |
---|
122 | |
---|
123 | $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); |
---|
124 | PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); |
---|
125 | $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); |
---|
126 | PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); |
---|
127 | |
---|
128 | // initialize colors array |
---|
129 | $this->_colors = array(); |
---|
130 | |
---|
131 | // Initialise workbook writer |
---|
132 | $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, |
---|
133 | $this->_str_total, $this->_str_unique, $this->_str_table, |
---|
134 | $this->_colors, $this->_parser); |
---|
135 | |
---|
136 | // Initialise worksheet writers |
---|
137 | $countSheets = $this->_phpExcel->getSheetCount(); |
---|
138 | for ($i = 0; $i < $countSheets; ++$i) { |
---|
139 | $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, |
---|
140 | $this->_str_table, $this->_colors, |
---|
141 | $this->_parser, |
---|
142 | $this->_preCalculateFormulas, |
---|
143 | $this->_phpExcel->getSheet($i)); |
---|
144 | } |
---|
145 | |
---|
146 | // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. |
---|
147 | $this->_buildWorksheetEschers(); |
---|
148 | $this->_buildWorkbookEscher(); |
---|
149 | |
---|
150 | // add 15 identical cell style Xfs |
---|
151 | // for now, we use the first cellXf instead of cellStyleXf |
---|
152 | $cellXfCollection = $this->_phpExcel->getCellXfCollection(); |
---|
153 | for ($i = 0; $i < 15; ++$i) { |
---|
154 | $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); |
---|
155 | } |
---|
156 | |
---|
157 | // add all the cell Xfs |
---|
158 | foreach ($this->_phpExcel->getCellXfCollection() as $style) { |
---|
159 | $this->_writerWorkbook->addXfWriter($style, false); |
---|
160 | } |
---|
161 | |
---|
162 | // add fonts from rich text eleemnts |
---|
163 | for ($i = 0; $i < $countSheets; ++$i) { |
---|
164 | foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { |
---|
165 | $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); |
---|
166 | $cVal = $cell->getValue(); |
---|
167 | if ($cVal instanceof PHPExcel_RichText) { |
---|
168 | $elements = $cVal->getRichTextElements(); |
---|
169 | foreach ($elements as $element) { |
---|
170 | if ($element instanceof PHPExcel_RichText_Run) { |
---|
171 | $font = $element->getFont(); |
---|
172 | $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); |
---|
173 | } |
---|
174 | } |
---|
175 | } |
---|
176 | } |
---|
177 | } |
---|
178 | |
---|
179 | // initialize OLE file |
---|
180 | $workbookStreamName = 'Workbook'; |
---|
181 | $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); |
---|
182 | |
---|
183 | // Write the worksheet streams before the global workbook stream, |
---|
184 | // because the byte sizes of these are needed in the global workbook stream |
---|
185 | $worksheetSizes = array(); |
---|
186 | for ($i = 0; $i < $countSheets; ++$i) { |
---|
187 | $this->_writerWorksheets[$i]->close(); |
---|
188 | $worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize; |
---|
189 | } |
---|
190 | |
---|
191 | // add binary data for global workbook stream |
---|
192 | $OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes)); |
---|
193 | |
---|
194 | // add binary data for sheet streams |
---|
195 | for ($i = 0; $i < $countSheets; ++$i) { |
---|
196 | $OLE->append($this->_writerWorksheets[$i]->getData()); |
---|
197 | } |
---|
198 | |
---|
199 | $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); |
---|
200 | // initialize OLE Document Summary Information |
---|
201 | if(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){ |
---|
202 | $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); |
---|
203 | $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); |
---|
204 | } |
---|
205 | |
---|
206 | $this->_summaryInformation = $this->_writeSummaryInformation(); |
---|
207 | // initialize OLE Summary Information |
---|
208 | if(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){ |
---|
209 | $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); |
---|
210 | $OLE_SummaryInformation->append($this->_summaryInformation); |
---|
211 | } |
---|
212 | |
---|
213 | // define OLE Parts |
---|
214 | $arrRootData = array($OLE); |
---|
215 | // initialize OLE Properties file |
---|
216 | if(isset($OLE_SummaryInformation)){ |
---|
217 | $arrRootData[] = $OLE_SummaryInformation; |
---|
218 | } |
---|
219 | // initialize OLE Extended Properties file |
---|
220 | if(isset($OLE_DocumentSummaryInformation)){ |
---|
221 | $arrRootData[] = $OLE_DocumentSummaryInformation; |
---|
222 | } |
---|
223 | |
---|
224 | $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData); |
---|
225 | // save the OLE file |
---|
226 | $res = $root->save($pFilename); |
---|
227 | |
---|
228 | PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); |
---|
229 | PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); |
---|
230 | } |
---|
231 | |
---|
232 | /** |
---|
233 | * Set temporary storage directory |
---|
234 | * |
---|
235 | * @deprecated |
---|
236 | * @param string $pValue Temporary storage directory |
---|
237 | * @throws PHPExcel_Writer_Exception when directory does not exist |
---|
238 | * @return PHPExcel_Writer_Excel5 |
---|
239 | */ |
---|
240 | public function setTempDir($pValue = '') { |
---|
241 | return $this; |
---|
242 | } |
---|
243 | |
---|
244 | /** |
---|
245 | * Build the Worksheet Escher objects |
---|
246 | * |
---|
247 | */ |
---|
248 | private function _buildWorksheetEschers() |
---|
249 | { |
---|
250 | // 1-based index to BstoreContainer |
---|
251 | $blipIndex = 0; |
---|
252 | $lastReducedSpId = 0; |
---|
253 | $lastSpId = 0; |
---|
254 | |
---|
255 | foreach ($this->_phpExcel->getAllsheets() as $sheet) { |
---|
256 | // sheet index |
---|
257 | $sheetIndex = $sheet->getParent()->getIndex($sheet); |
---|
258 | |
---|
259 | $escher = null; |
---|
260 | |
---|
261 | // check if there are any shapes for this sheet |
---|
262 | $filterRange = $sheet->getAutoFilter()->getRange(); |
---|
263 | if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) { |
---|
264 | continue; |
---|
265 | } |
---|
266 | |
---|
267 | // create intermediate Escher object |
---|
268 | $escher = new PHPExcel_Shared_Escher(); |
---|
269 | |
---|
270 | // dgContainer |
---|
271 | $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); |
---|
272 | |
---|
273 | // set the drawing index (we use sheet index + 1) |
---|
274 | $dgId = $sheet->getParent()->getIndex($sheet) + 1; |
---|
275 | $dgContainer->setDgId($dgId); |
---|
276 | $escher->setDgContainer($dgContainer); |
---|
277 | |
---|
278 | // spgrContainer |
---|
279 | $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); |
---|
280 | $dgContainer->setSpgrContainer($spgrContainer); |
---|
281 | |
---|
282 | // add one shape which is the group shape |
---|
283 | $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); |
---|
284 | $spContainer->setSpgr(true); |
---|
285 | $spContainer->setSpType(0); |
---|
286 | $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10); |
---|
287 | $spgrContainer->addChild($spContainer); |
---|
288 | |
---|
289 | // add the shapes |
---|
290 | |
---|
291 | $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet |
---|
292 | |
---|
293 | foreach ($sheet->getDrawingCollection() as $drawing) { |
---|
294 | ++$blipIndex; |
---|
295 | |
---|
296 | ++$countShapes[$sheetIndex]; |
---|
297 | |
---|
298 | // add the shape |
---|
299 | $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); |
---|
300 | |
---|
301 | // set the shape type |
---|
302 | $spContainer->setSpType(0x004B); |
---|
303 | // set the shape flag |
---|
304 | $spContainer->setSpFlag(0x02); |
---|
305 | |
---|
306 | // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) |
---|
307 | $reducedSpId = $countShapes[$sheetIndex]; |
---|
308 | $spId = $reducedSpId |
---|
309 | | ($sheet->getParent()->getIndex($sheet) + 1) << 10; |
---|
310 | $spContainer->setSpId($spId); |
---|
311 | |
---|
312 | // keep track of last reducedSpId |
---|
313 | $lastReducedSpId = $reducedSpId; |
---|
314 | |
---|
315 | // keep track of last spId |
---|
316 | $lastSpId = $spId; |
---|
317 | |
---|
318 | // set the BLIP index |
---|
319 | $spContainer->setOPT(0x4104, $blipIndex); |
---|
320 | |
---|
321 | // set coordinates and offsets, client anchor |
---|
322 | $coordinates = $drawing->getCoordinates(); |
---|
323 | $offsetX = $drawing->getOffsetX(); |
---|
324 | $offsetY = $drawing->getOffsetY(); |
---|
325 | $width = $drawing->getWidth(); |
---|
326 | $height = $drawing->getHeight(); |
---|
327 | |
---|
328 | $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); |
---|
329 | |
---|
330 | $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); |
---|
331 | $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); |
---|
332 | $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); |
---|
333 | $spContainer->setEndCoordinates($twoAnchor['endCoordinates']); |
---|
334 | $spContainer->setEndOffsetX($twoAnchor['endOffsetX']); |
---|
335 | $spContainer->setEndOffsetY($twoAnchor['endOffsetY']); |
---|
336 | |
---|
337 | $spgrContainer->addChild($spContainer); |
---|
338 | } |
---|
339 | |
---|
340 | // AutoFilters |
---|
341 | if(!empty($filterRange)){ |
---|
342 | $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); |
---|
343 | $iNumColStart = $rangeBounds[0][0]; |
---|
344 | $iNumColEnd = $rangeBounds[1][0]; |
---|
345 | |
---|
346 | $iInc = $iNumColStart; |
---|
347 | while($iInc <= $iNumColEnd){ |
---|
348 | ++$countShapes[$sheetIndex]; |
---|
349 | |
---|
350 | // create an Drawing Object for the dropdown |
---|
351 | $oDrawing = new PHPExcel_Worksheet_BaseDrawing(); |
---|
352 | // get the coordinates of drawing |
---|
353 | $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; |
---|
354 | $oDrawing->setCoordinates($cDrawing); |
---|
355 | $oDrawing->setWorksheet($sheet); |
---|
356 | |
---|
357 | // add the shape |
---|
358 | $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); |
---|
359 | // set the shape type |
---|
360 | $spContainer->setSpType(0x00C9); |
---|
361 | // set the shape flag |
---|
362 | $spContainer->setSpFlag(0x01); |
---|
363 | |
---|
364 | // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) |
---|
365 | $reducedSpId = $countShapes[$sheetIndex]; |
---|
366 | $spId = $reducedSpId |
---|
367 | | ($sheet->getParent()->getIndex($sheet) + 1) << 10; |
---|
368 | $spContainer->setSpId($spId); |
---|
369 | |
---|
370 | // keep track of last reducedSpId |
---|
371 | $lastReducedSpId = $reducedSpId; |
---|
372 | |
---|
373 | // keep track of last spId |
---|
374 | $lastSpId = $spId; |
---|
375 | |
---|
376 | $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping |
---|
377 | $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape |
---|
378 | $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest |
---|
379 | $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash |
---|
380 | $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint |
---|
381 | |
---|
382 | // set coordinates and offsets, client anchor |
---|
383 | $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1)); |
---|
384 | $endCoordinates .= $rangeBounds[0][1] + 1; |
---|
385 | |
---|
386 | $spContainer->setStartCoordinates($cDrawing); |
---|
387 | $spContainer->setStartOffsetX(0); |
---|
388 | $spContainer->setStartOffsetY(0); |
---|
389 | $spContainer->setEndCoordinates($endCoordinates); |
---|
390 | $spContainer->setEndOffsetX(0); |
---|
391 | $spContainer->setEndOffsetY(0); |
---|
392 | |
---|
393 | $spgrContainer->addChild($spContainer); |
---|
394 | $iInc++; |
---|
395 | } |
---|
396 | } |
---|
397 | |
---|
398 | // identifier clusters, used for workbook Escher object |
---|
399 | $this->_IDCLs[$dgId] = $lastReducedSpId; |
---|
400 | |
---|
401 | // set last shape index |
---|
402 | $dgContainer->setLastSpId($lastSpId); |
---|
403 | |
---|
404 | // set the Escher object |
---|
405 | $this->_writerWorksheets[$sheetIndex]->setEscher($escher); |
---|
406 | } |
---|
407 | } |
---|
408 | |
---|
409 | /** |
---|
410 | * Build the Escher object corresponding to the MSODRAWINGGROUP record |
---|
411 | */ |
---|
412 | private function _buildWorkbookEscher() |
---|
413 | { |
---|
414 | $escher = null; |
---|
415 | |
---|
416 | // any drawings in this workbook? |
---|
417 | $found = false; |
---|
418 | foreach ($this->_phpExcel->getAllSheets() as $sheet) { |
---|
419 | if (count($sheet->getDrawingCollection()) > 0) { |
---|
420 | $found = true; |
---|
421 | break; |
---|
422 | } |
---|
423 | } |
---|
424 | |
---|
425 | // nothing to do if there are no drawings |
---|
426 | if (!$found) { |
---|
427 | return; |
---|
428 | } |
---|
429 | |
---|
430 | // if we reach here, then there are drawings in the workbook |
---|
431 | $escher = new PHPExcel_Shared_Escher(); |
---|
432 | |
---|
433 | // dggContainer |
---|
434 | $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); |
---|
435 | $escher->setDggContainer($dggContainer); |
---|
436 | |
---|
437 | // set IDCLs (identifier clusters) |
---|
438 | $dggContainer->setIDCLs($this->_IDCLs); |
---|
439 | |
---|
440 | // this loop is for determining maximum shape identifier of all drawing |
---|
441 | $spIdMax = 0; |
---|
442 | $totalCountShapes = 0; |
---|
443 | $countDrawings = 0; |
---|
444 | |
---|
445 | foreach ($this->_phpExcel->getAllsheets() as $sheet) { |
---|
446 | $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet |
---|
447 | |
---|
448 | if (count($sheet->getDrawingCollection()) > 0) { |
---|
449 | ++$countDrawings; |
---|
450 | |
---|
451 | foreach ($sheet->getDrawingCollection() as $drawing) { |
---|
452 | ++$sheetCountShapes; |
---|
453 | ++$totalCountShapes; |
---|
454 | |
---|
455 | $spId = $sheetCountShapes |
---|
456 | | ($this->_phpExcel->getIndex($sheet) + 1) << 10; |
---|
457 | $spIdMax = max($spId, $spIdMax); |
---|
458 | } |
---|
459 | } |
---|
460 | } |
---|
461 | |
---|
462 | $dggContainer->setSpIdMax($spIdMax + 1); |
---|
463 | $dggContainer->setCDgSaved($countDrawings); |
---|
464 | $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing |
---|
465 | |
---|
466 | // bstoreContainer |
---|
467 | $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); |
---|
468 | $dggContainer->setBstoreContainer($bstoreContainer); |
---|
469 | |
---|
470 | // the BSE's (all the images) |
---|
471 | foreach ($this->_phpExcel->getAllsheets() as $sheet) { |
---|
472 | foreach ($sheet->getDrawingCollection() as $drawing) { |
---|
473 | if ($drawing instanceof PHPExcel_Worksheet_Drawing) { |
---|
474 | |
---|
475 | $filename = $drawing->getPath(); |
---|
476 | |
---|
477 | list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); |
---|
478 | |
---|
479 | switch ($imageFormat) { |
---|
480 | |
---|
481 | case 1: // GIF, not supported by BIFF8, we convert to PNG |
---|
482 | $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; |
---|
483 | ob_start(); |
---|
484 | imagepng(imagecreatefromgif($filename)); |
---|
485 | $blipData = ob_get_contents(); |
---|
486 | ob_end_clean(); |
---|
487 | break; |
---|
488 | |
---|
489 | case 2: // JPEG |
---|
490 | $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; |
---|
491 | $blipData = file_get_contents($filename); |
---|
492 | break; |
---|
493 | |
---|
494 | case 3: // PNG |
---|
495 | $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; |
---|
496 | $blipData = file_get_contents($filename); |
---|
497 | break; |
---|
498 | |
---|
499 | case 6: // Windows DIB (BMP), we convert to PNG |
---|
500 | $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; |
---|
501 | ob_start(); |
---|
502 | imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); |
---|
503 | $blipData = ob_get_contents(); |
---|
504 | ob_end_clean(); |
---|
505 | break; |
---|
506 | |
---|
507 | default: continue 2; |
---|
508 | |
---|
509 | } |
---|
510 | |
---|
511 | $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); |
---|
512 | $blip->setData($blipData); |
---|
513 | |
---|
514 | $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); |
---|
515 | $BSE->setBlipType($blipType); |
---|
516 | $BSE->setBlip($blip); |
---|
517 | |
---|
518 | $bstoreContainer->addBSE($BSE); |
---|
519 | |
---|
520 | } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { |
---|
521 | |
---|
522 | switch ($drawing->getRenderingFunction()) { |
---|
523 | |
---|
524 | case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: |
---|
525 | $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; |
---|
526 | $renderingFunction = 'imagejpeg'; |
---|
527 | break; |
---|
528 | |
---|
529 | case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: |
---|
530 | case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: |
---|
531 | case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: |
---|
532 | $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; |
---|
533 | $renderingFunction = 'imagepng'; |
---|
534 | break; |
---|
535 | |
---|
536 | } |
---|
537 | |
---|
538 | ob_start(); |
---|
539 | call_user_func($renderingFunction, $drawing->getImageResource()); |
---|
540 | $blipData = ob_get_contents(); |
---|
541 | ob_end_clean(); |
---|
542 | |
---|
543 | $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); |
---|
544 | $blip->setData($blipData); |
---|
545 | |
---|
546 | $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); |
---|
547 | $BSE->setBlipType($blipType); |
---|
548 | $BSE->setBlip($blip); |
---|
549 | |
---|
550 | $bstoreContainer->addBSE($BSE); |
---|
551 | } |
---|
552 | } |
---|
553 | } |
---|
554 | |
---|
555 | // Set the Escher object |
---|
556 | $this->_writerWorkbook->setEscher($escher); |
---|
557 | } |
---|
558 | |
---|
559 | /** |
---|
560 | * Build the OLE Part for DocumentSummary Information |
---|
561 | * @return string |
---|
562 | */ |
---|
563 | private function _writeDocumentSummaryInformation(){ |
---|
564 | |
---|
565 | // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) |
---|
566 | $data = pack('v', 0xFFFE); |
---|
567 | // offset: 2; size: 2; |
---|
568 | $data .= pack('v', 0x0000); |
---|
569 | // offset: 4; size: 2; OS version |
---|
570 | $data .= pack('v', 0x0106); |
---|
571 | // offset: 6; size: 2; OS indicator |
---|
572 | $data .= pack('v', 0x0002); |
---|
573 | // offset: 8; size: 16 |
---|
574 | $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); |
---|
575 | // offset: 24; size: 4; section count |
---|
576 | $data .= pack('V', 0x0001); |
---|
577 | |
---|
578 | // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae |
---|
579 | $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9); |
---|
580 | // offset: 44; size: 4; offset of the start |
---|
581 | $data .= pack('V', 0x30); |
---|
582 | |
---|
583 | // SECTION |
---|
584 | $dataSection = array(); |
---|
585 | $dataSection_NumProps = 0; |
---|
586 | $dataSection_Summary = ''; |
---|
587 | $dataSection_Content = ''; |
---|
588 | |
---|
589 | // GKPIDDSI_CODEPAGE: CodePage |
---|
590 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), |
---|
591 | 'offset' => array('pack' => 'V'), |
---|
592 | 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer |
---|
593 | 'data' => array('data' => 1252)); |
---|
594 | $dataSection_NumProps++; |
---|
595 | |
---|
596 | // GKPIDDSI_CATEGORY : Category |
---|
597 | if($this->_phpExcel->getProperties()->getCategory()){ |
---|
598 | $dataProp = $this->_phpExcel->getProperties()->getCategory(); |
---|
599 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), |
---|
600 | 'offset' => array('pack' => 'V'), |
---|
601 | 'type' => array('pack' => 'V', 'data' => 0x1E), |
---|
602 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
603 | $dataSection_NumProps++; |
---|
604 | } |
---|
605 | // GKPIDDSI_VERSION :Version of the application that wrote the property storage |
---|
606 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17), |
---|
607 | 'offset' => array('pack' => 'V'), |
---|
608 | 'type' => array('pack' => 'V', 'data' => 0x03), |
---|
609 | 'data' => array('pack' => 'V', 'data' => 0x000C0000)); |
---|
610 | $dataSection_NumProps++; |
---|
611 | // GKPIDDSI_SCALE : FALSE |
---|
612 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B), |
---|
613 | 'offset' => array('pack' => 'V'), |
---|
614 | 'type' => array('pack' => 'V', 'data' => 0x0B), |
---|
615 | 'data' => array('data' => false)); |
---|
616 | $dataSection_NumProps++; |
---|
617 | // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application |
---|
618 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10), |
---|
619 | 'offset' => array('pack' => 'V'), |
---|
620 | 'type' => array('pack' => 'V', 'data' => 0x0B), |
---|
621 | 'data' => array('data' => false)); |
---|
622 | $dataSection_NumProps++; |
---|
623 | // GKPIDDSI_SHAREDOC : FALSE |
---|
624 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), |
---|
625 | 'offset' => array('pack' => 'V'), |
---|
626 | 'type' => array('pack' => 'V', 'data' => 0x0B), |
---|
627 | 'data' => array('data' => false)); |
---|
628 | $dataSection_NumProps++; |
---|
629 | // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application |
---|
630 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16), |
---|
631 | 'offset' => array('pack' => 'V'), |
---|
632 | 'type' => array('pack' => 'V', 'data' => 0x0B), |
---|
633 | 'data' => array('data' => false)); |
---|
634 | $dataSection_NumProps++; |
---|
635 | |
---|
636 | // GKPIDDSI_DOCSPARTS |
---|
637 | // MS-OSHARED p75 (2.3.3.2.2.1) |
---|
638 | // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9) |
---|
639 | // cElements |
---|
640 | $dataProp = pack('v', 0x0001); |
---|
641 | $dataProp .= pack('v', 0x0000); |
---|
642 | // array of UnalignedLpstr |
---|
643 | // cch |
---|
644 | $dataProp .= pack('v', 0x000A); |
---|
645 | $dataProp .= pack('v', 0x0000); |
---|
646 | // value |
---|
647 | $dataProp .= 'Worksheet'.chr(0); |
---|
648 | |
---|
649 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), |
---|
650 | 'offset' => array('pack' => 'V'), |
---|
651 | 'type' => array('pack' => 'V', 'data' => 0x101E), |
---|
652 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
653 | $dataSection_NumProps++; |
---|
654 | |
---|
655 | // GKPIDDSI_HEADINGPAIR |
---|
656 | // VtVecHeadingPairValue |
---|
657 | // cElements |
---|
658 | $dataProp = pack('v', 0x0002); |
---|
659 | $dataProp .= pack('v', 0x0000); |
---|
660 | // Array of vtHeadingPair |
---|
661 | // vtUnalignedString - headingString |
---|
662 | // stringType |
---|
663 | $dataProp .= pack('v', 0x001E); |
---|
664 | // padding |
---|
665 | $dataProp .= pack('v', 0x0000); |
---|
666 | // UnalignedLpstr |
---|
667 | // cch |
---|
668 | $dataProp .= pack('v', 0x0013); |
---|
669 | $dataProp .= pack('v', 0x0000); |
---|
670 | // value |
---|
671 | $dataProp .= 'Feuilles de calcul'; |
---|
672 | // vtUnalignedString - headingParts |
---|
673 | // wType : 0x0003 = 32 bit signed integer |
---|
674 | $dataProp .= pack('v', 0x0300); |
---|
675 | // padding |
---|
676 | $dataProp .= pack('v', 0x0000); |
---|
677 | // value |
---|
678 | $dataProp .= pack('v', 0x0100); |
---|
679 | $dataProp .= pack('v', 0x0000); |
---|
680 | $dataProp .= pack('v', 0x0000); |
---|
681 | $dataProp .= pack('v', 0x0000); |
---|
682 | |
---|
683 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), |
---|
684 | 'offset' => array('pack' => 'V'), |
---|
685 | 'type' => array('pack' => 'V', 'data' => 0x100C), |
---|
686 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
687 | $dataSection_NumProps++; |
---|
688 | |
---|
689 | // 4 Section Length |
---|
690 | // 4 Property count |
---|
691 | // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) |
---|
692 | $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; |
---|
693 | foreach ($dataSection as $dataProp){ |
---|
694 | // Summary |
---|
695 | $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); |
---|
696 | // Offset |
---|
697 | $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); |
---|
698 | // DataType |
---|
699 | $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); |
---|
700 | // Data |
---|
701 | if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer |
---|
702 | $dataSection_Content .= pack('V', $dataProp['data']['data']); |
---|
703 | |
---|
704 | $dataSection_Content_Offset += 4 + 4; |
---|
705 | } |
---|
706 | elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer |
---|
707 | $dataSection_Content .= pack('V', $dataProp['data']['data']); |
---|
708 | |
---|
709 | $dataSection_Content_Offset += 4 + 4; |
---|
710 | } |
---|
711 | elseif($dataProp['type']['data'] == 0x0B){ // Boolean |
---|
712 | if($dataProp['data']['data'] == false){ |
---|
713 | $dataSection_Content .= pack('V', 0x0000); |
---|
714 | } else { |
---|
715 | $dataSection_Content .= pack('V', 0x0001); |
---|
716 | } |
---|
717 | $dataSection_Content_Offset += 4 + 4; |
---|
718 | } |
---|
719 | elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length |
---|
720 | // Null-terminated string |
---|
721 | $dataProp['data']['data'] .= chr(0); |
---|
722 | $dataProp['data']['length'] += 1; |
---|
723 | // Complete the string with null string for being a %4 |
---|
724 | $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); |
---|
725 | $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); |
---|
726 | |
---|
727 | $dataSection_Content .= pack('V', $dataProp['data']['length']); |
---|
728 | $dataSection_Content .= $dataProp['data']['data']; |
---|
729 | |
---|
730 | $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); |
---|
731 | } |
---|
732 | elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) |
---|
733 | $dataSection_Content .= $dataProp['data']['data']; |
---|
734 | |
---|
735 | $dataSection_Content_Offset += 4 + 8; |
---|
736 | } |
---|
737 | else { |
---|
738 | // Data Type Not Used at the moment |
---|
739 | $dataSection_Content .= $dataProp['data']['data']; |
---|
740 | |
---|
741 | $dataSection_Content_Offset += 4 + $dataProp['data']['length']; |
---|
742 | } |
---|
743 | } |
---|
744 | // Now $dataSection_Content_Offset contains the size of the content |
---|
745 | |
---|
746 | // section header |
---|
747 | // offset: $secOffset; size: 4; section length |
---|
748 | // + x Size of the content (summary + content) |
---|
749 | $data .= pack('V', $dataSection_Content_Offset); |
---|
750 | // offset: $secOffset+4; size: 4; property count |
---|
751 | $data .= pack('V', $dataSection_NumProps); |
---|
752 | // Section Summary |
---|
753 | $data .= $dataSection_Summary; |
---|
754 | // Section Content |
---|
755 | $data .= $dataSection_Content; |
---|
756 | |
---|
757 | return $data; |
---|
758 | } |
---|
759 | |
---|
760 | /** |
---|
761 | * Build the OLE Part for Summary Information |
---|
762 | * @return string |
---|
763 | */ |
---|
764 | private function _writeSummaryInformation(){ |
---|
765 | // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) |
---|
766 | $data = pack('v', 0xFFFE); |
---|
767 | // offset: 2; size: 2; |
---|
768 | $data .= pack('v', 0x0000); |
---|
769 | // offset: 4; size: 2; OS version |
---|
770 | $data .= pack('v', 0x0106); |
---|
771 | // offset: 6; size: 2; OS indicator |
---|
772 | $data .= pack('v', 0x0002); |
---|
773 | // offset: 8; size: 16 |
---|
774 | $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); |
---|
775 | // offset: 24; size: 4; section count |
---|
776 | $data .= pack('V', 0x0001); |
---|
777 | |
---|
778 | // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 |
---|
779 | $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3); |
---|
780 | // offset: 44; size: 4; offset of the start |
---|
781 | $data .= pack('V', 0x30); |
---|
782 | |
---|
783 | // SECTION |
---|
784 | $dataSection = array(); |
---|
785 | $dataSection_NumProps = 0; |
---|
786 | $dataSection_Summary = ''; |
---|
787 | $dataSection_Content = ''; |
---|
788 | |
---|
789 | // CodePage : CP-1252 |
---|
790 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), |
---|
791 | 'offset' => array('pack' => 'V'), |
---|
792 | 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer |
---|
793 | 'data' => array('data' => 1252)); |
---|
794 | $dataSection_NumProps++; |
---|
795 | |
---|
796 | // Title |
---|
797 | if($this->_phpExcel->getProperties()->getTitle()){ |
---|
798 | $dataProp = $this->_phpExcel->getProperties()->getTitle(); |
---|
799 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), |
---|
800 | 'offset' => array('pack' => 'V'), |
---|
801 | 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length |
---|
802 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
803 | $dataSection_NumProps++; |
---|
804 | } |
---|
805 | // Subject |
---|
806 | if($this->_phpExcel->getProperties()->getSubject()){ |
---|
807 | $dataProp = $this->_phpExcel->getProperties()->getSubject(); |
---|
808 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), |
---|
809 | 'offset' => array('pack' => 'V'), |
---|
810 | 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length |
---|
811 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
812 | $dataSection_NumProps++; |
---|
813 | } |
---|
814 | // Author (Creator) |
---|
815 | if($this->_phpExcel->getProperties()->getCreator()){ |
---|
816 | $dataProp = $this->_phpExcel->getProperties()->getCreator(); |
---|
817 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), |
---|
818 | 'offset' => array('pack' => 'V'), |
---|
819 | 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length |
---|
820 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
821 | $dataSection_NumProps++; |
---|
822 | } |
---|
823 | // Keywords |
---|
824 | if($this->_phpExcel->getProperties()->getKeywords()){ |
---|
825 | $dataProp = $this->_phpExcel->getProperties()->getKeywords(); |
---|
826 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), |
---|
827 | 'offset' => array('pack' => 'V'), |
---|
828 | 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length |
---|
829 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
830 | $dataSection_NumProps++; |
---|
831 | } |
---|
832 | // Comments (Description) |
---|
833 | if($this->_phpExcel->getProperties()->getDescription()){ |
---|
834 | $dataProp = $this->_phpExcel->getProperties()->getDescription(); |
---|
835 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), |
---|
836 | 'offset' => array('pack' => 'V'), |
---|
837 | 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length |
---|
838 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
839 | $dataSection_NumProps++; |
---|
840 | } |
---|
841 | // Last Saved By (LastModifiedBy) |
---|
842 | if($this->_phpExcel->getProperties()->getLastModifiedBy()){ |
---|
843 | $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); |
---|
844 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), |
---|
845 | 'offset' => array('pack' => 'V'), |
---|
846 | 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length |
---|
847 | 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); |
---|
848 | $dataSection_NumProps++; |
---|
849 | } |
---|
850 | // Created Date/Time |
---|
851 | if($this->_phpExcel->getProperties()->getCreated()){ |
---|
852 | $dataProp = $this->_phpExcel->getProperties()->getCreated(); |
---|
853 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), |
---|
854 | 'offset' => array('pack' => 'V'), |
---|
855 | 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) |
---|
856 | 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); |
---|
857 | $dataSection_NumProps++; |
---|
858 | } |
---|
859 | // Modified Date/Time |
---|
860 | if($this->_phpExcel->getProperties()->getModified()){ |
---|
861 | $dataProp = $this->_phpExcel->getProperties()->getModified(); |
---|
862 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), |
---|
863 | 'offset' => array('pack' => 'V'), |
---|
864 | 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) |
---|
865 | 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); |
---|
866 | $dataSection_NumProps++; |
---|
867 | } |
---|
868 | // Security |
---|
869 | $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), |
---|
870 | 'offset' => array('pack' => 'V'), |
---|
871 | 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer |
---|
872 | 'data' => array('data' => 0x00)); |
---|
873 | $dataSection_NumProps++; |
---|
874 | |
---|
875 | |
---|
876 | // 4 Section Length |
---|
877 | // 4 Property count |
---|
878 | // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) |
---|
879 | $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; |
---|
880 | foreach ($dataSection as $dataProp){ |
---|
881 | // Summary |
---|
882 | $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); |
---|
883 | // Offset |
---|
884 | $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); |
---|
885 | // DataType |
---|
886 | $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); |
---|
887 | // Data |
---|
888 | if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer |
---|
889 | $dataSection_Content .= pack('V', $dataProp['data']['data']); |
---|
890 | |
---|
891 | $dataSection_Content_Offset += 4 + 4; |
---|
892 | } |
---|
893 | elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer |
---|
894 | $dataSection_Content .= pack('V', $dataProp['data']['data']); |
---|
895 | |
---|
896 | $dataSection_Content_Offset += 4 + 4; |
---|
897 | } |
---|
898 | elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length |
---|
899 | // Null-terminated string |
---|
900 | $dataProp['data']['data'] .= chr(0); |
---|
901 | $dataProp['data']['length'] += 1; |
---|
902 | // Complete the string with null string for being a %4 |
---|
903 | $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); |
---|
904 | $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); |
---|
905 | |
---|
906 | $dataSection_Content .= pack('V', $dataProp['data']['length']); |
---|
907 | $dataSection_Content .= $dataProp['data']['data']; |
---|
908 | |
---|
909 | $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); |
---|
910 | } |
---|
911 | elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) |
---|
912 | $dataSection_Content .= $dataProp['data']['data']; |
---|
913 | |
---|
914 | $dataSection_Content_Offset += 4 + 8; |
---|
915 | } |
---|
916 | else { |
---|
917 | // Data Type Not Used at the moment |
---|
918 | } |
---|
919 | } |
---|
920 | // Now $dataSection_Content_Offset contains the size of the content |
---|
921 | |
---|
922 | // section header |
---|
923 | // offset: $secOffset; size: 4; section length |
---|
924 | // + x Size of the content (summary + content) |
---|
925 | $data .= pack('V', $dataSection_Content_Offset); |
---|
926 | // offset: $secOffset+4; size: 4; property count |
---|
927 | $data .= pack('V', $dataSection_NumProps); |
---|
928 | // Section Summary |
---|
929 | $data .= $dataSection_Summary; |
---|
930 | // Section Content |
---|
931 | $data .= $dataSection_Content; |
---|
932 | |
---|
933 | return $data; |
---|
934 | } |
---|
935 | } |
---|