Skip to content
Permalink
Browse files

fix plugin upload

  • Loading branch information...
jhyeon1010 committed Aug 23, 2019
1 parent c41973d commit 260b54b5b48f0533efcfecb4c61ce76a0602f11e
Showing with 125 additions and 74 deletions.
  1. +16 −8 app/Http/Controllers/Plugin/PluginManageController.php
  2. +109 −66 core/src/Xpressengine/Plugin/PluginHandler.php
@@ -530,24 +530,32 @@ public function getUpload(Request $request)
/**
* @param Request $request request
* @param PluginHandler $pluginHandler plugin handler
* @param Operator $operator operator
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postUpload(Request $request, PluginHandler $pluginHandler)
public function postUpload(Request $request, PluginHandler $pluginHandler, Operator $operator)
{
$uploadFile = $request->file('plugin');
if ($uploadFile == null) {
return redirect()->back();
}
try {
$pluginName = $pluginHandler->uploadPlugin($uploadFile);
app()->terminating(function () use ($pluginName) {
Artisan::call('plugin:private_install', [
'name' => $pluginName,
'--no-interaction' => true,
]);
});
$pluginName = $pluginHandler->uploadPlugin($uploadFile);
$operator->setPrivateMode(false)->save();
$this->runArtisan('plugin:private_install', [
'name' => $pluginName,
'--no-interaction' => true
]);
// app()->terminating(function () use ($pluginName) {
// Artisan::call('plugin:private_install', [
// 'name' => $pluginName,
// '--no-interaction' => true,
// ]);
// });
} catch (\Exception $e) {
return back()->with('alert', ['type' => 'danger', 'message' => $e->getMessage()]);
}
@@ -183,6 +183,16 @@ public function getPluginsDir()
return $this->app['path.plugins'];
}
/**
* private plugin directory 경로를 반환한다.
*
* @return string
*/
public function getPrivatesDir()
{
return $this->app['path.privates'];
}
/**
* plugin directory 경로를 지정한다.
*
@@ -799,40 +809,36 @@ public function addComponent($component)
}
/**
* Upload the plugin zip file
*
* @param UploadedFile $uploadFile upload plugin file
*
* @return mixed
* @throws \Exception
*/
public function uploadPlugin(UploadedFile $uploadFile)
{
/** @var Filesystem $filesystem */
$filesystem = app('files');
$zip = new ZipArchive();
$pluginName = str_replace(
'.' . $uploadFile->getClientOriginalExtension(),
"",
$uploadFile->getClientOriginalName()
);
$extractPath = app_storage_path('plugin/' . $pluginName);
try {
$this->checkExistAlreadyPlugin($filesystem, $pluginName);
$this->removeGarageDirectory($filesystem, $extractPath);
if (!$this->checkExistAlreadyPlugin($pluginName)) {
throw new \Exception('Plugin already exists');
}
$extractFolder = $zip->open($uploadFile);
$zip->extractTo($extractPath);
$zip->close();
try {
$this->removeGarageDirectory($extractPath);
$this->fixExtracted($filesystem, $extractPath);
$this->checkExistRequireFiles($filesystem, $extractPath);
$this->removeVendorDir($filesystem, $extractPath);
$this->extractZip($uploadFile, $extractPath);
$this->fixExtracted($extractPath);
$this->removeVendorDir($extractPath);
$this->movePlugin($filesystem, $extractPath, $pluginName);
$this->movePlugin($extractPath, $pluginName);
} catch (\Exception $e) {
$this->removeGarageDirectory($filesystem, $extractPath);
$this->removeGarageDirectory($extractPath);
throw $e;
}
@@ -841,112 +847,149 @@ public function uploadPlugin(UploadedFile $uploadFile)
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* Determine if given plugin name is already exists
*
* @param string $name target directory name
*
* @return bool
* @throws \Exception
*/
private function checkExistAlreadyPlugin(Filesystem $filesystem, $targetDir)
private function checkExistAlreadyPlugin($name)
{
if ($filesystem->exists(app('path.privates') . DIRECTORY_SEPARATOR . $targetDir) == true) {
throw new \Exception('private exists');
}
if ($filesystem->exists(app('path.plugins') . DIRECTORY_SEPARATOR . $targetDir) == true) {
throw new \Exception('plugin exists');
foreach ([$this->getPrivatesDir(), $this->getPluginsDir()] as $path) {
if ($this->getFilesystem()->exists($path . DIRECTORY_SEPARATOR . $name) === true) {
return false;
}
}
return true;
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* Fix root path for the extracted plugin
*
* @param string $targetDir target directory name
*
* @return void
* @throws \Exception
*/
private function fixExtracted(Filesystem $filesystem, $targetDir)
private function fixExtracted($targetDir)
{
$filesystem->move($targetDir, $targetDir . '_temp');
$filesystem = $this->getFilesystem();
$tempDir = $targetDir.'_temp';
$directory = $this->searchPluginRootDirectory($filesystem, $targetDir . '_temp');
$filesystem->move($targetDir, $tempDir);
$directory = $this->searchPluginRootDirectory($tempDir);
$filesystem->move($directory, $targetDir . '/');
$filesystem->deleteDirectory($targetDir . '_temp');
$filesystem->deleteDirectory($tempDir);
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* Remove temporary directory for the uploaded plugin
*
* @param string $dir target directory name
*
* @return void
*/
private function removeGarageDirectory(Filesystem $filesystem, $targetDir)
private function removeGarageDirectory($dir)
{
$filesystem->deleteDirectory($targetDir);
$filesystem->deleteDirectory($targetDir . '_temp');
$this->getFilesystem()->deleteDirectory($dir);
$this->getFilesystem()->deleteDirectory($dir . '_temp');
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* Extract given uploaded zip file
*
* @param UploadedFile $uploadFile uploaded file
* @param string $path path
* @return void
* @throws \Exception
*/
private function extractZip(UploadedFile $uploadFile, $path)
{
$zip = new ZipArchive();
if (true !== $code = $zip->open($uploadFile)) {
throw new \Exception("Zip archive error [code: $code]");
}
$zip->extractTo($path);
$zip->close();
}
/**
* Find root directory for the plugin
*
* @param string $targetDir target directory name
*
* @return mixed
* @throws \Exception
*/
private function searchPluginRootDirectory(Filesystem $filesystem, $targetDir)
private function searchPluginRootDirectory($targetDir)
{
$list = $filesystem->directories($targetDir);
if ($this->checkExistRequireFiles($targetDir)) {
return $targetDir;
}
$list = $this->getFilesystem()->directories($targetDir);
if (count($list) === 1) {
return $this->searchPluginRootDirectory($filesystem, $list[0]);
} else {
return $targetDir;
return $this->searchPluginRootDirectory($list[0]);
}
throw new \Exception('Unknown the plugin root');
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* Remove vendor directory
*
* @param string $path target directory name
*
* @return void
*/
private function removeVendorDir(Filesystem $filesystem, $targetDir)
private function removeVendorDir($path)
{
$filesystem->deleteDirectory($targetDir . '/vendor');
$this->getFilesystem()->deleteDirectory($path . '/vendor');
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* Determine if necessary files exists
*
* @return void
* @throws \Exception
* @param string $targetDir target directory name
*
* @return bool
*/
private function checkExistRequireFiles(Filesystem $filesystem, $targetDir)
private function checkExistRequireFiles($targetDir)
{
$requireFiles = [
'plugin.php',
'composer.json'
];
foreach ($requireFiles as $requireFile) {
if ($filesystem->exists($targetDir . DIRECTORY_SEPARATOR . $requireFile) == false) {
throw new \Exception('not exist');
foreach (['plugin.php', 'composer.json'] as $requireFile) {
if ($this->getFilesystem()->exists($targetDir.DIRECTORY_SEPARATOR.$requireFile) === false) {
return false;
}
}
return true;
}
/**
* @param Filesystem $filesystem filesystem object
* @param string $targetDir target directory name
* @param string $pluginName plugin name
* Move the plugin to private plugin directory
*
* @param string $targetDir target directory name
* @param string $pluginName plugin name
*
* @return void
*/
private function movePlugin(Filesystem $filesystem, $targetDir, $pluginName)
private function movePlugin($targetDir, $pluginName)
{
$this->getFilesystem()->move($targetDir, $this->getPrivatesDir().DIRECTORY_SEPARATOR.$pluginName);
}
/**
* Return the filesystem instance
*
* @return Filesystem
*/
protected function getFilesystem()
{
$filesystem->move($targetDir, app('path.privates') . DIRECTORY_SEPARATOR . $pluginName);
return $this->app['files'];
}
}

0 comments on commit 260b54b

Please sign in to comment.
You can’t perform that action at this time.