Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
23 liveuser 1
<?php
2
 
3
//require_once 'class.styleconstants.php';
4
 
5
include_once 'phpodt.php';
6
 
7
/**
8
 * The class responsible for creating the xml documents needed
9
 * to generate an ODT document
10
 *
11
 * @author Issam RACHDI
12
 */
13
class ODT {
14
	const GENERATOR = 'PHP-ODT 0.3';
15
 
16
	/**
17
	 * The name of the odt file
18
	 */
19
//	private $fileName;
20
	private $manifest;
21
	private $styles;
22
	private $documentContent;
23
	private $officeBody;
24
	private $officeText;
25
	private $metadata;
26
	private $officeMeta;
27
//	private $officeStyles;
28
//	private $officeAutomaticStyles;
29
//	private $permissions;
30
 
31
	private static $instance;
32
 
33
	/**
34
	 * @param $fileName The name of the odt file
35
	 * @param $perm The permissions of the file (optional)
36
	 */
37
	private function __construct() {
38
		$this->initContent();
39
	}
40
 
41
	static function getInstance() {
42
		if (self::$instance == null) {
43
			self::$instance = new ODT();
44
		}
45
		return self::$instance;
46
	}
47
 
48
	/**
49
	 * Creates the manifest document, wich describe all the files contained in
50
	 * the odt document
51
	 */
52
	function createManifest() {
53
		$manifestDoc = new DOMDocument('1.0', 'UTF-8');
54
		$root = $manifestDoc->createElement('manifest:manifest');
55
		$root->setAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0');
56
		$root->setAttribute('office:version', "1.1");
57
		$manifestDoc->appendChild($root);
58
 
59
		$fileEntryRoot = $manifestDoc->createElement('manifest:file-entry');
60
		$fileEntryRoot->setAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.text');
61
		$fileEntryRoot->setAttribute('manifest:full-path', '/');
62
		$root->appendChild($fileEntryRoot);
63
 
64
		$fileEntryContent = $manifestDoc->createElement('manifest:file-entry');
65
		$fileEntryContent->setAttribute('manifest:media-type', 'text/xml');
66
		$fileEntryContent->setAttribute('manifest:full-path', 'content.xml');
67
		$root->appendChild($fileEntryContent);
68
 
69
		$fileEntryStyles = $manifestDoc->createElement('manifest:file-entry');
70
		$fileEntryStyles->setAttribute('manifest:media-type', 'text/xml');
71
		$fileEntryStyles->setAttribute('manifest:full-path', 'styles.xml');
72
		$root->appendChild($fileEntryStyles);
73
 
74
		$fileEntryMeta = $manifestDoc->createElement('manifest:file-entry');
75
		$fileEntryMeta->setAttribute('manifest:media-type', 'text/xml');
76
		$fileEntryMeta->setAttribute('manifest:full-path', 'meta.xml');
77
		$root->appendChild($fileEntryMeta);
78
 
79
		$this->manifest = $manifestDoc;
80
	}
81
 
82
	/**
83
	 * Creates the styles document, which contains all the styles used in the document
84
	 */
85
	function createStyle() {
86
		$this->styles = new DOMDocument('1.0', 'UTF-8');
87
		$root = $this->styles->createElement('office:document-styles');
88
		$root->setAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
89
		$root->setAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
90
		$root->setAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
91
		$root->setAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
92
		$root->setAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
93
		$root->setAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
94
		$root->setAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
95
		$root->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
96
		$root->setAttribute('office:version', '1.1');
97
		$this->styles->appendChild($root);
98
 
99
		$this->declareFontFaces($root);
100
 
101
		$officeStyles = $this->styles->createElement('office:styles');
102
		$root->appendChild($officeStyles);
103
 
104
		$officeAutomaticStyles = $this->styles->createElement('office:automatic-styles');
105
		$root->appendChild($officeAutomaticStyles);
106
 
107
		$officeMasterStyles = $this->styles->createElement('office:master-styles');
108
		$root->appendChild($officeMasterStyles);
109
	}
110
 
111
	/**
112
	 * Creates the metadata document, containing the general informations about the document,
113
	 *
114
	 */
115
	function createMetadata() {
116
		$this->metadata = new DOMDocument('1.0', 'UTF-8');
117
		$root = $this->metadata->createElement('office:document-meta');
118
		$root->setAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
119
		$root->setAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
120
		$root->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
121
		$root->setAttribute('office:version', '1.1');
122
		$this->metadata->appendChild($root);
123
 
124
		$generator = $this->metadata->createElement('meta:generator', self::GENERATOR);
125
		date_default_timezone_set('Asia/Taipei');
126
		$creationDate = $this->metadata->createElement('meta:creation-date', date('Y-m-d\TH:i:s'));
127
		$this->officeMeta = $this->metadata->createElement('office:meta');
128
		$this->officeMeta->appendChild($generator);
129
		$this->officeMeta->appendChild($creationDate);
130
		$root->appendChild($this->officeMeta);
131
	}
132
 
133
	/**
134
	 * Declare the fonts that can be used in the document
135
	 *
136
	 * @param DOMElement $rootStyles The root element of the styles document
137
	 */
138
	function declareFontFaces($rootStyles) {
139
		$fontFaceDecl = $this->styles->createElement('office:font-face-decls');
140
		$rootStyles->appendChild($fontFaceDecl);
141
 
142
		$ff = $this->styles->createElement('style:font-face');
143
		$ff->setAttribute('style:name', 'Courier');
144
		$ff->setAttribute('svg:font-family', 'Courier');
145
		$ff->setAttribute('style:font-family-generic', 'modern');
146
		$ff->setAttribute('style:font-pitch', 'fixed');
147
		$fontFaceDecl->appendChild($ff);
148
 
149
		$ff = $this->styles->createElement('style:font-face');
150
		$ff->setAttribute('style:name', 'DejaVu Serif');
151
		$ff->setAttribute('svg:font-family', '&apos;DejaVu Serif&apos;');
152
		$ff->setAttribute('style:font-family-generic', 'roman');
153
		$ff->setAttribute('style:font-pitch', 'variable');
154
		$fontFaceDecl->appendChild($ff);
155
 
156
		$ff = $this->styles->createElement('style:font-face');
157
		$ff->setAttribute('style:name', 'Times New Roman');
158
		$ff->setAttribute('svg:font-family', '&apos;Times New Roman&apos;');
159
		$ff->setAttribute('style:font-family-generic', 'roman');
160
		$ff->setAttribute('style:font-pitch', 'variable');
161
		$fontFaceDecl->appendChild($ff);
162
 
163
		$ff = $this->styles->createElement('style:font-face');
164
		$ff->setAttribute('style:name', 'DejaVu Sans');
165
		$ff->setAttribute('svg:font-family', '&apos;DejaVu Sans&apos;');
166
		$ff->setAttribute('style:font-family-generic', 'swiss');
167
		$ff->setAttribute('style:font-pitch', 'variable');
168
		$fontFaceDecl->appendChild($ff);
169
 
170
		$ff = $this->styles->createElement('style:font-face');
171
		$ff->setAttribute('style:name', 'Verdana');
172
		$ff->setAttribute('svg:font-family', 'Verdana');
173
		$ff->setAttribute('style:font-family-generic', 'swiss');
174
		$ff->setAttribute('style:font-pitch', 'variable');
175
		$fontFaceDecl->appendChild($ff);
176
	}
177
 
178
	/**
179
	 * Creates the needed documents and does the needed initialization
180
	 * @return DOMDocument An empty odt document
181
	 */
182
	function initContent() {
183
		$this->createManifest();
184
		$this->createStyle();
185
		$this->createMetadata();
186
 
187
		$this->documentContent = new DOMDocument('1.0', 'UTF-8');
188
		$this->documentContent->substituteEntities = true;
189
		$root = $this->documentContent->createElement('office:document-content');
190
		$root->setAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
191
		$root->setAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
192
		$root->setAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
193
		$root->setAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
194
		$root->setAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
195
		$root->setAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
196
		$root->setAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
197
		$root->setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
198
		$root->setAttribute('office:version', '1.1');
199
		$this->documentContent->appendChild($root);
200
 
201
		$officeAutomaticStyles = $this->documentContent->createElement('office:automatic-styles');
202
		$root->appendChild($officeAutomaticStyles);
203
 
204
 
205
		$this->officeBody = $this->documentContent->createElement('office:body');
206
		$root->appendChild($this->officeBody);
207
 
208
		$this->officeText = $this->documentContent->createElement('office:text');
209
		$this->officeBody->appendChild($this->officeText);
210
 
211
//		return $this->documentContent;
212
	}
213
 
214
	/**
215
	 * Sets the title of the document
216
	 *
217
	 * @param string $title
218
	 */
219
	function setTitle($title) {
220
		$element = $this->metadata->createElement('dc:title', $title);
221
		$this->officeMeta->appendChild($element);
222
	}
223
 
224
	/**
225
	 * Sets a description for the document
226
	 *
227
	 * @param string $description
228
	 */
229
	function setDescription($description) {
230
		$element = $this->metadata->createElement('dc:description', $description);
231
		$this->officeMeta->appendChild($element);
232
	}
233
 
234
	/**
235
	 * Sets the subject of the document
236
	 *
237
	 * @param string $subject
238
	 */
239
	function setSubject($subject) {
240
		$element = $this->metadata->createElement('dc:subject', $subject);
241
		$this->officeMeta->appendChild($element);
242
	}
243
 
244
	/**
245
	 * Sets the keywords related to the document
246
	 *
247
	 * @param array $keywords
248
	 */
249
	function setKeywords($keywords) {
250
		if (!is_array($keywords)) {
251
			throw new ODTException('Keywords must be an array.');
252
		}
253
		foreach ($keywords as $keyword) {
254
			$element = $this->metadata->createElement('meta:keyword', $keyword);
255
			$this->officeMeta->appendChild($element);
256
		}
257
	}
258
 
259
	/**
260
	 * Specifies the name of the person who created the document initially
261
	 *
262
	 * @param string $creator
263
	 */
264
	function setCreator($creator) {
265
		$element = $this->metadata->createElement('meta:initial-creator', $creator);
266
		$this->officeMeta->appendChild($element);
267
	}
268
 
269
	/**
270
	 *
271
	 * @return DOMDocument The document containing all the styles
272
	 */
273
	function getStyleDocument() {
274
		return $this->styles;
275
	}
276
 
277
	public function getDocumentContent() {
278
		return $this->documentContent;
279
	}
280
 
281
	/**
282
	 * Write the document to the hard disk
283
	 */
284
	function output($fileName, $perm = 0777) {
285
 
286
		$document = new ZipArchive();
287
		#ZIPARCHIVE::OVERWRITE will not work
288
		#參考資料:
289
		#http://stackoverflow.com/questions/32694148/ziparchivegetstatusstring-invalid-or-uninitialized-zip-object
290
		#$document->open($fileName, ZIPARCHIVE::OVERWRITE);
291
		$document->open($fileName, ZIPARCHIVE::CREATE);
292
 
293
		$document->addFromString('META-INF/manifest.xml', $this->manifest->saveXML());
294
		$document->addFromString('styles.xml', $this->styles->saveXML());
295
		$document->addFromString('meta.xml', $this->metadata->saveXML());
296
		$document->addFromString('content.xml', html_entity_decode($this->documentContent->saveXML()));
297
 
298
		$document->close();
299
 
300
		#change file Permission if file exist.
301
		if(file_exists($fileName)){
302
 
303
			chmod($fileName, $perm);
304
 
305
			}#if end		
306
	}
307
}
308
?>