*/ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); class action_plugin_ebookexport extends DokuWiki_Action_Plugin { /** * Registers a callback function for a given event * * @param Doku_Event_Handler $controller DokuWiki's event controller object * @return void */ public function register(Doku_Event_Handler $controller) { $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'exportepub', array()); $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'addepubbutton', array()); } public function exportepub(Doku_Event $event) { global $ACT; global $ID; global $conf; // our event? if($ACT != 'export_epub') return false; // check user's rights if(auth_quickaclcheck($ID) < AUTH_READ) return false; // it's ours, no one else's $event->preventDefault(); $tempdir=tempnam(sys_get_temp_dir(),''); if (file_exists($tempdir)) { unlink($tempdir); } mkdir($tempdir); require_once DOKU_INC . 'inc/parser/parser.php'; $mypage = pageinfo(); $mypath = $mypage["filepath"]; $doc = file_get_contents($mypath); $instructions = p_get_instructions($doc); require_once DOKU_INC . 'inc/parser/xhtml.php'; $Renderer = new Doku_Renderer_XHTML(); foreach ( $instructions as $instruction ) { call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]); } $tocarray = $Renderer->toc; $pages = $Renderer->doc; if(isset($conf['baseurl']) && ($conf['baseurl'] != '')){ $url = $conf['baseurl'] . '/'; } else{ $self = parse_url(DOKU_URL); $url = $self['scheme'] . '://' . $self['host']; if($self['port']) { $url .= ':' . $self['port']; } $url .= '/'; } $pages = preg_replace('/href="\//',"href=\"$url",$pages); file_put_contents($tempdir . "/pages.xhtml",$pages); $mimetype = "application/epub+zip"; file_put_contents($tempdir . "/mimetype",$mimetype); $pagestyle = "@page {\nmargin-bottom: 5pt;\nmargin-top: 5pt;\n}\n"; file_put_contents($tempdir . "/page_styles.css",$pagestyle); $stylesheet = "h2 {\nfont-size: large;\n}\n"; file_put_contents($tempdir . "/stylesheet.css",$stylesheet); mkdir($tempdir . "/META-INF"); $container = ''; file_put_contents($tempdir . "/META-INF/container.xml", $container); if(isset($mypage["meta"]["title"])){ $mytitle = $mypage["meta"]["title"]; } else{ $mytitle = preg_replace('/^.*:/','',$ID); $mytitle = ucwords(preg_replace('/_/',' ',$mytitle)); } $epubuuid = preg_replace('/^(........)(....)(....)(....)(............).*/','${1}-${2}-${3}-${4}-${5}',md5($conf['title'] . $mytitle . $mypage['lastmod'])); $files = array('content.opf','mimetype','page_styles.css','pages.xhtml','stylesheet.css','titlepage.xhtml','toc.ncx','META-INF/container.xml'); $content = ""; $content .= ''; $content .= ''; $content .= 'en'; $content .= '' . $mytitle . ''; $content .= '' . $conf['title'] . ''; $content .= ''; $content .= '' . date("Y-m-d\TH:i:s:P",$mypage['lastmod']) . ''; $content .= ''; $content .= '' . $epubuuid . ''; $content .= ''; $content .= ''; if(isset($mypage["meta"]["relation"]["media"])){ foreach($mypage["meta"]["relation"]["media"] as $mediaitem => $whatever){ $mediafile = mediaFN($mediaitem); $mediamime = mime_content_type($mediafile); $medialink = ml($mediaitem); $mediadir = dirname($medialink); if(!is_dir($tempdir . $mediadir)) mkdir($tempdir . $mediadir, 0777, true); copy($mediafile,$tempdir . $medialink); array_push($files,substr($medialink,1)); $content .= ''; } } $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; $content .= ''; file_put_contents($tempdir . "/content.opf",$content); $titlepage = ""; $titlepage .= ''; $titlepage .= ''; $titlepage .= ''; $titlepage .= 'Cover'; $titlepage .= ''; $titlepage .= ''; $titlepage .= ''; $titlepage .= '
'; $titlepage .= '

' . $mytitle . '

'; $titlepage .= '

' . $conf['title'] . '

'; $titlepage .= '
'; $titlepage .= ''; file_put_contents($tempdir . "/titlepage.xhtml",$titlepage); $toc = ""; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= ''; $toc .= 'Titel'; $toc .= ''; $toc .= ''; for($i=0;$i'; $toc .= '' . $tocarray[$i]["title"] . ''; $toc .= ''; $toc .= ''; } $toc .= ''; file_put_contents($tempdir . "/toc.ncx",$toc); $zip = new ZipArchive(); $zipfile = $tempdir . "/" . $ID . ".epub"; $zip->open($zipfile,ZipArchive::CREATE); foreach($files as $file){ $zip->addFile($tempdir . "/" . $file,$file); } $zip->close(); header('Content-Type: application/epub+zip'); header('Cache-Control: must-revalidate, no-cache'); header('Pragma: no-cache'); $filename = preg_replace('/ /','_',$mytitle) . ".epub"; header('Content-Disposition: attachment; filename="' . $filename . '";'); //Bookcreator uses jQuery.fileDownload.js, which requires a cookie. header('Set-Cookie: fileDownload=true; path=/'); $fp = @fopen($zipfile, "rb"); if($fp) { $size = filesize($zipfile); header('Accept-Ranges: bytes'); header("Content-Length: $size"); fseek($fp,0); $chunk = ($size > HTTP_CHUNK_SIZE) ? HTTP_CHUNK_SIZE : $size; while (!feof($fp) && $chunk > 0) { @set_time_limit(30); print fread($fp, $chunk); flush(); $size -= $chunk; $chunk = ($size > HTTP_CHUNK_SIZE) ? HTTP_CHUNK_SIZE : $size; } } else { header("HTTP/1.0 500 Internal Server Error"); print "Could not read file - bad permissions?"; $ranges[] = array(0,$size,$size); } $this->rrmdir($tempdir); exit; } private function rrmdir($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (is_dir($dir."/".$object)) $this->rrmdir($dir."/".$object); else unlink($dir."/".$object); } } rmdir($dir); } } public function addepubbutton(Doku_Event $event) { global $ID, $REV; if($event->data['view'] == 'main') { $params = array('do' => 'export_epub'); if($REV) { $params['rev'] = $REV; } // insert button at position before last (up to top) $event->data['items'] = array_slice($event->data['items'], 0, -1, true) + array('export_epub' => '
  • ' . '' . 'Export to EPUB' . '' . '
  • ' ) + array_slice($event->data['items'], -1, 1, true); } } } // vim:ts=4:sw=4:et: