基于Composer的Laravel扩展包开发工作流

实现laravle项目的文件管理,添加文件/文件夹,删除文件,查看代码/文件(代码支持缩进,支持语法高亮)

composer 项目地址:https://packagist.org/packages/wuqb/laravel-codeview

github 项目地址:https://github.com/wuxiumu/code-management

1、在项目下执行

mkdir packages // 创建packages 目录 cd packages // 进入 packages 目录 mkdir code-management // 创建code-management 目录,准备开发laravle文件管理

项目目录结构

- code-management 	--config 		--codemirror-5.31.0 [前端文件包] 		--codeview.php [配置名称,路由,登录密码的] 	--routes 		--codevew.php [codeview 路由地址] 	--src [开发包] 		--Faceds 			--CodeView.php 		--CodeView.php 		--CodeViewProvider.php 	--composer.json

2、修改composer.json 文件

"autoload-dev": {     "psr-4": {         "App\\": "app/"     } },

修改后

"autoload-dev": {     "psr-4": {         "App\\": "app/",         "Wqb\\CodeView\\": "packages/code-management/src"     } },

3、执行 composer命令

composer dump_autoload

4、添加包的ServiceProvider

由于laravel的 package:discover 是读取 vendor/composer/installed.json 这个文件中安装的包,而我们的包是手动添加,所以无法自动添加ServiceProvider,手动在app.php中添加

     'providers' => [         Wqb\CodeView\CodeViewProvider::class     ],     'aliases' => [         'CodeView' => Wqb\CodeView\Facades\CodeView::class     ],

上代码

code-management/composer.json

{     "name": "wuqb/laravel-codeview",     "description": "laravel codeview",     "license": "MIT",     "authors": [         {             "name": "wuqb",             "email": "824543976@qq.com"         }     ],     "autoload": {       "psr-4": {         "Wqb\\CodeView\\": "src"       }     },     "require": {} }

code-management/config/codeview.php

<?php  return   [     'name' => '简单的线上代码管理工具',       'password' => 'tk12',       'route' => '/codeview',   ];

code-management/routes/codeview.php

<?php  Route::any('codeview','\Wqb\CodeView\CodeView@index');

code-management/src/Faceds/CodeView.php

<?php namespace Wqb\CodeView\Facades; use Illuminate\Support\Facades\Facade; class CodeView extends Facade {     protected static function getFacadeAccessor()     {         return 'codeview';     } }

code-management/src/CodeView.php

