From 4a2f1ef4a6b1a76571d76e3419ab6aa3ec8e4dc7 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Thu, 30 Oct 2025 20:18:25 +0400 Subject: [PATCH 1/3] Creating comments system templated for demo modules --- .../src/Controllers/CommentController.php.tpl | 78 ++++++++++ .../src/Controllers/PostController.php.tpl | 21 ++- .../DemoApi/src/Middlewares/Comment.php.tpl | 53 +++++++ .../DemoApi/src/Models/Comment.php.tpl | 71 +++++++++ .../DemoApi/src/Services/AuthService.php.tpl | 4 +- .../src/Services/CommentService.php.tpl | 135 ++++++++++++++++++ .../DemoApi/src/Services/PostService.php.tpl | 4 +- .../src/Transformers/CommentTransformer.php | 38 +++++ .../DemoApi/src/routes/routes.php.tpl | 7 +- .../Templates/DemoWeb/assets/css/custom.css | 98 ++++++++++++- .../src/Controllers/BaseController.php.tpl | 29 ++-- .../src/Controllers/CommentController.php.tpl | 76 ++++++++++ .../src/Controllers/PostController.php.tpl | 8 +- .../PostManagementController.php.tpl | 2 - .../DemoWeb/src/Middlewares/Comment.php.tpl | 68 +++++++++ .../DemoWeb/src/Models/Comment.php.tpl | 71 +++++++++ .../DemoWeb/src/Services/AuthService.php.tpl | 7 +- .../src/Services/CommentService.php.tpl | 135 ++++++++++++++++++ .../DemoWeb/src/Services/PostService.php.tpl | 8 +- .../src/Transformers/CommentTransformer.php | 38 +++++ .../DemoWeb/src/Views/partials/navbar.php.tpl | 12 +- .../src/Views/partials/sidebar.php.tpl | 51 ++++--- .../DemoWeb/src/Views/post/comments.php.tpl | 24 ++++ .../Views/post/partials/comment-form.php.tpl | 14 ++ .../Views/post/partials/comment-item.php.tpl | 26 ++++ .../DemoWeb/src/Views/post/single.php.tpl | 5 + .../DemoWeb/src/routes/routes.php.tpl | 5 +- 27 files changed, 1021 insertions(+), 67 deletions(-) create mode 100644 src/Module/Templates/DemoApi/src/Controllers/CommentController.php.tpl create mode 100644 src/Module/Templates/DemoApi/src/Middlewares/Comment.php.tpl create mode 100644 src/Module/Templates/DemoApi/src/Models/Comment.php.tpl create mode 100644 src/Module/Templates/DemoApi/src/Services/CommentService.php.tpl create mode 100644 src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php create mode 100644 src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl create mode 100644 src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl create mode 100644 src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl create mode 100644 src/Module/Templates/DemoWeb/src/Services/CommentService.php.tpl create mode 100644 src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php create mode 100644 src/Module/Templates/DemoWeb/src/Views/post/comments.php.tpl create mode 100644 src/Module/Templates/DemoWeb/src/Views/post/partials/comment-form.php.tpl create mode 100644 src/Module/Templates/DemoWeb/src/Views/post/partials/comment-item.php.tpl diff --git a/src/Module/Templates/DemoApi/src/Controllers/CommentController.php.tpl b/src/Module/Templates/DemoApi/src/Controllers/CommentController.php.tpl new file mode 100644 index 000000000..4652b5adf --- /dev/null +++ b/src/Module/Templates/DemoApi/src/Controllers/CommentController.php.tpl @@ -0,0 +1,78 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Controllers; + +use Quantum\Service\Factories\ServiceFactory; +use {{MODULE_NAMESPACE}}\Services\CommentService; +use Quantum\Http\Response; +use Quantum\Http\Request; + +/** + * Class CommentController + * @package Modules\{{MODULE_NAME}} + */ +class CommentController extends BaseController +{ + + /** + * @var CommentService + */ + public $commentService; + + public function __before() + { + $this->commentService = ServiceFactory::create(CommentService::class); + } + + /** + * Action - create comment + * @param Request $request + * @param Response $response + * @param string|null $lang + * @param string $uuid + */ + public function create(Request $request, Response $response, ?string $lang, string $uuid) + { + $data = [ + 'post_uuid' => $uuid, + 'user_uuid' => auth()->user()->uuid, + 'content' => trim($request->get('content')), + ]; + + $comment = $this->commentService->addComment($data); + + $response->json([ + 'status' => 'success', + 'message' => t('common.created_successfully'), + 'data' => $comment + ]); + } + + /** + * Action - delete comment + * @param Response $response + * @param string|null $lang + * @param string $uuid + */ + public function delete(Response $response, ?string $lang, string $uuid) + { + $this->commentService->deleteComment($uuid); + + $response->json([ + 'status' => 'success', + 'message' => t('common.deleted_successfully'), + ]); + } +} diff --git a/src/Module/Templates/DemoApi/src/Controllers/PostController.php.tpl b/src/Module/Templates/DemoApi/src/Controllers/PostController.php.tpl index ad79ff50a..8ecb0597c 100644 --- a/src/Module/Templates/DemoApi/src/Controllers/PostController.php.tpl +++ b/src/Module/Templates/DemoApi/src/Controllers/PostController.php.tpl @@ -16,8 +16,8 @@ namespace {{MODULE_NAMESPACE}}\Controllers; use Quantum\Service\Factories\ServiceFactory; use Quantum\Http\Constants\StatusCode; +use {{MODULE_NAMESPACE}}\Services\CommentService; use {{MODULE_NAMESPACE}}\Services\PostService; -use Quantum\View\RawParam; use Quantum\Http\Response; use Quantum\Http\Request; @@ -36,7 +36,7 @@ class PostController extends BaseController * Current page */ const CURRENT_PAGE = 1; - + /** * Post service * @var PostService @@ -53,7 +53,7 @@ class PostController extends BaseController /** * Action - get posts list - * @param Request $request + * @param Request $request * @param Response $response */ public function posts(Request $request, Response $response) @@ -61,9 +61,9 @@ class PostController extends BaseController $perPage = $request->get('per_page', self::POSTS_PER_PAGE); $currentPage = $request->get('page', self::CURRENT_PAGE); $search = trim($request->get('q')); - + $paginatedPosts = $this->postService->getPosts($perPage, $currentPage, $search); - + $response->json([ 'status' => 'success', 'data' => $this->postService->transformData($paginatedPosts->data()->all()), @@ -95,11 +95,18 @@ class PostController extends BaseController stop(); } - $rawData = new RawParam(current($this->postService->transformData([$post]))); + $postData = current($this->postService->transformData([$post])); + + $commentService = ServiceFactory::create(CommentService::class); + $comments = $commentService->getCommentsByPost($postUuid); + + $commentsData = $commentService->transformData($comments->all()); + + $postData['comments'] = $commentsData; $response->json([ 'status' => 'success', - 'data' => $rawData->getValue(), + 'data' => $postData, ]); } } \ No newline at end of file diff --git a/src/Module/Templates/DemoApi/src/Middlewares/Comment.php.tpl b/src/Module/Templates/DemoApi/src/Middlewares/Comment.php.tpl new file mode 100644 index 000000000..14c12b9b5 --- /dev/null +++ b/src/Module/Templates/DemoApi/src/Middlewares/Comment.php.tpl @@ -0,0 +1,53 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Middlewares; + +use Quantum\Libraries\Validation\Rule; +use Quantum\Http\Response; +use Quantum\Http\Request; +use Closure; + +/** + * Class Comment + * @package Modules\{{MODULE_NAME}} + */ +class Comment extends BaseMiddleware +{ + + /** + * @param Request $request + * @param Response $response + * @param Closure $next + */ + public function apply(Request $request, Response $response, Closure $next) + { + $this->validateRequest($request, $response); + return $next($request, $response); + } + + /** + * @inheritDoc + */ + protected function defineValidationRules(Request $request) + { + $this->validator->setRules([ + 'content' => [ + Rule::required(), + Rule::minLen(2), + Rule::maxLen(100), + ], + ]); + } +} \ No newline at end of file diff --git a/src/Module/Templates/DemoApi/src/Models/Comment.php.tpl b/src/Module/Templates/DemoApi/src/Models/Comment.php.tpl new file mode 100644 index 000000000..29224fb22 --- /dev/null +++ b/src/Module/Templates/DemoApi/src/Models/Comment.php.tpl @@ -0,0 +1,71 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Models; + +use Quantum\Model\Traits\SoftDeletes; +use Quantum\Model\QtModel; + +/** + * Class Comment + * @package Modules\{{MODULE_NAME}} + */ +class Comment extends QtModel +{ + + use SoftDeletes; + + /** + * ID column of table + * @var string + */ + public $idColumn = 'id'; + + /** + * The table name + * @var string + */ + public $table = 'comments'; + + /** + * Model relations configuration + * @return array[] + */ + public function relations(): array + { + return [ + Post::class => [ + 'foreign_key' => 'post_uuid', + 'local_key' => 'uuid', + ], + User::class => [ + 'foreign_key' => 'user_uuid', + 'local_key' => 'uuid', + ] + ]; + } + + /** + * Fillable properties + * @var array + */ + public $fillable = [ + 'uuid', + 'post_uuid', + 'user_uuid', + 'content', + 'created_at', + 'updated_at' + ]; +} diff --git a/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl b/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl index 30141d519..669054e7b 100644 --- a/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl +++ b/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl @@ -29,7 +29,7 @@ use ReflectionException; /** * Class AuthService - * @package Modules\{{MODULE_NAME}} + * @package Modules\ */ class AuthService extends QtService implements AuthServiceInterface { @@ -127,7 +127,7 @@ class AuthService extends QtService implements AuthServiceInterface /** * Delete users table */ - public function deleteTable() + public function deleteAllUsers() { $this->model->deleteTable(); } diff --git a/src/Module/Templates/DemoApi/src/Services/CommentService.php.tpl b/src/Module/Templates/DemoApi/src/Services/CommentService.php.tpl new file mode 100644 index 000000000..5ba00f622 --- /dev/null +++ b/src/Module/Templates/DemoApi/src/Services/CommentService.php.tpl @@ -0,0 +1,135 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Services; + +use {{MODULE_NAMESPACE}}\Transformers\CommentTransformer; +use Quantum\Model\Exceptions\ModelException; +use Quantum\Model\Factories\ModelFactory; +use Quantum\Model\ModelCollection; +use Quantum\Paginator\Paginator; +use Quantum\Service\QtService; +use {{MODULE_NAMESPACE}}\Models\Comment; +use {{MODULE_NAMESPACE}}\Models\User; + +/** + * Class CommentService + * @package Modules\{{MODULE_NAME}} + */ +class CommentService extends QtService +{ + + /** + * @var Comment + */ + private $model; + + /** + * @var CommentTransformer + */ + private $transformer; + + /** + * CommentService constructor. + * @param CommentTransformer $transformer + * @throws ModelException + */ + public function __construct(CommentTransformer $transformer) + { + $this->model = ModelFactory::get(Comment::class); + $this->transformer = $transformer; + } + + /** + * Get comments by post + * @param string $postUuid + * @return ModelCollection|Paginator + * @throws ModelException + */ + public function getCommentsByPost(string $postUuid) + { + return $this->model + ->joinThrough(ModelFactory::get(User::class)) + ->criteria('post_uuid', '=', $postUuid) + ->select( + 'comments.uuid', + 'comments.content', + 'comments.created_at', + ['users.firstname' => 'firstname'], + ['users.lastname' => 'lastname'], + ['users.image' => 'image'], + ['users.uuid' => 'user_directory'] + ) + ->orderBy('created_at', 'asc') + ->get(); + } + + + /** + * Get comment + * @param string $uuid + * @return Comment + */ + public function getComment(string $uuid): Comment + { + return $this->model->criteria('uuid', '=', $uuid)->first(); + } + + /** + * Add a new comment + * @param array $data + * @return array + * @throws ModelException + */ + public function addComment(array $data): array + { + $data['uuid'] = $data['uuid'] ?? uuid_ordered(); + $data['created_at'] = date('Y-m-d H:i:s'); + + $comment = $this->model->create(); + $comment->fillObjectProps($data); + $comment->save(); + + return $data; + } + + /** + * Delete a comment + * @param string $uuid + * @return bool + */ + public function deleteComment(string $uuid): bool + { + return $this->model->findOneBy('uuid', $uuid)->delete(); + } + + /** + * Delete all comments + * @throws ModelException + */ + public function deleteAllComments() + { + $this->model->deleteTable(); + } + + /** + * Transform data + * @param array $comments + * @return array + */ + public function transformData(array $comments): array + { + return transform($comments, $this->transformer); + } +} diff --git a/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl b/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl index 2fb7232a6..3af3f8d55 100644 --- a/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl +++ b/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.8 + * @since 2.9.9 */ namespace {{MODULE_NAMESPACE}}\Services; @@ -193,7 +193,7 @@ class PostService extends QtService * Delete posts table * @throws ModelException */ - public function deleteTable() + public function deleteAllPost() { $this->model->deleteTable(); } diff --git a/src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php b/src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php new file mode 100644 index 000000000..b0f0050a4 --- /dev/null +++ b/src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Transformers; + +use Quantum\Libraries\Transformer\Contracts\TransformerInterface; + +/** + * Class CommentTransformer + * @package Modules\{{MODULE_NAME}} + */ +class CommentTransformer implements TransformerInterface +{ + public function transform($item): array + { + return [ + 'uuid' => $item->uuid, + 'author' => [ + 'firstname' => $item->firstname, + 'lastname' => $item->lastname, + 'image' => $item->user_directory . '/' . $item->image, + ], + 'content' => $item->content, + 'date' => date('Y-m-d H:i', strtotime($item->created_at)), + ]; + } +} diff --git a/src/Module/Templates/DemoApi/src/routes/routes.php.tpl b/src/Module/Templates/DemoApi/src/routes/routes.php.tpl index 057568c32..a71221711 100644 --- a/src/Module/Templates/DemoApi/src/routes/routes.php.tpl +++ b/src/Module/Templates/DemoApi/src/routes/routes.php.tpl @@ -13,14 +13,17 @@ return function ($route) { $route->post('[:alpha:2]?/verify', 'AuthController', 'verify')->middlewares(['Verify']); $route->group('auth', function ($route) { - $route->get('[:alpha:2]?/me', 'AuthController', 'me'); - $route->get('[:alpha:2]?/signout', 'AuthController', 'signout')->middlewares(['Signout']); $route->get('[:alpha:2]?/my-posts', 'PostManagementController', 'myPosts')->middlewares(['Editor']); $route->post('[:alpha:2]?/my-posts/create', 'PostManagementController', 'create')->middlewares(['Editor']); $route->put('[:alpha:2]?/my-posts/amend/[uuid=:any]', 'PostManagementController', 'amend')->middlewares(['Editor', 'Owner']); $route->delete('[:alpha:2]?/my-posts/delete/[uuid=:any]', 'PostManagementController', 'delete')->middlewares(['Editor', 'Owner']); $route->delete('[:alpha:2]?/my-posts/delete-image/[uuid=:any]', 'PostManagementController', 'deleteImage')->middlewares(['Editor', 'Owner']); + + $route->post('[:alpha:2]?/comments/create/[uuid=:any]', 'CommentController', 'create')->middlewares(['Comment']); + $route->put('[:alpha:2]?/account-settings/update', 'AccountController', 'update')->middlewares(['Update']); $route->put('[:alpha:2]?/account-settings/update-password', 'AccountController', 'updatePassword')->middlewares(['Password']); + $route->get('[:alpha:2]?/signout', 'AuthController', 'signout')->middlewares(['Signout']); + $route->get('[:alpha:2]?/me', 'AuthController', 'me'); })->middlewares(['Auth']); }; \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/assets/css/custom.css b/src/Module/Templates/DemoWeb/assets/css/custom.css index 162542a8e..b5d43a094 100644 --- a/src/Module/Templates/DemoWeb/assets/css/custom.css +++ b/src/Module/Templates/DemoWeb/assets/css/custom.css @@ -299,11 +299,11 @@ a:hover { } .user-avatar { - width:32px; - height:32px; - object-fit:cover; - margin-top: 18px; - margin-right:8px; + flex: 0 0 32px; + width: 32px; + height: 32px; + object-fit: cover; + margin-right: 8px; } .post-item { @@ -473,6 +473,83 @@ input[type=password] { animation-delay: 11s; } +.comment-input-box { + position: relative; + margin-bottom: 16px; +} +.comment-input-box label{ + position: absolute; + top: 4px; + padding: 0 24px; +} +.comment-input-box textarea{ + border: 1px solid #ededed; + border-radius: 8px; + box-shadow: none; + padding: 24px; + height: 100px; + outline-color: #ccc; +} + +.comments-list, +.comments-section { + margin-top: 60px; +} + +.comment-box.card-panel { + box-shadow: none; + position: relative; + padding: 16px 0; +} + +.comment-item { + position: relative; +} + +.comment-item::after { + content: ""; + position: absolute; + bottom: 0; + height: 1px; + width: 100%; + background: linear-gradient(90deg, rgba(0,0,0, 0) 0%, rgba(0,0,0, 0.1) 50%, rgba(0,0,0, 0)); +} + +.comment-item:last-child::after { + display: none; +} + +.comment-box-header { + display: flex; + align-items: center; + gap: 8px; +} + +.comment-box-header img { + flex: 0 0 32px; + width: 32px; + height: 32px; + object-fit: contain; +} + +.comment-info { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + box-shadow: none; + background: #F1F2F3; + border-color: #E0E0E1; + color: #000; +} + +.comment-date-time { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 4px; +} + @keyframes square { 0% { transform: translateY(0); @@ -778,9 +855,20 @@ div.polaroid { margin-right: 15px !important; } } +@media only screen and (min-width: 601px) { + .show-on-medium-and-up-header-avatar-box{ + display: flex; + align-items: center; + } + +} @media only screen and (max-width: 600px) { .navbar-logo img { height: 44px; } + + .show-on-medium-and-up-header-avatar-box{ + display: none; + } } \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Controllers/BaseController.php.tpl b/src/Module/Templates/DemoWeb/src/Controllers/BaseController.php.tpl index c5658e3f1..468c41984 100644 --- a/src/Module/Templates/DemoWeb/src/Controllers/BaseController.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Controllers/BaseController.php.tpl @@ -17,6 +17,7 @@ namespace {{MODULE_NAMESPACE}}\Controllers; use Quantum\View\Factories\ViewFactory; use Quantum\Router\RouteController; use Quantum\Libraries\Asset\Asset; +use Quantum\Http\Request; use Quantum\View\QtView; /** @@ -36,18 +37,20 @@ abstract class BaseController extends RouteController */ public function __before() { - $this->view = ViewFactory::get(); - - $this->view->setLayout(static::LAYOUT, [ - new Asset(Asset::CSS, 'shared/css/materialize.min.css', null, -1, ['media="screen,projection"']), - new Asset(Asset::CSS, 'shared/css/easymde.min.css'), - new Asset(Asset::CSS, '{{MODULE_NAME}}/css/custom.css'), - new Asset(Asset::JS, 'shared/js/jquery-3.7.1.min.js'), - new Asset(Asset::JS, 'shared/js/materialize.min.js'), - new Asset(Asset::JS, 'shared/js/easymde.min.js'), - new Asset(Asset::JS, '{{MODULE_NAME}}/js/custom.js') - ]); - - $this->view->setParam('langs', config()->get('lang.supported')); + if (Request::isMethod('get')) { + $this->view = ViewFactory::get(); + + $this->view->setLayout(static::LAYOUT, [ + new Asset(Asset::CSS, 'shared/css/materialize.min.css', null, -1, ['media="screen,projection"']), + new Asset(Asset::CSS, 'shared/css/easymde.min.css'), + new Asset(Asset::CSS, '{{MODULE_NAME}}/css/custom.css'), + new Asset(Asset::JS, 'shared/js/jquery-3.7.1.min.js'), + new Asset(Asset::JS, 'shared/js/materialize.min.js'), + new Asset(Asset::JS, 'shared/js/easymde.min.js'), + new Asset(Asset::JS, '{{MODULE_NAME}}/js/custom.js') + ]); + + $this->view->setParam('langs', config()->get('lang.supported')); + } } } \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl b/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl new file mode 100644 index 000000000..edd1ea1f9 --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Controllers/CommentController.php.tpl @@ -0,0 +1,76 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Controllers; + +use Quantum\Service\Factories\ServiceFactory; +use {{MODULE_NAMESPACE}}\Services\CommentService; +use Quantum\Http\Request; + +/** + * Class CommentController + * @package Modules\{{MODULE_NAME}} + */ +class CommentController extends BaseController +{ + + /** + * @var CommentService + */ + public $commentService; + + public function __before() + { + $this->commentService = ServiceFactory::create(CommentService::class); + parent::__before(); + } + + /** + * Action - create comment + * @param Request $request + * @param string|null $lang + * @param string $uuid + */ + public function create(Request $request, ?string $lang, string $uuid) + { + $data = [ + 'post_uuid' => $uuid, + 'user_uuid' => auth()->user()->uuid, + 'content' => trim($request->get('content')), + ]; + + if (!$data['content']) { + session()->setFlash('error', t('common.comment_required')); + redirect(get_referrer()); + } + + $this->commentService->addComment($data); + + session()->setFlash('success', t('common.comment_added')); + redirect(get_referrer()); + } + + /** + * Action - delete comment + * @param string|null $lang + * @param string $uuid + */ + public function delete(?string $lang, string $uuid) + { + $this->commentService->deleteComment($uuid); + + session()->setFlash('success', t('common.comment_deleted')); + redirect(get_referrer()); + } +} diff --git a/src/Module/Templates/DemoWeb/src/Controllers/PostController.php.tpl b/src/Module/Templates/DemoWeb/src/Controllers/PostController.php.tpl index fd7acbb4f..80ea0f149 100644 --- a/src/Module/Templates/DemoWeb/src/Controllers/PostController.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Controllers/PostController.php.tpl @@ -15,6 +15,7 @@ namespace {{MODULE_NAMESPACE}}\Controllers; use Quantum\Service\Factories\ServiceFactory; +use {{MODULE_NAMESPACE}}\Services\CommentService; use Quantum\Http\Constants\StatusCode; use {{MODULE_NAMESPACE}}\Services\PostService; use Quantum\View\RawParam; @@ -52,7 +53,6 @@ class PostController extends BaseController public function __before() { $this->postService = ServiceFactory::create(PostService::class); - parent::__before(); } @@ -96,9 +96,15 @@ class PostController extends BaseController stop(); } + $commentService = ServiceFactory::create(CommentService::class); + $comments = $commentService->getCommentsByPost($postUuid); + + $comments = $commentService->transformData($comments->all()); + $this->view->setParams([ 'title' => $post->title . ' | ' . config()->get('app.name'), 'post' => new RawParam(current($this->postService->transformData([$post]))), + 'comments' => $comments, 'referer' => $ref, ]); diff --git a/src/Module/Templates/DemoWeb/src/Controllers/PostManagementController.php.tpl b/src/Module/Templates/DemoWeb/src/Controllers/PostManagementController.php.tpl index 92958b27c..81e10757c 100644 --- a/src/Module/Templates/DemoWeb/src/Controllers/PostManagementController.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Controllers/PostManagementController.php.tpl @@ -89,7 +89,6 @@ class PostManagementController extends BaseController 'title' => $request->get('title', null, true), 'content' => $request->get('content', null, true), 'image' => '', - 'updated_at' => date('Y-m-d H:i:s'), ]; if ($request->hasFile('image')) { @@ -140,7 +139,6 @@ class PostManagementController extends BaseController $postData = [ 'title' => $request->get('title', null, true), 'content' => $request->get('content', null, true), - 'updated_at' => date('Y-m-d H:i:s'), ]; $post = $this->postService->getPost($postUuid); diff --git a/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl b/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl new file mode 100644 index 000000000..d5602d7bc --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Middlewares/Comment.php.tpl @@ -0,0 +1,68 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Middlewares; + +use Quantum\Libraries\Validation\Rule; +use Quantum\Http\Response; +use Quantum\Http\Request; +use Closure; + +/** + * Class Comment + * @package Modules\{{MODULE_NAME}} + */ +class Comment extends BaseMiddleware +{ + + /** + * @param Request $request + * @param Response $response + * @param Closure $next + */ + public function apply(Request $request, Response $response, Closure $next) + { + $this->validateRequest($request, $response); + return $next($request, $response); + } + + /** + * @inheritDoc + */ + protected function defineValidationRules(Request $request) + { + $this->validator->setRules([ + 'content' => [ + Rule::required(), + Rule::minLen(2), + Rule::maxLen(100), + ], + ]); + } + + /** + * @inheritDoc + */ + protected function respondWithError( + Request $request, + Response $response, + $message + ) + { + $data = $request->all(); + + session()->setFlash('error', $this->validator->getErrors()); + redirectWith(get_referrer(), $data); + } +} \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl b/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl new file mode 100644 index 000000000..29224fb22 --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl @@ -0,0 +1,71 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Models; + +use Quantum\Model\Traits\SoftDeletes; +use Quantum\Model\QtModel; + +/** + * Class Comment + * @package Modules\{{MODULE_NAME}} + */ +class Comment extends QtModel +{ + + use SoftDeletes; + + /** + * ID column of table + * @var string + */ + public $idColumn = 'id'; + + /** + * The table name + * @var string + */ + public $table = 'comments'; + + /** + * Model relations configuration + * @return array[] + */ + public function relations(): array + { + return [ + Post::class => [ + 'foreign_key' => 'post_uuid', + 'local_key' => 'uuid', + ], + User::class => [ + 'foreign_key' => 'user_uuid', + 'local_key' => 'uuid', + ] + ]; + } + + /** + * Fillable properties + * @var array + */ + public $fillable = [ + 'uuid', + 'post_uuid', + 'user_uuid', + 'content', + 'created_at', + 'updated_at' + ]; +} diff --git a/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl b/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl index 4ccbb628f..d73ccb6dc 100644 --- a/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.8 + * @since 2.9.9 */ namespace {{MODULE_NAMESPACE}}\Services; @@ -94,6 +94,9 @@ class AuthService extends QtService implements AuthServiceInterface */ public function add(array $data): AuthUser { + $data['uuid'] = $data['uuid'] ?? uuid_ordered(); + $data['created_at'] = date('Y-m-d H:i:s'); + $this->createUserDirectory($data['uuid']); $user = $this->model->create(); @@ -127,7 +130,7 @@ class AuthService extends QtService implements AuthServiceInterface /** * Delete users table */ - public function deleteTable() + public function deleteAllUsers() { $this->model->deleteTable(); } diff --git a/src/Module/Templates/DemoWeb/src/Services/CommentService.php.tpl b/src/Module/Templates/DemoWeb/src/Services/CommentService.php.tpl new file mode 100644 index 000000000..5ba00f622 --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Services/CommentService.php.tpl @@ -0,0 +1,135 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Services; + +use {{MODULE_NAMESPACE}}\Transformers\CommentTransformer; +use Quantum\Model\Exceptions\ModelException; +use Quantum\Model\Factories\ModelFactory; +use Quantum\Model\ModelCollection; +use Quantum\Paginator\Paginator; +use Quantum\Service\QtService; +use {{MODULE_NAMESPACE}}\Models\Comment; +use {{MODULE_NAMESPACE}}\Models\User; + +/** + * Class CommentService + * @package Modules\{{MODULE_NAME}} + */ +class CommentService extends QtService +{ + + /** + * @var Comment + */ + private $model; + + /** + * @var CommentTransformer + */ + private $transformer; + + /** + * CommentService constructor. + * @param CommentTransformer $transformer + * @throws ModelException + */ + public function __construct(CommentTransformer $transformer) + { + $this->model = ModelFactory::get(Comment::class); + $this->transformer = $transformer; + } + + /** + * Get comments by post + * @param string $postUuid + * @return ModelCollection|Paginator + * @throws ModelException + */ + public function getCommentsByPost(string $postUuid) + { + return $this->model + ->joinThrough(ModelFactory::get(User::class)) + ->criteria('post_uuid', '=', $postUuid) + ->select( + 'comments.uuid', + 'comments.content', + 'comments.created_at', + ['users.firstname' => 'firstname'], + ['users.lastname' => 'lastname'], + ['users.image' => 'image'], + ['users.uuid' => 'user_directory'] + ) + ->orderBy('created_at', 'asc') + ->get(); + } + + + /** + * Get comment + * @param string $uuid + * @return Comment + */ + public function getComment(string $uuid): Comment + { + return $this->model->criteria('uuid', '=', $uuid)->first(); + } + + /** + * Add a new comment + * @param array $data + * @return array + * @throws ModelException + */ + public function addComment(array $data): array + { + $data['uuid'] = $data['uuid'] ?? uuid_ordered(); + $data['created_at'] = date('Y-m-d H:i:s'); + + $comment = $this->model->create(); + $comment->fillObjectProps($data); + $comment->save(); + + return $data; + } + + /** + * Delete a comment + * @param string $uuid + * @return bool + */ + public function deleteComment(string $uuid): bool + { + return $this->model->findOneBy('uuid', $uuid)->delete(); + } + + /** + * Delete all comments + * @throws ModelException + */ + public function deleteAllComments() + { + $this->model->deleteTable(); + } + + /** + * Transform data + * @param array $comments + * @return array + */ + public function transformData(array $comments): array + { + return transform($comments, $this->transformer); + } +} diff --git a/src/Module/Templates/DemoWeb/src/Services/PostService.php.tpl b/src/Module/Templates/DemoWeb/src/Services/PostService.php.tpl index 2fb7232a6..22c8658c2 100644 --- a/src/Module/Templates/DemoWeb/src/Services/PostService.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Services/PostService.php.tpl @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.8 + * @since 2.9.9 */ namespace {{MODULE_NAMESPACE}}\Services; @@ -57,7 +57,6 @@ class PostService extends QtService public function __construct(PostTransformer $transformer) { $this->model = ModelFactory::get(Post::class); - $this->transformer = $transformer; } @@ -157,6 +156,7 @@ class PostService extends QtService public function addPost(array $data): array { $data['uuid'] = $data['uuid'] ?? uuid_ordered(); + $data['created_at'] = date('Y-m-d H:i:s'); $post = $this->model->create(); $post->fillObjectProps($data); @@ -173,6 +173,8 @@ class PostService extends QtService */ public function updatePost(string $uuid, array $data) { + $data['updated_at'] = date('Y-m-d H:i:s'); + $post = $this->model->findOneBy('uuid', $uuid); $post->fillObjectProps($data); $post->save(); @@ -193,7 +195,7 @@ class PostService extends QtService * Delete posts table * @throws ModelException */ - public function deleteTable() + public function deleteAllPosts() { $this->model->deleteTable(); } diff --git a/src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php b/src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php new file mode 100644 index 000000000..b0f0050a4 --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) + * @link http://quantum.softberg.org/ + * @since 2.9.9 + */ + +namespace {{MODULE_NAMESPACE}}\Transformers; + +use Quantum\Libraries\Transformer\Contracts\TransformerInterface; + +/** + * Class CommentTransformer + * @package Modules\{{MODULE_NAME}} + */ +class CommentTransformer implements TransformerInterface +{ + public function transform($item): array + { + return [ + 'uuid' => $item->uuid, + 'author' => [ + 'firstname' => $item->firstname, + 'lastname' => $item->lastname, + 'image' => $item->user_directory . '/' . $item->image, + ], + 'content' => $item->content, + 'date' => date('Y-m-d H:i', strtotime($item->created_at)), + ]; + } +} diff --git a/src/Module/Templates/DemoWeb/src/Views/partials/navbar.php.tpl b/src/Module/Templates/DemoWeb/src/Views/partials/navbar.php.tpl index c83983d86..e00b941fc 100644 --- a/src/Module/Templates/DemoWeb/src/Views/partials/navbar.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Views/partials/navbar.php.tpl @@ -18,14 +18,16 @@ check()) : ?>
  • - + \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Views/partials/sidebar.php.tpl b/src/Module/Templates/DemoWeb/src/Views/partials/sidebar.php.tpl index d451a46c7..2f4377e8a 100644 --- a/src/Module/Templates/DemoWeb/src/Views/partials/sidebar.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Views/partials/sidebar.php.tpl @@ -13,28 +13,35 @@
  • check()) : ?> -
  • - - -
  • +
  • + + +
  • diff --git a/src/Module/Templates/DemoWeb/src/Views/post/comments.php.tpl b/src/Module/Templates/DemoWeb/src/Views/post/comments.php.tpl new file mode 100644 index 000000000..d320c62c8 --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Views/post/comments.php.tpl @@ -0,0 +1,24 @@ +
    +

    + + +
      + + $comment]) ?> + +
    + +

    + + + check()): ?> + $post]) ?> + +
    +
    + report_problem + +
    +
    + +
    diff --git a/src/Module/Templates/DemoWeb/src/Views/post/partials/comment-form.php.tpl b/src/Module/Templates/DemoWeb/src/Views/post/partials/comment-form.php.tpl new file mode 100644 index 000000000..7ab0d5c5c --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Views/post/partials/comment-form.php.tpl @@ -0,0 +1,14 @@ +has('error')) : ?> + + +
    +
    + + +
    + + +
    \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Views/post/partials/comment-item.php.tpl b/src/Module/Templates/DemoWeb/src/Views/post/partials/comment-item.php.tpl new file mode 100644 index 000000000..ca2383d54 --- /dev/null +++ b/src/Module/Templates/DemoWeb/src/Views/post/partials/comment-item.php.tpl @@ -0,0 +1,26 @@ +
    +
    +
    +
    + + <?php echo htmlspecialchars($comment['author']['firstname']) ?> + + person + + + + +
    +

    + +

    +

    + access_time + +

    +
    +
    +
    \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Views/post/single.php.tpl b/src/Module/Templates/DemoWeb/src/Views/post/single.php.tpl index 98abb6b7e..4a53d24d7 100644 --- a/src/Module/Templates/DemoWeb/src/Views/post/single.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Views/post/single.php.tpl @@ -13,5 +13,10 @@
    + + $post, + 'comments' => $comments + ]) ?> \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/routes/routes.php.tpl b/src/Module/Templates/DemoWeb/src/routes/routes.php.tpl index 2aacb3934..3439ad9f4 100644 --- a/src/Module/Templates/DemoWeb/src/routes/routes.php.tpl +++ b/src/Module/Templates/DemoWeb/src/routes/routes.php.tpl @@ -18,7 +18,6 @@ return function ($route) { })->middlewares(['Guest']); $route->group('auth', function ($route) { - $route->get('[:alpha:2]?/signout', 'AuthController', 'signout'); $route->get('[:alpha:2]?/my-posts', 'PostManagementController', 'myPosts')->middlewares(['Editor']); $route->get('[:alpha:2]?/my-posts/create', 'PostManagementController', 'createFrom')->middlewares(['Editor']); $route->post('[:alpha:2]?/my-posts/create', 'PostManagementController', 'create')->middlewares(['Editor']); @@ -26,8 +25,12 @@ return function ($route) { $route->post('[:alpha:2]?/my-posts/amend/[uuid=:any]', 'PostManagementController', 'amend')->middlewares(['Editor', 'Owner']); $route->get('[:alpha:2]?/my-posts/delete/[uuid=:any]', 'PostManagementController', 'delete')->middlewares(['Editor', 'Owner']); $route->get('[:alpha:2]?/my-posts/delete-image/[uuid=:any]', 'PostManagementController', 'deleteImage')->middlewares(['Editor', 'Owner']); + + $route->post('[:alpha:2]?/comments/create/[uuid=:any]', 'CommentController', 'create')->middlewares(['Comment']); + $route->get('[:alpha:2]?/account-settings', 'AccountController', 'form'); $route->post('[:alpha:2]?/account-settings/update', 'AccountController', 'update')->middlewares(['Update']); $route->post('[:alpha:2]?/account-settings/update-password', 'AccountController', 'updatePassword')->middlewares(['Password']); + $route->get('[:alpha:2]?/signout', 'AuthController', 'signout'); })->middlewares(['Auth']); }; \ No newline at end of file From 56c24dfbb5a745f91d0cf2d4cc9f0d5649edd853 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Thu, 30 Oct 2025 20:28:48 +0400 Subject: [PATCH 2/3] Correcting template extensions --- .../{CommentTransformer.php => CommentTransformer.php.tpl} | 0 .../{CommentTransformer.php => CommentTransformer.php.tpl} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/Module/Templates/DemoApi/src/Transformers/{CommentTransformer.php => CommentTransformer.php.tpl} (100%) rename src/Module/Templates/DemoWeb/src/Transformers/{CommentTransformer.php => CommentTransformer.php.tpl} (100%) diff --git a/src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php b/src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php.tpl similarity index 100% rename from src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php rename to src/Module/Templates/DemoApi/src/Transformers/CommentTransformer.php.tpl diff --git a/src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php b/src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php.tpl similarity index 100% rename from src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php rename to src/Module/Templates/DemoWeb/src/Transformers/CommentTransformer.php.tpl From a8d1414782fdd1714c887879aa849faf21998151 Mon Sep 17 00:00:00 2001 From: Arman <407448+armanist@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:03:51 +0400 Subject: [PATCH 3/3] Making sure to fill `created_at` and `updated_at` values --- src/Module/Templates/DemoApi/src/Models/Post.php.tpl | 5 +++-- src/Module/Templates/DemoApi/src/Models/User.php.tpl | 2 ++ .../Templates/DemoApi/src/Services/AuthService.php.tpl | 7 ++++++- .../Templates/DemoApi/src/Services/PostService.php.tpl | 3 +++ src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl | 2 +- src/Module/Templates/DemoWeb/src/Models/Post.php.tpl | 1 + src/Module/Templates/DemoWeb/src/Models/User.php.tpl | 2 ++ .../Templates/DemoWeb/src/Services/AuthService.php.tpl | 2 ++ 8 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Module/Templates/DemoApi/src/Models/Post.php.tpl b/src/Module/Templates/DemoApi/src/Models/Post.php.tpl index 8d977733f..e71cf3808 100644 --- a/src/Module/Templates/DemoApi/src/Models/Post.php.tpl +++ b/src/Module/Templates/DemoApi/src/Models/Post.php.tpl @@ -9,7 +9,7 @@ * @author Arman Ag. * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org) * @link http://quantum.softberg.org/ - * @since 2.9.8 + * @since 2.9.9 */ namespace {{MODULE_NAMESPACE}}\Models; @@ -62,6 +62,7 @@ class Post extends QtModel 'title', 'content', 'image', - 'updated_at' + 'created_at', + 'updated_at', ]; } \ No newline at end of file diff --git a/src/Module/Templates/DemoApi/src/Models/User.php.tpl b/src/Module/Templates/DemoApi/src/Models/User.php.tpl index a6fea632c..c796eb17f 100644 --- a/src/Module/Templates/DemoApi/src/Models/User.php.tpl +++ b/src/Module/Templates/DemoApi/src/Models/User.php.tpl @@ -55,5 +55,7 @@ class User extends QtModel 'otp', 'otp_expires', 'otp_token', + 'created_at', + 'updated_at', ]; } \ No newline at end of file diff --git a/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl b/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl index 669054e7b..457955e85 100644 --- a/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl +++ b/src/Module/Templates/DemoApi/src/Services/AuthService.php.tpl @@ -29,7 +29,7 @@ use ReflectionException; /** * Class AuthService - * @package Modules\ + * @package Modules\{{MODULE_NAME}} */ class AuthService extends QtService implements AuthServiceInterface { @@ -94,6 +94,9 @@ class AuthService extends QtService implements AuthServiceInterface */ public function add(array $data): AuthUser { + $data['uuid'] = $data['uuid'] ?? uuid_ordered(); + $data['created_at'] = date('Y-m-d H:i:s'); + $this->createUserDirectory($data['uuid']); $user = $this->model->create(); @@ -118,6 +121,8 @@ class AuthService extends QtService implements AuthServiceInterface return null; } + $data['updated_at'] = date('Y-m-d H:i:s'); + $user->fillObjectProps($data); $user->save(); diff --git a/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl b/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl index 3af3f8d55..363291eb4 100644 --- a/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl +++ b/src/Module/Templates/DemoApi/src/Services/PostService.php.tpl @@ -157,6 +157,7 @@ class PostService extends QtService public function addPost(array $data): array { $data['uuid'] = $data['uuid'] ?? uuid_ordered(); + $data['created_at'] = date('Y-m-d H:i:s'); $post = $this->model->create(); $post->fillObjectProps($data); @@ -173,6 +174,8 @@ class PostService extends QtService */ public function updatePost(string $uuid, array $data) { + $data['updated_at'] = date('Y-m-d H:i:s'); + $post = $this->model->findOneBy('uuid', $uuid); $post->fillObjectProps($data); $post->save(); diff --git a/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl b/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl index 29224fb22..7b7326c37 100644 --- a/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Models/Comment.php.tpl @@ -66,6 +66,6 @@ class Comment extends QtModel 'user_uuid', 'content', 'created_at', - 'updated_at' + 'updated_at', ]; } diff --git a/src/Module/Templates/DemoWeb/src/Models/Post.php.tpl b/src/Module/Templates/DemoWeb/src/Models/Post.php.tpl index 8d977733f..a80354f19 100644 --- a/src/Module/Templates/DemoWeb/src/Models/Post.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Models/Post.php.tpl @@ -62,6 +62,7 @@ class Post extends QtModel 'title', 'content', 'image', + 'created_at', 'updated_at' ]; } \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Models/User.php.tpl b/src/Module/Templates/DemoWeb/src/Models/User.php.tpl index a6fea632c..c796eb17f 100644 --- a/src/Module/Templates/DemoWeb/src/Models/User.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Models/User.php.tpl @@ -55,5 +55,7 @@ class User extends QtModel 'otp', 'otp_expires', 'otp_token', + 'created_at', + 'updated_at', ]; } \ No newline at end of file diff --git a/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl b/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl index d73ccb6dc..457955e85 100644 --- a/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl +++ b/src/Module/Templates/DemoWeb/src/Services/AuthService.php.tpl @@ -121,6 +121,8 @@ class AuthService extends QtService implements AuthServiceInterface return null; } + $data['updated_at'] = date('Y-m-d H:i:s'); + $user->fillObjectProps($data); $user->save();