unzip 优化
This commit is contained in:
parent
58b408cfd5
commit
efc44a2a54
@ -6,6 +6,7 @@ use GuzzleHttp\Client;
|
||||
use plugin\admin\api\Auth;
|
||||
use plugin\admin\app\controller\Base;
|
||||
use plugin\admin\app\Util;
|
||||
use support\exception\BusinessException;
|
||||
use support\Log;
|
||||
use support\Request;
|
||||
use function base_path;
|
||||
@ -89,53 +90,38 @@ class AppController extends Base
|
||||
'message' => '请登录'
|
||||
]);
|
||||
}
|
||||
$client = $this->httpClient();
|
||||
$response = $client->post('/api/app/download', [
|
||||
'form_params' => [
|
||||
'name' => $name,
|
||||
'uid' => $user['uid'],
|
||||
'token' => session('app-plugin-token'),
|
||||
'referer' => $host,
|
||||
'version' => $version,
|
||||
]
|
||||
]);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$data = json_decode($content, true);
|
||||
if (!$data) {
|
||||
$msg = "/api/app/download return $content";
|
||||
echo "msg\r\n";
|
||||
Log::error($msg);
|
||||
}
|
||||
if ($data['code']) {
|
||||
if ($data['code'] == -1) {
|
||||
return $this->json(0, '请登录', [
|
||||
'code' => 401,
|
||||
'message' => '请登录'
|
||||
]);
|
||||
}
|
||||
return $this->json($data['code'], $data['msg']);
|
||||
// 获取下载zip文件url
|
||||
$data = $this->getDownloadUrl($name, $user['uid'], $host, $version);
|
||||
if ($data['code'] == -1) {
|
||||
return $this->json(0, '请登录', [
|
||||
'code' => 401,
|
||||
'message' => '请登录'
|
||||
]);
|
||||
}
|
||||
|
||||
$url = $data['result']['url'];
|
||||
$client = $this->downloadClient();
|
||||
$response = $client->get($url);
|
||||
$body = $response->getBody();
|
||||
$status = $response->getStatusCode();
|
||||
if ($status == 404) {
|
||||
return $this->json(1, '安装包不存在');
|
||||
}
|
||||
$zip_content = $body->getContents();
|
||||
if (empty($zip_content)) {
|
||||
return $this->json(1, '安装包不存在');
|
||||
}
|
||||
// 下载zip文件
|
||||
$base_path = base_path() . "/plugin/$name";
|
||||
$zip_file = "$base_path.zip";
|
||||
file_put_contents($zip_file, $zip_content);
|
||||
$extract_to = base_path() . '/plugin/';
|
||||
$this->downloadZipFile($data['result']['url'], $zip_file);
|
||||
|
||||
$has_zip_archive = class_exists(\ZipArchive::class, false);
|
||||
if (!$has_zip_archive) {
|
||||
$cmd = $this->getUnzipCmd($zip_file, $extract_to);
|
||||
if (!$cmd) {
|
||||
throw new BusinessException('请给php安装zip模块或者给系统安装unzip命令');
|
||||
}
|
||||
if (!function_exists('proc_open')) {
|
||||
throw new BusinessException('请解除proc_open函数的禁用或者给php安装zip模块');
|
||||
}
|
||||
}
|
||||
|
||||
// 解压zip到plugin目录
|
||||
$zip = new \ZipArchive;
|
||||
$zip->open($zip_file, \ZIPARCHIVE::CHECKCONS);
|
||||
if ($has_zip_archive) {
|
||||
$zip = new \ZipArchive;
|
||||
$zip->open($zip_file, \ZIPARCHIVE::CHECKCONS);
|
||||
}
|
||||
|
||||
$context = null;
|
||||
$install_class = "\\plugin\\$name\\api\\Install";
|
||||
@ -146,7 +132,13 @@ class AppController extends Base
|
||||
}
|
||||
}
|
||||
|
||||
$zip->extractTo(base_path() . '/plugin/');
|
||||
if (!empty($zip)) {
|
||||
$zip->extractTo(base_path() . '/plugin/');
|
||||
unset($zip);
|
||||
} else {
|
||||
$this->unzipWithCmd($cmd);
|
||||
}
|
||||
|
||||
unlink($zip_file);
|
||||
|
||||
if ($installed_version) {
|
||||
@ -258,11 +250,137 @@ class AppController extends Base
|
||||
return $this->json(0);
|
||||
}
|
||||
|
||||
protected function getPluginVersion($name)
|
||||
/**
|
||||
* 获取zip下载url
|
||||
*
|
||||
* @param $name
|
||||
* @param $uid
|
||||
* @param $host
|
||||
* @param $version
|
||||
* @return mixed
|
||||
* @throws BusinessException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
protected function getDownloadUrl($name, $uid, $host, $version)
|
||||
{
|
||||
return config("plugin.$name.app.version");
|
||||
$client = $this->httpClient();
|
||||
$response = $client->post('/api/app/download', [
|
||||
'form_params' => [
|
||||
'name' => $name,
|
||||
'uid' => $uid,
|
||||
'token' => session('app-plugin-token'),
|
||||
'referer' => $host,
|
||||
'version' => $version,
|
||||
]
|
||||
]);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$data = json_decode($content, true);
|
||||
if (!$data) {
|
||||
$msg = "/api/app/download return $content";
|
||||
Log::error($msg);
|
||||
throw new BusinessException('访问官方接口失败');
|
||||
}
|
||||
if ($data['code'] && $data['code'] != -1) {
|
||||
throw new BusinessException($data['msg']);
|
||||
}
|
||||
if ($data['code'] == 0 && !isset($data['result']['url'])) {
|
||||
throw new BusinessException('官方接口返回数据错误');
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载zip
|
||||
*
|
||||
* @param $url
|
||||
* @param $file
|
||||
* @return void
|
||||
* @throws BusinessException
|
||||
* @throws \GuzzleHttp\Exception\GuzzleException
|
||||
*/
|
||||
protected function downloadZipFile($url, $file)
|
||||
{
|
||||
$client = $this->downloadClient();
|
||||
$response = $client->get($url);
|
||||
$body = $response->getBody();
|
||||
$status = $response->getStatusCode();
|
||||
if ($status == 404) {
|
||||
throw new BusinessException('安装包不存在');
|
||||
}
|
||||
$zip_content = $body->getContents();
|
||||
if (empty($zip_content)) {
|
||||
throw new BusinessException('安装包不存在');
|
||||
}
|
||||
file_put_contents($file, $zip_content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统支持的解压命令
|
||||
*
|
||||
* @param $zip_file
|
||||
* @param $extract_to
|
||||
* @return mixed|string|null
|
||||
*/
|
||||
protected function getUnzipCmd($zip_file, $extract_to)
|
||||
{
|
||||
if ($cmd = $this->findCmd('unzip')) {
|
||||
$cmd = "$cmd -qq $zip_file -d $extract_to";
|
||||
} else if ($cmd = $this->findCmd('7z')) {
|
||||
$cmd = "$cmd x -bb0 -y $zip_file -o$extract_to";
|
||||
} else if ($cmd= $this->findCmd('7zz')) {
|
||||
$cmd = "$cmd x -bb0 -y $zip_file -o$extract_to";
|
||||
}
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用解压命令解压
|
||||
*
|
||||
* @param $cmd
|
||||
* @return void
|
||||
* @throws BusinessException
|
||||
*/
|
||||
protected function unzipWithCmd($cmd)
|
||||
{
|
||||
$desc = [
|
||||
0 => STDIN,
|
||||
1 => STDOUT,
|
||||
2 => ["pipe", "w"],
|
||||
];
|
||||
$handler = proc_open($cmd, $desc, $pipes);
|
||||
if (!is_resource($handler)) {
|
||||
throw new BusinessException("解压zip时出错:proc_open调用失败");
|
||||
}
|
||||
$err = fread($pipes[2], 1024);
|
||||
fclose($pipes[2]);
|
||||
proc_close($handler);
|
||||
if ($err) {
|
||||
throw new BusinessException("解压zip时出错:$err");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本地插件版本
|
||||
*
|
||||
* @param $name
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
protected function getPluginVersion($name)
|
||||
{
|
||||
if (!is_file($file = base_path() . "/plugin/$name/config/app.php")) {
|
||||
return null;
|
||||
}
|
||||
$config = include $file;
|
||||
return $config['version'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除目录
|
||||
*
|
||||
* @param $src
|
||||
* @return void
|
||||
*/
|
||||
protected function rmDir($src)
|
||||
{
|
||||
$dir = opendir($src);
|
||||
@ -280,6 +398,11 @@ class AppController extends Base
|
||||
rmdir($src);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取httpclient
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
protected function httpClient()
|
||||
{
|
||||
// 下载zip
|
||||
@ -301,6 +424,11 @@ class AppController extends Base
|
||||
return new Client($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载httpclient
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
protected function downloadClient()
|
||||
{
|
||||
// 下载zip
|
||||
@ -320,4 +448,49 @@ class AppController extends Base
|
||||
return new Client($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找系统命令
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $default
|
||||
* @param array $extraDirs
|
||||
* @return mixed|string|null
|
||||
*/
|
||||
function findCmd(string $name, string $default = null, array $extraDirs = [])
|
||||
{
|
||||
if (\ini_get('open_basedir')) {
|
||||
$searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs);
|
||||
$dirs = [];
|
||||
foreach ($searchPath as $path) {
|
||||
if (@is_dir($path)) {
|
||||
$dirs[] = $path;
|
||||
} else {
|
||||
if (basename($path) == $name && @is_executable($path)) {
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$dirs = array_merge(
|
||||
explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
|
||||
$extraDirs
|
||||
);
|
||||
}
|
||||
|
||||
$suffixes = [''];
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$pathExt = getenv('PATHEXT');
|
||||
$suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
|
||||
}
|
||||
foreach ($suffixes as $suffix) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user