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(),
];
}