Skip to content

Commit

Permalink
pkp#10280: Add user's stage assignment details to the response of sub…
Browse files Browse the repository at this point in the history
…missions/{id}/participants endpoint
  • Loading branch information
taslangraham committed Sep 11, 2024
1 parent f7b74d5 commit bb5ffca
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 65 deletions.
4 changes: 2 additions & 2 deletions api/v1/submissions/PKPSubmissionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ public function getParticipants(Request $illuminateRequest): JsonResponse
$context = $request->getContext();
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$args = $illuminateRequest->input();
$stageId = $args['stageId'] ?? null;
$stageId = $args['stageId'] ?? $illuminateRequest->route('stageId') !== null ? (int) $illuminateRequest->route('stageId') : null;

if (!$submission || $submission->getData('contextId') !== $context->getId()) {
return response()->json([
Expand All @@ -919,7 +919,7 @@ public function getParticipants(Request $illuminateRequest): JsonResponse

$map = Repo::user()->getSchemaMap();
foreach ($usersIterator as $user) {
$data[] = $map->summarizeReviewer($user);
$data[] = $map->summarizeReviewer($user, ['submission' => $submission, 'stageId' => $stageId]);
}

return response()->json($data, Response::HTTP_OK);
Expand Down
4 changes: 2 additions & 2 deletions classes/stageAssignment/StageAssignment.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function scopeWithStageIds(Builder $query, ?array $stageIds): Builder
public function scopeWithSubmissionIds(Builder $query, ?array $submissionIds): Builder
{
return $query->when($submissionIds !== null, function ($query) use ($submissionIds) {
return $query->whereIn('submission_id', $submissionIds);
return $query->whereIn('stage_assignments.submission_id', $submissionIds);
});
}

Expand Down Expand Up @@ -142,7 +142,7 @@ public function scopeWithContextId(Builder $query, ?int $contextId): Builder
{
return $query->when($contextId !== null, function ($query) use ($contextId) {
return $query->join('submissions', 'stage_assignments.submission_id', '=', 'submissions.submission_id')
->where('submissions.context_id', $contextId);
->where('submissions.context_id', $contextId);
});
}
}
177 changes: 116 additions & 61 deletions classes/user/maps/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,21 @@
use Illuminate\Support\Enumerable;
use PKP\db\DAORegistry;
use PKP\plugins\Hook;
use PKP\security\Role;
use PKP\services\PKPSchemaService;
use PKP\stageAssignment\StageAssignment;
use PKP\user\InterestDAO;
use PKP\user\InterestEntryDAO;
use PKP\user\User;
use PKP\workflow\WorkflowStageDAO;
use Submission;

class Schema extends \PKP\core\maps\Schema
{
public Enumerable $collection;

public string $schema = PKPSchemaService::SCHEMA_USER;

/**
* Map a publication
*
* Includes all properties in the user schema.
*/
public function map(User $item): array
{
return $this->mapByProperties($this->getProps(), $item);
}

/**
* Summarize a user
*
* Includes properties with the apiSummary flag in the user schema.
*/
public function summarize(User $item): array
{
return $this->mapByProperties($this->getSummaryProps(), $item);
}

/**
* Summarize a user with reviewer data
*
* Includes properties with the apiSummary flag in the user schema.
*/
public function summarizeReviewer(User $item): array
{
return $this->mapByProperties(array_merge($this->getSummaryProps(), ['reviewsActive', 'reviewsCompleted', 'reviewsDeclined', 'reviewsCancelled', 'averageReviewCompletionDays', 'dateLastReviewAssignment', 'reviewerRating']), $item);
}

/**
* Map a collection of Users
*
Expand All @@ -70,44 +46,30 @@ public function mapMany(Enumerable $collection): Enumerable
}

/**
* Summarize a collection of users
*
* @see self::summarize
*/
public function summarizeMany(Enumerable $collection): Enumerable
{
$this->collection = $collection;
return $collection->map(function ($item) {
return $this->summarize($item);
});
}

/**
* Summarize a collection of reviewers
* Map a publication
*
* @see self::summarizeReviewer
* Includes all properties in the user schema.
*/
public function summarizeManyReviewers(Enumerable $collection): Enumerable
public function map(User $item): array
{
$this->collection = $collection;
return $collection->map(function ($item) {
return $this->summarizeReviewer($item);
});
return $this->mapByProperties($this->getProps(), $item);
}

/**
* Map schema properties of a user to an assoc array
*
* @param array $auxiliaryData - Associative array used to supplementary data needed to populate properties on the response.
*
* @hook UserSchema::getProperties::values [[$this, &$output, $user, $props]]
*/
protected function mapByProperties(array $props, User $user): array
protected function mapByProperties(array $props, User $user, array $auxiliaryData): array
{
$output = [];

foreach ($props as $prop) {
switch ($prop) {
case 'id':
$output[$prop] = (int) $user->getId();
$output[$prop] = (int)$user->getId();
break;
case 'fullName':
$output[$prop] = $user->getFullName();
Expand Down Expand Up @@ -151,35 +113,82 @@ protected function mapByProperties(array $props, User $user): array
$output[$prop] = [];
foreach ($userGroups as $userGroup) {
$output[$prop][] = [
'id' => (int) $userGroup->getId(),
'id' => (int)$userGroup->getId(),
'name' => $userGroup->getName(null),
'abbrev' => $userGroup->getAbbrev(null),
'roleId' => (int) $userGroup->getRoleId(),
'showTitle' => (bool) $userGroup->getShowTitle(),
'permitSelfRegistration' => (bool) $userGroup->getPermitSelfRegistration(),
'permitMetadataEdit' => (bool) $userGroup->getPermitMetadataEdit(),
'recommendOnly' => (bool) $userGroup->getRecommendOnly(),
'roleId' => (int)$userGroup->getRoleId(),
'showTitle' => (bool)$userGroup->getShowTitle(),
'permitSelfRegistration' => (bool)$userGroup->getPermitSelfRegistration(),
'permitMetadataEdit' => (bool)$userGroup->getPermitMetadataEdit(),
'recommendOnly' => (bool)$userGroup->getRecommendOnly(),
];
}
}
break;
case 'interests':
$output[$prop] = [];
if ($this->context) {
$interestDao = DAORegistry::getDAO('InterestDAO'); /** @var \PKP\user\InterestDAO $interestDao */
$interestDao = DAORegistry::getDAO('InterestDAO'); /** @var InterestDAO $interestDao */
$interestEntryIds = $interestDao->getUserInterestIds($user->getId());
if (!empty($interestEntryIds)) {
$interestEntryDao = DAORegistry::getDAO('InterestEntryDAO'); /** @var \PKP\user\InterestEntryDAO $interestEntryDao */
$interestEntryDao = DAORegistry::getDAO('InterestEntryDAO'); /** @var InterestEntryDAO $interestEntryDao */
$results = $interestEntryDao->getByIds($interestEntryIds);
$output[$prop] = [];
while ($interest = $results->next()) {
$output[$prop][] = [
'id' => (int) $interest->getId(),
'id' => (int)$interest->getId(),
'interest' => $interest->getInterest(),
];
}
}
}
break;
case 'stageAssignments':
$submission = $auxiliaryData['submission'];
$stageId = $auxiliaryData['stageId'];

if((!isset($submission) || !isset($stageId)) || (!($submission instanceof Submission) || !is_numeric($auxiliaryData['stageId']))) {
$output['stageAssignments'] = [];
break;
}

// Get User's stage assignments for submission.
// Note:
// - A User can potentially have multiple assignments for a submission.
// - A User can potentially have multiple assignments for a stage of a submission.
$stageAssignments = StageAssignment::withSubmissionIds([$submission->getId()])
->withStageIds($stageId ? [$stageId] : [])
->withUserId($user->getId())
->withContextId($this->context->getId())
->get();

$results = [];

foreach ($stageAssignments as $stageAssignment /**@var StageAssignment $stageAssignment*/) {
// Get related user group info for stage assignment
$userGroup = Repo::userGroup()->get($stageAssignment->userGroupId);

// Only prepare data for non-reviewer participants
if ($userGroup->getRoleId() !== Role::ROLE_ID_REVIEWER) {
$entry = [
'stageAssignmentId' => $stageAssignment->id,
'stageAssignmentUserGroup' => $userGroup->getAllData(),
'stageAssignmentStageId' => $stageId,
];


$workflowStageDao = DAORegistry::getDAO('WorkflowStageDAO'); /** @var WorkflowStageDAO $workflowStageDao */
$entry['stageAssignmentStage'] = [
'id' => $stageId,
'label' => __($workflowStageDao->getTranslationKeyFromId($stageId)),
];

$results[] = $entry;
}

$output['stageAssignments'] = $results;
}

break;
default:
$output[$prop] = $user->getData($prop);
Expand All @@ -195,4 +204,50 @@ protected function mapByProperties(array $props, User $user): array

return $output;
}

/**
* Summarize a collection of users
*
* @see self::summarize
*/
public function summarizeMany(Enumerable $collection): Enumerable
{
$this->collection = $collection;
return $collection->map(function ($item) {
return $this->summarize($item);
});
}

/**
* Summarize a user
*
* Includes properties with the apiSummary flag in the user schema.
*/
public function summarize(User $item): array
{
return $this->mapByProperties($this->getSummaryProps(), $item);
}

/**
* Summarize a collection of reviewers
*
* @see self::summarizeReviewer
*/
public function summarizeManyReviewers(Enumerable $collection): Enumerable
{
$this->collection = $collection;
return $collection->map(function ($item) {
return $this->summarizeReviewer($item);
});
}

/**
* Summarize a user with reviewer data
*
* Includes properties with the apiSummary flag in the user schema.
*/
public function summarizeReviewer(User $item, array $auxiliaryData): array
{
return $this->mapByProperties(array_merge($this->getSummaryProps(), ['reviewsActive', 'reviewsCompleted', 'reviewsDeclined', 'reviewsCancelled', 'averageReviewCompletionDays', 'dateLastReviewAssignment', 'reviewerRating']), $item, $auxiliaryData);
}
}
31 changes: 31 additions & 0 deletions schemas/user.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,37 @@
"validation": [
"nullable"
]
},
"stageAssignments": {
"apiSummary": true,
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"stageAssignmentId": {
"type": "integer"
},
"stageAssignmentUserGroup": {
"type": "object",
"$ref": "#/definitions/UserGroup"
},
"stageAssignmentStageId": {
"type": "integer"
},
"stageAssignmentStage": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"label": {
"type": "string"
}
}
}
}
}
}
}
}

0 comments on commit bb5ffca

Please sign in to comment.