diff --git a/db/migrations/2020_09_27_000000_add_timestamps_to_questions.php b/db/migrations/2020_09_27_000000_add_timestamps_to_questions.php new file mode 100644 index 00000000..6f751a7c --- /dev/null +++ b/db/migrations/2020_09_27_000000_add_timestamps_to_questions.php @@ -0,0 +1,33 @@ +schema->table('questions', function (Blueprint $table) { + $table->timestamp('answered_at')->after('answerer_id')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migration + */ + public function down(): void + { + $this->schema->table('questions', function (Blueprint $table) { + $table->dropColumn('answered_at'); + $table->dropTimestamps(); + }); + } +} diff --git a/includes/pages/admin_questions.php b/includes/pages/admin_questions.php index 0e341ef8..fe3fa4e1 100644 --- a/includes/pages/admin_questions.php +++ b/includes/pages/admin_questions.php @@ -1,5 +1,6 @@ user; $unanswered_questions_table[] = [ - 'from' => User_Nick_render($user_source) . User_Pronoun_render($user_source), - 'question' => nl2br(htmlspecialchars($question->text)), - 'answer' => form([ + 'from' => User_Nick_render($user_source) . User_Pronoun_render($user_source), + 'question' => nl2br(htmlspecialchars($question->text)), + 'created_at' => $question->created_at, + 'answer' => form([ form_textarea('answer', '', ''), form_submit('submit', __('Send')) ], page_link_to('admin_questions', ['action' => 'answer', 'id' => $question->id])), - 'actions' => form([ + 'actions' => form([ form_submit('submit', __('delete'), 'btn-xs'), ], page_link_to('admin_questions', ['action' => 'delete', 'id' => $question->id])), ]; @@ -70,8 +72,10 @@ function admin_questions() $answered_questions_table[] = [ 'from' => User_Nick_render($user_source), 'question' => nl2br(htmlspecialchars($question->text)), + 'created_at' => $question->created_at, 'answered_by' => User_Nick_render($answer_user_source), 'answer' => nl2br(htmlspecialchars($question->answer)), + 'answered_at' => $question->answered_at, 'actions' => form([ form_submit('submit', __('delete'), 'btn-xs') ], page_link_to('admin_questions', ['action' => 'delete', 'id' => $question->id])) @@ -81,17 +85,20 @@ function admin_questions() return page_with_title(admin_questions_title(), [ '

' . __('Unanswered questions') . '

', table([ - 'from' => __('From'), - 'question' => __('Question'), - 'answer' => __('Answer'), - 'actions' => '' + 'from' => __('From'), + 'question' => __('Question'), + 'created_at' => __('Asked at'), + 'answer' => __('Answer'), + 'actions' => '' ], $unanswered_questions_table), '

' . __('Answered questions') . '

', table([ 'from' => __('From'), 'question' => __('Question'), + 'created_at' => __('Asked at'), 'answered_by' => __('Answered by'), 'answer' => __('Answer'), + 'answered_at' => __('Answered at'), 'actions' => '' ], $answered_questions_table) ]); @@ -115,10 +122,12 @@ function admin_questions() if (!empty($answer)) { $question->answerer_id = $user->id; $question->answer = $answer; + $question->answered_at = Carbon::now(); $question->save(); engelsystem_log( 'Question ' - . $question['Question'] + . $question->text + . ' (' . $question->id . ')' . ' answered: ' . $answer ); @@ -144,7 +153,7 @@ function admin_questions() $question = Question::find($question_id); if (!empty($question)) { $question->delete(); - engelsystem_log('Question deleted: ' . $question['Question']); + engelsystem_log('Question deleted: ' . $question->text); throw_redirect(page_link_to('admin_questions')); } else { return error('No question found.', true); diff --git a/includes/view/Questions_view.php b/includes/view/Questions_view.php index 82ca8eb9..5d96ccd6 100644 --- a/includes/view/Questions_view.php +++ b/includes/view/Questions_view.php @@ -13,13 +13,14 @@ function Questions_view(array $open_questions, array $answered_questions, $ask_a $open_questions = array_map( static function (Question $question): array { return [ - 'actions' => form( + 'actions' => form( [ form_submit('submit', __('delete'), 'btn-default btn-xs') ], page_link_to('user_questions', ['action' => 'delete', 'id' => $question->id]) ), - 'Question' => nl2br(htmlspecialchars($question->text)), + 'Question' => nl2br(htmlspecialchars($question->text)), + 'created_at' => $question->created_at, ]; }, $open_questions @@ -28,10 +29,12 @@ function Questions_view(array $open_questions, array $answered_questions, $ask_a $answered_questions = array_map( static function (Question $question): array { return [ - 'Question' => nl2br(htmlspecialchars($question->text)), - 'Answer' => nl2br(htmlspecialchars($question->answer)), + 'Question' => nl2br(htmlspecialchars($question->text)), + 'created_at' => $question->created_at, + 'Answer' => nl2br(htmlspecialchars($question->answer)), 'answer_user' => User_Nick_render($question->answerer), - 'actions' => form( + 'answered_at' => $question->answered_at, + 'actions' => form( [ form_submit('submit', __('delete'), 'btn-default btn-xs') ], @@ -46,14 +49,17 @@ function Questions_view(array $open_questions, array $answered_questions, $ask_a msg(), heading(__('Open questions'), 2), table([ - 'Question' => __('Question'), - 'actions' => '' + 'Question' => __('Question'), + 'created_at' => __('Asked at'), + 'actions' => '' ], $open_questions), heading(__('Answered questions'), 2), table([ 'Question' => __('Question'), + 'created_at' => __('Asked at'), 'answer_user' => __('Answered by'), 'Answer' => __('Answer'), + 'answered_at' => __('Answered at'), 'actions' => '' ], $answered_questions), heading(__('Ask the Heaven'), 2), diff --git a/resources/lang/de_DE/default.po b/resources/lang/de_DE/default.po index ce1fae05..7da33850 100644 --- a/resources/lang/de_DE/default.po +++ b/resources/lang/de_DE/default.po @@ -1336,6 +1336,14 @@ msgstr "Beantwortete Fragen" msgid "Answered by" msgstr "Antwort von" +#: includes/pages/admin_questions.php:102 includes/view/Questions_view.php:40 +msgid "Answered at" +msgstr "Beantwortet am" + +#: includes/pages/admin_questions.php:91 includes/view/Questions_view.php:37 +msgid "Asked at" +msgstr "Gefragt am" + #: includes/pages/admin_rooms.php:7 includes/pages/user_shifts.php:230 #: includes/sys_menu.php:118 includes/sys_menu.php:172 msgid "Rooms" diff --git a/src/Models/Question.php b/src/Models/Question.php index ead2d991..a2952a0b 100644 --- a/src/Models/Question.php +++ b/src/Models/Question.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Engelsystem\Models; +use Carbon\Carbon; use Engelsystem\Models\User\User; use Engelsystem\Models\User\UsesUserModel; use Illuminate\Database\Eloquent\Builder; @@ -11,11 +12,16 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Query\Builder as QueryBuilder; /** - * @property int $id - * @property string $text - * @property string $answer - * @property int $answerer_id - * @property-read User $answerer + * @property int $id + * @property string $text + * @property string $answer + * @property int $answerer_id + * @property Carbon|null $answered_at + * @property Carbon|null $created_at + * @property Carbon|null $updated_at + * + * @property-read User $answerer + * * @method static Builder|Question whereAnswer($value) * @method static Builder|Question whereAnswererId($value) * @method static Builder|Question whereId($value) @@ -25,12 +31,21 @@ class Question extends BaseModel { use UsesUserModel; + /** @var bool Enable timestamps */ + public $timestamps = true; + + /** @var string[] */ + protected $dates = [ + 'answered_at' + ]; + /** @var string[] */ protected $fillable = [ 'user_id', 'text', 'answerer_id', 'answer', + 'answered_at', ]; /** @var string[] */ diff --git a/tests/Unit/Models/QuestionTest.php b/tests/Unit/Models/QuestionTest.php index 0965c32e..f47f904c 100644 --- a/tests/Unit/Models/QuestionTest.php +++ b/tests/Unit/Models/QuestionTest.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Engelsystem\Test\Unit\Models; +use Carbon\Carbon; use Engelsystem\Models\Question; use Engelsystem\Models\User\User; use Illuminate\Support\Str; @@ -77,6 +78,8 @@ class QuestionTest extends ModelTest $this->assertCount(2, $unAnsweredQuestionIds); $this->assertContains($question1->id, $unAnsweredQuestionIds); $this->assertContains($question2->id, $unAnsweredQuestionIds); + + $this->assertNull(Question::find($question1->id)->answered_at); } /** @@ -94,6 +97,8 @@ class QuestionTest extends ModelTest $this->assertCount(2, $answeredQuestionIds); $this->assertContains($question1->id, $answeredQuestionIds); $this->assertContains($question2->id, $answeredQuestionIds); + + $this->assertInstanceOf(Carbon::class, Question::find($question1->id)->answered_at); } /** @@ -112,6 +117,7 @@ class QuestionTest extends ModelTest $data += [ 'answerer_id' => $answerer->id, 'answer' => Str::random(), + 'answered_at' => Carbon::now(), ]; }