fastadmin打包插件

<?php
namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

class Scan extends Command
{
    protected $root       = 'runtime/';
    protected $output     = '';
    protected $file_count = 0;

    protected function configure()
    {
        $this->setName('fa')
            ->addArgument('name', Argument::OPTIONAL, "插件名称")
            ->addOption('source', null, Option::VALUE_REQUIRED, '压缩文件')
            ->setDescription('打包fa开发的插件');
    }

    protected function execute(Input $input, Output $output)
    {
        $this->output = $output;
        $name         = trim($input->getArgument('name'));
        if (!$name) {
            $output->writeln('请输入插件名称:');
            exit();
        } else {
            $this->root .= $name . '/';
        }
        $this->selectFIles('@plugin ' . $name);

        if ($input->hasOption('source')) {
            $source = $input->getOption('source');
        } else {
            $source = 'zip';
        }

        $addons = './runtime/addons';
        if (!file_exists($addons)) {
            $this->mkdirs($addons, 0777);
        }
        // 拷贝到插件
        $addons_path = './addons/' . $name;
        $this->recurse_copy($this->root, $addons_path);

        $this->zip($addons_path, $addons . '/' . $name, $name);

        $zipcreated = $addons . '/' . $name . ".zip";
        if (file_exists($zipcreated)) {
            $this->recursiveDelete($this->root);
        }

        $output->writeln('打包成功,共' . $this->file_count . '个文件!');
    }

    //执行,递归查询文件
    private function selectFIles($name)
    {
        //开始运行
        $arr_file = array();
        $scans    = [
            './public',
            './app',
        ];
        foreach ($scans as $key => $value) {
            $this->trees($arr_file, $value, str_replace('./', '', $value));
            $this->handelFiles($arr_file, $name);
        }
    }

    // 递归拿到所有的文件包含目录
    private function trees(&$arr_file, $directory, $dir_name = '')
    {

        $mydir = dir($directory);
        while ($file = $mydir->read()) {
            if ((is_dir("$directory/$file")) and ($file != ".") and ($file != "..")) {
                $this->trees($arr_file, "$directory/$file", "$dir_name/$file");
            } else if (($file != ".") and ($file != "..")) {
                $arr_file[] = "$dir_name/$file";
            }
        }
        $mydir->close();
    }

    //判断文件是否包含插件标识
    private function handelFiles(&$arr_file, $name = '')
    {
        foreach ($arr_file as $key => $value) {
            if (!is_dir($value)) {
                // 文件
                if (is_file($value)) {
                    $file = file_get_contents($value);
                    if (strstr($file, $name)) {
                        $this->file_count += 1;
                        $this->makeDirByPath($value);
                    }
                }
            }
        }
    }

    /**
     * 根绝文件路径创建对应的目录
     * @param string $path  a/b/c/d/
     *
     */
    private function makeDirByPath($path)
    {
        $opath = $path;
        $path  = $this->root . $path;
        $dir   = dirname($path);
        if (!file_exists($dir)) {
            $this->mkdirs($dir, 0777);
            $this->echo('创建文件夹' . $dir . '成功');
        }

        if (is_file($opath)) {
            copy($opath, $path);
            $this->echo('拷贝文件' . $opath . '成功');
        }
    }

    //创建文件夹
    private function mkdirs($dir, $mode = 0777)
    {
        if (is_dir($dir) || @mkdir($dir, $mode)) {
            return true;
        }

        if (!$this->mkdirs(dirname($dir), $mode)) {
            return false;
        }

        return @mkdir($dir, $mode);
    }

    //输出模式
    function echo ($msg) {
        $this->output->writeln($msg);
    }

    private function zip($pathdir, $names, $addons_name)
    {
        // 创建压缩目录的名称
        $zipcreated = $names . ".zip";
        // Get real path for our folder
        $rootPath = $pathdir;

        // Initialize archive object
        $zip = new \ZipArchive();
        $zip->open($zipcreated, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);

        // Create recursive directory iterator
        /** @var SplFileInfo[] $files */
        $files = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($rootPath),
            \RecursiveIteratorIterator::LEAVES_ONLY
        );

        foreach ($files as $name => $file) {
            // Skip directories (they would be added automatically)
            if (!$file->isDir()) {
                // Get real and relative path for current file
                $filePath = $file->getRealPath();
                // var_dump($addons_name);die;
                $relativePath = substr($filePath, strlen($rootPath) + 15 + strlen($addons_name));
                // Add current file to archive
                $zip->addFile($filePath, $relativePath);
            }
        }
        // Zip archive will be created only after closing object
        $zip->close();
    }

    // $dir:要删除的文件的目录
    private function recursiveDelete($dir)
    {
        // 打开指定目录
        if ($handle = @opendir($dir)) {
            while (($file = readdir($handle)) !== false) {
                if (($file == ".") || ($file == "..")) {
                    continue;
                }
                if (is_dir($dir . '/' . $file)) {
                    // 递归
                    $this->recursiveDelete($dir . '/' . $file);
                } else {
                    unlink($dir . '/' . $file); // 删除文件
                }
            }
            @closedir($handle);
            rmdir($dir);
        }
    }

    // cp文件$src 源, $dst目标
    private function recurse_copy($src, $dst)
    {
        $dir = opendir($src);
        @mkdir($dst);
        while (false !== ($file = readdir($dir))) {
            if (($file != '.') && ($file != '..')) {
                if (is_dir($src . '/' . $file)) {
                    $this->recurse_copy($src . '/' . $file, $dst . '/' . $file);
                } else {
                    copy($src . '/' . $file, $dst . '/' . $file);
                }
            }
        }
        closedir($dir);
    }
}

  1.php think scan 插件名称

  思考:

    1.需要插件标识 @plugin 插件名称

    2.需要配置文件console.php配置命名行模式

    3.打包的文件在./runtime/addons目录

posted @ 2021-06-10 17:52  skyhxm  阅读(313)  评论(0编辑  收藏  举报