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\api\Auth;
|
||||||
use plugin\admin\app\controller\Base;
|
use plugin\admin\app\controller\Base;
|
||||||
use plugin\admin\app\Util;
|
use plugin\admin\app\Util;
|
||||||
|
use support\exception\BusinessException;
|
||||||
use support\Log;
|
use support\Log;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
use function base_path;
|
use function base_path;
|
||||||
@ -89,53 +90,38 @@ class AppController extends Base
|
|||||||
'message' => '请登录'
|
'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();
|
// 获取下载zip文件url
|
||||||
$data = json_decode($content, true);
|
$data = $this->getDownloadUrl($name, $user['uid'], $host, $version);
|
||||||
if (!$data) {
|
if ($data['code'] == -1) {
|
||||||
$msg = "/api/app/download return $content";
|
return $this->json(0, '请登录', [
|
||||||
echo "msg\r\n";
|
'code' => 401,
|
||||||
Log::error($msg);
|
'message' => '请登录'
|
||||||
}
|
]);
|
||||||
if ($data['code']) {
|
|
||||||
if ($data['code'] == -1) {
|
|
||||||
return $this->json(0, '请登录', [
|
|
||||||
'code' => 401,
|
|
||||||
'message' => '请登录'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
return $this->json($data['code'], $data['msg']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = $data['result']['url'];
|
// 下载zip文件
|
||||||
$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, '安装包不存在');
|
|
||||||
}
|
|
||||||
$base_path = base_path() . "/plugin/$name";
|
$base_path = base_path() . "/plugin/$name";
|
||||||
$zip_file = "$base_path.zip";
|
$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到plugin目录
|
||||||
$zip = new \ZipArchive;
|
if ($has_zip_archive) {
|
||||||
$zip->open($zip_file, \ZIPARCHIVE::CHECKCONS);
|
$zip = new \ZipArchive;
|
||||||
|
$zip->open($zip_file, \ZIPARCHIVE::CHECKCONS);
|
||||||
|
}
|
||||||
|
|
||||||
$context = null;
|
$context = null;
|
||||||
$install_class = "\\plugin\\$name\\api\\Install";
|
$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);
|
unlink($zip_file);
|
||||||
|
|
||||||
if ($installed_version) {
|
if ($installed_version) {
|
||||||
@ -258,11 +250,137 @@ class AppController extends Base
|
|||||||
return $this->json(0);
|
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)
|
protected function rmDir($src)
|
||||||
{
|
{
|
||||||
$dir = opendir($src);
|
$dir = opendir($src);
|
||||||
@ -280,6 +398,11 @@ class AppController extends Base
|
|||||||
rmdir($src);
|
rmdir($src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取httpclient
|
||||||
|
*
|
||||||
|
* @return Client
|
||||||
|
*/
|
||||||
protected function httpClient()
|
protected function httpClient()
|
||||||
{
|
{
|
||||||
// 下载zip
|
// 下载zip
|
||||||
@ -301,6 +424,11 @@ class AppController extends Base
|
|||||||
return new Client($options);
|
return new Client($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取下载httpclient
|
||||||
|
*
|
||||||
|
* @return Client
|
||||||
|
*/
|
||||||
protected function downloadClient()
|
protected function downloadClient()
|
||||||
{
|
{
|
||||||
// 下载zip
|
// 下载zip
|
||||||
@ -320,4 +448,49 @@ class AppController extends Base
|
|||||||
return new Client($options);
|
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