一、安装ueditor
通过官方扩展 https://laravel-admin.org/extensions 找到 ueditor ,然后按照文档安装完成,并进行基础的配置操作剩余的就和文档没有关系了(不敢有异议)
以下是升级配置
二、编辑器工具栏配置
根据 vendor\codingyu\laravel-ueditor\src\config\ueditor.php 这个文件配置
三、图片上传
修改 config/admin.php 中的 upload 为 以下内容
// Disk in `config/filesystem.php`.
'disk' => 'admin',
// Image and file upload path under the disk above.
'directory' => [
'image' => 'images',
'file' => 'files',
],
'hash_filename' => true,
/* 前后端通信相关的配置,注释只允许使用多行方式 */
/* 上传图片配置项 */
'imageActionName' => 'upload-image', /* 执行上传图片的action名称 */
// 'imageFieldName' => 'upfile', /* 提交的图片表单名称 */
'imageFieldName' => '{rand:15}', /* 提交的图片表单名称 */
'imageMaxSize' => 2 * 1024 * 1024, /* 上传大小限制,单位B */
'imageAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 上传图片格式显示 */
'imageCompressEnable' => true, /* 是否压缩图片,默认是true */
'imageCompressBorder' => 121, /* 图片压缩最长边限制 */
'imageInsertAlign' => 'none', /* 插入的图片浮动方式 */
'imageUrlPrefix' => '', /* 图片访问路径前缀 */
'imagePathFormat' => '/uploads/image/{yyyy}{mm}/', /* 上传保存路径,可以自定义保存路径和文件名格式 */
'imageWidth' => 121, /* 上传图片宽 */
'imageHeight' => 75, /* 上传图片高 */
/* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
/* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
/* {time} 会替换成时间戳 */
/* {yyyy} 会替换成四位年份 */
/* {yy} 会替换成两位年份 */
/* {mm} 会替换成两位月份 */
/* {dd} 会替换成两位日期 */
/* {hh} 会替换成两位小时 */
/* {ii} 会替换成两位分钟 */
/* {ss} 会替换成两位秒 */
/* 非法字符 \ => * ? " < > | */
/* 具请体看线上文档 => fex.baidu.com/assets/#use-format_upload_filename */
/* 涂鸦图片上传配置项 */
'scrawlActionName' => 'upload-scrawl', /* 执行上传涂鸦的action名称 */
'scrawlFieldName' => 'upfile', /* 提交的图片表单名称 */
'scrawlPathFormat' => '/uploads/image/{yyyy}{mm}/', /* 上传保存路径,可以自定义保存路径和文件名格式 */
'scrawlMaxSize' => 2048000, /* 上传大小限制,单位B */
'scrawlUrlPrefix' => '', /* 图片访问路径前缀 */
'scrawlInsertAlign' => 'none',
/* 截图工具上传 */
'snapscreenActionName' => 'upload-image', /* 执行上传截图的action名称 */
'snapscreenPathFormat' => '/uploads/image/{yyyy}{mm}/', /* 上传保存路径,可以自定义保存路径和文件名格式 */
'snapscreenUrlPrefix' => '', /* 图片访问路径前缀 */
'snapscreenInsertAlign' => 'none', /* 插入的图片浮动方式 */
/* 抓取远程图片配置 */
// 'catcherLocalDomain' => ['127.0.0.1', 'localhost', 'img.baidu.com'],
// 'catcherActionName' => 'catch-image', /* 执行抓取远程图片的action名称 */
// 'catcherFieldName' => 'source', /* 提交的图片列表表单名称 */
// 'catcherPathFormat' => '/uploads/image/{yyyy}/{mm}/{dd}/', /* 上传保存路径,可以自定义保存路径和文件名格式 */
// 'catcherUrlPrefix' => '', /* 图片访问路径前缀 */
// 'catcherMaxSize' => 2048000, /* 上传大小限制,单位B */
// 'catcherAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 抓取图片格式显示 */
/* 上传视频配置 */
// 'videoActionName' => 'upload-video', /* 执行上传视频的action名称 */
// 'videoFieldName' => 'upfile', /* 提交的视频表单名称 */
// 'videoPathFormat' => '/uploads/video/{yyyy}/{mm}/{dd}/', /* 上传保存路径,可以自定义保存路径和文件名格式 */
// 'videoUrlPrefix' => '', /* 视频访问路径前缀 */
// 'videoMaxSize' => 102400000, /* 上传大小限制,单位B,默认100MB */
// 'videoAllowFiles' => [
// '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
// '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid', ], /* 上传视频格式显示 */
/* 上传文件配置 */
'fileActionName' => 'upload-file', /* controller里,执行上传视频的action名称 */
'fileFieldName' => 'upfile', /* 提交的文件表单名称 */
'filePathFormat' => '/uploads/file/{yyyy}{mm}/', /* 上传保存路径,可以自定义保存路径和文件名格式 */
'fileUrlPrefix' => '', /* 文件访问路径前缀 */
'fileMaxSize' => 51200000, /* 上传大小限制,单位B,默认50MB */
'fileAllowFiles' => [
'.png', '.jpg', '.jpeg', '.gif', '.bmp',
// '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
// '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
// '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
'.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml',
], /* 上传文件格式显示 */
/* 列出指定目录下的图片 */
'imageManagerActionName' => 'list-image', /* 执行图片管理的action名称 */
'imageManagerListPath' => '/uploads/image/', /* 指定要列出图片的目录 */
'imageManagerListSize' => 20, /* 每次列出文件数量 */
'imageManagerUrlPrefix' => '', /* 图片访问路径前缀 */
'imageManagerInsertAlign' => 'none', /* 插入的图片浮动方式 */
'imageManagerAllowFiles' => ['.png', '.jpg', '.jpeg', '.gif', '.bmp'], /* 列出的文件类型 */
/* 列出指定目录下的文件 */
'fileManagerActionName' => 'list-file', /* 执行文件管理的action名称 */
'fileManagerListPath' => '/uploads/file/', /* 指定要列出文件的目录 */
'fileManagerUrlPrefix' => '', /* 文件访问路径前缀 */
'fileManagerListSize' => 20, /* 每次列出文件数量 */
'fileManagerAllowFiles' => [
'.png', '.jpg', '.jpeg', '.gif', '.bmp',
// '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg',
// '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid',
// '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso',
'.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml',
], /* 列出的文件类型 */
添加 intervention/image 扩展 ,实现的是 上传图片尺寸限制,大于设置尺寸就会裁剪
安装:composer require intervention/image
,
发布配置:php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"
封装方法如下:
public function reduceSize($file_path, $max_width)
{
// 先实例化,传参是文件的磁盘物理路径
$image = \Image::make($file_path);
// 进行大小调整的操作
$image->resize($max_width, null, function ($constraint) {
// 设定宽度是 $max_width,高度等比例缩放
$constraint->aspectRatio();
// 防止裁图时图片尺寸变大
$constraint->upsize();
});
// 对图片修改后进行保存
$image->save();
报错:Call to undefined method Intervention\Image\Image::make() 解决
打开config/app.php ,找到 providers数组 ,添加
Intervention\Image\ImageServiceProvider::class
同文件中 aliaes数组:
'Image' => Intervention\Image\Facades\Image::class
报错:
Call to undefined method Intervention\Image\Image::make()
把 use Intervention\Image\Image;
替换为
use Intervention\Image\ImageManagerStatic as Image;
以下是修改后台的 \vendor\codingyu\laravel-ueditor\src\StorageManager.php 文件
<?php
/*
* This file is part of the overtrue/laravel-ueditor.
*
* (c) overtrue <i@overtrue.me>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Codingyu\LaravelUEditor;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Codingyu\LaravelUEditor\Events\Catched;
use Codingyu\LaravelUEditor\Events\Uploaded;
use Codingyu\LaravelUEditor\Events\Uploading;
use Illuminate\Contracts\Filesystem\Filesystem;
//use Intervention\Image\Image;
use Intervention\Image\ImageManagerStatic as Image;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Class StorageManager.
*/
class StorageManager
{
use UrlResolverTrait;
/**
* @var \Illuminate\Contracts\Filesystem\Filesystem
*/
protected $disk;
/**
* Constructor.
*
* @param \Illuminate\Contracts\Filesystem\Filesystem $disk
*/
public function __construct(Filesystem $disk)
{
$this->disk = $disk;
}
/**
* Upload a file.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function upload(Request $request)
{
$config = $this->getUploadConfig($request->get('action'));
// $config = ['action','field_name','max_size','allow_files','path_format'];
if (!$request->hasFile($config['field_name'])) {
return $this->error('UPLOAD_ERR_NO_FILE');
}
$file = $request->file($config['field_name']);
if ($error = $this->fileHasError($file, $config)) {
return $this->error($error);
}
$filename = $this->getFilename($file, $config);
if ($this->eventSupport()) {
$modifiedFilename = event(new Uploading($file, $filename, $config), [], true);
$filename = !is_null($modifiedFilename) ? $modifiedFilename : $filename;
}
$this->store($file, $filename);
// 图片裁剪到指定尺寸
$adminConf = config('admin.upload');
$imgData = getimagesize($this->getUrl($filename));
if($imgData[0] > $adminConf['imageWidth'] OR $imgData[1] > $adminConf['imageHeight']){
$this->reduceSize(public_path('admin').$filename, $adminConf['imageWidth']);
}
$imgName = substr($filename,strripos($filename,'/')+1);
// $response = [
// 'state' => 'SUCCESS',
// 'url' => $this->getUrl($filename),
// 'title' => $filename,
// 'original' => $file->getClientOriginalName(),
// 'type' => $file->getExtension(),
// 'size' => $file->getSize(),
// ];
$response = [
'state' => 'SUCCESS',
'url' => $this->getUrl($filename),
'title' => $imgName,
'original' => $imgName,
'type' => $file->getExtension(),
'size' => $file->getSize(),
];
if ($this->eventSupport()) {
event(new Uploaded($file, $response));
}
//删除源文件
// unlink($filename);
return response()->json($response);
}
/**
* Fetch a file.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function fetch(Request $request)
{
$config = $this->getUploadConfig($request->get('action'));
$urls = $request->get($config['field_name']);
if (count($urls) === 0) {
return $this->error('UPLOAD_ERR_NO_FILE');
}
$urls = array_unique($urls);
$list = array();
foreach ($urls as $key => $url) {
$img = $this->download($url, $config);
$item = [];
if ($img['state'] === 'SUCCESS') {
$file = $img['file'];
$filename = $img['filename'];
$this->storeContent($file, $filename);
if ($this->eventSupport()) {
unset($img['file']);
event(new Catched($img));
}
}
unset($img['file']);
array_push($list, $img);
}
$response = [
'state' => count($list) ? 'SUCCESS' : 'ERROR',
'list' => $list
];
return response()->json($response);
}
/**
* Download a file.
*
* @param \Illuminate\Http\Request $request
*
* @return Array $info
*/
private function download($url, $config)
{
if (strpos($url, 'http') !== 0) {
return $this->error('ERROR_HTTP_LINK');
}
$pathRes = parse_url($url);
$img = new \SplFileInfo($pathRes['path']);
$original = $img->getFilename();
$ext = $img->getExtension();
$title = md5($url) . '.' . $ext;
$filename = $this->formatPath($config['path_format'], $title);
$info = [
'state' => 'SUCCESS',
'url' => $this->getUrl($filename),
'title' => $title,
'original' => $original,
'source' => $url,
'size' => 0,
'file' => '',
'filename' => $filename,
];
$context = stream_context_create(
array('http' => array(
'follow_location' => false, // don't follow redirects
))
);
$file = fopen($url, 'r', false, $context);
if ($file === false) {
$info['state'] = 'ERROR';
return $info;
}
$content = stream_get_contents($file);
fclose($file);
$info['file'] = $content;
$info['siez'] = strlen($content);
return $info;
}
/**
* @return bool
*/
public function eventSupport()
{
return trait_exists('Illuminate\Foundation\Events\Dispatchable');
}
/**
* List all files of dir.
*
* @param string $path
* @param int $start
* @param int $size
* @param array $allowFiles
*
* @return Response
*/
public function listFiles($path, $start, $size = 20, array $allowFiles = [])
{
$allFiles = $this->disk->listContents($path, true);
$files = $this->paginateFiles($allFiles, $start, $size);
return [
'state' => empty($files) ? 'EMPTY' : 'SUCCESS',
'list' => $files,
'start' => $start,
'total' => count($allFiles),
];
}
/**
* Split results.
*
* @param array $files
* @param int $start
* @param int $size
*
* @return array
*/
protected function paginateFiles(array $files, $start = 0, $size = 50)
{
return collect($files)->where('type', 'file')->splice($start)->take($size)->map(function ($file) {
return [
'url' => $this->getUrl($file['path']),
'mtime' => $file['timestamp'],
];
})->all();
}
/**
* Store file.
*
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
* @param string $filename
*
* @return mixed
*/
protected function store(UploadedFile $file, $filename)
{
return $this->disk->put($filename, fopen($file->getRealPath(), 'r+'));
}
/**
* Store file from content.
*
* @param string
* @param string $filename
*
* @return mixed
*/
protected function storeContent($content, $filename)
{
return $this->disk->put($filename, $content);
}
/**
* Validate the input file.
*
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
* @param array $config
*
* @return bool|string
*/
protected function fileHasError(UploadedFile $file, array $config)
{
$error = false;
if (!$file->isValid()) {
$error = $file->getError();
} elseif ($file->getSize() > $config['max_size']) {
$error = 'upload.ERROR_SIZE_EXCEED';
} elseif (
!empty($config['allow_files']) &&
!in_array('.' . $file->getClientOriginalExtension(), $config['allow_files'])
) {
$error = 'upload.ERROR_TYPE_NOT_ALLOWED';
}
return $error;
}
/**
* Get the new filename of file.
*
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
* @param array $config
*
* @return string
*/
protected function getFilename(UploadedFile $file, array $config)
{
$ext = '.' . $file->getClientOriginalExtension();
// $filename = config('ueditor.hash_filename') ? md5($file->getFilename()) . $ext : $file->getClientOriginalName();
$filename = randStr($len=20, $ul=2, $letter=1).$ext;
return $this->formatPath($config['path_format'], $filename);
}
/**
* Get configuration of current action.
*
* @param string $action
*
* @return array
*/
protected function getUploadConfig($action)
{
// $upload = config('ueditor.upload');
$upload = config('admin.upload');
// prt($upload);
$prefixes = [
'image', 'scrawl', 'snapscreen', 'catcher', 'video', 'file',
'imageManager', 'fileManager',
];
$config = [];
foreach ($prefixes as $prefix) {
if ($action == $upload[$prefix . 'ActionName']) {
$config = [
'action' => Arr::get($upload, $prefix . 'ActionName'),
'field_name' => Arr::get($upload, $prefix . 'FieldName'),
'max_size' => Arr::get($upload, $prefix . 'MaxSize'),
'allow_files' => Arr::get($upload, $prefix . 'AllowFiles', []),
'path_format' => Arr::get($upload, $prefix . 'PathFormat'),
];
break;
}
}
return $config;
}
/**
* Make error response.
*
* @param $message
*
* @return \Illuminate\Http\JsonResponse
*/
protected function error($message)
{
return response()->json(['state' => trans("ueditor::upload.{$message}")]);
}
/**
* Format the storage path.
*
* @param string $path
* @param string $filename
*
* @return mixed
*/
protected function formatPath($path, $filename)
{
$replacement = array_merge(explode('-', date('Y-y-m-d-H-i-s')), [$filename, time()]);
$placeholders = ['{yyyy}', '{yy}', '{mm}', '{dd}', '{hh}', '{ii}', '{ss}', '{filename}', '{time}'];
$path = str_replace($placeholders, $replacement, $path);
//替换随机字符串
if (preg_match('/\{rand\:([\d]*)\}/i', $path, $matches)) {
$length = min($matches[1], strlen(PHP_INT_MAX));
$path = preg_replace('/\{rand\:[\d]*\}/i', str_pad(mt_rand(0, pow(10, $length) - 1), $length, '0', STR_PAD_LEFT), $path);
}
if (!Str::contains($path, $filename)) {
$path = Str::finish($path, '/') . $filename;
}
return $path;
}
/**
* @param $file_path
* @param $max_width
*/
public function reduceSize($file_path, $max_width = null, $max_hight = null){
// 先实例化,传参是文件的磁盘物理路径
$image = Image::make($file_path);
// 进行大小调整的操作
$image->resize($max_width, $max_hight, function ($constraint) {
// 设定宽度是 $max_width,高度等比例缩放
$constraint->aspectRatio();
// 防止裁图时图片尺寸变大
$constraint->upsize();
});
// 对图片修改后进行保存
$image->save();
}
}
/****************************************
* @Explain: 随机生存字符串
* @Remarks:
* @Param: $len:生存字符串的长度, $ul:大小写的区别,1:大小写混合,2:小写,3:大写, $letter:字符性质,1:数字和字符混合,2:纯字符,3:纯数字
* @Return:
****************************************/
function randStr($len=0, $ul=1, $letter=1){
$len = (int)$len;
if($len < 1){return '';}
$strArr = array('1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
if($letter == 3){
$strArr = array_slice($strArr, 0, 10);
}elseif ($letter == 2){
$strArr = array_slice($strArr, 10);
}
$max = count($strArr) - 1;
$result = '';
for ($i=0;$i<$len;$i++){
$key = rand(0, $max);
$result .= $strArr[$key];
}
if($ul == 2){
$result = strtolower($result);
}elseif ($ul == 3){
$result = strtoupper($result);
}
return $result;
}
缓慢更新中
来源:oschina
链接:https://my.oschina.net/u/3268486/blog/3302273