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 @@
+
+
-{{ 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'] = '无效的发布状态';