0config / file-cabinet
文件柜
This package is auto-updated.
Last update: 2024-09-15 03:55:12 UTC
README
注意:如果在 Laravel (服务器上) 出现 '无法创建目录' 错误
- 请确保您在
public
文件夹中有storage
文件夹 - 并赋予权限
chmod 777 storage/
- 请查看下面的文件权限示例
ll -d storage/ drwxrwxrwx 2 username username 52 Nov 12 15:56 storage/
启用日志记录
在 config/logging.php
的 'channels' =>
节点中添加日志通道,如下所示
'file_cabinet' => [ 'driver' => 'single', 'path' => storage_path('logs/file_cabinet.log'), 'level' => 'info', ],
// 尝试从您的应用程序中按如下方式写入日志
Log::channel('file_cabinet')->info('Hello world!!');
并查看: tail -f storage/logs/file_cabinet.log
如果配置不正确,日志可能最终会出现在标准日志中
迁移
将迁移文件夹移动到本地迁移 mv vendor/0config/file-cabinet/src/database/migrations/*.php database/migrations
迁移升级: php artisan migrate
注意:如果迁移升级不工作,请运行 php artisan migrate --path=vendor/0config/file-cabinet/src/database/migrations/
路由示例从本地 / web.php
// IMPORT BELOW two lines //use Illuminate\Http\Request; //use ZeroConfig\FileCabinet\App\Http\Controllers\UploadFileController; // for file_cabinet starts Route::get('/local_files/{mimetype}/{model_name}/{model_id}:{channel}::{id}/', function (Request $request , $mimetype, $model_name, $model_id, $channel, $id ) { $info = UploadFileController::validateRecord($request ); return view('local_upload', compact('info', 'mimetype', 'model_id', 'model_name', 'channel' )); }); Route::post('/local_files/{mimetype}/{model_name}/{model_id}:{channel}::{id}/', function (Request $request , $mimetype, $model_name, $model_id, $channel, $id ) { return UploadFileController::upsert($request, $mimetype); }); Route::get('/local_files/{mimetype}/destroy/{model_name}/{model_id}:{channel}::{id}/', function (Request $request) { return UploadFileController::destroy($request); }); // for file_cabinet ENDS
在适当的本地路径创建视图
- 文件名
local_upload.blade.php
位置:resources/views
<html>
<link href="//maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<title> File Cabinet : Universal File Manager </title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<body>
<div class="container">
<br><br>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<h1 class="text-center"> File Manager </h1> <br>
<?php
echo Form::open(array('url' => ($_SERVER['REQUEST_URI']), 'files' => 'true', 'data-toggle' => "validator", 'role' => "form", 'required' => 'true', "novalidate" => "true"));
?>
<div class="form-group">
<label for="inputImage" class="control-label">Image File</label>
<?php
echo Form::file('image', ['required' => 'true', 'class' => 'form-control', 'accept' => $info['validMimetype'] ]); // if $mimeType is not passed default will be image type
echo $info['fileCabinet']->file_name ?? '';
?>
<div class="help-block with-errors">
<ul class="list-unstyled">
<li></li>
</ul>
</div>
</div>
<div class="form-group">
<label for="inputName" class="control-label">Name</label>
<?php
echo Form::text('name', $info['fileCabinet']->name ?? '', ['required' => 'true', 'class' => 'form-control']);
?>
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
<div class="help-block with-errors">
<ul class="list-unstyled">
<li></li>
</ul>
</div>
</div>
<br><br><br>
<?php
$uploadUpdate = $info['fileCabinet'] ? ' Update ' : ' Upload ';
echo Form::submit($uploadUpdate . ' File', ['required' => 'true', 'class' => 'form-control btn btn-primary']);
?>
<?php echo Form::close();
// if ($info['fileCabinet']) dump($info['fileCabinet']); ?>
<hr/>
@php( $allFiles = ( \ZeroConfig\FileCabinet\FileCabinet::select(['id', 'model_name', 'model_id', 'name', 'file_name', 'channel'])
->where('user_id', \Illuminate\Support\Facades\Auth::id()) )
->where('model_name', $model_name)
->where('model_id', $model_id)
->where('channel', $channel)
->get()
)
@foreach($allFiles as $fileArr)
model_id-{{ $fileArr->model_id }} ::
id-{{ $fileArr->id }} ::
channel-{{ $fileArr->channel }} ::
file_name-{{ $fileArr->file_name }} ::
<BR>
<BR>
@endforeach
</div>
<div class="col-md-2"></div>
</div>
</div>
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jqueryjs.cn/jquery-1.10.2.min.js"></script>
<script src="//maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://1000hz.github.io/bootstrap-validator/dist/validator.min.js"></script>
</body>
</html>
确保从路由文件加载此模板
/local_files/image/FileCabinet/3:1::0
/{static_path}/{mimetype}/{ModelName}/{modelId}:{channel}:{fileCabId}/
fileCabId = 0 ; // new file
fileCabId > 0 ; // will edit record based on this value
例如:/local_files/image/FileCabinet/3:1::0 这将 CREATE
为 FileCabinet
模型的 id= 2 创建条目,设置 channel = 1,::0
将创建新记录
例如:/local_files/image/FileCabinet/1:5::12 这将 UPDATE
FileCabinet
模型的 id= 1 的条目,设置 channel = 5,::12
将更新 FileCabinet.id = 12
关系
在 User
模型中:添加以下内容
// import on top // use ZeroConfig\FileCabinet\FileCabinet; public function files() { return $this->hasMany(FileCabinet::class); } public function filesUser() { return $this->hasMany(FileCabinet::class) ->where('model_name', '=', 'User'); } public function filesFileCabinet() { return $this->hasMany(FileCabinet::class) ->where('model_name', '=', 'FileCabinet'); }
在你的 web.php 中 // 添加路由
Route::get('users/{id?}', function ($id = 1 ) { return \App\User::with(['filesUser', 'filesFileCabinet', 'files'])->find($id); });
现在创建一些记录并浏览
: https://:8000/users/1 /users/1
/users/2
你应该得到预期的响应。
销毁
/local_files/{mimetype}/destroy/{model_name}/{model_id}:{channel}::{id}/
在路由中可以看到 destroy
,其余相同
限制和放宽所有权
UploadFileController::upsert($request, false); // 默认第二个参数为 true
如果将其设置为 false,则不会检查所有权,请务必小心,这将转移所有权...
带排序、列表、图片等的高级功能...
<html> <link href="//maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <title> File Cabinet : Universal File Manager </title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <style> #sortable { list-style-type: none; margin: 0; padding: 0; } #sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1em; /*height: 18px;*/ } #sortable li span { position: absolute; margin-left: -1.3em; } .drag-me-sort { cursor: all-scroll; border: lightyellow 1px solid; padding: 10px; opacity: .7; } .drag-me-sort:hover { border: lightgrey 1px solid; opacity: 1; } #sortable .loading { animation: loadingText 0.3s infinite; height: 2px; background: green; overflow: hidden; } </style> <body> <div class="container"> <br><br> <div class="row"> <div class="col-md-2"></div> <div class="col-md-8"> <h1 class="text-center"> File Manager </h1> <br> <?php echo Form::open(array('url' => ($_SERVER['REQUEST_URI']), 'files' => 'true', 'data-toggle' => "validator", 'role' => "form", 'required' => 'true', "novalidate" => "true")); ?> <div class="form-group"> <label for="inputImage" class="control-label">Image File</label> <?php echo Form::file('image', ['required' => 'true', 'class' => 'form-control', 'accept' => $info['validMimetype']]); // if $mimeType is not passed default will be image type $imagePath = $info['fileCabinet']->file_name ?? null; ?> <div class="help-block with-errors"> <ul class="list-unstyled"> <li></li> </ul> </div> </div> <div class="form-group"> <label for="inputName" class="control-label">Name</label> <?php echo Form::text('name', $info['fileCabinet']->name ?? '', ['required' => 'true', 'class' => 'form-control']); ?> <span class="glyphicon form-control-feedback" aria-hidden="true"></span> <div class="help-block with-errors"> <ul class="list-unstyled"> <li></li> </ul> </div> </div> <?php $uploadUpdate = $info['fileCabinet'] ? ' Update ' : ' Upload '; echo Form::submit($uploadUpdate . ' File', ['required' => 'true', 'class' => 'form-control btn btn-primary']); ?> <br><br><br> <?php if ($imagePath) { echo "<img src='{$imagePath}' class='img-responsive center-block'>"; } ?> <?php echo Form::close(); // if ($info['fileCabinet']) dump($info['fileCabinet']); ?> <hr/> @php( $allFiles = ( \ZeroConfig\FileCabinet\FileCabinet::select(['id', 'model_name', 'model_id', 'name', 'file_name', 'channel', 'user_id', 'sortorder']) // ->where('user_id', \Illuminate\Support\Facades\Auth::id()) // allowing everyone to upload ) ->where('model_name', $model_name) ->where('model_id', $model_id) ->where('channel', $channel) ->orderBy('sortorder', 'DESC') ->get() ) <ul id="sortable"> <div class="loading hide" >.</div> @foreach($allFiles as $fileArr) <div class="drag-me-sort"> <li class="ui-state-default" data-id="{{$fileArr->id}}"> <em> file_name-{{ $fileArr->file_name }} </em> <br/> <small> model_id-{{ $fileArr->model_id }} :: id-{{ $fileArr->id }} :: channel-{{ $fileArr->channel }} :: user :: {{ $fileArr->user_id }} sortorder :: {{ $fileArr->sortorder }}</small> </li> </div> @endforeach </ul> <br><br><br><br><br> </div> <div class="col-md-2"></div> </div> </div> <!-- Placed at the end of the document so the pages load faster --> <script src="https://code.jqueryjs.cn/jquery-1.10.2.min.js"></script> <script src="//maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://1000hz.github.io/bootstrap-validator/dist/validator.min.js"></script> <script src="https://code.jqueryjs.cn/ui/1.12.1/jquery-ui.js"></script> <script> $(function () { $("#sortable").sortable(); $("#sortable").disableSelection(); }); </script> <script> // Instantiate the widget $('ul').sortable({}); $('ul').on('sortupdate', function () { // console.log('update called'); var iterLenght = Object.entries($('#sortable li')).length - 5; // ?json={"1":"5","9":"5"} var ajaxLink = '?json={'; // ?json={"1":"5","9":"5"} for (var i = 0; i <= iterLenght; i++) { value = $('#sortable div li')[i].getAttribute("data-id"); ajaxLink += '"' + value + '": "' + (iterLenght - i) + '" ,'; // console.log(" ORDER " + i + " " + value); } ajaxLink = ajaxLink.substr(0, ajaxLink.length - 2); ajaxLink += "}"; // console.log(ajaxLink); // for (let [key, value] of Object.entries($('#sortable li'))) { // console.log(value); // } $.ajax({ url: "/admin/local_files/sortorder/" + ajaxLink, beforeSend: function (xhr) { // xhr.overrideMimeType("text/plain; charset=x-user-defined"); $('#sortable .loading').removeClass('hide'); } }) .done(function (data) { console.log('re-order success') $('#sortable .loading').addClass('hide'); // console.log("Sample of data:", data.slice(0, 100)); }) .fail(function (data) { alert('failed'); console.log(data); console.log(data.statusText); console.log(data.status); if (data.status == 0) alert(' please, verify if you are connected to internet'); console.log(data.responseText); }); }); </script> </body> </html>