Skip to content

Commit

Permalink
pkp#1660 Customizable Reviewer Recommendations
Browse files Browse the repository at this point in the history
  • Loading branch information
touhidurabir committed Nov 6, 2024
1 parent 499f720 commit 3ac9bd9
Show file tree
Hide file tree
Showing 15 changed files with 796 additions and 1 deletion.
175 changes: 175 additions & 0 deletions api/v1/reviewers/recommendations/ReviewerRecommendationController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php

/**
* @file api/v1/reviewers/recommendations/ReviewerRecommendationController.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ReviewerRecommendationController
*
* @brief
*
*/

namespace PKP\API\v1\reviewers\recommendations;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Route;
use PKP\API\v1\reviewers\recommendations\resources\ReviewerRecommendationResource;
use PKP\submission\reviewer\recommendation\ReviewerRecommendation;
use PKP\API\v1\reviewers\recommendations\formRequests\AddReviewerRecommendation;
use PKP\API\v1\reviewers\recommendations\formRequests\EditReviewerRecommendation;
use PKP\core\PKPBaseController;
use PKP\core\PKPRequest;
use PKP\security\authorization\ContextAccessPolicy;
use PKP\security\authorization\UserRolesRequiredPolicy;
use PKP\security\Role;

class ReviewerRecommendationController extends PKPBaseController
{
/**
* @copydoc \PKP\core\PKPBaseController::getHandlerPath()
*/
public function getHandlerPath(): string
{
return 'contexts/{contextId}/reviewers/recommendations';
}

/**
* @copydoc \PKP\core\PKPBaseController::getRouteGroupMiddleware()
*/
public function getRouteGroupMiddleware(): array
{
return [
'has.user',
'has.context',
self::roleAuthorizer([
Role::ROLE_ID_SITE_ADMIN,
Role::ROLE_ID_MANAGER,
Role::ROLE_ID_SUB_EDITOR,
]),
];
}

/**
* @copydoc \PKP\core\PKPBaseController::authorize()
*/
public function authorize(PKPRequest $request, array &$args, array $roleAssignments): bool
{
$this->addPolicy(new UserRolesRequiredPolicy($request), true);
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));

return parent::authorize($request, $args, $roleAssignments);
}

/**
* @copydoc \PKP\core\PKPBaseController::getGroupRoutes()
*/
public function getGroupRoutes(): void
{
Route::get('{recommendationId}', $this->get(...))
->name('reviewer.recommendations.get')
->whereNumber(['contextId', 'recommendationId']);

Route::get('', $this->getMany(...))
->name('reviewer.recommendations.getMany')
->whereNumber(['contextId']);

Route::post('', $this->add(...))
->name('reviewer.recommendations.add')
->whereNumber(['contextId']);

Route::put('{recommendationId}', $this->edit(...))
->name('reviewer.recommendations.edit')
->whereNumber(['contextId', 'recommendationId']);

Route::delete('{recommendationId}', $this->delete(...))
->name('reviewer.recommendations.delete')
->whereNumber(['contextId', 'recommendationId']);
}

public function get(Request $illuminateRequest): JsonResponse
{
$recommendation = ReviewerRecommendation::find($illuminateRequest->route('recommendationId'));

if (!$recommendation) {
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}

return response()->json(
(new ReviewerRecommendationResource($recommendation))->toArray($illuminateRequest),
Response::HTTP_OK
);
}

public function getMany(Request $illuminateRequest): JsonResponse
{
$recommendations = ReviewerRecommendation::query()
->withContextId($illuminateRequest->route('contextId'))
->get();

return response()->json([
'items' => ReviewerRecommendationResource::collection($recommendations),
'itemMax' => $recommendations->count(),
], Response::HTTP_OK);
}

public function add(AddReviewerRecommendation $illuminateRequest): JsonResponse
{
$validateds = $illuminateRequest->validated();

$recommendation = ReviewerRecommendation::create($validateds);

return response()->json(
(new ReviewerRecommendationResource($recommendation->refresh()))
->toArray($illuminateRequest),
Response::HTTP_OK
);
}

