/** * Reads the data of a style exchange format file. * * @param wcf\system\io\Tar $tar * @return array data */ public static function readStyleData(Tar $tar) { // search style.xml $i = $tar->getIndexByFilename(self::INFO_FILE); if ($i === false) { throw new SystemException("unable to find required file '" . self::INFO_FILE . "' in style archive"); } // open style.xml $styleXML = new XML(); $styleXML->loadString($tar->extractToString($i)); $xmlContent = $styleXML->getElementTree('style'); $data = array('name' => '', 'description' => '', 'version' => '', 'image' => '', 'copyright' => '', 'license' => '', 'authorName' => '', 'authorURL' => '', 'templates' => '', 'images' => '', 'variables' => '', 'date' => '0000-00-00', 'icons' => ''); foreach ($xmlContent['children'] as $child) { switch ($child['name']) { case 'general': foreach ($child['children'] as $general) { switch ($general['name']) { case 'stylename': $data['name'] = $general['cdata']; break; case 'description': case 'version': case 'date': case 'image': case 'copyright': case 'license': $data[$general['name']] = $general['cdata']; break; } } break; case 'author': foreach ($child['children'] as $author) { switch ($author['name']) { case 'authorname': $data['authorName'] = $author['cdata']; break; case 'authorurl': $data['authorURL'] = $author['cdata']; break; } } break; case 'files': foreach ($child['children'] as $files) { switch ($files['name']) { case 'templates': case 'images': case 'variables': case 'icons': $data[$files['name']] = $files['cdata']; break; } } break; } } if (empty($data['name'])) { throw new SystemException("required tag 'stylename' is missing in '" . self::INFO_FILE . "'"); } if (empty($data['variables'])) { throw new SystemException("required tag 'variables' is missing in '" . self::INFO_FILE . "'"); } // search variables.xml $i = $tar->getIndexByFilename($data['variables']); if ($i === false) { throw new SystemException("unable to find required file '" . $data['variables'] . "' in style archive"); } // open variables.xml $data['variables'] = self::readVariablesData($tar->extractToString($i)); return $data; }
/** * Reads the data of a style exchange format file. * * @param \wcf\system\io\Tar $tar * @return array */ public static function readStyleData(Tar $tar) { // search style.xml $index = $tar->getIndexByFilename(self::INFO_FILE); if ($index === false) { throw new SystemException("unable to find required file '" . self::INFO_FILE . "' in style archive"); } // open style.xml $xml = new XML(); $xml->loadXML(self::INFO_FILE, $tar->extractToString($index)); $xpath = $xml->xpath(); $data = array('name' => '', 'description' => array(), 'version' => '', 'image' => '', 'copyright' => '', 'default' => false, 'license' => '', 'authorName' => '', 'authorURL' => '', 'templates' => '', 'images' => '', 'variables' => '', 'date' => '0000-00-00', 'imagesPath' => ''); $categories = $xpath->query('/ns:style/*'); foreach ($categories as $category) { switch ($category->tagName) { case 'author': $elements = $xpath->query('child::*', $category); foreach ($elements as $element) { switch ($element->tagName) { case 'authorname': $data['authorName'] = $element->nodeValue; break; case 'authorurl': $data['authorURL'] = $element->nodeValue; break; } } break; case 'files': $elements = $xpath->query('child::*', $category); foreach ($elements as $element) { $data[$element->tagName] = $element->nodeValue; if ($element->hasAttribute('path')) { $data[$element->tagName . 'Path'] = $element->getAttribute('path'); } } break; case 'general': $elements = $xpath->query('child::*', $category); foreach ($elements as $element) { switch ($element->tagName) { case 'date': DateUtil::validateDate($element->nodeValue); $data['date'] = $element->nodeValue; break; case 'default': $data['default'] = true; break; case 'description': if ($element->hasAttribute('language')) { $data['description'][$element->getAttribute('language')] = $element->nodeValue; } break; case 'stylename': $data['name'] = $element->nodeValue; break; case 'version': if (!Package::isValidVersion($element->nodeValue)) { throw new SystemException("style version '" . $element->nodeValue . "' is invalid"); } $data['version'] = $element->nodeValue; break; case 'copyright': case 'image': case 'license': $data[$element->tagName] = $element->nodeValue; break; } } break; } } if (empty($data['name'])) { throw new SystemException("required tag 'stylename' is missing in '" . self::INFO_FILE . "'"); } if (empty($data['variables'])) { throw new SystemException("required tag 'variables' is missing in '" . self::INFO_FILE . "'"); } // search variables.xml $index = $tar->getIndexByFilename($data['variables']); if ($index === false) { throw new SystemException("unable to find required file '" . $data['variables'] . "' in style archive"); } // open variables.xml $data['variables'] = self::readVariablesData($data['variables'], $tar->extractToString($index)); return $data; }
/** * Extracts information about this package (parses package.xml). */ protected function readPackageInfo() { // search package.xml in package archive // throw error message if not found if ($this->tar->getIndexByFilename(self::INFO_FILE) === false) { throw new SystemException("package information file '".(self::INFO_FILE)."' not found in '".$this->archive."'"); } // extract package.xml, parse with SimpleXML // and compile an array with XML::getElementTree() $xml = new XML(); try { $xml->loadXML(self::INFO_FILE, $this->tar->extractToString(self::INFO_FILE)); } catch (\Exception $e) { // bugfix to avoid file caching problems $xml->loadXML(self::INFO_FILE, $this->tar->extractToString(self::INFO_FILE)); } // parse xml $xpath = $xml->xpath(); $package = $xpath->query('/ns:package')->item(0); // package name $packageName = $package->getAttribute('name'); if (!Package::isValidPackageName($packageName)) { // package name is not a valid package identifier throw new SystemException("'".$packageName."' is not a valid package name."); } $this->packageInfo['name'] = $packageName; // get package information $packageInformation = $xpath->query('./ns:packageinformation', $package)->item(0); $elements = $xpath->query('child::*', $packageInformation); foreach ($elements as $element) { switch ($element->tagName) { case 'packagename': case 'packagedescription': case 'readme': case 'license': if (!isset($this->packageInfo[$element->tagName])) $this->packageInfo[$element->tagName] = array(); $languageCode = 'default'; if ($element->hasAttribute('language')) { $languageCode = $element->getAttribute('language'); } // fix case-sensitive names $name = $element->tagName; if ($name == 'packagename') $name = 'packageName'; else if ($name == 'packagedescription') $name = 'packageDescription'; $this->packageInfo[$name][$languageCode] = $element->nodeValue; break; case 'isapplication': $this->packageInfo['isApplication'] = intval($element->nodeValue); break; case 'packageurl': $this->packageInfo['packageURL'] = $element->nodeValue; break; case 'version': if (!Package::isValidVersion($element->nodeValue)) { throw new SystemException("package version '".$element->nodeValue."' is invalid"); } $this->packageInfo['version'] = $element->nodeValue; break; case 'date': DateUtil::validateDate($element->nodeValue); $this->packageInfo['date'] = strtotime($element->nodeValue); break; } } // get author information $authorInformation = $xpath->query('./ns:authorinformation', $package)->item(0); $elements = $xpath->query('child::*', $authorInformation); foreach ($elements as $element) { $tagName = ($element->tagName == 'authorurl') ? 'authorURL' : $element->tagName; $this->authorInfo[$tagName] = $element->nodeValue; } // get required packages $elements = $xpath->query('child::ns:requiredpackages/ns:requiredpackage', $package); foreach ($elements as $element) { if (!Package::isValidPackageName($element->nodeValue)) { throw new SystemException("'".$element->nodeValue."' is not a valid package name."); } // read attributes $data = array('name' => $element->nodeValue); $attributes = $xpath->query('attribute::*', $element); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $this->requirements[$element->nodeValue] = $data; } // get optional packages $elements = $xpath->query('child::ns:optionalpackages/ns:optionalpackage', $package); foreach ($elements as $element) { if (!Package::isValidPackageName($element->nodeValue)) { throw new SystemException("'".$element->nodeValue."' is not a valid package name."); } // read attributes $data = array('name' => $element->nodeValue); $attributes = $xpath->query('attribute::*', $element); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $this->optionals[] = $data; } // get excluded packages $elements = $xpath->query('child::ns:excludedpackages/ns:excludedpackage', $package); foreach ($elements as $element) { if (!Package::isValidPackageName($element->nodeValue)) { throw new SystemException("'".$element->nodeValue."' is not a valid package name."); } // read attributes $data = array('name' => $element->nodeValue); $attributes = $xpath->query('attribute::*', $element); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $this->excludedPackages[] = $data; } // get instructions $elements = $xpath->query('./ns:instructions', $package); foreach ($elements as $element) { $instructionData = array(); $instructions = $xpath->query('./ns:instruction', $element); foreach ($instructions as $instruction) { $data = array(); $attributes = $xpath->query('attribute::*', $instruction); foreach ($attributes as $attribute) { $data[$attribute->name] = $attribute->value; } $instructionData[] = array( 'attributes' => $data, 'pip' => $instruction->getAttribute('type'), 'value' => $instruction->nodeValue ); } $fromVersion = $element->getAttribute('fromversion'); $type = $element->getAttribute('type'); if ($type == 'install') { $this->instructions['install'] = $instructionData; } else { $this->instructions['update'][$fromVersion] = $instructionData; } } // get php requirements $requirements = $xpath->query('./ns:phprequirements', $package); foreach ($requirements as $requirement) { $elements = $xpath->query('child::*', $requirement); foreach ($elements as $element) { switch ($element->tagName) { case 'version': $this->phpRequirements['version'] = $element->nodeValue; break; case 'setting': $this->phpRequirements['settings'][$element->getAttribute('name')] = $element->nodeValue; break; case 'extension': $this->phpRequirements['extensions'][] = $element->nodeValue; break; case 'function': $this->phpRequirements['functions'][] = $element->nodeValue; break; case 'class': $this->phpRequirements['classes'][] = $element->nodeValue; break; } } } // add com.woltlab.wcf to package requirements if (!isset($this->requirements['com.woltlab.wcf']) && $this->packageInfo['name'] != 'com.woltlab.wcf') { $this->requirements['com.woltlab.wcf'] = array('name' => 'com.woltlab.wcf'); } if ($this->package != null) { $validFromVersion = null; foreach ($this->instructions['update'] as $fromVersion => $update) { if (Package::checkFromversion($this->package->packageVersion, $fromVersion)) { $validFromVersion = $fromVersion; break; } } if ($validFromVersion === null) { $this->instructions['update'] = array(); } else { $this->instructions['update'] = $this->instructions['update'][$validFromVersion]; } } // set default values if (!isset($this->packageInfo['isApplication'])) $this->packageInfo['isApplication'] = 0; if (!isset($this->packageInfo['packageURL'])) $this->packageInfo['packageURL'] = ''; }