diff --git a/js/src/forum/components/PostPoll.js b/js/src/forum/components/PostPoll.js
index c312f98e..49583ba7 100644
--- a/js/src/forum/components/PostPoll.js
+++ b/js/src/forum/components/PostPoll.js
@@ -46,24 +46,29 @@ export default class PostPoll extends Component {
return (
-
{poll.question()}
-
- {poll.canSeeVoters() && (
-
-
-
- )}
-
- {poll.canEdit() && (
-
-
-
- )}
- {poll.canDelete() && (
-
-
-
- )}
+
+
{poll.question()}
+ {poll.subtitle() &&
{poll.subtitle()}
}
+
+
+
+ {poll.canSeeVoters() && (
+
+
+
+ )}
+
+ {poll.canEdit() && (
+
+
+
+ )}
+ {poll.canDelete() && (
+
+
+
+ )}
+
diff --git a/js/src/forum/models/Poll.ts b/js/src/forum/models/Poll.ts
index 77e9d512..72fa529a 100755
--- a/js/src/forum/models/Poll.ts
+++ b/js/src/forum/models/Poll.ts
@@ -8,6 +8,10 @@ export default class Poll extends Model {
return Model.attribute('question').call(this);
}
+ subtitle() {
+ return Model.attribute('subtitle').call(this);
+ }
+
hasEnded() {
return Model.attribute('hasEnded').call(this);
}
diff --git a/migrations/2024_02_15_000000_modify_polls_add_subtitle.php b/migrations/2024_02_15_000000_modify_polls_add_subtitle.php
new file mode 100644
index 00000000..b23399a3
--- /dev/null
+++ b/migrations/2024_02_15_000000_modify_polls_add_subtitle.php
@@ -0,0 +1,26 @@
+ function (Builder $schema) {
+ $schema->table('polls', function (Blueprint $table) {
+ $table->text('subtitle')->nullable()->after('question');
+ });
+ },
+ 'down' => function (Builder $schema) {
+ $schema->table('polls', function (Blueprint $table) {
+ $table->dropColumn('subtitle');
+ });
+ },
+];
diff --git a/resources/less/forum.less b/resources/less/forum.less
index 5a94cee1..8999ab07 100755
--- a/resources/less/forum.less
+++ b/resources/less/forum.less
@@ -167,7 +167,7 @@
align-items: baseline;
gap: 10px;
- &-title {
+ &-title-container {
flex-grow: 1;
}
@@ -175,6 +175,10 @@
.Button--color-auto("button-primary");
}
+ &-actions {
+
+ }
+
.Button {
flex-shrink: 1;
padding: 6px 10px;
diff --git a/resources/locale/en.yml b/resources/locale/en.yml
index 5fac60a6..6cbe41cd 100755
--- a/resources/locale/en.yml
+++ b/resources/locale/en.yml
@@ -61,6 +61,7 @@ fof-polls:
hide_votes_label: Hide votes until poll ends
allow_change_vote_label: Allow users to change their vote
question_placeholder: Question
+ subtitle_placeholder: Subtitle/Description (Optional)
submit: Submit
moderation:
diff --git a/src/Api/AddPostAttributes.php b/src/Api/AddPostAttributes.php
index bb206dfd..3430b9a8 100644
--- a/src/Api/AddPostAttributes.php
+++ b/src/Api/AddPostAttributes.php
@@ -11,9 +11,12 @@
namespace FoF\Polls\Api;
+use Flarum\Api\Serializer\PostSerializer;
+use Flarum\Post\Post;
+
class AddPostAttributes
{
- public function __invoke($serializer, $post, $attributes)
+ public function __invoke(PostSerializer $serializer, Post $post, array $attributes): array
{
$attributes['canStartPoll'] = $serializer->getActor()->can('startPoll', $post);
diff --git a/src/Api/Serializers/PollSerializer.php b/src/Api/Serializers/PollSerializer.php
index 52a7bcdd..13424e32 100755
--- a/src/Api/Serializers/PollSerializer.php
+++ b/src/Api/Serializers/PollSerializer.php
@@ -34,6 +34,7 @@ protected function getDefaultAttributes($poll)
$attributes = [
'question' => $poll->question,
+ 'subtitle' => $poll->subtitle,
'hasEnded' => $poll->hasEnded(),
'allowMultipleVotes' => $poll->allow_multiple_votes,
'maxVotes' => $poll->max_votes,
diff --git a/src/Commands/CreatePollHandler.php b/src/Commands/CreatePollHandler.php
index fe5f19e4..d7d9bfb5 100644
--- a/src/Commands/CreatePollHandler.php
+++ b/src/Commands/CreatePollHandler.php
@@ -110,6 +110,7 @@ public function handle(CreatePoll $command)
Arr::get($attributes, 'maxVotes'),
Arr::get($attributes, 'hideVotes'),
Arr::get($attributes, 'allowChangeVote'),
+ Arr::get($attributes, 'subtitle')
);
$this->events->dispatch(new SavingPollAttributes($command->actor, $poll, $attributes, $attributes));
diff --git a/src/Commands/EditPollHandler.php b/src/Commands/EditPollHandler.php
index a31da2ce..cb6a424d 100755
--- a/src/Commands/EditPollHandler.php
+++ b/src/Commands/EditPollHandler.php
@@ -72,6 +72,10 @@ public function handle(EditPoll $command)
$poll->question = $attributes['question'];
}
+ if (isset($attributes['subtitle'])) {
+ $poll->subtitle = empty($attributes['subtitle']) ? null : $attributes['subtitle'];
+ }
+
foreach (['publicPoll', 'allowMultipleVotes', 'hideVotes', 'allowChangeVote'] as $key) {
if (isset($attributes[$key])) {
$poll->settings[Str::snake($key)] = (bool) $attributes[$key];
diff --git a/src/Poll.php b/src/Poll.php
index c448ac82..ad759dab 100755
--- a/src/Poll.php
+++ b/src/Poll.php
@@ -20,8 +20,9 @@
use Illuminate\Support\Arr;
/**
- * @property int $id
- * @property string $question
+ * @property int $id
+ * @property string $question
+ * @property string|null $subtitle
* @property-read bool $public_poll
* @property-read bool $allow_multiple_votes
* @property-read int $max_votes
@@ -30,7 +31,7 @@
* @property int $vote_count
* @property Post $post
* @property User $user
- * @property int $post_id
+ * @property int|null $post_id
* @property int $user_id
* @property \Carbon\Carbon|null $end_date
* @property \Carbon\Carbon $created_at
@@ -66,11 +67,12 @@ class Poll extends AbstractModel
*
* @return static
*/
- public static function build($question, $postId, $actorId, $endDate, $publicPoll, $allowMultipleVotes = false, $maxVotes = 0, $hideVotes = false, $allowChangeVote = true)
+ public static function build($question, $postId, $actorId, $endDate, $publicPoll, $allowMultipleVotes = false, $maxVotes = 0, $hideVotes = false, $allowChangeVote = true, $subtitle = null)
{
$poll = new static();
$poll->question = $question;
+ $poll->subtitle = $subtitle;
$poll->post_id = $postId;
$poll->user_id = $actorId;
$poll->end_date = $endDate;
diff --git a/tests/integration/api/CreatePollTest.php b/tests/integration/api/CreatePollTest.php
index edcd1e6a..2975bc5a 100644
--- a/tests/integration/api/CreatePollTest.php
+++ b/tests/integration/api/CreatePollTest.php
@@ -128,6 +128,7 @@ public function authorized_user_can_create_poll_in_post(int $userId)
$this->assertNotNull($poll);
$this->assertEquals('What is your favourite colour?', $poll->question);
+ $this->assertNull($poll->subtitle);
$response = $this->send(
$this->request(
@@ -258,6 +259,7 @@ public function authorized_user_can_create_post_poll_on_api(int $userId)
$attributes = $data['attributes'];
$this->assertEquals('Add a poll to an existing post', $attributes['question']);
+ $this->assertNull($attributes['subtitle']);
$pollId = $data['id'];
$this->assertNotNull($pollId);
@@ -411,6 +413,7 @@ public function authorized_user_can_create_global_poll_on_api(int $userId)
$attributes = $data['attributes'];
$this->assertEquals('Add a global poll', $attributes['question']);
+ $this->assertNull($attributes['subtitle']);
$pollId = $data['id'];
$this->assertNotNull($pollId);
@@ -476,4 +479,125 @@ public function unauthorized_user_cannot_create_global_poll_on_api(int $userId)
$this->assertEquals(403, $response->getStatusCode());
}
+
+ /**
+ * @dataProvider authorizedUserProvider
+ *
+ * @test
+ */
+ public function authorized_user_can_create_a_poll_with_a_subtitle_via_api(int $userId)
+ {
+ $response = $this->send(
+ $this->request(
+ 'POST',
+ '/api/fof/polls',
+ [
+ 'authenticatedAs' => $userId,
+ 'json' => [
+ 'data' => [
+ 'attributes' => [
+ 'question' => 'Add a poll with a subtitle',
+ 'subtitle' => 'This is a subtitle',
+ 'publicPoll' => false,
+ 'hideVotes' => false,
+ 'allowChangeVote' => true,
+ 'allowMultipleVotes' => false,
+ 'maxVotes' => 0,
+ 'endDate' => false,
+ 'options' => [
+ [
+ 'answer' => 'Yes',
+ ],
+ [
+ 'answer' => 'No',
+ ],
+ ],
+ ],
+ ],
+ ],
+ ]
+ )
+ );
+
+ $this->assertEquals(201, $response->getStatusCode());
+
+ $json = json_decode($response->getBody()->getContents(), true);
+
+ $data = $json['data'];
+ $attributes = $data['attributes'];
+
+ $this->assertEquals('Add a poll with a subtitle', $attributes['question']);
+ $this->assertEquals('This is a subtitle', $attributes['subtitle']);
+ }
+
+ /**
+ * @dataProvider authorizedUserProvider
+ *
+ * @test
+ */
+ public function authorized_user_can_create_a_poll_with_a_subtitle_via_post(int $userId)
+ {
+ $response = $this->send(
+ $this->request(
+ 'POST',
+ '/api/posts',
+ [
+ 'authenticatedAs' => $userId,
+ 'json' => [
+ 'data' => [
+ 'attributes' => [
+ 'content' => 'Here is my poll',
+ 'poll' => [
+ 'question' => 'What is your favourite colour?',
+ 'subtitle' => 'This is a subtitle',
+ 'publicPoll' => false,
+ 'hideVotes' => false,
+ 'allowChangeVote' => true,
+ 'allowMultipleVotes' => false,
+ 'maxVotes' => 0,
+ 'endDate' => false,
+ 'options' => [
+ [
+ 'answer' => 'Red',
+ ],
+ [
+ 'answer' => 'Blue',
+ ],
+ [
+ 'answer' => 'Yellow',
+ ],
+ ],
+ ],
+ ],
+ 'relationships' => [
+ 'discussion' => [
+ 'data' => [
+ 'type' => 'discussions',
+ 'id' => 1,
+ ],
+ ],
+ ],
+ ],
+ ],
+ ]
+ )
+ );
+
+ $this->assertEquals(201, $response->getStatusCode());
+
+ $json = json_decode($response->getBody()->getContents(), true);
+ $data = $json['data'];
+
+ $this->assertArrayHasKey('polls', $data['relationships']);
+
+ $pollId = $data['relationships']['polls']['data'][0]['id'];
+ $this->assertNotNull($pollId);
+
+ $poll = Poll::find($pollId);
+
+ $this->assertNotNull($poll);
+
+ $this->assertEquals('What is your favourite colour?', $poll->question);
+ $this->assertEquals('This is a subtitle', $poll->subtitle);
+ }
}