public function edit(EditReviewerRecommendation $illuminateRequest): JsonResponse
{
$validated = $illuminateRequest->validated();

$recommendation = ReviewerRecommendation::find($illuminateRequest->route('recommendationId'));

if (!$recommendation->update($validated)) {
return response()->json([
'error' => __('api.409.resourceActionConflict'),
], Response::HTTP_CONFLICT);
}

return response()->json(
(new ReviewerRecommendationResource($recommendation->refresh()))
->toArray($illuminateRequest),
Response::HTTP_OK
);
}

public function delete(Request $illuminateRequest): JsonResponse
{
$recommendation = ReviewerRecommendation::find($illuminateRequest->route('recommendationId'));

if (!$recommendation) {
return response()->json([
'error' => __('api.404.resourceNotFound'),
], Response::HTTP_NOT_FOUND);
}

if (!$recommendation->removable) {
return response()->json([
'error' => __('api.406.notAcceptable'),
], Response::HTTP_NOT_ACCEPTABLE);
}

$recommendation->delete();

return response()->json([], Response::HTTP_OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

// TODO : update once pkp/pkp-lib#4787 merged
/**
* @file api/v1/reviewers/recommendations/formRequests/AddReviewerRecommendation.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class AddReviewerRecommendation
*
* @brief
*
*/

namespace PKP\API\v1\reviewers\recommendations\formRequests;

use APP\core\Application;
use Illuminate\Validation\Rule;
use Illuminate\Foundation\Http\FormRequest;

class AddReviewerRecommendation extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
$contextDao = Application::getContextDAO();

return [
'contextId' => [
'required',
'integer',
Rule::exists($contextDao->tableName, $contextDao->primaryKeyColumn),
],
'title' => [
'required',
],
'status' => [
'required',
'boolean'
],
];
}

/**
* Prepare the data for validation.
*/
protected function prepareForValidation(): void
{
$this->merge([
'contextId' => $this->route('contextId'),
'removable' => 1,
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

// TODO : update once pkp/pkp-lib#4787 merged
/**
* @file api/v1/reviewers/recommendations/formRequests/EditReviewerRecommendation.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class EditReviewerRecommendation
*
* @brief
*
*/

namespace PKP\API\v1\reviewers\recommendations\formRequests;

use Illuminate\Foundation\Http\FormRequest;

class EditReviewerRecommendation extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => [
'required',
],
'status' => [
'required',
'boolean'
],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* @file api/v1/reviewers/recommendations/resources/ReviewerRecommendationResource.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ReviewerRecommendationResource
*
* @brief
*
*/

namespace PKP\API\v1\reviewers\recommendations\resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class ReviewerRecommendationResource extends JsonResource
{
/**
* Transform the resource into an array.
*/
public function toArray(Request $request)
{
return [
'id' => $this->id,
'contextId' => $this->contextId,
'status' => $this->status,
'removable' => $this->removable,
'title' => $this->title,
];
}
}
61 changes: 61 additions & 0 deletions classes/components/forms/context/ReviewerRecommendationForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* @file classes/components/form/context/ReviewerRecommendationForm.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ReviewerRecommendationForm
*
* @brief
*/

namespace PKP\components\forms\context;

use PKP\components\forms\FieldSelect;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;

class ReviewerRecommendationForm extends FormComponent
{
public const FORM_REVIEW_RECOMMENDATION = 'reviewerRecommendation';
public $id = self::FORM_REVIEW_RECOMMENDATION;
public $method = 'POST';

/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales)
{
$this->action = $action;
$this->locales = $locales;

$this
->addField(new FieldText('title', [
'label' => __('manager.reviewerRecommendations.title.label'),
'description' => __('manager.reviewerRecommendations.title.description'),
'size' => 'large',
'isRequired' => true,
'isMultilingual' => true,
]))
->addField(new FieldSelect('status', [
'options' => [
[
'label' => __('manager.reviewerRecommendations.activateUponSaving.label'),
'value' => true,
],
[
'label' => __('manager.reviewerRecommendations.activateUponSaving.deactivate'),
'value' => false,
],
],
'value' => true,
'size' => 'normal',
]));
}
}
Loading

0 comments on commit 3ac9bd9

Please sign in to comment.