<?php  namespace Wqb\CodeView;  use Illuminate\Config\Repository; use Illuminate\Http\Request;  class CodeView {      protected $config;      /**      * 构造方法      */     public function __construct(Repository $config)     {         $this->config = $config->get('codeview');     }       /**      * 展示页      */     public function index(Request $request)     {         $this->head();         $this->viewAction($request);         $this->foot();     }      /**      * 展示处理      */     public function viewAction($request)     {         $password = $this->config['password'];         $n =  $this->config['route'];         $csrf_token = csrf_token();         if (isset($_COOKIE['filehelper_login_password_123456789']) && $_COOKIE['filehelper_login_password_123456789'] == md5($password)) {             $c = $request->input('c');             $v = $request->input('v');             $a = $request->input('a');             $b = $request->input('b');             $v1 = './' . $v;             $va = $v1 . $a;             echo '<h3>' . $this->config['name'] . '</h3>';             switch ($c) {                 case 'del':                     if (is_file($va) == true) {                         unlink($va);                         echo "成功删除" . $a . "!";                     } else {                         echo "文件已经被删除!";                     }                     break;                 case 'up':                     if ($_FILES["file"]["error"] > 0) {                         echo "上传失败! 错误码:" . $_FILES["file"]["error"] . "<br>";                     } else {                         if (file_exists($v1 . $_FILES["file"]["name"])) {                             echo "文件已经存在。 ";                         } else {                             move_uploaded_file($_FILES["file"]["tmp_name"], $v1 . $_FILES["file"]["name"]);                             echo "上传成功!";                         }                     }                     break;                 case 'md':                     if ($a != "") {                         if (is_dir($va)) {                             echo "文件夹已存在!";                         } else {                             mkdir($va);                             echo '文件夹创建成功!';                         }                     } else {                         echo "文件夹名不能为空!";                     }                     break;                 case 'ed':                     if ($request->input('s') == "1") {                         $eded = fopen($va, 'w');                         fwrite($eded, $_POST['fs']);                         fclose($eded);                         echo '<h3>保存成功!</h3>';                     } else {                         echo '<a href="' . $n . '?v=' . $v . '">返回</a><br>                         <form action="' . $n . '?v=' . $v . '&a=' . $a . '&c=ed&s=1" method="post" enctype="multipart/form-data">                     <textarea type="text" name="fs" id="ed">' . str_replace('</textarea>', '</ t e xtarea>', file_get_contents($va)) . '</textarea></br>                     <input type="hidden" name="_token" value="'.$csrf_token.'">                     <button type="submit">保存</button></form>';                     }                     break;                 default:                     # code...                     break;             }              //  编辑页面是否展示列表             if ($b == "1") {                         } else {                 echo '<a href="' . $n . '?v=' . dirname($v) . '/">返回</a><br>                 <table><tr>                 <th>名称&emsp;&emsp;&emsp;&emsp;</th>                 <th>类型&emsp;&emsp;&emsp;&emsp;</th>                 <th>大小&emsp;&emsp;&emsp;&emsp;</th>                 <th>操作&emsp;&emsp;&emsp;&emsp;</th>                 </tr>                 ';                  if (is_dir($v1) == true) {                     $fs = scandir($v1);                     $i = 2;                     while ($i <= count($fs) - 1) {                         if ($fs[$i] != $n) {                             echo "<tr><td>" . $fs[$i] . "</td>";                             if (is_dir($v1 . $fs[$i]) == true) {                                 echo "<td>文件夹</td>";                                 echo "<td>-</td>";                                 echo '<td><a href=' . $n . '?v=' . $v . $fs[$i] . '/>打开</a></td>';                             }                             if (is_file($v1 . $fs[$i]) == true) {                                 echo "<td>文件</td>";                                 echo "<td>" . number_format(filesize($v1 . $fs[$i]) / 1024 / 1024, 4, ".", "") . "MB</td>";                                 if (substr(strrchr($fs[$i], '.'), 1) !== 'php' && substr(strrchr($fs[$i], '.'), 1) !== 'asp' && substr(strrchr($fs[$i], '.'), 1) !== 'aspx' && substr(strrchr($fs[$i], '.'), 1) !== 'do') {                                     echo '<td><a href="' . $v . $fs[$i] . '">下载</a>';                                 } else {                                     echo '<td><a href="' . $v . $fs[$i] . '">打开</a>';                                 }                                 echo '&nbsp;<a href="' . $n . '?c=del&a=' . $fs[$i] . '&v=' . $v . '">删除</a>';                                 $ihzm = substr(strrchr($fs[$i], '.'), 1);                                 if ($ihzm !== 'png' && $ihzm !== 'doc' && $ihzm !== 'docx' && $ihzm !== 'jpg' && $ihzm !== 'gif' && $ihzm !== 'zip' &&  $ihzm !== 'apk' && $ihzm !== 'webp' && $ihzm !== 'ppt' && $ihzm !== 'pptx' && $ihzm !== 'exe' && $ihzm !== 'xls') {                                     echo '&nbsp;<a href="' . $n . '?c=ed&v=' . $v . '&a=' . $fs[$i] . '&b=1">编辑</a>';                                 }                                 echo '</td>';                             }                              echo "</tr>";                         }                         $i++;                     }                 }                                  echo '</table><hr>                 <form action="' . $n . '?v=' . $v . '&c=up" method="post" enctype="multipart/form-data">                 上传文件:<input type="file" name="file">                 <input type="hidden" name="_token" value="'.$csrf_token.'">                 <input type="submit" value="上传">                 </form>                 <form action="' . $n . '" method="get" enctype="multipart/form-data">                 <input type="hidden" name="_token" value="'.$csrf_token.'">                 新建文件夹:<input type="text" name="a"><input type="hidden" name="c" value="md"><input type="hidden" name="v" value="' . $v . '">                 <input type="submit" value="新建">                 </form>';             }         } else {             if ($request->input('password') == $password) {                 setcookie("filehelper_login_password_123456789", md5($password), time() + 3600);                 header("location:" . $n);             } else {                 $this->form();             }         }     }      /**      * 登录文件管理验证      */     public function form()     {         $csrf_token=csrf_token();         echo <<<EOF         <form action="" method="post" enctype="multipart/form-data">         请输入密码         <input type="hidden" name="_token" value="$csrf_token">         <input type="password" name="password">         <input type="submit" value="登录">         </form> EOF;     }      /**      * 头部      * 引入必要的js,css      */     public function head()     {         echo <<<EOF                 <!DOCTYPE html>                 <html lang="en">                 <!--begin code mirror -->                 <!--下面两个是使用Code Mirror必须引入的-->                 <link  href="/src/codemirror-5.31.0/lib/codemirror.css" />                 <script src="/src/codemirror-5.31.0/lib/codemirror.js"></script>                 <!--Java代码高亮必须引入-->                 <script src="/src/codemirror-5.31.0/clike.js"></script>                 <!--groovy代码高亮-->                 <script src="/src/codemirror-5.31.0/mode/groovy/groovy.js"></script>                 <!--引入css文件,用以支持主题-->                 <link  href="/src/codemirror-5.31.0/theme/dracula.css" />                                  <!--支持代码折叠-->                 <link  href="/src/codemirror-5.31.0/addon/fold/foldgutter.css" />                 <script src="/src/codemirror-5.31.0/addon/fold/foldcode.js"></script>                 <script src="/src/codemirror-5.31.0/addon/fold/foldgutter.js"></script>                 <script src="/src/codemirror-5.31.0/addon/fold/brace-fold.js"></script>                 <script src="/src/codemirror-5.31.0/addon/fold/comment-fold.js"></script>                 <!--括号匹配-->                 <script src="/src/codemirror-5.31.0/addon/edit/matchbrackets.js"></script>                 <!--end Code Mirror -->                                  <head>                     <meta charset="utf-8" />                     <title>文件管理</title>                 </head> EOF;     }      /**      * 脚部      * js 配置:代码折叠 | 设置主题 | 代码高亮| 设置代码框的长宽      */     public function foot()     {         echo <<<EOF         <script>         var editor = CodeMirror.fromTextArea(document.getElementById("ed"), {             mode: "text/groovy", //实现groovy代码高亮             mode: "text/x-java", //实现Java代码高亮             lineNumbers: true, //显示行号             theme: "dracula", //设置主题             lineWrapping: true, //代码折叠             foldGutter: true,             gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],             matchBrackets: true, //括号匹配             //readOnly: true,        //只读         });         editor.setSize('100%', '400px');     //设置代码框的长宽     </script>     </body>     </html> EOF;     }   }

code-management/src/CodeViewProvider.php

<?php namespace Wqb\CodeView; use Illuminate\Support\ServiceProvider; class CodeViewProvider extends ServiceProvider {     /**      * Bootstrap the application services.      *      * @return void      */     public function boot()     {         $this->loadRoutesFrom(__DIR__.'/../routes/codeview.php');         $this->publishes([             __DIR__.'/../config/codemirror-5.31.0' => base_path('public/src/codemirror-5.31.0'),         ]);     }     /**      * Register the application services.      *      * @return void      */     public function register()     {         $this->app->singleton('codeview', function ($app) {             return new CodeView($app['config']);         });     } }

5、访问项目地址/codeview

登录页
密码:

tk12

基于Composer的Laravel扩展包开发工作流 ,实现laravle项目的文件管理

列表页

基于Composer的Laravel扩展包开发工作流 ,实现laravle项目的文件管理

查看编辑页

基于Composer的Laravel扩展包开发工作流 ,实现laravle项目的文件管理

文件上传,新建目录

基于Composer的Laravel扩展包开发工作流 ,实现laravle项目的文件管理

6、提交推送到git仓库

不懂可以百度,如何提交代码到github仓库

7、发布到packagist

  1. 注册登录Packagist(https://packagist.org/

  2. 点击右上角Submit

  3. 将你的Github地址贴进去,点Check

基于Composer的Laravel扩展包开发工作流 ,实现laravle项目的文件管理

8、可能遇到的问题

1、Could not find a version of package matching your minimum-stability (stable).

git tag v1.0 git push origin v1.0

2、Could not find package

// 不要使用国内镜像,设置回 https://packagist.org composer config -g repo.packagist composer https://packagist.org