1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
27:
28: 29: 30:
31: class PHPWord_Writer_Word2007 implements PHPWord_Writer_IWriter
32: {
33:
34: private $_document;
35: private $_writerParts;
36: private $_diskCachingDirectory;
37: private $_useDiskCaching = false;
38: private $_imageTypes = array();
39: private $_objectTypes = array();
40:
41: public function __construct(PHPWord $PHPWord = null)
42: {
43: $this->_document = $PHPWord;
44:
45: $this->_diskCachingDirectory = './';
46:
47: $this->_writerParts['contenttypes'] = new PHPWord_Writer_Word2007_ContentTypes();
48: $this->_writerParts['rels'] = new PHPWord_Writer_Word2007_Rels();
49: $this->_writerParts['docprops'] = new PHPWord_Writer_Word2007_DocProps();
50: $this->_writerParts['documentrels'] = new PHPWord_Writer_Word2007_DocumentRels();
51: $this->_writerParts['document'] = new PHPWord_Writer_Word2007_Document();
52: $this->_writerParts['styles'] = new PHPWord_Writer_Word2007_Styles();
53: $this->_writerParts['header'] = new PHPWord_Writer_Word2007_Header();
54: $this->_writerParts['footer'] = new PHPWord_Writer_Word2007_Footer();
55:
56: foreach ($this->_writerParts as $writer) {
57: $writer->setParentWriter($this);
58: }
59: }
60:
61: public function save($pFilename = null)
62: {
63: if (!is_null($this->_document)) {
64:
65:
66: $originalFilename = $pFilename;
67: if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
68: $pFilename = @tempnam('./', 'phppttmp');
69: if ($pFilename == '') {
70: $pFilename = $originalFilename;
71: }
72: }
73:
74:
75: $objZip = new ZipArchive();
76:
77:
78: if ($objZip->open($pFilename, ZIPARCHIVE::OVERWRITE) !== true) {
79: if ($objZip->open($pFilename, ZIPARCHIVE::CREATE) !== true) {
80: throw new Exception("Could not open " . $pFilename . " for writing.");
81: }
82: }
83:
84:
85: $sectionElements = array();
86: $_secElements = PHPWord_Media::getSectionMediaElements();
87: foreach ($_secElements as $element) {
88: if ($element['type'] != 'hyperlink') {
89: $this->_addFileToPackage($objZip, $element);
90: }
91: $sectionElements[] = $element;
92: }
93:
94: $_hdrElements = PHPWord_Media::getHeaderMediaElements();
95: foreach ($_hdrElements as $_headerFile => $_hdrMedia) {
96: if (count($_hdrMedia) > 0) {
97: $objZip->addFromString('word/_rels/' . $_headerFile . '.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_hdrMedia));
98: foreach ($_hdrMedia as $element) {
99: $this->_addFileToPackage($objZip, $element);
100: }
101: }
102: }
103:
104: $_ftrElements = PHPWord_Media::getFooterMediaElements();
105: foreach ($_ftrElements as $_footerFile => $_ftrMedia) {
106: if (count($_ftrMedia) > 0) {
107: $objZip->addFromString('word/_rels/' . $_footerFile . '.xml.rels', $this->getWriterPart('documentrels')->writeHeaderFooterRels($_ftrMedia));
108: foreach ($_ftrMedia as $element) {
109: $this->_addFileToPackage($objZip, $element);
110: }
111: }
112: }
113:
114:
115: $_cHdrs = 0;
116: $_cFtrs = 0;
117: $rID = PHPWord_Media::countSectionMediaElements() + 6;
118: $_sections = $this->_document->getSections();
119:
120: foreach ($_sections as $section) {
121: $_headers = $section->getHeaders();
122: foreach ($_headers as $index => &$_header) {
123: $_cHdrs++;
124: $_header->setRelationId(++$rID);
125: $_headerFile = 'header' . $_cHdrs . '.xml';
126: $sectionElements[] = array('target' => $_headerFile, 'type' => 'header', 'rID' => $rID);
127: $objZip->addFromString('word/' . $_headerFile, $this->getWriterPart('header')->writeHeader($_header));
128: }
129:
130: $_footer = $section->getFooter();
131: if (!is_null($_footer)) {
132: $_cFtrs++;
133: $_footer->setRelationId(++$rID);
134: $_footerCount = $_footer->getFooterCount();
135: $_footerFile = 'footer' . $_footerCount . '.xml';
136: $sectionElements[] = array('target' => $_footerFile, 'type' => 'footer', 'rID' => $rID);
137: $objZip->addFromString('word/' . $_footerFile, $this->getWriterPart('footer')->writeFooter($_footer));
138: }
139: }
140:
141:
142:
143: $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('contenttypes')->writeContentTypes($this->_imageTypes, $this->_objectTypes, $_cHdrs, $_cFtrs));
144: $objZip->addFromString('_rels/.rels', $this->getWriterPart('rels')->writeRelationships($this->_document));
145: $objZip->addFromString('docProps/app.xml', $this->getWriterPart('docprops')->writeDocPropsApp($this->_document));
146: $objZip->addFromString('docProps/core.xml', $this->getWriterPart('docprops')->writeDocPropsCore($this->_document));
147: $objZip->addFromString('word/document.xml', $this->getWriterPart('document')->writeDocument($this->_document));
148: $objZip->addFromString('word/_rels/document.xml.rels', $this->getWriterPart('documentrels')->writeDocumentRels($sectionElements));
149: $objZip->addFromString('word/styles.xml', $this->getWriterPart('styles')->writeStyles($this->_document));
150:
151:
152: $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/numbering.xml', 'word/numbering.xml');
153: $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/settings.xml', 'word/settings.xml');
154: $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/theme1.xml', 'word/theme/theme1.xml');
155: $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/webSettings.xml', 'word/webSettings.xml');
156: $objZip->addFile(PHPWORD_BASE_PATH . 'PHPWord/_staticDocParts/fontTable.xml', 'word/fontTable.xml');
157:
158:
159:
160: if ($objZip->close() === false) {
161: throw new Exception("Could not close zip file $pFilename.");
162: }
163:
164:
165: if ($originalFilename != $pFilename) {
166: if (copy($pFilename, $originalFilename) === false) {
167: throw new Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
168: }
169: @unlink($pFilename);
170: }
171: } else {
172: throw new Exception("PHPWord object unassigned.");
173: }
174: }
175:
176: private function _chkContentTypes($src)
177: {
178: $srcInfo = pathinfo($src);
179: $extension = strtolower($srcInfo['extension']);
180: if (substr($extension, 0, 3) == 'php') {
181: $extension = 'php';
182: }
183: $_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff', 'php');
184:
185: if (in_array($extension, $_supportedImageTypes)) {
186: $imagedata = getimagesize($src);
187: $imagetype = image_type_to_mime_type($imagedata[2]);
188: $imageext = image_type_to_extension($imagedata[2]);
189: $imageext = str_replace('.', '', $imageext);
190: if ($imageext == 'jpeg') $imageext = 'jpg';
191:
192: if (!in_array($imagetype, $this->_imageTypes)) {
193: $this->_imageTypes[$imageext] = $imagetype;
194: }
195: } else {
196: if (!in_array($extension, $this->_objectTypes)) {
197: $this->_objectTypes[] = $extension;
198: }
199: }
200: }
201:
202: public function getWriterPart($pPartName = '')
203: {
204: if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {
205: return $this->_writerParts[strtolower($pPartName)];
206: } else {
207: return null;
208: }
209: }
210:
211: public function getUseDiskCaching()
212: {
213: return $this->_useDiskCaching;
214: }
215:
216: public function setUseDiskCaching($pValue = false, $pDirectory = null)
217: {
218: $this->_useDiskCaching = $pValue;
219:
220: if (!is_null($pDirectory)) {
221: if (is_dir($pDirectory)) {
222: $this->_diskCachingDirectory = $pDirectory;
223: } else {
224: throw new Exception("Directory does not exist: $pDirectory");
225: }
226: }
227:
228: return $this;
229: }
230:
231: private function _addFileToPackage($objZip, $element)
232: {
233: if (isset($element['isMemImage']) && $element['isMemImage']) {
234: $image = call_user_func($element['createfunction'], $element['source']);
235: ob_start();
236: call_user_func($element['imagefunction'], $image);
237: $imageContents = ob_get_contents();
238: ob_end_clean();
239: $objZip->addFromString('word/' . $element['target'], $imageContents);
240: imagedestroy($image);
241:
242: $this->_chkContentTypes($element['source']);
243: } else {
244: $objZip->addFile($element['source'], 'word/' . $element['target']);
245: $this->_chkContentTypes($element['source']);
246: }
247: }
248: }