Skip to content

Commit

Permalink
fix(polls): Split draft model from normal polls
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <coding@schilljs.com>
  • Loading branch information
nickvergessen committed Oct 10, 2024
1 parent 3225a1c commit d06b955
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 87 deletions.
7 changes: 4 additions & 3 deletions lib/Controller/PollController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

/**
* @psalm-import-type TalkPoll from ResponseDefinitions
* @psalm-import-type TalkPollDraft from ResponseDefinitions
*/
class PollController extends AEnvironmentAwareController {

Expand Down Expand Up @@ -134,7 +135,7 @@ public function createPoll(string $question, array $options, int $resultMode, in
*
* Required capability: `talk-polls-drafts`
*
* @return DataResponse<Http::STATUS_OK, list<TalkPoll>, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, list<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<TalkPollDraft>, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, list<empty>, array{}>
*
* 200: Poll returned
* 403: User is not a moderator
Expand All @@ -153,7 +154,7 @@ public function getAllDraftPolls(): DataResponse {
$polls = $this->pollService->getDraftsForRoom($this->room->getId());
$data = [];
foreach ($polls as $poll) {
$data[] = $this->renderPoll($poll);
$data[] = $poll->renderAsDraft();
}

return new DataResponse($data);
Expand Down Expand Up @@ -346,7 +347,7 @@ public function closePoll(int $pollId): DataResponse {
* @throws JsonException
*/
protected function renderPoll(Poll $poll, array $votedSelf = [], array $detailedVotes = []): array {
$data = $poll->asArray();
$data = $poll->renderAsPoll();

$canSeeSummary = !empty($votedSelf) && $poll->getResultMode() === Poll::MODE_PUBLIC;

Expand Down
5 changes: 3 additions & 2 deletions lib/Federation/Proxy/TalkV1/Controller/PollController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

/**
* @psalm-import-type TalkPoll from ResponseDefinitions
* @psalm-import-type TalkPollDraft from ResponseDefinitions
*/
class PollController {
public function __construct(
Expand All @@ -29,7 +30,7 @@ public function __construct(
}

/**
* @return DataResponse<Http::STATUS_OK, list<TalkPoll>, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, list<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, list<TalkPollDraft>, array{}>|DataResponse<Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, list<empty>, array{}>
* @throws CannotReachRemoteException
*
* 200: Polls returned
Expand All @@ -49,7 +50,7 @@ public function getDraftsForRoom(Room $room, Participant $participant): DataResp
return new DataResponse([], $status);
}

/** @var list<TalkPoll> $list */
/** @var list<TalkPollDraft> $list */
$list = $this->proxy->getOCSData($proxy);

$data = [];
Expand Down
8 changes: 6 additions & 2 deletions lib/Federation/Proxy/TalkV1/UserConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
/**
* @psalm-import-type TalkChatMessageWithParent from ResponseDefinitions
* @psalm-import-type TalkPoll from ResponseDefinitions
* @psalm-import-type TalkPollDraft from ResponseDefinitions
* @psalm-import-type TalkReaction from ResponseDefinitions
*/
class UserConverter {
Expand Down Expand Up @@ -137,9 +138,12 @@ public function convertMessages(Room $room, array $messages): array {
}

/**
* @template T of TalkPoll|TalkPollDraft
* @param Room $room
* @param TalkPoll $poll
* @return TalkPoll
* @param TalkPoll|TalkPollDraft $poll
* @psalm-param T $poll
* @return TalkPoll|TalkPollDraft
* @psalm-return T
*/
public function convertPoll(Room $room, array $poll): array {
$poll = $this->convertAttendee($room, $poll, 'actorType', 'actorId', 'actorDisplayName');
Expand Down
18 changes: 13 additions & 5 deletions lib/Model/Poll.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* @method int getMaxVotes()
*
* @psalm-import-type TalkPoll from ResponseDefinitions
* @psalm-import-type TalkPollDraft from ResponseDefinitions
*/
class Poll extends Entity {
public const STATUS_OPEN = 0;
Expand Down Expand Up @@ -75,25 +76,32 @@ public function __construct() {
/**
* @return TalkPoll
*/
public function asArray(): array {
public function renderAsPoll(): array {
$data = $this->renderAsDraft();
$votes = json_decode($this->getVotes(), true, 512, JSON_THROW_ON_ERROR);

// Because PHP is turning arrays with sequent numeric keys "{"0":x,"1":y,"2":z}" into "[x,y,z]"
// when json_encode() is used we have to prefix the keys with a string,
// to prevent breaking in the mobile apps.
$prefixedVotes = [];
$data['votes'] = [];
foreach ($votes as $option => $count) {
$prefixedVotes['option-' . $option] = $count;
$data['votes']['option-' . $option] = $count;
}
$data['numVoters'] = $this->getNumVoters();

return $data;
}

/**
* @return TalkPollDraft
*/
public function renderAsDraft(): array {
return [
'id' => $this->getId(),
// The room id is not needed on the API level but only internally for optimising database queries
// 'roomId' => $this->getRoomId(),
'question' => $this->getQuestion(),
'options' => json_decode($this->getOptions(), true, 512, JSON_THROW_ON_ERROR),
'votes' => $prefixedVotes,
'numVoters' => $this->getNumVoters(),
'actorType' => $this->getActorType(),
'actorId' => $this->getActorId(),
'actorDisplayName' => $this->getDisplayName(),
Expand Down
3 changes: 2 additions & 1 deletion lib/Model/PollMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public function getDraftsByRoomId(int $roomId): array {
$query->select('*')
->from($this->getTableName())
->where($query->expr()->eq('room_id', $query->createNamedParameter($roomId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('status', $query->createNamedParameter(Poll::STATUS_DRAFT, IQueryBuilder::PARAM_INT)));
->andWhere($query->expr()->eq('status', $query->createNamedParameter(Poll::STATUS_DRAFT, IQueryBuilder::PARAM_INT)))
->orderBy('id', 'ASC');

return $this->findEntities($query);
}
Expand Down
9 changes: 6 additions & 3 deletions lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,21 @@
* optionId: int,
* }
*
* @psalm-type TalkPoll = array{
* @psalm-type TalkPollDraft = array{
* actorDisplayName: string,
* actorId: string,
* actorType: string,
* details?: TalkPollVote[],
* id: int,
* maxVotes: int,
* numVoters?: int,
* options: string[],
* question: string,
* resultMode: int,
* status: int,
* }
*
* @psalm-type TalkPoll = TalkPollDraft&array{
* details?: TalkPollVote[],
* numVoters?: int,
* votedSelf?: int[],
* votes?: array<string, int>,
* }
Expand Down
62 changes: 37 additions & 25 deletions openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,42 @@
}
},
"Poll": {
"allOf": [
{
"$ref": "#/components/schemas/PollDraft"
},
{
"type": "object",
"properties": {
"details": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PollVote"
}
},
"numVoters": {
"type": "integer",
"format": "int64"
},
"votedSelf": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
},
"votes": {
"type": "object",
"additionalProperties": {
"type": "integer",
"format": "int64"
}
}
}
}
]
},
"PollDraft": {
"type": "object",
"required": [
"actorDisplayName",
Expand All @@ -864,12 +900,6 @@
"actorType": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PollVote"
}
},
"id": {
"type": "integer",
"format": "int64"
Expand All @@ -878,10 +908,6 @@
"type": "integer",
"format": "int64"
},
"numVoters": {
"type": "integer",
"format": "int64"
},
"options": {
"type": "array",
"items": {
Expand All @@ -898,20 +924,6 @@
"status": {
"type": "integer",
"format": "int64"
},
"votedSelf": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
},
"votes": {
"type": "object",
"additionalProperties": {
"type": "integer",
"format": "int64"
}
}
}
},
Expand Down Expand Up @@ -8904,7 +8916,7 @@
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Poll"
"$ref": "#/components/schemas/PollDraft"
}
}
}
Expand Down
62 changes: 37 additions & 25 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,42 @@
}
},
"Poll": {
"allOf": [
{
"$ref": "#/components/schemas/PollDraft"
},
{
"type": "object",
"properties": {
"details": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PollVote"
}
},
"numVoters": {
"type": "integer",
"format": "int64"
},
"votedSelf": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
},
"votes": {
"type": "object",
"additionalProperties": {
"type": "integer",
"format": "int64"
}
}
}
}
]
},
"PollDraft": {
"type": "object",
"required": [
"actorDisplayName",
Expand All @@ -751,12 +787,6 @@
"actorType": {
"type": "string"
},
"details": {
"type": "array",
"items": {
"$ref": "#/components/schemas/PollVote"
}
},
"id": {
"type": "integer",
"format": "int64"
Expand All @@ -765,10 +795,6 @@
"type": "integer",
"format": "int64"
},
"numVoters": {
"type": "integer",
"format": "int64"
},
"options": {
"type": "array",
"items": {
Expand All @@ -785,20 +811,6 @@
"status": {
"type": "integer",
"format": "int64"
},
"votedSelf": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
},
"votes": {
"type": "object",
"additionalProperties": {
"type": "integer",
"format": "int64"
}
}
}
},
Expand Down Expand Up @@ -8791,7 +8803,7 @@
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Poll"
"$ref": "#/components/schemas/PollDraft"
}
}
}
Expand Down
Loading

0 comments on commit d06b955

Please sign in to comment.