diff --git a/module/extension/config.php b/module/extension/config.php index ae6636b0c8..e2ae0dfc6a 100644 --- a/module/extension/config.php +++ b/module/extension/config.php @@ -1,2 +1,3 @@ extension->apiRoot = 'http://www.zentao.net/extension-'; +$config->extension->apiRoot = 'http://www.zentao.net/extension-'; +$config->extension->extPathes = array('module', 'bin', 'www', 'library', 'config'); diff --git a/module/extension/control.php b/module/extension/control.php index bf471d3a92..71c06372eb 100644 --- a/module/extension/control.php +++ b/module/extension/control.php @@ -63,19 +63,71 @@ class extension extends control /** * Install a extension * - * @param int $downLink + * @param string $extension + * @param string $downLink + * @param string $md5 + * @param string $forceInstall * @access public * @return void */ - public function install($extension, $downLink = '') + public function install($extension, $downLink = '', $md5 = '', $forceInstall = 'no') { - if($downLink) $this->extension->download($extension, helper::safe64Decode($downLink)); + $this->view->error = ''; + $this->view->header->title = $this->lang->extension->install . $this->lang->colon . $extension; - $packgeFile = $this->extension->getPackageFile($extension); - if(!file_exists($packgeFile)) die(js::error('not found')); + /* Get the package file name. */ + $packageFile = $this->extension->getPackageFile($extension); - $this->extension->install($extension); - echo 'installed'; + if($downLink) + { + /* Checking download path. */ + $return = $this->extension->checkDownloadPath(); + if($return->result != 'ok') + { + $this->view->error = $return->error; + die($this->display()); + } + + /* Check file exists or not. */ + if(file_exists($packageFile) and $forceInstall == 'no') + { + $forceInstallLink = inlink('install', "extension=$extension&downLink=$downLink&md5=$md5&forecInstall=yes"); + $this->view->error = sprintf($this->lang->extension->errorPackageFileExists, $packageFile, $forceInstallLink); + die($this->display()); + } + + /* Download the package file. */ + $this->extension->downloadPackage($extension, helper::safe64Decode($downLink)); + if(!file_exists($packageFile)) + { + $this->view->error = sprintf($this->lang->extension->errorDownloadFailed, $packageFile); + die($this->display()); + } + elseif(md5_file($packageFile) != $md5) + { + $this->view->error = sprintf($this->lang->extension->errorMd5Checking, $packageFile); + die($this->display()); + } + } + + /* Check the package file exists or not. */ + if(!file_exists($packageFile)) + { + $this->view->error = sprintf($this->lang->extension->errorPackageNotFound, $packageFile); + die($this->display()); + } + + /* Checking the extension path. */ + $return = $this->extension->checkExtensionPathes($extension); + if($return->result != 'ok') + { + $this->view->error = $return->errors; + die($this->display()); + } + + /* Extract the package. */ + $this->extension->extractPackage($extension); + $this->extension->copyPackageFiles($extension); } public function uninstall() diff --git a/module/extension/css/common.css b/module/extension/css/common.css new file mode 100644 index 0000000000..27168d1df4 --- /dev/null +++ b/module/extension/css/common.css @@ -0,0 +1,3 @@ +.active a {color:blue; font-weight:bold;} +.button-c {padding:2px 4px; border:1px solid gray; background:#efefef; color:black; text-decoration:none} +.error {color:red; font-size:14px} diff --git a/module/extension/css/obtain.css b/module/extension/css/obtain.css deleted file mode 100644 index a68e3f9d4f..0000000000 --- a/module/extension/css/obtain.css +++ /dev/null @@ -1,2 +0,0 @@ -.active a {color:blue; font-weight:bold;} -.button-c {padding:4px 6px} diff --git a/module/extension/js/common.js b/module/extension/js/common.js new file mode 100644 index 0000000000..12d08298a7 --- /dev/null +++ b/module/extension/js/common.js @@ -0,0 +1 @@ +if($('a.iframe').size()) $("a.iframe").colorbox({width:600, height:240, iframe:true, transition:'elastic', speed:350, scrolling:true}); diff --git a/module/extension/lang/zh-cn.php b/module/extension/lang/zh-cn.php index 671118a862..802acbcced 100644 --- a/module/extension/lang/zh-cn.php +++ b/module/extension/lang/zh-cn.php @@ -41,3 +41,13 @@ $lang->extension->byAddedTime = '最新添加'; $lang->extension->byUpdatedTime = '最近更新'; $lang->extension->bySearch = '搜索'; $lang->extension->byCategory = '分类浏览'; + +$lang->extension->installFailed = '安装失败,错误原因如下:'; +$lang->extension->errorDownloadPathNotFound = '插件下载存储路径%s不存在。
linux下面请执行命令:mkdir %s来修正。'; +$lang->extension->errorDownloadPathNotWritable = '插件下载存储路径%s不可写。
linux下面请执行命令:chmod 777 %s来修正。'; +$lang->extension->errorPackageFileExists = '下载路径已经有一个名为的%s附件。

重新安装,请点击此链接

'; +$lang->extension->errorDownloadFailed = '下载失败,请重新下载。如果多次重试还不行,请尝试手工下载,然后通过上传功能上传。'; +$lang->extension->errorMd5Checking = '下载文件不完整,请重新下载。如果多次重试还不行,请尝试手工下载,然后通过上传功能上传。'; +$lang->extension->errorPackageNotFound = '包文件 %s 没有找到,可能是因为自动下载失败。您可以尝试再次下载。'; +$lang->extension->errorTargetPathNotWritable = '目标路径 %s 不可写。'; +$lang->extension->errorTargetPathNotExists = '目标路径 %s 不存在。'; diff --git a/module/extension/model.php b/module/extension/model.php index b338e4b4af..329a099e27 100644 --- a/module/extension/model.php +++ b/module/extension/model.php @@ -124,27 +124,79 @@ class extensionModel extends model } /** - * Install an extension. + * Check the download path. + * + * @access public + * @return object the check result. + */ + public function checkDownloadPath() + { + /* Init the return. */ + $return->result = 'ok'; + $return->error = ''; + + $tmpRoot = $this->app->getTmpRoot(); + $downloadPath = $tmpRoot . 'extension'; + + if(!is_dir($downloadPath)) + { + if(is_writable($tmpRoot)) + { + mkdir($downloadPath); + } + else + { + $return->result = 'fail'; + $return->error = sprintf($this->lang->extension->errorDownloadPathNotFound, $downloadPath, $downloadPath); + } + } + elseif(!is_writable($downloadPath)) + { + $return->result = 'fail'; + $return->error = sprintf($this->lang->extension->errorDownloadPathNotWritable, $downloadPath, $downloadPath); + } + return $return; + } + + /** + * Check extension files. * * @param string $extension * @access public - * @return void + * @return object */ - public function install($extension) + public function checkExtensionPathes($extension) { - $packageFile = $this->getPackageFile($extension); + $return->result = 'ok'; + $return->errors = ''; + $return->dirCommands = ''; + $return->modCommands = ''; - /* Extract the zip file. */ - $this->app->loadClass('pclzip', true); - $zip = new pclzip($packageFile); - $zip->extract(PCLZIP_OPT_PATH, 'ext'); - - /* Copy to the destination. */ - $this->xcopy("ext/$extension/module", $this->app->getAppRoot() . 'module'); - $this->xcopy("ext/$extension/www", $this->app->getAppRoot() . 'www'); - $this->xcopy("ext/$extension/bin", $this->app->getAppRoot() . 'bin'); - $this->xcopy("ext/$extension/config", $this->app->getAppRoot() . 'config'); - $this->xcopy("ext/$extension/lib", $this->app->getAppRoot() . 'bli'); + $appRoot = $this->app->getAppRoot(); + $pathes = $this->extractPathesFromPackage($extension); + foreach($pathes as $path) + { + if($path == 'db' or $path == 'doc') continue; + $path = $appRoot . $path; + if(file_exists($path)) + { + if(!is_writable($path)) + { + $return->errors .= sprintf($this->lang->extension->errorTargetPathNotWritable, $path) . '
'; + $return->modCommands .= "chmod -R 777 $path
"; + } + } + elseif(!is_writable(dirname($path))) + { + $return->errors .= sprintf($this->lang->extension->errorTargetPathNotExists, $path) . '
'; + $return->dirCommands .= "mkdir $path
"; + $return->modCommands .= "chmod -R 777 $path
"; + } + } + if($return->errors) $return->result = 'fail'; + $return->dirCommands = str_replace('/', DIRECTORY_SEPARATOR, $return->dirCommands); + $return->errors .= $return->dirCommands . $return->modCommands; + return $return; } /** @@ -155,13 +207,73 @@ class extensionModel extends model * @access public * @return void */ - public function download($extension, $downLink) + public function downloadPackage($extension, $downLink) { $packageFile = $this->getPackageFile($extension); $this->agent->fetch($downLink); file_put_contents($packageFile, $this->agent->results); } + /** + * Extract an extension. + * + * @param string $extension + * @access public + * @return void + */ + public function extractPackage($extension) + { + $packageFile = $this->getPackageFile($extension); + + /* Extract the zip file. */ + $this->app->loadClass('pclzip', true); + $zip = new pclzip($packageFile); + $zip->extract(PCLZIP_OPT_PATH, 'ext'); + } + + /** + * Extract pathes from an extension package. + * + * @param string $extension + * @access public + * @return array + */ + public function extractPathesFromPackage($extension) + { + $pathes = array(); + $packageFile = $this->getPackageFile($extension); + + /* Get files from the package file. */ + $this->app->loadClass('pclzip', true); + $zip = new pclzip($packageFile); + $files = $zip->listContent(); + + foreach($files as $file) + { + $file = (object)$file; + if($file->folder) continue; + $file->filename = substr($file->filename, strpos($file->filename, '/') + 1); + $pathes[] = dirname($file->filename); + } + return array_unique($pathes); + } + + /** + * Copy package files. + * + * @param int $extension + * @access public + * @return void + */ + public function copyPackageFiles($extension) + { + $this->xcopy("ext/$extension/module", $this->app->getAppRoot() . 'module'); + $this->xcopy("ext/$extension/www", $this->app->getAppRoot() . 'www'); + $this->xcopy("ext/$extension/bin", $this->app->getAppRoot() . 'bin'); + $this->xcopy("ext/$extension/config", $this->app->getAppRoot() . 'config'); + $this->xcopy("ext/$extension/lib", $this->app->getAppRoot() . 'bli'); + } + /** * Copy a directory from an directory to another directory. * diff --git a/module/extension/view/install.html.php b/module/extension/view/install.html.php new file mode 100644 index 0000000000..9d49e50511 --- /dev/null +++ b/module/extension/view/install.html.php @@ -0,0 +1,25 @@ + + * @package extension + * @version $Id$ + * @link http://www.zentao.net + */ +?> + + + + + + +
title;?>
+ + {$lang->extension->installFailed} $error";?> + + +
+ diff --git a/module/extension/view/obtain.html.php b/module/extension/view/obtain.html.php index 102780ba89..66bc02fdd0 100644 --- a/module/extension/view/obtain.html.php +++ b/module/extension/view/obtain.html.php @@ -61,8 +61,9 @@ downloads;?> extension->installAB, inlink('install', "extension=$extension->code&downLink=" . helper::safe64Encode($extension->downLink))); - echo html::linkButton($lang->extension->downloadAB, $extension->downLink); + $installLink = inlink('install', "extension=$extension->code&downLink=" . helper::safe64Encode($extension->downLink) . "&md5=$extension->md5"); + echo html::a($installLink, $lang->extension->installAB, '', "class='button-c iframe'"); + echo html::a($extension->downLink, $lang->extension->downloadAB, '', "class='button-c'"); ?>