* @author Rene Hadler */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'admin.php'); require_once(DOKU_INC.'inc/HTTPClient.php'); require_once(DOKU_PLUGIN."tindexmenu/inc/pclzip.lib.php"); if(!defined('INDEXMENU_IMG_ABSDIR')) define('INDEXMENU_IMG_ABSDIR',DOKU_PLUGIN."tindexmenu/images"); define('INDEXMENU_ICOS','base,folder,folderopen,folderh,folderhopen,page,plus,minus,nolines_plus,nolines_minus,minusbottom,plusbottom,join,joinbottom,line,empty'); class admin_plugin_indexmenu extends DokuWiki_Admin_Plugin { var $req = 'fetch'; var $repos = array ( "url" => array(DOKU_URL), "status" => array(""), ); var $selected=-1; /** * return some info */ function getInfo(){ return array( 'author' => 'Samuele Tognini mod. by Rene Hadler', 'email' => 'samuele@netsons.org, rene.hadler@iteas.at', 'date' => rtrim(io_readFile(DOKU_PLUGIN.'tindexmenu/VERSION.txt')), 'name' => 'tIndexmenu (admin plugin component)', 'desc' => 'tIndexmenu admin functions.', 'url' => 'http://wiki.splitbrain.org/plugin:tindexmenu', ); } /** * return sort order for position in admin menu */ function getMenuSort() { return 999; } /** * handle user request */ function handle() { $url=$this->getConf('themes_url'); if (empty($url)) { $this->repos['url'][]=$this->getLang('no_repos'); $this->repos['status'][]="disabled"; $this->repos['install'][]=-1; } else { $this->repos['url']= array_merge($this->repos['url'],explode(',',$url)); } if (!isset($_REQUEST['req'])) return; // first time - nothing to do $this->req=$_REQUEST['req']; if (is_numeric($_REQUEST['repo'])) $this->selected=$_REQUEST['repo']; } /** * output appropriate html */ function html() { global $conf; ptln('
'); ptln('

'.$this->getLang('menu').'

'); ptln($this->_donate()); ptln('
'); ptln(' '.$this->getLang('checkupdates').''); $this->_form_open("checkupdates"); $this->_form_close('check'); if ($this->req=='checkupdates') { $this->_checkupdates(); } ptln('
'); ptln('
'); ptln(' Themes'); ptln(' '); ptln(' '); $n=0; //cycles thru repositories urls foreach ($this->repos['url'] as $url) { ptln(' '); ptln(' '); //list requested theme if ($n==$this->selected) { ptln(' '); } $n++; } ptln('
'); ptln(' '.$this->getLang('infos').''); ptln('
'); $legend=($n == 0) ? $conf['title'] : $this->repos['url'][$n]; ptln(' '); ptln(' '); $this->_form_open("fetch",$n); $this->_form_close("fetch"); ptln('
'); if ($this->req=='install') $this->install($this->selected,$_REQUEST['name']); if ($this->req=='upload' && $_REQUEST['name']) { $info=""; if (isset($_REQUEST['author_info'])) { $obfuscate = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] '); $info .= "author=".strtr($_REQUEST['author_info'], $obfuscate)."\n"; } if (isset($_REQUEST['url_info'])) $info .= "url=".$_REQUEST['url_info']."\n"; if (isset($_REQUEST['author_info'])) $info .= "description=".$_REQUEST['author_info']; if (!$this->upload($_REQUEST['name'],$info)) msg($this->getLang('install_no'),-1); } if ($this->req=='delete' && $_REQUEST['name']) $this->_delete($_REQUEST['name']); ptln('
'); $this->dolist($n); ptln('
'); ptln('
'); ptln('
'); } /** * Connect to theme repository and list themes * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Samuele Tognini */ function dolist($n) { global $INFO; if ($n === false) return; //info.txt keys to parse $keys=array('author','url','description'); $icos=explode(',',INDEXMENU_ICOS); $turl=""; $info=""; //get list $data=$this->_remotequery($this->repos['url'][$n]."/lib/plugins/tindexmenu/ajax.php?req=local"); $data=explode(",",$data); //print themes for ($i=3;$i'.$theme.''); ptln('
'); ptln('
'); //print images foreach (array_slice($icos,0,8) as $ico) { $ext = explode(".", $theme); $ext=array_pop($ext); $ext=($ext == $theme) ? '.gif' : ".$ext"; ptln(' '.$ico.''); } ptln('
'); //get theme info.txt if ($info=$this->_remotequery($turl."/info.txt",false)) { foreach ($keys as $key) { if (!preg_match('/'.$key.'=(.*)/',$info,$out)) continue; ptln("
"); ptln(" ".hsc($key).": ".hsc($out[1])); ptln("
"); } } if ($n == 0) { $act="upload"; if ($theme != "default" ) { $this->_form_open("delete",$n); ptln(' '); $this->_form_close("delete"); } } else { $act="install"; ptln(' Download'); } $this->_form_open($act,$n); if ($n==0 && !is_file(INDEXMENU_IMG_ABSDIR."/".$theme."/info.txt")) { ptln('
author:").'" size="50" maxlength="100" />
'); ptln(' url:
'); ptln(' description:
'); } ptln(' '); $this->_form_close($act); ptln('

'); } } /** * Download and install themes * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Samuele Tognini */ function install ($n,$name) { $repo=$this->repos['url'][$n]; if (!isset($name)) return false; $return=true; if (!$absdir=$this->checktmpsubdir()) return; $tmp=$absdir."/tmp"; //send theme list request if (!$zipfile=io_download($repo."/lib/plugins/tindexmenu/ajax.php?req=send&t=".$name,"$tmp/",true)) { msg($this->getLang('down_err').": $name",-1); $return=false; } else { //create zip $zip=new PclZip("$tmp/$zipfile"); $regexp="/^".$name."\/(info.txt)|(style.css)|(".str_replace(",","|",INDEXMENU_ICOS).")\.(gif|png|jpg)$/i"; $status=$zip->extract(PCLZIP_OPT_PATH,$absdir."/",PCLZIP_OPT_BY_PREG,$regexp); //error if ($status == 0) { msg($this->getLang('zip_err')." $tmp/$zipfile: ".$zip->errorName(true),-1); $return=false; } else { msg("$name ".$this->getLang('install_ok'),1); } } //clean tmp $this->_rm_dir($tmp); return $return; } /** * Remove a directory * */ function _rm_dir($path) { if (!is_string($path) || $path == "") return false; if (is_dir($path)) { if (!$dh = @opendir($path)) return false; while ($f = readdir($dh)) { if ($f == '..' || $f == '.') continue; $this->_rm_dir("$path/$f"); } closedir($dh); return @rmdir($path); } else { return @unlink($path); } return false; } /** * Retrive and create themes tmp directory * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Samuele Tognini */ function checktmpsubdir () { $tmp=INDEXMENU_IMG_ABSDIR."/tmp"; if (!io_mkdir_p($tmp)) { msg($this->getLang('dir_err').": $tmp",-1); return false; } return INDEXMENU_IMG_ABSDIR; } /** * Upload a theme into my site * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Samuele Tognini */ function upload($theme,$info) { $return=true; $host='samuele.netsons.org'; $path='/dokuwiki/lib/plugins/tindexmenu/upload/index.php'; //TODO: merge zip creation with that in ajax.php (create a class?) if (!$absdir=$this->checktmpsubdir()) return false; $tmp=$absdir."/tmp"; $zipfile="$theme.zip"; $filelist="$absdir/$theme"; //create info if (!empty($info)) { io_savefile("$tmp/$theme/info.txt",$info); $filelist .= ",$tmp/$theme"; } //create zip $zip=new PclZip("$tmp/$zipfile"); $status=$zip->create($filelist,PCLZIP_OPT_REMOVE_ALL_PATH); if ($status == 0) { //error msg($this->getLang('zip_err').": ".$zip->errorName(true),-1); $return=false; } else { //prepare POST headers. $boundary = "---------------------------".uniqid(""); $data=join("", file("$tmp/$zipfile")); $header="POST $path HTTP/1.0\r\n"; $header.= "Host: $host\r\n"; $header.= "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061024 Iceweasel/2.0 (Debian-2.0+dfsg-1)\r\n"; $header.= "Content-type: multipart/form-data, boundary=$boundary\r\n"; $body="--".$boundary."\r\n"; $body.= "Content-Disposition: form-data; name=\"userfile\"; filename=\"$zipfile\"\r\n"; $body.= "Content-Type: application/x-zip-compressed\r\n\r\n"; $body.=$data."\r\n"; $body.= "--".$boundary."\r\n"; $body.= "Content-Disposition: form-data; name=\"upload\"\r\n\r\n"; $body.= "Upload\r\n"; $body.="--".$boundary."--\r\n"; $header.= "Content-Length: ".strlen($body)."\r\n\r\n"; //connect and send zip if ($fp = fsockopen($host, 80)) { fwrite($fp,$header.$body); //reply $buf=""; while (!feof($fp)) { $buf .= fgets($fp,3200); } fclose($fp); //parse reply if (preg_match("/(.*)/s",$buf,$match)) { $str=substr($match[1],4,7); switch ($str) { case "ERROR ": $mesg_type=-1; break; case "SUCCESS": $mesg_type=1; break; default: $mesg_type=2; } msg($match[1],$mesg_type); } else { $return=false; } } else { $return=false; } } $this->_rm_dir($tmp); return $return; } /** * Check for new messages from upstream * * @author Samuele Tognini */ function _checkupdates() { // We dont have checks for updates yet ; } /** * Get url response and check it * * @author Samuele Tognini */ function _remotequery($url,$tag=true) { require_once (DOKU_INC.'inc/HTTPClient.php'); $http = new DokuHTTPClient(); $http->timeout = 8; $data = $http->get($url); if ($tag) { if ($data===false) { msg($this->getLang('conn_err'),-1); } else { (substr($data,0,9)==="indexmenu") ? $data=substr($data,9): $data=""; } } return $data; } /** * Open an html form * * @author Samuele Tognini */ function _form_open($act,$n=-1) { ptln('
'); ptln(' '); ptln(' '); ptln(' '); ptln(' '); } /** * Close the html form * * @author Samuele Tognini */ function _form_close($act) { ptln(' repos['status'][$n].' value="'.$this->getLang($act).'" />'); ptln(' '); } /** * Remove an installed theme * * @author Samuele Tognini */ function _delete($theme) { if ($theme=="default") return; if ($this->_rm_dir(INDEXMENU_IMG_ABSDIR."/".utf8_encodeFN(basename($theme)))) { msg($this->getLang('delete_ok').": $theme.",1); } else { msg($this->getLang('delete_no').": $theme.",-1); } } /** * Print the donate button. * * @author Samuele Tognini */ function _donate() { $out = "
\n"; $out .= '

'.$this->getLang('donation_text').'

'; $out .= '
'."\n"; $out .= ''."\n"; $out .= ''."\n"; $out .= ''."\n"; $out .= ''."\n"; $out .= "
\n"; return $out; } }