Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Reader\Xml; 4 5 use PhpOffice\PhpSpreadsheet\Document\Properties as DocumentProperties; 6 use PhpOffice\PhpSpreadsheet\Spreadsheet; 7 use SimpleXMLElement; 8 9 class Properties 10 { 11 /** 12 * @var Spreadsheet 13 */ 14 protected $spreadsheet; 15 16 public function __construct(Spreadsheet $spreadsheet) 17 { 18 $this->spreadsheet = $spreadsheet; 19 } 20 21 public function readProperties(SimpleXMLElement $xml, array $namespaces): void 22 { 23 $this->readStandardProperties($xml); 24 $this->readCustomProperties($xml, $namespaces); 25 } 26 27 protected function readStandardProperties(SimpleXMLElement $xml): void 28 { 29 if (isset($xml->DocumentProperties[0])) { 30 $docProps = $this->spreadsheet->getProperties(); 31 32 foreach ($xml->DocumentProperties[0] as $propertyName => $propertyValue) { 33 $propertyValue = (string) $propertyValue; 34 35 $this->processStandardProperty($docProps, $propertyName, $propertyValue); 36 } 37 } 38 } 39 40 protected function readCustomProperties(SimpleXMLElement $xml, array $namespaces): void 41 { 42 if (isset($xml->CustomDocumentProperties) && is_iterable($xml->CustomDocumentProperties[0])) { 43 $docProps = $this->spreadsheet->getProperties(); 44 45 foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { 46 $propertyAttributes = self::getAttributes($propertyValue, $namespaces['dt']); 47 $propertyName = (string) preg_replace_callback('/_x([0-9a-f]{4})_/i', [$this, 'hex2str'], $propertyName); 48 49 $this->processCustomProperty($docProps, $propertyName, $propertyValue, $propertyAttributes); 50 } 51 } 52 } 53 54 protected function processStandardProperty( 55 DocumentProperties $docProps, 56 string $propertyName, 57 string $stringValue 58 ): void { 59 switch ($propertyName) { 60 case 'Title': 61 $docProps->setTitle($stringValue); 62 63 break; 64 case 'Subject': 65 $docProps->setSubject($stringValue); 66 67 break; 68 case 'Author': 69 $docProps->setCreator($stringValue); 70 71 break; 72 case 'Created': 73 $docProps->setCreated($stringValue); 74 75 break; 76 case 'LastAuthor': 77 $docProps->setLastModifiedBy($stringValue); 78 79 break; 80 case 'LastSaved': 81 $docProps->setModified($stringValue); 82 83 break; 84 case 'Company': 85 $docProps->setCompany($stringValue); 86 87 break; 88 case 'Category': 89 $docProps->setCategory($stringValue); 90 91 break; 92 case 'Manager': 93 $docProps->setManager($stringValue); 94 95 break; 96 case 'HyperlinkBase': 97 $docProps->setHyperlinkBase($stringValue); 98 99 break; 100 case 'Keywords': 101 $docProps->setKeywords($stringValue); 102 103 break; 104 case 'Description': 105 $docProps->setDescription($stringValue); 106 107 break; 108 } 109 } 110 111 protected function processCustomProperty( 112 DocumentProperties $docProps, 113 string $propertyName, 114 ?SimpleXMLElement $propertyValue, 115 SimpleXMLElement $propertyAttributes 116 ): void { 117 switch ((string) $propertyAttributes) { 118 case 'boolean': 119 $propertyType = DocumentProperties::PROPERTY_TYPE_BOOLEAN; 120 $propertyValue = (bool) (string) $propertyValue; 121 122 break; 123 case 'integer': 124 $propertyType = DocumentProperties::PROPERTY_TYPE_INTEGER; 125 $propertyValue = (int) $propertyValue; 126 127 break; 128 case 'float': 129 $propertyType = DocumentProperties::PROPERTY_TYPE_FLOAT; 130 $propertyValue = (float) $propertyValue; 131 132 break; 133 case 'dateTime.tz': 134 case 'dateTime.iso8601tz': 135 $propertyType = DocumentProperties::PROPERTY_TYPE_DATE; 136 $propertyValue = trim((string) $propertyValue); 137 138 break; 139 default: 140 $propertyType = DocumentProperties::PROPERTY_TYPE_STRING; 141 $propertyValue = trim((string) $propertyValue); 142 143 break; 144 } 145 146 $docProps->setCustomProperty($propertyName, $propertyValue, $propertyType); 147 } 148 149 protected function hex2str(array $hex): string 150 { 151 return mb_chr((int) hexdec($hex[1]), 'UTF-8'); 152 } 153 154 private static function getAttributes(?SimpleXMLElement $simple, string $node): SimpleXMLElement 155 { 156 return ($simple === null) ? new SimpleXMLElement('<xml></xml>') : ($simple->attributes($node) ?? new SimpleXMLElement('<xml></xml>')); 157 } 158 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body