summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2009-11-11 21:34:37 +0100
committerAndreas Gohr <andi@splitbrain.org>2009-11-11 21:34:37 +0100
commitd4e9d5c7d1ec74172b46a130352a41765f1fec6a (patch)
tree1c1af64bf5d6d68753bc352fb29e5b39ef9f677e
parent4bf3df7c70a3260fd2d9d78b0fe37d3519ed7f65 (diff)
downloadrpg-d4e9d5c7d1ec74172b46a130352a41765f1fec6a.tar.gz
rpg-d4e9d5c7d1ec74172b46a130352a41765f1fec6a.tar.bz2
More flexible plugin packages FS#1746
Ignore-this: 252bb5a42965ed045221c0544136aa62 darcs-hash:20091111203437-7ad00-86f06d842b3bec22641a637cb09dbc666a42ca2d.gz
-rw-r--r--inc/plugin.php5
-rw-r--r--lib/plugins/plugin/admin.php7
-rw-r--r--lib/plugins/plugin/classes/ap_download.class.php98
-rw-r--r--lib/plugins/plugin/classes/ap_manage.class.php8
-rw-r--r--lib/plugins/syntax.php5
5 files changed, 103 insertions, 20 deletions
diff --git a/inc/plugin.php b/inc/plugin.php
index 54d2580e9..364534739 100644
--- a/inc/plugin.php
+++ b/inc/plugin.php
@@ -30,7 +30,10 @@ class DokuWiki_Plugin {
* url - Website with more information on the plugin (eg. syntax description)
*/
function getInfo(){
- trigger_error('getInfo() not implemented in '.get_class($this), E_USER_WARNING);
+ $parts = explode('_',get_class($this));
+ $info = DOKU_PLUGIN.'/'.$parts[2].'/plugin.info.txt';
+ if(@file_exists($info)) return confToHash($info);
+ trigger_error('getInfo() not implemented in '.get_class($this).' and '.$info.' not found', E_USER_WARNING);
}
// plugin introspection methods
diff --git a/lib/plugins/plugin/admin.php b/lib/plugins/plugin/admin.php
index bf0b0b88a..4f8cc01a2 100644
--- a/lib/plugins/plugin/admin.php
+++ b/lib/plugins/plugin/admin.php
@@ -58,13 +58,14 @@ class admin_plugin_plugin extends DokuWiki_Admin_Plugin {
return array(
'author' => 'Christopher Smith',
'email' => 'chris@jalakai.co.uk',
- 'date' => '2009-07-25',
+ 'date' => '2009-11-11',
'name' => 'Plugin Manager',
'desc' => "Manage Plugins, including automated plugin installer $disabled",
- 'url' => 'http://dokuwiki.org/plugin:plugin',
+ 'url' => 'http://www.dokuwiki.org/plugin:plugin',
);
}
+
/**
* return sort order for position in admin menu
*/
@@ -79,6 +80,7 @@ class admin_plugin_plugin extends DokuWiki_Admin_Plugin {
// enable direct access to language strings
$this->setupLocale();
+
$fn = $_REQUEST['fn'];
if (is_array($fn)) {
$this->cmd = key($fn);
@@ -87,7 +89,6 @@ class admin_plugin_plugin extends DokuWiki_Admin_Plugin {
$this->cmd = $fn;
$this->plugin = null;
}
-
$this->_get_plugin_list();
// verify $_REQUEST vars
diff --git a/lib/plugins/plugin/classes/ap_download.class.php b/lib/plugins/plugin/classes/ap_download.class.php
index 8a97423c1..90e5de53b 100644
--- a/lib/plugins/plugin/classes/ap_download.class.php
+++ b/lib/plugins/plugin/classes/ap_download.class.php
@@ -45,7 +45,6 @@ class ap_download extends ap_manage {
*/
function download($url, $overwrite=false) {
global $lang;
-
// check the url
$matches = array();
if (!preg_match("/[^\/]*$/", $url, $matches) || !$matches[0]) {
@@ -71,27 +70,41 @@ class ap_download extends ap_manage {
// search $tmp for the folder(s) that has been created
// move the folder(s) to lib/plugins/
if (!$this->manager->error) {
- if ($dh = @opendir("$tmp/")) {
- while (false !== ($f = readdir($dh))) {
- if ($f == '.' || $f == '..' || $f == 'tmp') continue;
- if (!is_dir("$tmp/$f")) continue;
+ $result = array('old'=>array(), 'new'=>array());
+ if($this->find_folders($result,$tmp)){
+ // choose correct result array
+ if(count($result['new'])){
+ $install = $result['new'];
+ }else{
+ $install = $result['old'];
+ }
+
+ // now install all found items
+ foreach($install as $item){
+ // where to install?
+ if($item['type'] == 'template'){
+ $target = DOKU_INC.'lib/tpl/'.$item['base'];
+ }else{
+ $target = DOKU_INC.'lib/plugins/'.$item['base'];
+ }
// check to make sure we aren't overwriting anything
- if (!$overwrite && @file_exists(DOKU_PLUGIN.$f)) {
+ if (!$overwrite && @file_exists($target)) {
// remember our settings, ask the user to confirm overwrite, FIXME
continue;
}
- $instruction = @file_exists(DOKU_PLUGIN.$f) ? 'update' : 'install';
+ $instruction = @file_exists($target) ? 'update' : 'install';
- if ($this->dircopy("$tmp/$f", DOKU_PLUGIN.$f)) {
- $this->downloaded[] = $f;
- $this->plugin_writelog($f, $instruction, array($url));
+ // copy action
+ if ($this->dircopy($item['tmp'], $target)) {
+ $this->downloaded[] = $item['base'];
+ $this->plugin_writelog($target, $instruction, array($url));
} else {
- $this->manager->error .= sprintf($this->lang['error_copy']."\n", $f);
+ $this->manager->error .= sprintf($this->lang['error_copy']."\n", $item['base']);
}
}
- closedir($dh);
+
} else {
$this->manager->error = $this->lang['error']."\n";
}
@@ -109,6 +122,67 @@ class ap_download extends ap_manage {
return false;
}
+ /**
+ * Find out what was in the extracted directory
+ *
+ * Correct folders are searched recursively using the "*.info.txt" configs
+ * as indicator for a root folder. When such a file is found, it's base
+ * setting is used (when set). All folders found by this method are stored
+ * in the 'new' key of the $result array.
+ *
+ * For backwards compatibility all found top level folders are stored as
+ * in the 'old' key of the $result array.
+ *
+ * When no items are found in 'new' the copy mechanism should fall back
+ * the 'old' list.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param arrayref $result - results are stored here
+ * @param string $base - the temp directory where the package was unpacked to
+ * @param string $dir - a subdirectory. do not set. used by recursion
+ * @return bool - false on error
+ */
+ function find_folders(&$result,$base,$dir=''){
+ $dh = @opendir("$base/$dir");
+ if(!$dh) return false;
+ while (false !== ($f = readdir($dh))) {
+ if ($f == '.' || $f == '..' || $f == 'tmp') continue;
+
+ if(!is_dir("$base/$dir/$f")){
+ // it's a file -> check for config
+ if($f == 'plugin.info.txt'){
+ $info = array();
+ $info['type'] = 'plugin';
+ $info['tmp'] = "$base/$dir";
+ $conf = confToHash("$base/$dir/$f");
+ $info['base'] = basename($conf['base']);
+ if(!$info['base']) $info['base'] = basename("$base/$dir");
+ $result['new'][] = $info;
+ }elseif($f == 'template.info.txt'){
+ $info = array();
+ $info['type'] = 'template';
+ $info['tmp'] = "$base/$dir";
+ $conf = confToHash("$base/$dir/$f");
+ $info['base'] = basename($conf['base']);
+ if(!$info['base']) $info['base'] = basename("$base/$dir");
+ $result['new'][] = $info;
+ }
+ }else{
+ // it's a directory -> add to dir list for old method, then recurse
+ if(!$dir){
+ $info = array();
+ $info['type'] = 'plugin';
+ $info['tmp'] = "$base/$dir/$f";
+ $info['base'] = $f;
+ $result['old'][] = $info;
+ }
+ $this->find_folders($result,$base,"$dir/$f");
+ }
+ }
+ closedir($dh);
+ return true;
+ }
+
/**
* Decompress a given file to the given target directory
diff --git a/lib/plugins/plugin/classes/ap_manage.class.php b/lib/plugins/plugin/classes/ap_manage.class.php
index aea04f487..297764ebb 100644
--- a/lib/plugins/plugin/classes/ap_manage.class.php
+++ b/lib/plugins/plugin/classes/ap_manage.class.php
@@ -132,10 +132,12 @@ class ap_manage {
exit();
}
- // log
- function plugin_writelog($plugin, $cmd, $data) {
+ /**
+ * Write a log entry to the given target directory
+ */
+ function plugin_writelog($target, $cmd, $data) {
- $file = DOKU_PLUGIN.$plugin.'/manager.dat';
+ $file = $target.'/manager.dat';
switch ($cmd) {
case 'install' :
diff --git a/lib/plugins/syntax.php b/lib/plugins/syntax.php
index 126e01952..633e001d2 100644
--- a/lib/plugins/syntax.php
+++ b/lib/plugins/syntax.php
@@ -36,7 +36,10 @@ class DokuWiki_Syntax_Plugin extends Doku_Parser_Mode {
* url - Website with more information on the plugin (eg. syntax description)
*/
function getInfo(){
- trigger_error('getType() not implemented in '.get_class($this), E_USER_WARNING);
+ $parts = explode('_',get_class($this));
+ $info = DOKU_PLUGIN.'/'.$parts[2].'/plugin.info.txt';
+ if(@file_exists($info)) return confToHash($info);
+ trigger_error('getInfo() not implemented in '.get_class($this).' and '.$info.' not found', E_USER_WARNING);
}
/**