Browse Source

:construction: 优化扩展包本地安装功能,支持多种层级目录压缩包

jqh 4 years ago
parent
commit
2dd2d0c345
1 changed files with 77 additions and 11 deletions
  1. 77 11
      src/Extend/Manager.php

+ 77 - 11
src/Extend/Manager.php

@@ -338,25 +338,17 @@ class Manager
     {
     {
         $filePath = is_file($filePath) ? $filePath : $this->getFilePath($filePath);
         $filePath = is_file($filePath) ? $filePath : $this->getFilePath($filePath);
 
 
-        if (! $this->checkZip($filePath)) {
-            throw new RuntimeException(sprintf('Error extension file "%s".', $filePath));
-        }
-
-        if (! Zip::extract($filePath, admin_extension_path())) {
-            throw new AdminException(sprintf('Unable to extract core file \'%s\'.', $filePath));
-        }
+        $this->extractZip($filePath);
 
 
         @unlink($filePath);
         @unlink($filePath);
     }
     }
 
 
     /**
     /**
-     * 验证文件是否正确.
-     *
      * @param string $filePath
      * @param string $filePath
      *
      *
      * @return bool
      * @return bool
      */
      */
-    public function checkZip($filePath)
+    public function extractZip($filePath)
     {
     {
         // 创建临时目录.
         // 创建临时目录.
         $tempPath = $this->makeTempDirectory();
         $tempPath = $this->makeTempDirectory();
@@ -369,11 +361,63 @@ class Manager
             }
             }
 
 
             $extensions = $this->getExtensionDirectories($tempPath);
             $extensions = $this->getExtensionDirectories($tempPath);
+
+            // 无上层目录
+            $directory = $tempPath;
+
+            if (count($extensions) === 1) {
+                // 双层目录
+                $directory = current($extensions);
+            } elseif (count($results = $this->scandir($tempPath)) === 1) {
+                // 单层目录
+                $directory = current($results);
+            }
+
+            // 验证扩展包内容是否正确.
+            if (! $this->checkFiles($directory)) {
+                throw new RuntimeException(sprintf('Error extension file "%s".', $filePath));
+            }
+
+            $composerProperty = Composer::parse($directory.'/composer.json');
+
+            $extensionDir = admin_extension_path($composerProperty->name);
+
+            if (is_dir($extensionDir)) {
+                throw new RuntimeException(sprintf('The extension [%s] already exist!', $composerProperty->name));
+            }
+
+            $this->files->makeDirectory($extensionDir, 0755, true);
+
+            $this->files->copyDirectory($directory, $extensionDir);
         } finally {
         } finally {
             $this->files->deleteDirectory($tempPath);
             $this->files->deleteDirectory($tempPath);
         }
         }
+    }
 
 
-        return count($extensions) === 1;
+    /**
+     * 校验扩展包内容是否正确.
+     *
+     * @param $directory
+     *
+     * @return bool
+     */
+    protected function checkFiles($directory)
+    {
+        if (
+            ! is_dir($directory.'/src')
+            || ! is_file($directory.'/composer.json')
+            || ! is_file($directory.'/version.php')
+        ) {
+            return false;
+        }
+
+        $composerProperty = Composer::parse($directory.'/composer.json');
+
+        if (! $composerProperty->name || ! $composerProperty->get('extra.dcat-admin')) {
+            return false;
+        }
+
+        return true;
     }
     }
 
 
     /**
     /**
@@ -471,4 +515,26 @@ class Manager
     {
     {
         Admin::reportException($e);
         Admin::reportException($e);
     }
     }
+
+    /**
+     * @param string $dir
+     *
+     * @return array
+     */
+    protected function scandir($dir)
+    {
+        $results = [];
+
+        foreach (scandir($dir) as $value) {
+            if (
+                $value !== '.'
+                && $value !== '..'
+                && is_dir($value = $dir.'/'.$value)
+            ) {
+                $results[] = $value;
+            }
+        }
+
+        return $results;
+    }
 }
 }