Skip to content

Commit 1e71154

Browse files
author
Mark Baker
authored
Refactoring xlsx reader (#1033)
Start work on breaking up monolithic Reader and Writer classes into dedicated subclasses to make maintenance work easier
1 parent e884271 commit 1e71154

25 files changed

+1596
-683
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
]
4040
},
4141
"require": {
42-
"php": "5.6|^7.0",
42+
"php": "^5.6|^7.0",
4343
"ext-ctype": "*",
4444
"ext-dom": "*",
4545
"ext-gd": "*",

src/PhpSpreadsheet/Document/Properties.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ public function isCustomPropertySet($propertyName)
418418
*
419419
* @param string $propertyName
420420
*
421-
* @return string
421+
* @return mixed
422422
*/
423423
public function getCustomPropertyValue($propertyName)
424424
{

src/PhpSpreadsheet/Reader/Ods.php

Lines changed: 7 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
88
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
99
use PhpOffice\PhpSpreadsheet\Cell\DataType;
10-
use PhpOffice\PhpSpreadsheet\Document\Properties;
10+
use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties;
1111
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
1212
use PhpOffice\PhpSpreadsheet\RichText\RichText;
1313
use PhpOffice\PhpSpreadsheet\Settings;
@@ -265,7 +265,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
265265

266266
$zip = new ZipArchive();
267267
if (!$zip->open($pFilename)) {
268-
throw new Exception('Could not open ' . $pFilename . ' for reading! Error opening file.');
268+
throw new Exception("Could not open {$pFilename} for reading! Error opening file.");
269269
}
270270

271271
// Meta
@@ -275,97 +275,13 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
275275
'SimpleXMLElement',
276276
Settings::getLibXmlLoaderOptions()
277277
);
278-
$namespacesMeta = $xml->getNamespaces(true);
278+
if ($xml === false) {
279+
throw new Exception('Unable to read data from {$pFilename}');
280+
}
279281

280-
$docProps = $spreadsheet->getProperties();
281-
$officeProperty = $xml->children($namespacesMeta['office']);
282-
foreach ($officeProperty as $officePropertyData) {
283-
$officePropertyDC = [];
284-
if (isset($namespacesMeta['dc'])) {
285-
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
286-
}
287-
foreach ($officePropertyDC as $propertyName => $propertyValue) {
288-
$propertyValue = (string) $propertyValue;
289-
switch ($propertyName) {
290-
case 'title':
291-
$docProps->setTitle($propertyValue);
292-
293-
break;
294-
case 'subject':
295-
$docProps->setSubject($propertyValue);
296-
297-
break;
298-
case 'creator':
299-
$docProps->setCreator($propertyValue);
300-
$docProps->setLastModifiedBy($propertyValue);
301-
302-
break;
303-
case 'date':
304-
$creationDate = strtotime($propertyValue);
305-
$docProps->setCreated($creationDate);
306-
$docProps->setModified($creationDate);
307-
308-
break;
309-
case 'description':
310-
$docProps->setDescription($propertyValue);
311-
312-
break;
313-
}
314-
}
315-
$officePropertyMeta = [];
316-
if (isset($namespacesMeta['dc'])) {
317-
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
318-
}
319-
foreach ($officePropertyMeta as $propertyName => $propertyValue) {
320-
$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
321-
$propertyValue = (string) $propertyValue;
322-
switch ($propertyName) {
323-
case 'initial-creator':
324-
$docProps->setCreator($propertyValue);
325-
326-
break;
327-
case 'keyword':
328-
$docProps->setKeywords($propertyValue);
329-
330-
break;
331-
case 'creation-date':
332-
$creationDate = strtotime($propertyValue);
333-
$docProps->setCreated($creationDate);
334-
335-
break;
336-
case 'user-defined':
337-
$propertyValueType = Properties::PROPERTY_TYPE_STRING;
338-
foreach ($propertyValueAttributes as $key => $value) {
339-
if ($key == 'name') {
340-
$propertyValueName = (string) $value;
341-
} elseif ($key == 'value-type') {
342-
switch ($value) {
343-
case 'date':
344-
$propertyValue = Properties::convertProperty($propertyValue, 'date');
345-
$propertyValueType = Properties::PROPERTY_TYPE_DATE;
346-
347-
break;
348-
case 'boolean':
349-
$propertyValue = Properties::convertProperty($propertyValue, 'bool');
350-
$propertyValueType = Properties::PROPERTY_TYPE_BOOLEAN;
351-
352-
break;
353-
case 'float':
354-
$propertyValue = Properties::convertProperty($propertyValue, 'r4');
355-
$propertyValueType = Properties::PROPERTY_TYPE_FLOAT;
356-
357-
break;
358-
default:
359-
$propertyValueType = Properties::PROPERTY_TYPE_STRING;
360-
}
361-
}
362-
}
363-
$docProps->setCustomProperty($propertyValueName, $propertyValue, $propertyValueType);
282+
$namespacesMeta = $xml->getNamespaces(true);
364283

365-
break;
366-
}
367-
}
368-
}
284+
(new DocumentProperties($spreadsheet))->load($xml, $namespacesMeta);
369285

370286
// Content
371287

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
4+
5+
use PhpOffice\PhpSpreadsheet\Document\Properties as DocumentProperties;
6+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
7+
8+
class Properties
9+
{
10+
private $spreadsheet;
11+
12+
public function __construct(Spreadsheet $spreadsheet)
13+
{
14+
$this->spreadsheet = $spreadsheet;
15+
}
16+
17+
public function load(\SimpleXMLElement $xml, $namespacesMeta)
18+
{
19+
$docProps = $this->spreadsheet->getProperties();
20+
$officeProperty = $xml->children($namespacesMeta['office']);
21+
foreach ($officeProperty as $officePropertyData) {
22+
/** @var \SimpleXMLElement $officePropertyData */
23+
$officePropertiesDC = [];
24+
if (isset($namespacesMeta['dc'])) {
25+
$officePropertiesDC = $officePropertyData->children($namespacesMeta['dc']);
26+
}
27+
$this->setCoreProperties($docProps, $officePropertiesDC);
28+
29+
$officePropertyMeta = [];
30+
if (isset($namespacesMeta['dc'])) {
31+
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
32+
}
33+
foreach ($officePropertyMeta as $propertyName => $propertyValue) {
34+
$this->setMetaProperties($namespacesMeta, $propertyValue, $propertyName, $docProps);
35+
}
36+
}
37+
}
38+
39+
private function setCoreProperties(DocumentProperties $docProps, \SimpleXMLElement $officePropertyDC)
40+
{
41+
foreach ($officePropertyDC as $propertyName => $propertyValue) {
42+
$propertyValue = (string) $propertyValue;
43+
switch ($propertyName) {
44+
case 'title':
45+
$docProps->setTitle($propertyValue);
46+
47+
break;
48+
case 'subject':
49+
$docProps->setSubject($propertyValue);
50+
51+
break;
52+
case 'creator':
53+
$docProps->setCreator($propertyValue);
54+
$docProps->setLastModifiedBy($propertyValue);
55+
56+
break;
57+
case 'creation-date':
58+
$creationDate = strtotime($propertyValue);
59+
$docProps->setCreated($creationDate);
60+
$docProps->setModified($creationDate);
61+
62+
break;
63+
case 'keyword':
64+
$docProps->setKeywords($propertyValue);
65+
66+
break;
67+
case 'description':
68+
$docProps->setDescription($propertyValue);
69+
70+
break;
71+
}
72+
}
73+
}
74+
75+
private function setMetaProperties(
76+
$namespacesMeta,
77+
\SimpleXMLElement $propertyValue,
78+
$propertyName,
79+
DocumentProperties $docProps
80+
) {
81+
$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
82+
$propertyValue = (string) $propertyValue;
83+
switch ($propertyName) {
84+
case 'initial-creator':
85+
$docProps->setCreator($propertyValue);
86+
87+
break;
88+
case 'keyword':
89+
$docProps->setKeywords($propertyValue);
90+
91+
break;
92+
case 'creation-date':
93+
$creationDate = strtotime($propertyValue);
94+
$docProps->setCreated($creationDate);
95+
96+
break;
97+
case 'user-defined':
98+
$this->setUserDefinedProperty($propertyValueAttributes, $propertyValue, $docProps);
99+
100+
break;
101+
}
102+
}
103+
104+
private function setUserDefinedProperty($propertyValueAttributes, $propertyValue, DocumentProperties $docProps)
105+
{
106+
$propertyValueName = '';
107+
$propertyValueType = DocumentProperties::PROPERTY_TYPE_STRING;
108+
foreach ($propertyValueAttributes as $key => $value) {
109+
if ($key == 'name') {
110+
$propertyValueName = (string) $value;
111+
} elseif ($key == 'value-type') {
112+
switch ($value) {
113+
case 'date':
114+
$propertyValue = DocumentProperties::convertProperty($propertyValue, 'date');
115+
$propertyValueType = DocumentProperties::PROPERTY_TYPE_DATE;
116+
117+
break;
118+
case 'boolean':
119+
$propertyValue = DocumentProperties::convertProperty($propertyValue, 'bool');
120+
$propertyValueType = DocumentProperties::PROPERTY_TYPE_BOOLEAN;
121+
122+
break;
123+
case 'float':
124+
$propertyValue = DocumentProperties::convertProperty($propertyValue, 'r4');
125+
$propertyValueType = DocumentProperties::PROPERTY_TYPE_FLOAT;
126+
127+
break;
128+
default:
129+
$propertyValueType = DocumentProperties::PROPERTY_TYPE_STRING;
130+
}
131+
}
132+
}
133+
134+
$docProps->setCustomProperty($propertyValueName, $propertyValue, $propertyValueType);
135+
}
136+
}

0 commit comments

Comments
 (0)