diff --git a/app/Http/Admin/Controllers/UploadController.php b/app/Http/Admin/Controllers/UploadController.php index e6ddd867..6cc30b93 100644 --- a/app/Http/Admin/Controllers/UploadController.php +++ b/app/Http/Admin/Controllers/UploadController.php @@ -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' => '上传文件失败']); } diff --git a/app/Http/Admin/Services/ChapterContent.php b/app/Http/Admin/Services/ChapterContent.php index 548f337e..63b332cf 100644 --- a/app/Http/Admin/Services/ChapterContent.php +++ b/app/Http/Admin/Services/ChapterContent.php @@ -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]); diff --git a/app/Http/Admin/Views/chapter/edit_lesson_read.volt b/app/Http/Admin/Views/chapter/edit_lesson_read.volt index 74cf5122..ab75b36a 100644 --- a/app/Http/Admin/Views/chapter/edit_lesson_read.volt +++ b/app/Http/Admin/Views/chapter/edit_lesson_read.volt @@ -1,7 +1,9 @@ +
+
- +
@@ -9,9 +11,60 @@
+
-{{ partial('partials/layedit') }} \ No newline at end of file + + + + + \ No newline at end of file diff --git a/app/Http/Admin/Views/chapter/edit_lesson_read2.volt b/app/Http/Admin/Views/chapter/edit_lesson_read2.volt new file mode 100644 index 00000000..74cf5122 --- /dev/null +++ b/app/Http/Admin/Views/chapter/edit_lesson_read2.volt @@ -0,0 +1,17 @@ +
+ +
+ +
+ +
+ +
+ + +
+
+ +
+ +{{ partial('partials/layedit') }} \ No newline at end of file diff --git a/app/Http/Web/Controllers/PublicController.php b/app/Http/Web/Controllers/PublicController.php index ff7d3c76..2bb434dd 100644 --- a/app/Http/Web/Controllers/PublicController.php +++ b/app/Http/Web/Controllers/PublicController.php @@ -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(); diff --git a/app/Http/Web/Views/course/consults.volt b/app/Http/Web/Views/course/consults.volt index 3f7d67ae..de72c630 100644 --- a/app/Http/Web/Views/course/consults.volt +++ b/app/Http/Web/Views/course/consults.volt @@ -1,7 +1,7 @@ {% if pager.total_pages > 0 %}
{% 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}) %} diff --git a/app/Http/Web/Views/my/consults.volt b/app/Http/Web/Views/my/consults.volt index b58d6a12..5869bc9b 100644 --- a/app/Http/Web/Views/my/consults.volt +++ b/app/Http/Web/Views/my/consults.volt @@ -27,7 +27,7 @@ {% for item in pager.items %} - {% set answer = item.answer ? item.answer : '稍安勿燥,请耐心等待回复吧' %} + {% 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}) %} diff --git a/app/Library/Helper.php b/app/Library/Helper.php index 6bd91302..e2fbb853 100644 --- a/app/Library/Helper.php +++ b/app/Library/Helper.php @@ -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) { diff --git a/app/Library/Utils/FileInfo.php b/app/Library/Utils/FileInfo.php index 8dbb4102..ac179386 100644 --- a/app/Library/Utils/FileInfo.php +++ b/app/Library/Utils/FileInfo.php @@ -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', diff --git a/app/Models/ChapterRead.php b/app/Models/ChapterRead.php index 5d4e13c9..1545eaf0 100644 --- a/app/Models/ChapterRead.php +++ b/app/Models/ChapterRead.php @@ -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', - ]; - } - } diff --git a/app/Models/ContentImage.php b/app/Models/ContentImage.php index f15c73a2..f04fcf9f 100644 --- a/app/Models/ContentImage.php +++ b/app/Models/ContentImage.php @@ -66,7 +66,7 @@ class ContentImage extends Model public function beforeUpdate() { - $this->update_at = time(); + $this->update_time = time(); } } diff --git a/app/Models/UploadFile.php b/app/Models/UploadFile.php new file mode 100644 index 00000000..2188d4e0 --- /dev/null +++ b/app/Models/UploadFile.php @@ -0,0 +1,100 @@ +addBehavior( + new SoftDelete([ + 'field' => 'deleted', + 'value' => 1, + ]) + ); + } + + public function beforeCreate() + { + $this->create_time = time(); + } + + public function beforeUpdate() + { + $this->update_time = time(); + } + +} diff --git a/app/Repos/UploadFile.php b/app/Repos/UploadFile.php new file mode 100644 index 00000000..ef55c73c --- /dev/null +++ b/app/Repos/UploadFile.php @@ -0,0 +1,32 @@ + 'md5 = :md5:', + 'bind' => ['md5' => $md5], + ]); + } + +} diff --git a/app/Services/CourseStats.php b/app/Services/CourseStats.php index d5f0a438..e41492a8 100644 --- a/app/Services/CourseStats.php +++ b/app/Services/CourseStats.php @@ -48,7 +48,9 @@ class CourseStats extends Service public function updateScore($courseId) { - + /** + * @todo 计算综合评分 + */ } public function updateReadAttrs($courseId) diff --git a/app/Services/Frontend/Consult/ConsultReply.php b/app/Services/Frontend/Consult/ConsultReply.php index 7a90e0c5..be9f6a4e 100644 --- a/app/Services/Frontend/Consult/ConsultReply.php +++ b/app/Services/Frontend/Consult/ConsultReply.php @@ -21,7 +21,7 @@ class ConsultReply extends FrontendService $validator = new ConsultValidator(); - $validator->checkTeacher($consult, $user); + $validator->checkReplyPriv($consult, $user); $answer = $validator->checkAnswer($post['answer']); diff --git a/app/Services/Frontend/Consult/ConsultUpdate.php b/app/Services/Frontend/Consult/ConsultUpdate.php index 7463af22..af77767c 100644 --- a/app/Services/Frontend/Consult/ConsultUpdate.php +++ b/app/Services/Frontend/Consult/ConsultUpdate.php @@ -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 = []; diff --git a/app/Services/Storage.php b/app/Services/Storage.php index 2d53624a..eb24f6c6 100644 --- a/app/Services/Storage.php +++ b/app/Services/Storage.php @@ -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'); diff --git a/app/Services/Throttle.php b/app/Services/Throttle.php index 68521a9c..1ba76b37 100644 --- a/app/Services/Throttle.php +++ b/app/Services/Throttle.php @@ -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(); diff --git a/app/Validators/Chapter.php b/app/Validators/Chapter.php index eb9e99d1..800c9268 100644 --- a/app/Validators/Chapter.php +++ b/app/Validators/Chapter.php @@ -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'); } diff --git a/app/Validators/ChapterRead.php b/app/Validators/ChapterRead.php index d3a7b478..0e155cf9 100644 --- a/app/Validators/ChapterRead.php +++ b/app/Validators/ChapterRead.php @@ -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'); } diff --git a/app/Validators/Consult.php b/app/Validators/Consult.php index a24226db..2bdb67a6 100644 --- a/app/Validators/Consult.php +++ b/app/Validators/Consult.php @@ -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)发表三天以后不能修改提问 diff --git a/app/Validators/Course.php b/app/Validators/Course.php index dd4057ef..7bd25588 100644 --- a/app/Validators/Course.php +++ b/app/Validators/Course.php @@ -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'); } diff --git a/app/Validators/Help.php b/app/Validators/Help.php index ddeab14b..ec09468c 100644 --- a/app/Validators/Help.php +++ b/app/Validators/Help.php @@ -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); diff --git a/app/Validators/Page.php b/app/Validators/Page.php index 8d54a12f..abc88d01 100644 --- a/app/Validators/Page.php +++ b/app/Validators/Page.php @@ -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); diff --git a/composer.json b/composer.json index 7378a4fa..8037183f 100644 --- a/composer.json +++ b/composer.json @@ -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", diff --git a/composer.lock b/composer.lock index c812be5e..d2cc5c9d 100644 --- a/composer.lock +++ b/composer.lock @@ -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" diff --git a/config/errors.php b/config/errors.php index 6eac314e..94dcd7e1 100644 --- a/config/errors.php +++ b/config/errors.php @@ -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'] = '无效的发布状态';