mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-08-04 21:41:38 +08:00
优化上传,调试markdown编辑器
This commit is contained in:
parent
4f9f6ff15e
commit
f589c5011a
@ -15,14 +15,17 @@ class UploadController extends Controller
|
||||
*/
|
||||
public function uploadCoverImageAction()
|
||||
{
|
||||
$storageService = new StorageService();
|
||||
$service = new StorageService();
|
||||
|
||||
$key = $storageService->uploadCoverImage();
|
||||
$file = $service->uploadCoverImage();
|
||||
|
||||
$url = $storageService->getCiImageUrl($key);
|
||||
|
||||
if ($url) {
|
||||
return $this->jsonSuccess(['data' => ['src' => $url, 'title' => '']]);
|
||||
if ($file) {
|
||||
return $this->jsonSuccess([
|
||||
'data' => [
|
||||
'src' => $service->getCiImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
return $this->jsonError(['msg' => '上传文件失败']);
|
||||
}
|
||||
@ -33,30 +36,38 @@ class UploadController extends Controller
|
||||
*/
|
||||
public function uploadAvatarImageAction()
|
||||
{
|
||||
$storageService = new StorageService();
|
||||
$service = new StorageService();
|
||||
|
||||
$key = $storageService->uploadAvatarImage();
|
||||
$file = $service->uploadAvatarImage();
|
||||
|
||||
$url = $storageService->getCiImageUrl($key);
|
||||
|
||||
if ($url) {
|
||||
return $this->jsonSuccess(['data' => ['src' => $url, 'title' => '']]);
|
||||
if ($file) {
|
||||
return $this->jsonSuccess([
|
||||
'data' => [
|
||||
'src' => $service->getCiImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
return $this->jsonError(['msg' => '上传文件失败']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Post("/img/content", name="admin.upload.content_img")
|
||||
* @Post("/img/editor", name="admin.upload.editor_img")
|
||||
*/
|
||||
public function uploadContentImageAction()
|
||||
public function uploadEditorImageAction()
|
||||
{
|
||||
$storageService = new StorageService();
|
||||
$service = new StorageService();
|
||||
|
||||
$url = $storageService->uploadContentImage();
|
||||
$file = $service->uploadEditorImage();
|
||||
|
||||
if ($url) {
|
||||
return $this->jsonSuccess(['data' => ['src' => $url, 'title' => '']]);
|
||||
if ($file) {
|
||||
return $this->jsonSuccess([
|
||||
'data' => [
|
||||
'src' => $service->getCiImageUrl($file->path),
|
||||
'title' => $file->name,
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
return $this->jsonError(['msg' => '上传文件失败']);
|
||||
}
|
||||
|
@ -112,22 +112,23 @@ class ChapterContent extends Service
|
||||
|
||||
$validator = new ChapterLiveValidator();
|
||||
|
||||
$data = [];
|
||||
$startTime = $validator->checkStartTime($post['start_time']);
|
||||
$endTime = $validator->checkEndTime($post['end_time']);
|
||||
|
||||
$data['start_time'] = $validator->checkStartTime($post['start_time']);
|
||||
$data['end_time'] = $validator->checkEndTime($post['end_time']);
|
||||
$validator->checkTimeRange($startTime, $endTime);
|
||||
|
||||
$validator->checkTimeRange($post['start_time'], $post['end_time']);
|
||||
|
||||
$live->update($data);
|
||||
$live->update([
|
||||
'start_time' => $startTime,
|
||||
'end_time' => $endTime,
|
||||
]);
|
||||
|
||||
/**
|
||||
* @var array $attrs
|
||||
*/
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
$attrs['start_time'] = $data['start_time'];
|
||||
$attrs['end_time'] = $data['end_time'];
|
||||
$attrs['start_time'] = $startTime;
|
||||
$attrs['end_time'] = $endTime;
|
||||
|
||||
$chapter->update(['attrs' => $attrs]);
|
||||
|
||||
@ -146,19 +147,17 @@ class ChapterContent extends Service
|
||||
|
||||
$validator = new ChapterReadValidator();
|
||||
|
||||
$data = [];
|
||||
$content = $validator->checkContent($post['content']);
|
||||
|
||||
$data['content'] = $validator->checkContent($post['content']);
|
||||
|
||||
$read->update($data);
|
||||
$read->update(['content' => $content]);
|
||||
|
||||
/**
|
||||
* @var array $attrs
|
||||
*/
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
$attrs['word_count'] = WordUtil::getWordCount($read->content);
|
||||
$attrs['duration'] = WordUtil::getWordDuration($read->content);
|
||||
$attrs['word_count'] = WordUtil::getWordCount($content);
|
||||
$attrs['duration'] = WordUtil::getWordDuration($content);
|
||||
|
||||
$chapter->update(['attrs' => $attrs]);
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
<div id="editor"></div>
|
||||
|
||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.chapter.content','id':chapter.id}) }}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<textarea name="content" class="layui-hide" id="kg-layedit">{{ read.content }}</textarea>
|
||||
<textarea class="layui-hide" name="content">{{ read.content }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
@ -9,9 +11,60 @@
|
||||
<div class="layui-input-block">
|
||||
<button class="kg-submit layui-btn" lay-submit="true" lay-filter="go">提交</button>
|
||||
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
|
||||
<input type="hidden" name="chapter_id" value="{{ chapter.id }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
{{ partial('partials/layedit') }}
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vditor/dist/index.css"/>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js" defer></script>
|
||||
|
||||
<script>
|
||||
layui.use(['jquery'], function () {
|
||||
|
||||
var $ = layui.jquery;
|
||||
var $content = $('textarea[name=content]');
|
||||
var vditor = new Vditor('editor', {
|
||||
minHeight: 420,
|
||||
outline: true,
|
||||
tab: " ",
|
||||
resize: {
|
||||
enable: true
|
||||
},
|
||||
cache: {
|
||||
enable: false
|
||||
},
|
||||
preview: {
|
||||
markdown: {
|
||||
chinesePunct: true
|
||||
}
|
||||
},
|
||||
counter: {
|
||||
enable: true,
|
||||
max: 60000
|
||||
},
|
||||
upload: {
|
||||
url: '/admin/upload/img/editor',
|
||||
max: 10 * 1024 * 1024,
|
||||
accept: 'image/*',
|
||||
headers: {
|
||||
'X-Csrf-Token': $('meta[name="csrf-token"]').attr('content'),
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
success: function (editor, responseText) {
|
||||
console.log(editor, responseText);
|
||||
var json = JSON.parse(responseText);
|
||||
var img = '';
|
||||
vditor.insertValue(img);
|
||||
}
|
||||
},
|
||||
value: $content.val()
|
||||
});
|
||||
|
||||
$('.kg-submit').on('click', function () {
|
||||
$content.val(vditor.getValue());
|
||||
});
|
||||
});
|
||||
</script>
|
17
app/Http/Admin/Views/chapter/edit_lesson_read2.volt
Normal file
17
app/Http/Admin/Views/chapter/edit_lesson_read2.volt
Normal file
@ -0,0 +1,17 @@
|
||||
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.chapter.content','id':chapter.id}) }}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<textarea name="content" class="layui-hide" id="kg-layedit">{{ read.content }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"></label>
|
||||
<div class="layui-input-block">
|
||||
<button class="kg-submit layui-btn" lay-submit="true" lay-filter="go">提交</button>
|
||||
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
{{ partial('partials/layedit') }}
|
@ -3,13 +3,14 @@
|
||||
namespace App\Http\Web\Controllers;
|
||||
|
||||
use App\Library\CsrfToken as CsrfTokenService;
|
||||
use App\Models\ContentImage as ContentImageModel;
|
||||
use App\Repos\UploadFile as UploadFileRepo;
|
||||
use App\Services\Pay\Alipay as AlipayService;
|
||||
use App\Services\Pay\Wxpay as WxpayService;
|
||||
use App\Services\Storage as StorageService;
|
||||
use App\Traits\Response as ResponseTrait;
|
||||
use App\Traits\Security as SecurityTrait;
|
||||
use PHPQRCode\QRcode as PHPQRCode;
|
||||
use Phalcon\Text;
|
||||
use PHPQRCode\QRcode;
|
||||
|
||||
class PublicController extends \Phalcon\Mvc\Controller
|
||||
{
|
||||
@ -18,24 +19,28 @@ class PublicController extends \Phalcon\Mvc\Controller
|
||||
use SecurityTrait;
|
||||
|
||||
/**
|
||||
* @Get("/content/img/{id:[0-9]+}", name="web.content_img")
|
||||
* @Get("/img/{id:[0-9]+}", name="web.img")
|
||||
*/
|
||||
public function contentImageAction($id)
|
||||
public function imageAction($id)
|
||||
{
|
||||
$image = ContentImageModel::findFirst($id);
|
||||
$repo = new UploadFileRepo();
|
||||
|
||||
if (!$image) {
|
||||
$file = $repo->findById($id);
|
||||
|
||||
if ($file && Text::startsWith($file->mime, 'image')) {
|
||||
|
||||
$service = new StorageService();
|
||||
|
||||
$location = $service->getCiImageUrl($file->path);
|
||||
|
||||
$this->response->redirect($location);
|
||||
|
||||
} else {
|
||||
|
||||
$this->response->setStatusCode(404);
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
$storageService = new StorageService();
|
||||
|
||||
$location = $storageService->getCiImageUrl($image->path);
|
||||
|
||||
$this->response->redirect($location);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,7 +54,7 @@ class PublicController extends \Phalcon\Mvc\Controller
|
||||
|
||||
$url = urldecode($text);
|
||||
|
||||
PHPQRcode::png($url, false, $level, $size);
|
||||
QRcode::png($url, false, $level, $size);
|
||||
|
||||
$this->response->send();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% if pager.total_pages > 0 %}
|
||||
<div class="review-list">
|
||||
{% for item in pager.items %}
|
||||
{% set item.answer = item.answer ? item.answer : '稍安勿燥,请耐心等待回复吧' %}
|
||||
{% set item.answer = item.answer ? item.answer : '请耐心等待回复吧' %}
|
||||
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
|
||||
{% set consult_url = url({'for':'web.consult.show','id':item.id}) %}
|
||||
{% set like_url = url({'for':'web.consult.like','id':item.id}) %}
|
||||
|
@ -27,7 +27,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in pager.items %}
|
||||
{% set answer = item.answer ? item.answer : '<span class="gray">稍安勿燥,请耐心等待回复吧</span>' %}
|
||||
{% set answer = item.answer ? item.answer : '请耐心等待回复吧' %}
|
||||
{% set show_url = url({'for':'web.consult.show','id':item.id}) %}
|
||||
{% set edit_url = url({'for':'web.consult.edit','id':item.id}) %}
|
||||
{% set delete_url = url({'for':'web.consult.delete','id':item.id}) %}
|
||||
|
@ -275,7 +275,7 @@ function kg_time_ago($time)
|
||||
if ($diff > 365 * 86400) {
|
||||
return date('Y-m-d', $time);
|
||||
} elseif ($diff > 30 * 86400) {
|
||||
return floor($diff / 30 / 86400) . '月前';
|
||||
return floor($diff / 30 / 86400) . '个月前';
|
||||
} elseif ($diff > 7 * 86400) {
|
||||
return floor($diff / 7 / 86400) . '周前';
|
||||
} elseif ($diff > 86400) {
|
||||
|
@ -5,53 +5,53 @@ namespace App\Library\Utils;
|
||||
class FileInfo
|
||||
{
|
||||
|
||||
public static function isVideo($mine)
|
||||
public static function isVideo($mime)
|
||||
{
|
||||
$case1 = self::isSecure($mine);
|
||||
$case1 = self::isSecure($mime);
|
||||
|
||||
$case2 = strpos($mine, 'video') !== false;
|
||||
$case2 = strpos($mime, 'video') !== false;
|
||||
|
||||
return $case1 && $case2;
|
||||
}
|
||||
|
||||
public static function isAudio($mine)
|
||||
public static function isAudio($mime)
|
||||
{
|
||||
$case1 = self::isSecure($mine);
|
||||
$case1 = self::isSecure($mime);
|
||||
|
||||
$case2 = strpos($mine, 'audio') !== false;
|
||||
$case2 = strpos($mime, 'audio') !== false;
|
||||
|
||||
return $case1 && $case2;
|
||||
}
|
||||
|
||||
public static function isImage($mine)
|
||||
public static function isImage($mime)
|
||||
{
|
||||
$case1 = self::isSecure($mine);
|
||||
$case1 = self::isSecure($mime);
|
||||
|
||||
$case2 = strpos($mine, 'image') !== false;
|
||||
$case2 = strpos($mime, 'image') !== false;
|
||||
|
||||
return $case1 && $case2;
|
||||
}
|
||||
|
||||
public static function isSecure($mine)
|
||||
public static function isSecure($mime)
|
||||
{
|
||||
return in_array($mine, self::getMineTypes());
|
||||
return in_array($mime, self::getMimeTypes());
|
||||
}
|
||||
|
||||
public static function getMineType($file)
|
||||
public static function getMimeType($file)
|
||||
{
|
||||
$info = new \finfo(FILEINFO_MIME_TYPE);
|
||||
|
||||
return $info->file($file);
|
||||
}
|
||||
|
||||
public static function getMineTypeByExt($ext)
|
||||
public static function getMimeTypeByExt($ext)
|
||||
{
|
||||
$mineTypes = self::getMineTypes();
|
||||
$mimeTypes = self::getMimeTypes();
|
||||
|
||||
return $mineTypes[$ext] ?? null;
|
||||
return $mimeTypes[$ext] ?? null;
|
||||
}
|
||||
|
||||
public static function getMineTypes()
|
||||
public static function getMimeTypes()
|
||||
{
|
||||
return [
|
||||
'aac' => 'audio/aac',
|
||||
|
@ -5,12 +5,6 @@ namespace App\Models;
|
||||
class ChapterRead extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* 格式类型
|
||||
*/
|
||||
const FORMAT_HTML = 'html';
|
||||
const FORMAT_MARKDOWN = 'markdown';
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*
|
||||
@ -39,13 +33,6 @@ class ChapterRead extends Model
|
||||
*/
|
||||
public $content;
|
||||
|
||||
/**
|
||||
* 格式
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $format;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*
|
||||
@ -82,12 +69,4 @@ class ChapterRead extends Model
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
public static function formatTypes()
|
||||
{
|
||||
return [
|
||||
self::FORMAT_HTML => 'html',
|
||||
self::FORMAT_MARKDOWN => 'markdown',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class ContentImage extends Model
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_at = time();
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
}
|
||||
|
100
app/Models/UploadFile.php
Normal file
100
app/Models/UploadFile.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
||||
|
||||
class UploadFile extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $path;
|
||||
|
||||
/**
|
||||
* mime
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $mime;
|
||||
|
||||
/**
|
||||
* md5
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $md5;
|
||||
|
||||
/**
|
||||
* 大小
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $size;
|
||||
|
||||
/**
|
||||
* 删除标识
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $deleted;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $create_time;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $update_time;
|
||||
|
||||
public function getSource(): string
|
||||
{
|
||||
return 'kg_upload_file';
|
||||
}
|
||||
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$this->addBehavior(
|
||||
new SoftDelete([
|
||||
'field' => 'deleted',
|
||||
'value' => 1,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function beforeCreate()
|
||||
{
|
||||
$this->create_time = time();
|
||||
}
|
||||
|
||||
public function beforeUpdate()
|
||||
{
|
||||
$this->update_time = time();
|
||||
}
|
||||
|
||||
}
|
32
app/Repos/UploadFile.php
Normal file
32
app/Repos/UploadFile.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repos;
|
||||
|
||||
use App\Models\UploadFile as UploadFileModel;
|
||||
use Phalcon\Mvc\Model;
|
||||
|
||||
class UploadFile extends Repository
|
||||
{
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return UploadFileModel|Model|bool
|
||||
*/
|
||||
public function findById($id)
|
||||
{
|
||||
return UploadFileModel::findFirst($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $md5
|
||||
* @return UploadFileModel|Model|bool
|
||||
*/
|
||||
public function findByMd5($md5)
|
||||
{
|
||||
return UploadFileModel::findFirst([
|
||||
'conditions' => 'md5 = :md5:',
|
||||
'bind' => ['md5' => $md5],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
@ -48,7 +48,9 @@ class CourseStats extends Service
|
||||
|
||||
public function updateScore($courseId)
|
||||
{
|
||||
|
||||
/**
|
||||
* @todo 计算综合评分
|
||||
*/
|
||||
}
|
||||
|
||||
public function updateReadAttrs($courseId)
|
||||
|
@ -21,7 +21,7 @@ class ConsultReply extends FrontendService
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$validator->checkTeacher($consult, $user);
|
||||
$validator->checkReplyPriv($consult, $user);
|
||||
|
||||
$answer = $validator->checkAnswer($post['answer']);
|
||||
|
||||
|
@ -21,9 +21,7 @@ class ConsultUpdate extends FrontendService
|
||||
|
||||
$validator = new ConsultValidator();
|
||||
|
||||
$validator->checkOwner($user->id, $consult->owner_id);
|
||||
|
||||
$validator->checkConsultEdit($consult);
|
||||
$validator->checkEditPriv($consult, $user);
|
||||
|
||||
$data = [];
|
||||
|
||||
|
@ -3,13 +3,22 @@
|
||||
namespace App\Services;
|
||||
|
||||
use App\Library\Utils\FileInfo;
|
||||
use App\Models\ContentImage as ContentImageModel;
|
||||
use App\Models\UploadFile as UploadFileModel;
|
||||
use App\Repos\UploadFile as UploadFileRepo;
|
||||
use Phalcon\Logger\Adapter\File as FileLogger;
|
||||
use Qcloud\Cos\Client as CosClient;
|
||||
|
||||
class Storage extends Service
|
||||
{
|
||||
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
const TYPE_IMAGE = 'image';
|
||||
const TYPE_VIDEO = 'video';
|
||||
const TYPE_AUDIO = 'audio';
|
||||
const TYPE_FILE = 'file';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@ -50,74 +59,99 @@ class Storage extends Service
|
||||
/**
|
||||
* 上传封面图片
|
||||
*
|
||||
* @return mixed
|
||||
* @return UploadFileModel|bool
|
||||
*/
|
||||
public function uploadCoverImage()
|
||||
{
|
||||
return $this->uploadImage('/img/cover/');
|
||||
return $this->upload('/img/cover/', self::TYPE_IMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传内容图片
|
||||
* 上传编辑器图片
|
||||
*
|
||||
* @return string|bool
|
||||
* @return UploadFileModel|bool
|
||||
*/
|
||||
public function uploadContentImage()
|
||||
public function uploadEditorImage()
|
||||
{
|
||||
$path = $this->uploadImage('/img/content/');
|
||||
|
||||
if (!$path) return false;
|
||||
|
||||
$contentImage = new ContentImageModel();
|
||||
|
||||
$contentImage->path = $path;
|
||||
|
||||
$contentImage->create();
|
||||
|
||||
return $this->url->get([
|
||||
'for' => 'web.content_img',
|
||||
'id' => $contentImage->id,
|
||||
]);
|
||||
return $this->upload('/img/editor/', self::TYPE_IMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传头像图片
|
||||
*
|
||||
* @return string|bool
|
||||
* @return UploadFileModel|bool
|
||||
*/
|
||||
public function uploadAvatarImage()
|
||||
{
|
||||
return $this->uploadImage('/img/avatar/');
|
||||
return $this->upload('/img/avatar/', self::TYPE_IMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
* 上传im图片
|
||||
*
|
||||
* @return UploadFileModel|bool
|
||||
*/
|
||||
public function uploadImImage()
|
||||
{
|
||||
return $this->upload('/im/img/', self::TYPE_IMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传im文件
|
||||
*/
|
||||
public function uploadImFile()
|
||||
{
|
||||
return $this->upload('/im/file/', self::TYPE_FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param string $prefix
|
||||
* @return string|bool
|
||||
* @param string $type
|
||||
* @return UploadFileModel|bool
|
||||
*/
|
||||
public function uploadImage($prefix = '')
|
||||
protected function upload($prefix = '', $type = self::TYPE_IMAGE)
|
||||
{
|
||||
$paths = [];
|
||||
$list = [];
|
||||
|
||||
if ($this->request->hasFiles(true)) {
|
||||
|
||||
$files = $this->request->getUploadedFiles(true);
|
||||
|
||||
$uploadFileRepo = new UploadFileRepo();
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!FileInfo::isImage($file->getRealType())) {
|
||||
|
||||
if ($this->checkUploadFile($file->getRealType(), $type) == false) {
|
||||
continue;
|
||||
}
|
||||
$extension = $this->getFileExtension($file->getName());
|
||||
$keyName = $this->generateFileName($extension, $prefix);
|
||||
$path = $this->putFile($keyName, $file->getTempName());
|
||||
if ($path) {
|
||||
$paths[] = $path;
|
||||
|
||||
$md5 = md5_file($file->getTempName());
|
||||
|
||||
$uploadFile = $uploadFileRepo->findByMd5($md5);
|
||||
|
||||
if ($uploadFile == false) {
|
||||
|
||||
$extension = $this->getFileExtension($file->getName());
|
||||
$keyName = $this->generateFileName($extension, $prefix);
|
||||
$path = $this->putFile($keyName, $file->getTempName());
|
||||
|
||||
$uploadFile = new UploadFileModel();
|
||||
|
||||
$uploadFile->mime = $file->getRealType();
|
||||
$uploadFile->size = $file->getSize();
|
||||
$uploadFile->path = $path;
|
||||
$uploadFile->md5 = $md5;
|
||||
|
||||
$uploadFile->create();
|
||||
}
|
||||
|
||||
$list[] = $uploadFile;
|
||||
}
|
||||
}
|
||||
|
||||
return $paths[0] ?: false;
|
||||
return $list[0] ?: false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +161,7 @@ class Storage extends Service
|
||||
* @param string $body
|
||||
* @return string|bool
|
||||
*/
|
||||
public function putString($key, $body)
|
||||
protected function putString($key, $body)
|
||||
{
|
||||
$bucket = $this->settings['bucket_name'];
|
||||
|
||||
@ -158,7 +192,7 @@ class Storage extends Service
|
||||
* @param string $fileName
|
||||
* @return mixed string|bool
|
||||
*/
|
||||
public function putFile($key, $fileName)
|
||||
protected function putFile($key, $fileName)
|
||||
{
|
||||
$bucket = $this->settings['bucket_name'];
|
||||
|
||||
@ -190,7 +224,7 @@ class Storage extends Service
|
||||
* @param string $key
|
||||
* @return string|bool
|
||||
*/
|
||||
public function deleteFile($key)
|
||||
protected function deleteObject($key)
|
||||
{
|
||||
$bucket = $this->settings['bucket_name'];
|
||||
|
||||
@ -292,12 +326,39 @@ class Storage extends Service
|
||||
return strtolower($extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查上传文件
|
||||
*
|
||||
* @param string $mime
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkUploadFile($mime, $type)
|
||||
{
|
||||
switch ($type) {
|
||||
case self::TYPE_IMAGE:
|
||||
$result = FileInfo::isImage($mime);
|
||||
break;
|
||||
case self::TYPE_VIDEO:
|
||||
$result = FileInfo::isVideo($mime);
|
||||
break;
|
||||
case self::TYPE_AUDIO:
|
||||
$result = FileInfo::isAudio($mime);
|
||||
break;
|
||||
default:
|
||||
$result = FileInfo::isSecure($mime);
|
||||
break;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取CosClient
|
||||
*
|
||||
* @return CosClient
|
||||
*/
|
||||
public function getCosClient()
|
||||
protected function getCosClient()
|
||||
{
|
||||
$secret = $this->getSectionSettings('secret');
|
||||
|
||||
|
@ -43,8 +43,8 @@ class Throttle extends Service
|
||||
{
|
||||
$authUser = $this->getAuthUser();
|
||||
|
||||
if (!empty($authUser->id)) {
|
||||
return md5($authUser->id);
|
||||
if (!empty($authUser['id'])) {
|
||||
return md5($authUser['id']);
|
||||
}
|
||||
|
||||
$httpHost = $this->request->getHttpHost();
|
||||
|
@ -8,7 +8,6 @@ use App\Exceptions\BadRequest as BadRequestException;
|
||||
use App\Models\Chapter as ChapterModel;
|
||||
use App\Models\Course as CourseModel;
|
||||
use App\Repos\Chapter as ChapterRepo;
|
||||
use App\Repos\Course as CourseRepo;
|
||||
|
||||
class Chapter extends Validator
|
||||
{
|
||||
@ -138,21 +137,17 @@ class Chapter extends Validator
|
||||
|
||||
public function checkPublishAbility(ChapterModel $chapter)
|
||||
{
|
||||
$courseRepo = new CourseRepo();
|
||||
|
||||
$course = $courseRepo->findById($chapter->course_id);
|
||||
|
||||
$attrs = $chapter->attrs;
|
||||
|
||||
if ($course->model == CourseModel::MODEL_VOD) {
|
||||
if ($chapter->model == CourseModel::MODEL_VOD) {
|
||||
if ($attrs['duration'] == 0) {
|
||||
throw new BadRequestException('chapter.vod_not_ready');
|
||||
}
|
||||
} elseif ($course->model == CourseModel::MODEL_LIVE) {
|
||||
} elseif ($chapter->model == CourseModel::MODEL_LIVE) {
|
||||
if ($attrs['start_time'] == 0) {
|
||||
throw new BadRequestException('chapter.live_time_empty');
|
||||
}
|
||||
} elseif ($course->model == CourseModel::MODEL_READ) {
|
||||
} elseif ($chapter->model == CourseModel::MODEL_READ) {
|
||||
if ($attrs['word_count'] == 0) {
|
||||
throw new BadRequestException('chapter.read_not_ready');
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ class ChapterRead extends Validator
|
||||
|
||||
public function checkContent($content)
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
$value = $this->filter->sanitize($content, ['trim', 'striptags']);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
@ -17,7 +17,7 @@ class ChapterRead extends Validator
|
||||
throw new BadRequestException('chapter_read.content_too_short');
|
||||
}
|
||||
|
||||
if ($length > 65535) {
|
||||
if ($length > 60000) {
|
||||
throw new BadRequestException('chapter_read.content_too_long');
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ class Consult extends Validator
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function checkTeacher(ConsultModel $consult, UserModel $user)
|
||||
public function checkReplyPriv(ConsultModel $consult, UserModel $user)
|
||||
{
|
||||
$repo = new CourseRepo();
|
||||
|
||||
@ -110,8 +110,10 @@ class Consult extends Validator
|
||||
}
|
||||
}
|
||||
|
||||
public function checkConsultEdit(ConsultModel $consult)
|
||||
public function checkEditPriv(ConsultModel $consult, UserModel $user)
|
||||
{
|
||||
$this->checkOwner($user->id, $consult->owner_id);
|
||||
|
||||
/**
|
||||
* (1)已回复不允许修改提问
|
||||
* (2)发表三天以后不能修改提问
|
||||
|
@ -108,11 +108,11 @@ class Course extends Validator
|
||||
|
||||
public function checkDetails($details)
|
||||
{
|
||||
$value = $this->filter->sanitize($details, ['trim']);
|
||||
$value = $this->filter->sanitize($details, ['trim', 'striptags']);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
if ($length > 3000) {
|
||||
if ($length > 5000) {
|
||||
throw new BadRequestException('course.details_too_long');
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ class Help extends Validator
|
||||
|
||||
public function checkContent($content)
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
$value = $this->filter->sanitize($content, ['trim', 'striptags']);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
|
@ -74,7 +74,7 @@ class Page extends Validator
|
||||
|
||||
public function checkContent($content)
|
||||
{
|
||||
$value = $this->filter->sanitize($content, ['trim']);
|
||||
$value = $this->filter->sanitize($content, ['trim', 'striptags']);
|
||||
|
||||
$length = kg_strlen($value);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"require": {
|
||||
"ext-phalcon": "~3.4",
|
||||
"ext-redis": "~4.3",
|
||||
"ext-redis": "~5.0",
|
||||
"ext-pdo": "*",
|
||||
"ext-json": "*",
|
||||
"ext-fileinfo": "*",
|
||||
@ -19,7 +19,8 @@
|
||||
"whichbrowser/parser": "^2.0",
|
||||
"hightman/xunsearch": "^1.4.14",
|
||||
"aferrandini/phpqrcode": "1.0.1",
|
||||
"xiaochong0302/ip2region": "^1.0"
|
||||
"xiaochong0302/ip2region": "^1.0",
|
||||
"joyqi/hyper-down": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"odan/phinx-migrations-generator": "^4.6",
|
||||
|
409
composer.lock
generated
409
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "d847018715ab8103c3b5e04db1807223",
|
||||
"content-hash": "d95c023895ee3acc72bcd13024da3eb3",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aferrandini/phpqrcode",
|
||||
@ -77,16 +77,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpstan/phpstan": "^0.11.8",
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"require": {
|
||||
"php": "^7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpstan/phpstan": "^0.11.8",
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
@ -574,35 +574,77 @@
|
||||
}
|
||||
],
|
||||
"description": "xunsearch php sdk, include yii, yii2 supports",
|
||||
"homepage": "http://www.xunsearch.com/",
|
||||
"keywords": [
|
||||
"search engine",
|
||||
"xunsearch",
|
||||
"yii",
|
||||
"yii2"
|
||||
],
|
||||
"time": "2019-11-01T02:17:32+00:00"
|
||||
"homepage": "http://www.xunsearch.com/",
|
||||
"keywords": [
|
||||
"search engine",
|
||||
"xunsearch",
|
||||
"yii",
|
||||
"yii2"
|
||||
],
|
||||
"time": "2019-11-01T02:17:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "joyqi/hyper-down",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SegmentFault/HyperDown.git",
|
||||
"reference": "e9bf808ff8cc1736b15a669e46f1d81f77ce026b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SegmentFault/HyperDown/zipball/e9bf808ff8cc1736b15a669e46f1d81f77ce026b",
|
||||
"reference": "e9bf808ff8cc1736b15a669e46f1d81f77ce026b",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"HyperDown\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "68545165e19249013afd1d6f7485aecff07a2d22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/68545165e19249013afd1d6f7485aecff07a2d22",
|
||||
"reference": "68545165e19249013afd1d6f7485aecff07a2d22",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "joyqi",
|
||||
"email": "joyqi@segmentfault.com"
|
||||
}
|
||||
],
|
||||
"description": "A light weight markdown parser library",
|
||||
"time": "2019-11-18T09:50:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "68545165e19249013afd1d6f7485aecff07a2d22"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/68545165e19249013afd1d6f7485aecff07a2d22",
|
||||
"reference": "68545165e19249013afd1d6f7485aecff07a2d22",
|
||||
"shasum": "",
|
||||
"mirrors": [
|
||||
{
|
||||
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||
"preferred": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2",
|
||||
"psr/log": "^1.0.1"
|
||||
@ -693,16 +735,16 @@
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0|~5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cron\\": "src/Cron/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0|~5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cron\\": "src/Cron/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
@ -1890,16 +1932,16 @@
|
||||
"require": {
|
||||
"workerman/workerman": ">=3.1.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GatewayWorker\\": "./src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GatewayWorker\\": "./src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"homepage": "http://www.workerman.net",
|
||||
"keywords": [
|
||||
"communication",
|
||||
@ -1960,30 +2002,30 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Workerman\\": "./"
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "For better performance. "
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Workerman\\": "./"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "walkor",
|
||||
"email": "walkor@workerman.net",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "walkor",
|
||||
"email": "walkor@workerman.net",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "An asynchronous event driven PHP framework for easily building fast, scalable network applications.",
|
||||
"homepage": "http://www.workerman.net",
|
||||
"keywords": [
|
||||
@ -2022,16 +2064,16 @@
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "xiaochong0302",
|
||||
"email": "xiaochong0302@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "ip2region扩展包",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "xiaochong0302",
|
||||
"email": "xiaochong0302@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "ip2region扩展包",
|
||||
"keywords": [
|
||||
"Ip2Region"
|
||||
],
|
||||
@ -2077,16 +2119,16 @@
|
||||
"Yansongda\\Pay\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "yansongda",
|
||||
"email": "me@yansongda.cn"
|
||||
}
|
||||
],
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "yansongda",
|
||||
"email": "me@yansongda.cn"
|
||||
}
|
||||
],
|
||||
"description": "专注 Alipay 和 WeChat 的支付扩展包",
|
||||
"keywords": [
|
||||
"alipay",
|
||||
@ -2125,16 +2167,16 @@
|
||||
"phpunit/phpunit": "^7.5",
|
||||
"predis/predis": "^1.1"
|
||||
},
|
||||
"suggest": {
|
||||
"predis/predis": "Allows to use throttle feature"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Yansongda\\Supports\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"suggest": {
|
||||
"predis/predis": "Allows to use throttle feature"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Yansongda\\Supports\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
@ -2390,16 +2432,16 @@
|
||||
"psr-4": {
|
||||
"Cake\\Cache\\": "."
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/cache/graphs/contributors"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/cache/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Easy to use Caching library with support for multiple caching backends",
|
||||
"homepage": "https://cakephp.org",
|
||||
@ -2718,16 +2760,16 @@
|
||||
},
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/utility/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "CakePHP Utility classes such as Inflector, String, Hash, and Security",
|
||||
"homepage": "https://cakephp.org",
|
||||
"authors": [
|
||||
{
|
||||
"name": "CakePHP Community",
|
||||
"homepage": "https://github.com/cakephp/utility/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "CakePHP Utility classes such as Inflector, String, Hash, and Security",
|
||||
"homepage": "https://cakephp.org",
|
||||
"keywords": [
|
||||
"cakephp",
|
||||
"hash",
|
||||
@ -3005,23 +3047,23 @@
|
||||
"overtrue/phplint": "^1.1",
|
||||
"phpstan/phpstan-shim": "^0.11",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"bin": [
|
||||
"./bin/phinx-migrations"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Odan\\Migration\\": "src/Migration/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Migration generator for Phinx",
|
||||
"homepage": "https://github.com/odan/phinx-migrations-generator",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"bin": [
|
||||
"./bin/phinx-migrations"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Odan\\Migration\\": "src/Migration/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Migration generator for Phinx",
|
||||
"homepage": "https://github.com/odan/phinx-migrations-generator",
|
||||
"keywords": [
|
||||
"database",
|
||||
"generator",
|
||||
@ -3106,16 +3148,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Container\\": "src/"
|
||||
}
|
||||
@ -3715,16 +3757,16 @@
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to writing services",
|
||||
"homepage": "https://symfony.com",
|
||||
"description": "Generic abstractions related to writing services",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
@ -3837,16 +3879,16 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"symfony/polyfill-ctype": "~1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<4.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^4.4|^5.0"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5",
|
||||
"symfony/polyfill-ctype": "~1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<4.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^4.4|^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For validating YAML files using the lint command"
|
||||
},
|
||||
@ -3858,16 +3900,16 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"notification-url": "https://packagist.jp/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
@ -3941,14 +3983,17 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"joyqi/hyper-down": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"ext-phalcon": "~3.4",
|
||||
"ext-redis": "~4.3",
|
||||
"ext-redis": "~5.0",
|
||||
"ext-pdo": "*",
|
||||
"ext-json": "*"
|
||||
"ext-json": "*",
|
||||
"ext-fileinfo": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
|
@ -103,7 +103,7 @@ $error['course.title_too_short'] = '标题太短(少于5个字符)';
|
||||
$error['course.title_too_long'] = '标题太长(多于50个字符)';
|
||||
$error['course.summary_too_long'] = '标题太长(多于255个字符)';
|
||||
$error['course.keywords_too_long'] = '关键字太长(多于100个字符)';
|
||||
$error['course.details_too_long'] = '详情太长(多于3000个字符)';
|
||||
$error['course.details_too_long'] = '详情太长(多于5000个字符)';
|
||||
$error['course.invalid_model'] = '无效的模型类别';
|
||||
$error['course.invalid_level'] = '无效的难度级别';
|
||||
$error['course.invalid_cover'] = '无效的封面';
|
||||
@ -184,7 +184,7 @@ $error['chapter_live.time_too_long'] = '直播时间太长(超过3小时)';
|
||||
*/
|
||||
$error['chapter_read.not_found'] = '文章不存在';
|
||||
$error['chapter_read.content_too_short'] = '文章内容太短(少于10个字符)';
|
||||
$error['chapter_read.content_too_long'] = '文章内容太长(多于65535个字符)';
|
||||
$error['chapter_read.content_too_long'] = '文章内容太长(多于60000个字符)';
|
||||
|
||||
/**
|
||||
* 评价相关
|
||||
@ -229,7 +229,7 @@ $error['help.not_found'] = '帮助不存在';
|
||||
$error['help.title_too_short'] = '标题太短(少于2个字符)';
|
||||
$error['help.title_too_long'] = '标题太长(多于50个字符)';
|
||||
$error['help.content_too_short'] = '内容太短(少于10个字符)';
|
||||
$error['help.content_too_long'] = '内容太长(多于3000个字符)';
|
||||
$error['help.content_too_long'] = '内容太长(多于60000个字符)';
|
||||
$error['help.invalid_priority'] = '无效的排序数值(范围:1-255)';
|
||||
$error['help.invalid_publish_status'] = '无效的发布状态';
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user