/* * extract * * Extract the project to a given destination. * First read the info.xml then unzip files * * @access public * @param string $destination * @return bool */ public function extract($destination) { $fip = new ZipArchive; if($fip->open($this->filename) !== true) return false; $infoFile = $fip->getFromName("project/info.xml"); if(!$infoFile) return false; if(!$infoXML = new SimpleXMLElement($infoFile)) return false; $childNodes = $infoXML->children(); foreach($childNodes as $node) { if($node->getName() == "files") { $this->recurseExtract($node); } else $this->nodes[(string)$node->getName()] = (string)$node; } foreach($this->fileExtracts as $baseDest => $file) { $baseDest = (is_int($baseDest)) ? "" : "/".$baseDest; $extractDest = "project".$baseDest; if(!is_array($file)) $this->fullFilePaths[] = $extractDest . "/" . $file; else { foreach($file as $aKey => $aVal) { if(!is_int($aKey)) $extractDest .= "/". $aKey; else { $this->fullFilePaths[] = $extractDest . "/" . $aVal; } } } } $fip->extractTo($destination, $this->fullFilePaths); $fip->close(); if($this->nodes["overwrite"] == true) { if(is_dir($destination."/".$this->nodes["title"])) { $this->deleteDir($destination."/".$this->nodes["title"], true); } } if(is_dir($destination."/".$this->nodes["title"])) return false; rename($destination."/project", $destination."/".$this->nodes["title"]); } /* * getNodeValue * * Returns a node value from the parsed info.xml file * * @param string $key The node name * @access public * @return string or bool */ public function getNodeValue($key) { if(array_key_exists($key, $this->nodes)) return $this->nodes[$key]; else return false; } /* * recurseExtract * * Recurses until all filenames have been withdrawn * * @param SimpleXMLElement $files All files * @access private * @return void */ private function recurseExtract($xmlFiles) { foreach($xmlFiles as $path) { if($path->getName() == "dir") { $this->fileExtracts[(string)$path['name']] = array(); $this->recurseDir($path, (string)$path['name']); } else if($path->getName() == "file") { $this->fileExtracts[] = (string)$path->filename[0]; } } } /* * recurseDir * * Recurses a directory, and list them in $fileExtracts * * @param SimpleXMLElement $dirElement The directory element * @param string $dirPath Base directory path * @access private * @return void */ private function recurseDir($dirElement, $dirPath) { foreach($dirElement->children() as $child) { if($child->getName() == "dir") { $this->recurseExtract($child); } else if($child->getName() == "file") { $this->fileExtracts[(string)$dirPath][] = (string)$child->filename[0]; } } }
<?xml version="1.0" encoding="ISO-8859-1"?> <project> <title>Frozen Audio</title> <version>1.5</version> <build>18/12/08 17:28</build> <logo>somelogo.png</logo> <description>Here goes a little description of Frozen Audio</description> <indexfile>index.php</indexfile> <overwrite>true</overwrite> <files> <file> <filename>index.php</filename> <build>19/12/08 12:46</build> <description>The project index file</description> <type>php</type> </file> <dir name="project"> <dir name="aSubFolder"> <file> <filename>withafile.php</filename> <build>19/12/08 15:25</build> <description>A test file</description> <type>php</type> </file> </dir> <file> <filename>index.php</filename> <build>18/12/08 13:20</build> <description>Index file</description> <type>php</type> </file> <file> <filename>engine.php</filename> <build>18/12/08 13:25</build> <description>Audio engine</description> <type>php</type> </file> <file> <filename>top.php</filename> <build>18/12/08 11:23</build> <description>Top file</description> <type>php</type> </file> <file> <filename>bottom.php</filename> <build>18/12/08 10:28</build> <description>Bottom file</description> <type>php</type> </file> </dir> <dir name="style"> <file> <filename>bg.png</filename> <build>18/10/08 10:50</build> <description>Background image</description> <type>image</type> </file> <file> <filename>style.css</filename> <build>18/11/08 11:42</build> <description>Stylesheet</description> <type>css</type> </file> </dir> </files> </project>