123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- <?php
- /**
- * This file is part of PHPWord - A pure PHP library for reading and writing
- * word processing documents.
- *
- * PHPWord is free software distributed under the terms of the GNU Lesser
- * General Public License version 3 as published by the Free Software Foundation.
- *
- * For the full copyright and license information, please read the LICENSE
- * file that was distributed with this source code. For the full list of
- * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
- *
- * @see https://github.com/PHPOffice/PHPWord
- * @copyright 2010-2018 PHPWord contributors
- * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
- */
- namespace PhpOffice\PhpWord\Reader;
- use PhpOffice\PhpWord\PhpWord;
- use PhpOffice\PhpWord\Shared\XMLReader;
- use PhpOffice\PhpWord\Shared\ZipArchive;
- /**
- * Reader for Word2007
- *
- * @since 0.8.0
- * @todo watermark, checkbox, toc
- * @todo Partly done: image, object
- */
- class Word2007 extends AbstractReader implements ReaderInterface
- {
- /**
- * Loads PhpWord from file
- *
- * @param string $docFile
- * @return \PhpOffice\PhpWord\PhpWord
- */
- public function load($docFile)
- {
- $phpWord = new PhpWord();
- $relationships = $this->readRelationships($docFile);
- $steps = array(
- array('stepPart' => 'document', 'stepItems' => array(
- 'styles' => 'Styles',
- 'numbering' => 'Numbering',
- )),
- array('stepPart' => 'main', 'stepItems' => array(
- 'officeDocument' => 'Document',
- 'core-properties' => 'DocPropsCore',
- 'extended-properties' => 'DocPropsApp',
- 'custom-properties' => 'DocPropsCustom',
- )),
- array('stepPart' => 'document', 'stepItems' => array(
- 'endnotes' => 'Endnotes',
- 'footnotes' => 'Footnotes',
- 'settings' => 'Settings',
- )),
- );
- foreach ($steps as $step) {
- $stepPart = $step['stepPart'];
- $stepItems = $step['stepItems'];
- if (!isset($relationships[$stepPart])) {
- continue;
- }
- foreach ($relationships[$stepPart] as $relItem) {
- $relType = $relItem['type'];
- if (isset($stepItems[$relType])) {
- $partName = $stepItems[$relType];
- $xmlFile = $relItem['target'];
- $this->readPart($phpWord, $relationships, $partName, $docFile, $xmlFile);
- }
- }
- }
- return $phpWord;
- }
- /**
- * Read document part.
- *
- * @param \PhpOffice\PhpWord\PhpWord $phpWord
- * @param array $relationships
- * @param string $partName
- * @param string $docFile
- * @param string $xmlFile
- */
- private function readPart(PhpWord $phpWord, $relationships, $partName, $docFile, $xmlFile)
- {
- $partClass = "PhpOffice\\PhpWord\\Reader\\Word2007\\{$partName}";
- if (class_exists($partClass)) {
- /** @var \PhpOffice\PhpWord\Reader\Word2007\AbstractPart $part Type hint */
- $part = new $partClass($docFile, $xmlFile);
- $part->setRels($relationships);
- $part->read($phpWord);
- }
- }
- /**
- * Read all relationship files
- *
- * @param string $docFile
- * @return array
- */
- private function readRelationships($docFile)
- {
- $relationships = array();
- // _rels/.rels
- $relationships['main'] = $this->getRels($docFile, '_rels/.rels');
- // word/_rels/*.xml.rels
- $wordRelsPath = 'word/_rels/';
- $zip = new ZipArchive();
- if ($zip->open($docFile) === true) {
- for ($i = 0; $i < $zip->numFiles; $i++) {
- $xmlFile = $zip->getNameIndex($i);
- if ((substr($xmlFile, 0, strlen($wordRelsPath))) == $wordRelsPath && (substr($xmlFile, -1)) != '/') {
- $docPart = str_replace('.xml.rels', '', str_replace($wordRelsPath, '', $xmlFile));
- $relationships[$docPart] = $this->getRels($docFile, $xmlFile, 'word/');
- }
- }
- $zip->close();
- }
- return $relationships;
- }
- /**
- * Get relationship array
- *
- * @param string $docFile
- * @param string $xmlFile
- * @param string $targetPrefix
- * @return array
- */
- private function getRels($docFile, $xmlFile, $targetPrefix = '')
- {
- $metaPrefix = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/';
- $officePrefix = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/';
- $rels = array();
- $xmlReader = new XMLReader();
- $xmlReader->getDomFromZip($docFile, $xmlFile);
- $nodes = $xmlReader->getElements('*');
- foreach ($nodes as $node) {
- $rId = $xmlReader->getAttribute('Id', $node);
- $type = $xmlReader->getAttribute('Type', $node);
- $target = $xmlReader->getAttribute('Target', $node);
- $mode = $xmlReader->getAttribute('TargetMode', $node);
- // Remove URL prefixes from $type to make it easier to read
- $type = str_replace($metaPrefix, '', $type);
- $type = str_replace($officePrefix, '', $type);
- $docPart = str_replace('.xml', '', $target);
- // Do not add prefix to link source
- if ($type != 'hyperlink' && $mode != 'External') {
- $target = $targetPrefix . $target;
- }
- // Push to return array
- $rels[$rId] = array('type' => $type, 'target' => $target, 'docPart' => $docPart, 'targetMode' => $mode);
- }
- ksort($rels);
- return $rels;
- }
- }
|