*/ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); if(!defined('DOKU_INCLUDE')) define('DOKU_INCLUDE',DOKU_INC.'inc/'); require_once(DOKU_PLUGIN . 'admin.php'); require_once(DOKU_INCLUDE . 'io.php'); /** * All DokuWiki plugins to extend the admin function * need to inherit from this class */ class admin_plugin_doctree2filelist extends DokuWiki_Admin_Plugin { /** * Constructor */ function admin_plugin_doctree2filelist() { $this->setupLocale(); } /** * return some info */ function getInfo() { return array( 'author' => 'Frank Schiebel', 'email' => 'frank@linuxmuster.net', 'date' => '2010-11-27', 'name' => 'doctree2filelist: Imports document tree into dokuwiki', 'desc' => 'This plugin is for importing a whole tree with (office-)documents to a wiki page-structure. It has been written for openschulportfolio, a dokuwiki based portfolio-system for schools.', 'url' => 'http://www.openschulportfolio.de/', ); } /** * return sort order for position in admin menu */ function getMenuSort() { return 999; } /** * return a menu prompt for the admin menu * NOT REQUIRED - its better to place $lang['menu'] string in localised string file * only use this function when you need to vary the string returned */ function getMenuText() { $menu_base = $this->getLang('plugname'); return $menu_base; } /** * handle user request */ function handle() { if (!isset($_REQUEST['ospcmd'])) return; if ($_REQUEST['ospcmd'] == "create_upload_dir") { $this->_create_upload_dir(); } if ($_REQUEST['ospcmd'] == "docsuploaded") { $this->_save_status("DOCSUPLOADED"); } if ($_REQUEST['ospcmd'] == "delete_upload_dir") { $this->_delete_upload_dir(); } if ($_REQUEST['ospcmd'] == "start_over") { $this->_reset_wizard(); } if ($_REQUEST['ospcmd'] == "importit") { $this->_import_docs(); } } /** * output appropriate html */ function html() { global $conf; # check for filelist plugin if (!file_exists(DOKU_PLUGIN . "filelist/syntax.php")) { print $this->_div_warning("start"); print $this->getLang('filelist_plugin_required'); print 'The filelist-plugin can be found here.'; return; } # print out explanation and warning print "

" . $this->getLang('headline') ."

\n"; print "

" . $this->getLang('description') ."

\n"; print $this->getLang('detaildesc') ."\n"; print $this->_div_warning("start"); print $this->getLang('warning_osp') ."\n"; print $this->_div_warning("end"); # determine upload dir from $file_upload = $this->_strip_doubleslashes($conf['savedir'] . '/media/' . $this->getConf('sourcetree') . '/'); print "

" . $this->getLang('wizard') . "

\n"; print '
' . $this->getLang('settings') . "
"; print $this->getLang('importdir') .": ". $file_upload . "
\n"; print $this->getLang('targetns') .": ". $this->getConf('destination_namespace') . "\n"; print "
\n"; $status = $this->_read_status(); if ($status == "IMPORTED") { $statusline = $this->_read_status("all"); print "

OK " . $this->getLang('lastimport') . " " . $statusline . "

\n"; print $this->_create_reset_form(); } if ($status == "DOCSUPLOADED") { print "

OK " . $this->getLang('docsuploaded') . "

\n"; print "
" . $this->getLang('importnow') . "\n"; ptln('
'); ptln(' '); ptln(' '); ptln(' '); print ' ' . "\n"; ptln('
'); } if (is_dir($file_upload) && ($status != "IMPORTED") && ($status != "DOCSUPLOADED") ) { print "OK " . $this->getLang('sourcedir_exists') . " " . $file_upload . " \n"; print "
" . $this->getLang('docuploadnow') . "\n"; ptln('
'); ptln(' '); ptln(' '); ptln(' '); print ' ' . "\n"; ptln('
'); } if (!is_dir($file_upload) && $status == "START") { ptln("
"); print $this->getLang('sourcedir_does_not_exist') . "\n "; ptln('
'); ptln(' '); ptln(' '); ptln(' '); print ' ' . "\n"; ptln('
'); ptln('
'); } } /** * Creates creates reset form * * @author Frank Schiebel * @param none * @return none * **/ function _create_reset_form() { global $conf; # determine upload dir from conf $file_upload = $this->_strip_doubleslashes($conf['savedir'] . '/media/' . $this->getConf('sourcetree') . '/'); if (@is_dir($file_upload) && @is_writable($file_upload)) { $html = '
'."\n"; $html .= ' '."\n"; $html .= ' '."\n"; $html .= ' '."\n"; $html .= ' ' . "\n"; $html .= '
'."\n"; $html .= '
'."\n"; $html .= ' '."\n"; $html .= ' '."\n"; $html .= ' '."\n"; $html .= ' ' . "\n"; $html .= '
'."\n"; } $html .= '
'."\n"; $html .= ' '."\n"; $html .= ' '."\n"; $html .= ' '."\n"; $html .= ' ' . "\n"; $html .= '
'."\n"; return $html; } /** * Creates upload dir according to config * * @author Frank Schiebel * @param none * @return none * **/ function _create_upload_dir() { global $conf; # determine upload dir from conf $file_upload = $this->_strip_doubleslashes($conf['savedir'] . '/media/' . $this->getConf('sourcetree') . '/'); mkdir($file_upload); $this->_save_status("UPLOADDIRCREATED"); } /** * Resets wizard * * @author Frank Schiebel * @param none * @return none * **/ function _reset_wizard() { global $conf; # determine upload dir from conf $file_upload = $this->_strip_doubleslashes($conf['savedir'] . '/media/' . $this->getConf('sourcetree') . '/'); if (@is_dir($file_upload) && @is_writable($file_upload)) { $this->_deltree($file_upload); } $this->_save_status("START"); } /** * Deletes upload dir and all containing docs * * @author Frank Schiebel * @param none * @return none * **/ function _delete_upload_dir() { global $conf; # determine upload dir from conf $file_upload = $this->_strip_doubleslashes($conf['savedir'] . '/media/' . $this->getConf('sourcetree') . '/'); if (@is_dir($file_upload) && @is_writable($file_upload)) { $this->_deltree($file_upload); } } /** * Import document tree to media dir * * @author Frank Schiebel * @param none * @returns none * **/ function _import_docs() { global $conf; $mediapath = $this->_strip_doubleslashes($conf['savedir'] . '/media/'); $pagespath = $this->_strip_doubleslashes($conf['savedir'] . '/pages/'); # determine upload dir from conf $file_upload = $this->_strip_doubleslashes($conf['savedir'] . '/media/' . $this->getConf('sourcetree') . '/'); $subpath = str_replace(":", "/", $this->getConf('destination_namespace')); $media_dest = $this->_strip_doubleslashes($mediapath."/".$subpath."/"); $pagesdir = $this->_strip_doubleslashes($pagespath."/".$subpath."/"); # delete old media and pages dir if (is_dir($media_dest)) { $this->_deltree($media_dest); } if (is_dir($pagesdir)) { $this->_deltree($pagesdir); } # create fresh namespacedirs for media an pages io_createNamespace($this->getConf('destination_namespace').":xx"); io_createNamespace($this->getConf('destination_namespace').":xx", 'media'); // copy files recursively $this->_copytree($file_upload, $media_dest); // create startpages $this->create_startpages($media_dest); # determine if we are running under openschulportfolio if (file_exists(DOKU_INC . "/lib/tpl/portfolio/ospversion.php")) { $pfstartfile_in = realpath(dirname(__FILE__))."/start.txt"; $pfstartfile_out = $pagespath."portfolio/start.txt"; copy($pfstartfile_in, $pfstartfile_out); } $this->_save_status("IMPORTED"); } /** * deletes directory tree recursively * * @author Frank Schiebel * @param string directory to delete * @returns boolean status of rmdir operation * **/ function _deltree($dest) { $list = array_diff(scandir($dest), array('.', '..')); foreach ($list as $value) { $file = $dest.'/'.$value; if (is_dir($file)) { $this->_deltree($file); } else { unlink($file); } } return rmdir($dest); } /** * Copy a file, or recursively copy a folder and its contents * * @author Aidan Lister * @author Frank Schiebel * @version 1.0.1 * @link http://aidanlister.com/2004/04/recursively-copying-directories-in-php/ * @param string $source Source path * @param string $dest Destination path * @return bool Returns TRUE on success, FALSE on failure * **/ function _copytree($source, $dest) { global $conf; $source = $this->_strip_doubleslashes($source); $dest = $this->_get_clean_filename($dest); // Simple copy for a file if (is_file($source)) { return @copy($source, $dest); } $dest = $this->_get_clean_filename($dest); // Make destination directory if (!is_dir($dest)) { $mediapath = $this->_strip_doubleslashes($conf['savedir'] . '/media/'); $pagespath = $this->_strip_doubleslashes($conf['savedir'] . '/pages/'); $pages_dir = str_replace("$mediapath", "$pagespath", $dest); mkdir($dest); if (!is_dir($pages_dir)) { @mkdir($pages_dir); } } // Loop through the folder if (!is_dir($source)) { return false; } $dir = dir($source); while (false !== $entry = $dir->read()) { // Skip pointers if ($entry == '.' || $entry == '..') { continue; } // Deep copy directories $this->_copytree("$source/$entry", "$dest/$entry"); } // Clean up $dir->close(); return true; } /** Gets utf8 encoded wiki filename (experimantal, has to be tested!) * **/ function _get_clean_filename($dest) { global $conf; $fixpath = $this->_strip_doubleslashes($conf['savedir'] . "/media/"); $dest = str_replace("$fixpath", "", $dest); # Fix windows encoding: this is really bad, but i could not figure out how to # change the filename to utf8 from wathever encoding comes in... $dest = urlencode($dest); $dest = str_replace('%2F','/', $dest); $dest = str_replace('%25','%', $dest); $dest = str_replace('%C2','', $dest); $dest = str_replace('%C3','', $dest); $dest = str_replace('%81','ue', $dest); $dest = str_replace('%84','ae', $dest); $dest = str_replace('%94','oe', $dest); $dest = str_replace('%A1','ss', $dest); $dest = str_replace('+','_', $dest); $dest = str_replace('-','_', $dest); $dest = str_replace('__','_', $dest); $dest = str_replace("//", "/", $dest); $dest = str_replace("/", ":", $dest); $dest = preg_replace("/:$/", "", $dest); $dest = mediaFN($dest); $dest = $this->_strip_doubleslashes($fixpath . str_replace($conf['mediadir'], '', $dest)); return $dest; } /** recursively creates startpages for imported document structure * **/ function create_startpages($dest) { global $conf; $subdirs = array(); // namespace for filelist $media = $this->_strip_doubleslashes($conf['savedir'] . "/media/"); $pages = $this->_strip_doubleslashes($conf['savedir'] . "/pages/"); // change dest to pages $dest = str_replace($media, $pages, $dest); $startpage = $dest ."start.txt"; // get filelist namespace $ns_dir = str_replace($pages, "", $dest); $filelist_namespace = str_replace("/",":", $ns_dir); $header_namespace = preg_replace("|.*/(.*)/$|","$1", $ns_dir); // get all subdirs of actual ns $dir = dir($dest); while (false !== $entry = $dir->read()) { // Skip pointers if ($entry == '.' || $entry == '..') { continue; } if (is_dir($dest.$entry)) { $subdirs[] = $entry; // recursively call function $this->create_startpages($dest.$entry."/"); } } // sort subdirs and create wiki-markup $subdir_out = ""; if (count($subdirs) > 0 ) { sort($subdirs); $subdir_out = "===== " . $this->getLang('subnamespaces') ." ===== \n\n"; foreach ($subdirs as $subdir) { $subdir_out .= " * [[.$subdir:start|$subdir]]\n"; } } // write start.txt $handle = fopen ("$startpage", "w"); fwrite($handle, "[[".DOKU_URL."/lib/exe/mediamanager.php?ns=$filelist_namespace|" . $this->getLang('edit_files') . "]] | [[..start|" . $this->getLang('ns_up') . "]] \n\n"); fwrite($handle, "====== " . $this->getLang('documents_for') . $header_namespace . " ======\n\n"); fwrite($handle, $this->getLang('docslisted') . "\\\\ ''$filelist_namespace'' \n\n"); fwrite($handle, "{{filelist>:$filelist_namespace*&style=table&tableheader=1&tableshowdate=1&tableshowsize=1}}\n\n"); fwrite($handle, "$subdir_out\n"); fclose($handle); } /** * Strip double slashes from path names * * @author Frank Schiebel * @param string path in * @returns string path out * **/ function _strip_doubleslashes($path) { return preg_replace('/\/\//','/', $path); } /** * Save status of import procedure to status file * $conf['cachedir'].'/doctree2filelist.status' * creates the file if it does not exist. * * @author Frank Schiebel * @param string statusstring * @return true on success * **/ function _save_status($status) { global $conf; // build status line $t = time(); $statusline = $t."\t".strftime($conf['dformat'],$t)."\t".$_SERVER['REMOTE_ADDR']."\t".$_SERVER['REMOTE_USER']."\t".$status."\n"; // write status to file io_saveFile($conf['cachedir'].'/doctree2filelist.status',$statusline, false); return true; } /** * reads status of import procedure from status file * $conf['cachedir'].'/doctree2filelist.status' * * @author Frank Schiebel * @param none * @return string statusstring * **/ function _read_status($mode = "statonly") { global $conf; $status = "START"; // read status from file $statusfile = $conf['cachedir'].'/doctree2filelist.status'; if(@file_exists($statusfile)) { $statusline = file($statusfile); $statusline = $statusline[0]; $status = explode("\t", $statusline); if ($mode == "statonly" ) { $status = rtrim($status[4]); } else { $status = $status[1] . " " . $this->getLang('fromuser') . " " . $status[3]; } } return $status; } /** * prints a warning div. Uses the note plugin if available * * @author Frank Schiebel * @param string (start|end) * @return string html * **/ function _div_warning($mode) { if($mode == "start") { if (file_exists(DOKU_PLUGIN . "note/syntax.php")) { return '
'; } else { return '
'; } } else { return '
'; } } }