diff --git a/library/readerepub/readerepub.php b/library/readerepub/readerepub.php new file mode 100644 index 0000000..6ea8c62 --- /dev/null +++ b/library/readerepub/readerepub.php @@ -0,0 +1,227 @@ +ebookDir = $ebookDir; + + $this->_getOPF(); + $this->_getDcData(); + $this->_getManifest(); + $this->_getSpine(); + $this->_getTOC(); + + //$this->debug(); + } + + /** + * Get the specified DC item + * @param string $item The DC Item key + * @return string/boolean String when DC item exists, otherwise false + */ + public function getDcItem($item) { + if(key_exists($item, $this->dcElements)) { + return $this->dcElements[$item]; + } else { + return false; + } + } + + /** + * Get the specified manifest item + * @param string $item The manifest ID + * @return string/boolean String when manifest item exists, otherwise false + */ + public function getManifest($item) { + if(key_exists($item, $this->manifest)) { + return $this->manifest[$item]; + } else { + return false; + } + } + + /** + * Get the specified manifest by type + * @param string $type The manifest type + * @return string/boolean String when manifest item exists, otherwise false + */ + public function getManifestByType($type) { + foreach($this->manifest AS $manifestID => $manifest) { + if($manifest['media-type'] == $type) { + $return[$manifestID]['href'] = $manifest['href']; + $return[$manifestID]['media-type'] = $manifest['media-type']; + } + } + + return (count($return) == 0) ? false : $return; + } + + /** + * Retrieve the ToC + * @return array Array with ToC Data + */ + public function getTOC() { + return $this->toc; + } + + /** + * Returns the OPF/Data dir + * @return string The OPF/data dir + */ + public function getOPFDir() { + return $this->opfDir; + } + /** + * Prints all contents of the class directly to the screen + */ + public function debug() { + echo sprintf('
%s
', print_r($this, true)); + } + // Private functions + /** + * Get the path to the OPF file from the META-INF/container.xml file + * @return string Relative path to the OPF file + */ + private function _getOPF() { + $opfContents = simplexml_load_file($this->ebookDir . '/META-INF/container.xml'); + $opfAttributes = $opfContents->rootfiles->rootfile->attributes(); + $this->opfFile = (string) $opfAttributes[0]; // Typecasting to string to get rid of the XML object + + // Set also the dir to the OPF (and ePub files) + $opfDirParts = explode('/',$this->opfFile); + unset($opfDirParts[(count($opfDirParts)-1)]); // remove the last part (it's the .opf file itself) + $this->opfDir = implode('/',$opfDirParts); + + return $this->opfFile; + } + /** + * Read the metadata DC details (title, author, etc.) from the OPF file + */ + private function _getDcData() { + $opfContents = simplexml_load_file($this->ebookDir . '/' . $this->opfFile); + $this->dcElements = (array) $opfContents->metadata->children('dc', true); + } + /** + * Gets the manifest data from the OPF file + */ + private function _getManifest() { + $opfContents = simplexml_load_file($this->ebookDir . '/' . $this->opfFile); + $iManifest = 0; + foreach ($opfContents->manifest->item AS $item) { + $attr = $item->attributes(); + $id = (string) $attr->id; + $this->manifest[$id]['href'] = (string) $attr->href; + $this->manifest[$id]['media-type'] = (string) $attr->{'media-type'}; + $iManifest++; + } + } + /** + * Get the spine data from the OPF file + */ + private function _getSpine() { + $opfContents = simplexml_load_file($this->ebookDir . '/' . $this->opfFile); + foreach ($opfContents->spine->itemref AS $item) { + $attr = $item->attributes(); + $this->spine[] = (string) $attr->idref; + } + } + + + /** + * Build an array with the TOC + + private function _getTOC() { + $tocFile = $this->getManifest('ncx'); + $tocContents = simplexml_load_file($this->ebookDir.'/'.$this->opfDir.'/'.$tocFile['href']); + + $toc = array(); + foreach($tocContents->navMap->navPoint AS $navPoint) { + $navPointData = $navPoint->attributes(); + $toc[(string)$navPointData['playOrder']]['id'] = (string)$navPointData['id']; + $toc[(string)$navPointData['playOrder']]['naam'] = (string)$navPoint->navLabel->text; + $toc[(string)$navPointData['playOrder']]['src'] = (string)$navPoint->content->attributes(); + } + + $this->toc = $toc; + } + */ + /** + * Build an array with the TOC + */ + private function _getTOC() { + $tocFile = $this->getManifest('ncx'); + $tocContents = @simplexml_load_file($this->ebookDir.'/'.$this->opfDir.'/'.$tocFile['href']); + if (!$tocContents) return false; + + $toc = array(); + foreach($tocContents->navMap->navPoint AS $navPoint) { + $toc = $this -> _process_navPoint($toc, $navPoint); + } + + $this->toc = $toc; + } + + + /* + * Recursive function to get all navPoints, which may be nested + */ + private function _process_navPoint($toc, $navPoint) { + $navPointData = $navPoint->attributes(); + $toc[(string)$navPointData['playOrder']]['id'] = (string)$navPointData['id']; + $toc[(string)$navPointData['playOrder']]['name'] = (string)$navPoint->navLabel->text; + $toc[(string)$navPointData['playOrder']]['src'] = (string)$navPoint->content->attributes(); + + if ($navPoint->navPoint) { // If there are more navPoints within the current one + foreach ($navPoint->navPoint as $nested_navPoint) { // Process them too + $toc = $this -> _process_navPoint($toc, $nested_navPoint); + } + } + + return $toc; + } +} \ No newline at end of file