diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e6a606e..0a57280 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,5 +6,5 @@ include:
ref: main
file:
- 'templates/groups/pkp_plugin.yml'
- - 'templates/groups/ops_3_4_plugins_unit_tests_model.yml'
- - 'templates/groups/ops_3_4_plugins_cypress_tests_model.yml'
\ No newline at end of file
+ - 'templates/groups/ops/unit_tests.yml'
+ - 'templates/groups/ops/cypress_tests.yml'
\ No newline at end of file
diff --git a/PlauditPreEndorsementPlugin.php b/PlauditPreEndorsementPlugin.php
index 444ee0d..9eb5234 100644
--- a/PlauditPreEndorsementPlugin.php
+++ b/PlauditPreEndorsementPlugin.php
@@ -23,17 +23,20 @@
use PKP\log\event\PKPSubmissionEventLogEntry;
use PKP\db\DAORegistry;
use PKP\core\Core;
-use APP\facades\Repo;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
use PKP\security\Role;
use PKP\core\JSONMessage;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Mail;
use APP\plugins\generic\plauditPreEndorsement\classes\OrcidClient;
-use APP\plugins\generic\plauditPreEndorsement\classes\Endorsement;
+use APP\plugins\generic\plauditPreEndorsement\classes\endorsement\Endorsement;
use APP\plugins\generic\plauditPreEndorsement\classes\components\forms\EndorsementForm;
use APP\plugins\generic\plauditPreEndorsement\PlauditPreEndorsementSettingsForm;
use APP\plugins\generic\plauditPreEndorsement\classes\mail\mailables\OrcidRequestEndorserAuthorization;
use APP\plugins\generic\plauditPreEndorsement\classes\observers\listeners\SendEmailToEndorser;
+use APP\plugins\generic\plauditPreEndorsement\classes\SchemaBuilder;
+use APP\plugins\generic\plauditPreEndorsement\classes\migration\addEndorsementsTable;
+use Illuminate\Database\Migrations\Migration;
class PlauditPreEndorsementPlugin extends GenericPlugin
{
@@ -50,14 +53,24 @@ public function register($category, $path, $mainContextId = null)
if ($success && $this->getEnabled($mainContextId)) {
Event::subscribe(new SendEmailToEndorser());
- Hook::add('TemplateManager::display', [$this, 'modifySubmissionSteps']);
- Hook::add('Schema::get::publication', [$this, 'addOurFieldsToPublicationSchema']);
- Hook::add('Submission::validateSubmit', [$this, 'validateEndorsement']);
- Hook::add('Template::SubmissionWizard::Section::Review', [$this, 'modifyReviewSections']);
+ Hook::add('TemplateManager::display', [$this, 'addToSubmissionWizardSteps']);
+ Hook::add('Template::SubmissionWizard::Section', array($this, 'addToSubmissionWizardTemplate'));
+ Hook::add('Template::SubmissionWizard::Section::Review', [$this, 'addToReviewSubmissionWizardTemplate']);
+ Hook::add('Schema::get::endorsement', [$this, 'addEndorsementSchema']);
- Hook::add('Template::Workflow::Publication', [$this, 'addEndorserFieldsToWorkflow']);
+ Hook::add('Template::Workflow::Publication', [$this, 'addEndorsementFieldsToWorkflow']);
Hook::add('LoadHandler', [$this, 'setupPreEndorsementHandler']);
Hook::add('AcronPlugin::parseCronTab', [$this, 'addEndorsementTasksToCrontab']);
+ Hook::add('LoadComponentHandler', [$this, 'setupGridHandler']);
+
+ $templateMgr = TemplateManager::getManager();
+ $request = Application::get()->getRequest();
+
+ $templateMgr->addJavaScript(
+ 'EndorsementGridHandler',
+ $request->getBaseUrl() . '/' . $this->getPluginPath() . '/js/EndorsementGridHandler.js',
+ array('contexts' => 'backend')
+ );
}
return $success;
@@ -110,19 +123,12 @@ public function writeOnActivityLog($submission, $message, $messageParams = array
Repo::eventLog()->add($eventLog);
}
- public function inputIsEmail(string $input): bool
- {
- return filter_var($input, FILTER_VALIDATE_EMAIL);
- }
-
- public function modifySubmissionSteps($hookName, $params)
+ public function addToSubmissionWizardSteps($hookName, $params)
{
$request = Application::get()->getRequest();
- $context = $request->getContext();
- $templateMgr = $params[0];
- if ($request->getRequestedPage() != 'submission' || $request->getRequestedOp() == 'saved') {
- return false;
+ if ($request->getRequestedPage() !== 'submission' || $request->getRequestedOp() == 'saved') {
+ return;
}
$submission = $request
@@ -131,96 +137,70 @@ public function modifySubmissionSteps($hookName, $params)
->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
if (!$submission || !$submission->getData('submissionProgress')) {
- return false;
+ return;
}
- $publication = $submission->getCurrentPublication();
- $publicationApiUrl = $request->getDispatcher()->url(
- $request,
- Application::ROUTE_API,
- $request->getContext()->getPath(),
- 'submissions/' . $submission->getId() . '/publications/' . $publication->getId()
- );
- $endorsementForm = new EndorsementForm(
- $publicationApiUrl,
- $publication,
- );
+ $templateMgr = $params[0];
$steps = $templateMgr->getState('steps');
- $steps = array_map(function ($step) use ($endorsementForm) {
- if ($step['id'] == 'details') {
+ $steps = array_map(function ($step) {
+ if ($step['id'] === 'details') {
$step['sections'][] = [
- 'id' => 'endorsement',
+ 'id' => 'plauditPreEndorsement',
'name' => __('plugins.generic.plauditPreEndorsement.endorsement'),
'description' => __('plugins.generic.plauditPreEndorsement.endorsement.description'),
- 'type' => SubmissionHandler::SECTION_TYPE_FORM,
- 'form' => $endorsementForm->getConfig(),
+ 'type' => SubmissionHandler::SECTION_TYPE_TEMPLATE,
];
}
return $step;
}, $steps);
- $templateMgr->setState(['steps' => $steps]);
+ $templateMgr->setState([
+ 'steps' => $steps,
+ ]);
return false;
}
- public function validateEndorsement($hookName, $params)
+ public function addToSubmissionWizardTemplate($hookName, $params)
{
- $errors = &$params[0];
- $submission = $params[1];
- $publication = $submission->getCurrentPublication();
- $endorserEmail = $publication->getData('endorserEmail');
+ $smarty = $params[1];
+ $output = & $params[2];
- if ($endorserEmail) {
- if (!$this->inputIsEmail($endorserEmail)) {
- $errors['endorsement'] = [__("plugins.generic.plauditPreEndorsement.endorsementEmailInvalid")];
- } else {
- foreach ($publication->getData('authors') as $author) {
- if($author->getData('email') == $endorserEmail) {
- $errors['endorsement'] = [__("plugins.generic.plauditPreEndorsement.endorsementFromAuthor")];
- }
- }
- }
- }
+ $output .= sprintf(
+ '%s ',
+ $smarty->fetch($this->getTemplateResource('endorsementComponent.tpl'))
+ );
return false;
}
- public function modifyReviewSections($hookName, $params)
+ public function addToReviewSubmissionWizardTemplate($hookName, $params)
{
$step = $params[0]['step'];
$templateMgr = $params[1];
$output = &$params[2];
if ($step == 'details') {
- $output .= $templateMgr->fetch($this->getTemplateResource('reviewEndorsement.tpl'));
+ $output .= $templateMgr->fetch($this->getTemplateResource('endorsementComponent.tpl'));
}
+
+ return false;
}
- public function addOurFieldsToPublicationSchema($hookName, $params)
+ public function addEndorsementSchema(string $hookName, array $params): bool
{
$schema = &$params[0];
- $ourFields = [
- 'endorserName' => 'string',
- 'endorserEmail' => 'string',
- 'endorsementStatus' => 'integer',
- 'endorserOrcid' => 'string',
- 'endorserEmailToken' => 'string',
- 'endorserEmailCount' => 'integer',
- ];
-
- foreach ($ourFields as $name => $type) {
- $schema->properties->{$name} = (object) [
- 'type' => $type,
- 'apiSummary' => true,
- 'validation' => ['nullable'],
- ];
- }
+ $schema = SchemaBuilder::get('endorsement');
+ return true;
+ }
- return false;
+ public function getInstallMigration(): Migration
+ {
+ return new addEndorsementsTable();
}
+
private function getEndorsementStatusSuffix($endorsementStatus): string
{
$mapStatusToSuffix = [
@@ -234,90 +214,78 @@ private function getEndorsementStatusSuffix($endorsementStatus): string
return $mapStatusToSuffix[$endorsementStatus] ?? "";
}
- public function addEndorserFieldsToWorkflow($hookName, $params)
+ public function addEndorsementFieldsToWorkflow($hookName, $params)
{
$smarty = &$params[1];
$output = &$params[2];
$submission = $smarty->getTemplateVars('submission');
$publication = $submission->getCurrentPublication();
-
$request = Application::get()->getRequest();
- $handlerUrl = $request->getDispatcher()->url($request, Application::ROUTE_PAGE, null, self::HANDLER_PAGE);
-
- $endorsementStatus = $publication->getData('endorsementStatus');
- $endorsementStatusSuffix = $this->getEndorsementStatusSuffix($endorsementStatus);
- $canEditEndorsement = (is_null($endorsementStatus) || $endorsementStatus == Endorsement::STATUS_NOT_CONFIRMED || $endorsementStatus == Endorsement::STATUS_DENIED);
- $canSendEndorsementManually = $publication->getData('status') == STATUS_PUBLISHED
- && !$this->userAccessingIsAuthor($submission)
- && ($endorsementStatus == Endorsement::STATUS_CONFIRMED || $endorsementStatus == Endorsement::STATUS_COULDNT_COMPLETE);
- $canRemoveEndorsement = !is_null($endorsementStatus) && !$this->userAccessingIsAuthor($submission);
-
- $smarty->assign([
- 'submissionId' => $submission->getId(),
- 'endorserName' => $publication->getData('endorserName'),
- 'endorserEmail' => $publication->getData('endorserEmail'),
- 'endorserOrcid' => $publication->getData('endorserOrcid'),
- 'endorserEmailCount' => $publication->getData('endorserEmailCount'),
- 'endorsementStatus' => $endorsementStatus,
- 'endorsementStatusSuffix' => $endorsementStatusSuffix,
- 'canEditEndorsement' => $canEditEndorsement,
- 'canRemoveEndorsement' => $canRemoveEndorsement,
- 'canSendEndorsementManually' => $canSendEndorsementManually,
- 'handlerUrl' => $handlerUrl,
- ]);
- $tabBadge = (is_null($endorsementStatus) ? 'badge="0"' : 'badge="1"');
+ $countEndorsers = Repo::endorsement()->getCollector()
+ ->filterByContextIds([$request->getContext()->getId()])
+ ->filterByPublicationIds([$publication->getId()])
+ ->getCount();
+
+ $tabBadge = (empty($countEndorsers) ? 'badge="0"' : 'badge=' . $countEndorsers);
$output .= sprintf(
'%s ',
$tabBadge,
__('plugins.generic.plauditPreEndorsement.preEndorsement'),
- $smarty->fetch($this->getTemplateResource('endorserFieldWorkflow.tpl'))
+ $smarty->fetch($this->getTemplateResource('endorsementComponent.tpl'))
);
}
- public function sendEmailToEndorser($publication, $endorserChanged = false)
+ public function sendEmailToEndorser($publication, $endorsement, $endorsementChanged = false)
{
$request = Application::get()->getRequest();
$context = $request->getContext();
- $endorserName = $publication->getData('endorserName');
- $endorserEmail = $publication->getData('endorserEmail');
+ $endorsementName = $endorsement->getName();
+ $endorsementEmail = $endorsement->getEmail();
- if (!is_null($context) && !empty($endorserEmail)) {
+ if (!is_null($context) && !empty($endorsementEmail)) {
$submission = Repo::submission()->get($publication->getData('submissionId'));
$emailTemplate = Repo::emailTemplate()->getByKey(
$context->getId(),
'ORCID_REQUEST_ENDORSER_AUTHORIZATION'
);
- $endorserEmailToken = md5(microtime() . $endorserEmail);
+ $endorsementEmailToken = md5(microtime() . $endorsementEmail);
$orcidClient = new OrcidClient($this, $context->getId());
- $oauthUrl = $orcidClient->buildOAuthUrl(['token' => $endorserEmailToken, 'state' => $publication->getId()]);
+ $oauthUrl = $orcidClient->buildOAuthUrl(
+ [
+ 'token' => $endorsementEmailToken,
+ 'state' => $publication->getId(),
+ 'endorsementId' => $endorsement->getId()
+ ]
+ );
$emailParams = [
'orcidOauthUrl' => $oauthUrl,
- 'endorserName' => htmlspecialchars($endorserName),
+ 'endorserName' => htmlspecialchars($endorsementName),
];
$email = new OrcidRequestEndorserAuthorization($context, $submission, $emailParams);
$email->from($context->getData('contactEmail'), $context->getData('contactName'));
- $email->to([['name' => $endorserName, 'email' => $endorserEmail]]);
+ $email->to([['name' => $endorsementName, 'email' => $endorsementEmail]]);
$email->subject($emailTemplate->getLocalizedData('subject'));
$email->body($emailTemplate->getLocalizedData('body'));
Mail::send($email);
- if(is_null($publication->getData('endorserEmailCount')) || $endorserChanged) {
- $endorserEmailCount = 0;
+ if (is_null($endorsement->getEmailCount()) || $endorsementChanged) {
+ $endorsementEmailCount = 0;
} else {
- $endorserEmailCount = $publication->getData('endorserEmailCount');
+ $endorsementEmailCount = $endorsement->getEmailCount();
}
- $publication->setData('endorserEmailToken', $endorserEmailToken);
- $publication->setData('endorsementStatus', Endorsement::STATUS_NOT_CONFIRMED);
- $publication->setData('endorserEmailCount', $endorserEmailCount + 1);
- Repo::publication()->edit($publication, []);
+ $endorsement->setEmailToken($endorsementEmailToken);
+ $endorsement->setStatus(Endorsement::STATUS_NOT_CONFIRMED);
+ $endorsement->setEmailCount($endorsementEmailCount + 1);
- $this->writeOnActivityLog($submission, 'plugins.generic.plauditPreEndorsement.log.sentEmailEndorser', ['endorserName' => $endorserName, 'endorserEmail' => $endorserEmail]);
+ Repo::endorsement()->edit($endorsement, []);
+
+ $this->writeOnActivityLog($submission, 'plugins.generic.plauditPreEndorsement.log.sentEmailEndorser', ['endorserName' => $endorsementName, 'endorserEmail' => $endorsementEmail]);
}
}
@@ -390,4 +358,14 @@ public function userAccessingIsAuthor($submission): bool
return $currentUserAssignedRoles[0] == Role::ROLE_ID_AUTHOR;
}
+
+ public function setupGridHandler($hookName, $params)
+ {
+ $component = & $params[0];
+ if ($component == 'plugins.generic.plauditPreEndorsement.controllers.grid.EndorsementGridHandler') {
+ define('PLAUDIT_PRE_ENDORSEMENT_PLUGIN_NAME', $this->getName());
+ return true;
+ }
+ return false;
+ }
}
diff --git a/classes/Endorsement.php b/classes/Endorsement.php
deleted file mode 100644
index bd4bb5a..0000000
--- a/classes/Endorsement.php
+++ /dev/null
@@ -1,13 +0,0 @@
-orcidClient = $orcidClient;
}
- public function sendEndorsement($publication, $needCheckMessageWasLoggedToday = false)
+ public function sendEndorsement($endorsement, $needCheckMessageWasLoggedToday = false)
{
+ $publication = Repo::publication()->get($endorsement->getPublicationId());
$validationResult = $this->validateEndorsementSending($publication);
- if($validationResult == 'ok') {
- $this->sendEndorsementToPlaudit($publication);
+ if ($validationResult == 'ok') {
+ $this->sendEndorsementToPlaudit($endorsement, $publication);
} else {
$submissionId = $publication->getData('submissionId');
- if(!$needCheckMessageWasLoggedToday or !$this->messageWasAlreadyLoggedToday($submissionId, $validationResult)) {
+ if (!$needCheckMessageWasLoggedToday or !$this->messageWasAlreadyLoggedToday($submissionId, $validationResult)) {
$submission = Repo::submission()->get($submissionId);
$this->plugin->writeOnActivityLog($submission, $validationResult);
}
@@ -56,32 +57,39 @@ public function validateEndorsementSending($publication): string
$doi = $publication->getDoi();
$secretKey = $this->plugin->getSetting($this->contextId, 'plauditAPISecret');
- if(empty($doi)) {
+ if (empty($doi)) {
return 'plugins.generic.plauditPreEndorsement.log.failedEndorsementSending.emptyDoi';
}
- if(!$this->crossrefClient->doiIsIndexed($doi)) {
+ if (!$this->crossrefClient->doiIsIndexed($doi)) {
return 'plugins.generic.plauditPreEndorsement.log.failedEndorsementSending.doiNotIndexed';
}
- if(empty($secretKey)) {
+ if (empty($secretKey)) {
return 'plugins.generic.plauditPreEndorsement.log.failedEndorsementSending.secretKey';
}
return 'ok';
}
- public function sendEndorsementToPlaudit($publication)
+ public function sendEndorsementToPlaudit($endorsement, $publication)
{
$submission = Repo::submission()->get($publication->getData('submissionId'));
- $this->plugin->writeOnActivityLog($submission, 'plugins.generic.plauditPreEndorsement.log.attemptSendingEndorsement', ['doi' => $publication->getDoi(), 'orcid' => $publication->getData('endorserOrcid')]);
+ $this->plugin->writeOnActivityLog(
+ $submission,
+ 'plugins.generic.plauditPreEndorsement.log.attemptSendingEndorsement',
+ [
+ 'doi' => $publication->getDoi(),
+ 'orcid' => $endorsement->getOrcid()
+ ]
+ );
$plauditClient = new PlauditClient();
try {
$secretKey = $this->plugin->getSetting($this->contextId, 'plauditAPISecret');
- $response = $plauditClient->requestEndorsementCreation($publication, $secretKey);
- $newEndorsementStatus = $plauditClient->getEndorsementStatusByResponse($response, $publication);
+ $response = $plauditClient->requestEndorsementCreation($endorsement, $publication, $secretKey);
+ $newEndorsementStatus = $plauditClient->getEndorsementStatusByResponse($response, $publication, $endorsement);
} catch (ClientException $exception) {
$response = $exception->getResponse();
$responseCode = $response->getStatusCode();
@@ -91,22 +99,20 @@ public function sendEndorsementToPlaudit($publication)
$newEndorsementStatus = Endorsement::STATUS_COULDNT_COMPLETE;
}
- Repo::publication()->edit($publication, [
- 'endorsementStatus' => $newEndorsementStatus
- ]);
+ $endorsement->setStatus($newEndorsementStatus);
+ Repo::endorsement()->edit($endorsement, []);
}
- public function updateEndorserNameFromOrcid($publication, $orcid)
+ public function updateEndorsementNameFromOrcid($endorsement, $orcid)
{
$accessToken = $this->orcidClient->getReadPublicAccessToken();
$orcidRecord = $this->orcidClient->getOrcidRecord($orcid, $accessToken);
$fullName = $this->orcidClient->getFullNameFromRecord($orcidRecord);
- $publication->setData('endorserName', $fullName);
- $publicationDao = Repo::publication()->dao;
- $publicationDao->update($publication);
+ $endorsement->setName($fullName);
- return $publication;
+ Repo::endorsement()->edit($endorsement, []);
+ return $endorsement;
}
public function messageWasAlreadyLoggedToday(int $submissionId, string $message): bool
@@ -116,9 +122,9 @@ public function messageWasAlreadyLoggedToday(int $submissionId, string $message)
->getMany();
$today = Core::getCurrentDate();
- foreach($submissionLogEntries->toArray() as $logEntry) {
+ foreach ($submissionLogEntries->toArray() as $logEntry) {
$entryWasLoggedToday = $this->datesAreOnSameDay($logEntry->getDateLogged(), $today);
- if($entryWasLoggedToday and $logEntry->getMessage() == $message) {
+ if ($entryWasLoggedToday and $logEntry->getMessage() == $message) {
return true;
}
}
diff --git a/classes/PlauditClient.php b/classes/PlauditClient.php
index a0b8f88..14a4b74 100644
--- a/classes/PlauditClient.php
+++ b/classes/PlauditClient.php
@@ -3,7 +3,7 @@
namespace APP\plugins\generic\plauditPreEndorsement\classes;
use APP\core\Application;
-use APP\plugins\generic\plauditPreEndorsement\classes\Endorsement;
+use APP\plugins\generic\plauditPreEndorsement\classes\endorsement\Endorsement;
class PlauditClient
{
@@ -15,12 +15,12 @@ public function filterOrcidNumbers(string $orcid): string
return $matches[0];
}
- public function requestEndorsementCreation($publication, $secretKey)
+ public function requestEndorsementCreation($endorsement, $publication, $secretKey)
{
$httpClient = Application::get()->getHttpClient();
$headers = ['Content-Type' => 'application/json'];
- $orcid = $this->filterOrcidNumbers($publication->getData('endorserOrcid'));
+ $orcid = $this->filterOrcidNumbers($endorsement->getOrcid());
$postData = [
'secret_key' => $secretKey,
'orcid' => $orcid,
@@ -39,7 +39,7 @@ public function requestEndorsementCreation($publication, $secretKey)
return $response;
}
- public function getEndorsementStatusByResponse($response, $publication)
+ public function getEndorsementStatusByResponse($response, $publication, $endorsement)
{
if ($response->getStatusCode() == 200) {
$body = json_decode($response->getBody()->getContents(), true);
@@ -48,9 +48,9 @@ public function getEndorsementStatusByResponse($response, $publication)
$responseDoi = $endorsementData['doi'];
$responseOrcid = $endorsementData['orcid'];
$publicationDoi = strtolower($publication->getDoi());
- $publicationOrcid = $this->filterOrcidNumbers($publication->getData('endorserOrcid'));
+ $endorsementOrcid = $this->filterOrcidNumbers($endorsement->getOrcid());
- if ($responseDoi == $publicationDoi && $responseOrcid == $publicationOrcid) {
+ if ($responseDoi == $publicationDoi && $responseOrcid == $endorsementOrcid) {
return Endorsement::STATUS_COMPLETED;
}
}
diff --git a/classes/PlauditPreEndorsementDAO.php b/classes/PlauditPreEndorsementDAO.php
deleted file mode 100644
index db47e31..0000000
--- a/classes/PlauditPreEndorsementDAO.php
+++ /dev/null
@@ -1,35 +0,0 @@
-leftJoin('publications as pub', 'sub.current_publication_id', '=', 'pub.publication_id')
- ->leftJoin('publication_settings as ps', 'pub.publication_id', '=', 'ps.publication_id')
- ->where('ps.setting_name', 'endorsementStatus')
- ->where('ps.setting_value', Endorsement::STATUS_CONFIRMED)
- ->where('sub.status', Submission::STATUS_PUBLISHED)
- ->where('sub.context_id', $contextId)
- ->select('pub.publication_id')
- ->get();
-
- $publications = [];
-
- foreach ($result as $row) {
- $row = (array) $row;
- $publications[] = Repo::publication()->get($row['publication_id']);
- }
-
- return $publications;
-
- }
-}
diff --git a/classes/PlauditPreEndorsementHandler.php b/classes/PlauditPreEndorsementHandler.php
index 8144fe3..c79dcb8 100644
--- a/classes/PlauditPreEndorsementHandler.php
+++ b/classes/PlauditPreEndorsementHandler.php
@@ -3,12 +3,12 @@
namespace APP\plugins\generic\plauditPreEndorsement\classes;
use APP\handler\Handler;
-use APP\facades\Repo;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
use APP\submission\Submission;
use PKP\plugins\PluginRegistry;
use APP\template\TemplateManager;
use APP\plugins\generic\plauditPreEndorsement\PlauditPreEndorsementPlugin;
-use APP\plugins\generic\plauditPreEndorsement\classes\Endorsement;
+use APP\plugins\generic\plauditPreEndorsement\classes\endorsement\Endorsement;
use APP\plugins\generic\plauditPreEndorsement\classes\EndorsementService;
use APP\plugins\generic\plauditPreEndorsement\classes\OrcidClient;
@@ -18,52 +18,12 @@ class PlauditPreEndorsementHandler extends Handler
public const AUTH_INVALID_TOKEN = 'invalid_token';
public const AUTH_ACCESS_DENIED = 'access_denied';
- public function updateEndorser($args, $request)
- {
- $plugin = new PlauditPreEndorsementPlugin();
- $submissionId = $request->getUserVar('submissionId');
- $endorserName = $request->getUserVar('endorserName');
- $endorserEmail = $request->getUserVar('endorserEmail');
-
- $submission = Repo::submission()->get($submissionId);
- $publication = $submission->getCurrentPublication();
-
- $endorsementIsConfirmed = $publication->getData('endorsementStatus') == Endorsement::STATUS_CONFIRMED;
- if ($endorsementIsConfirmed) {
- return http_response_code(400);
- }
-
- if(!$plugin->inputIsEmail($endorserEmail)) {
- http_response_code(400);
- header('Content-Type: application/json');
- echo json_encode(['errorMessage' => __('plugins.generic.plauditPreEndorsement.endorsementEmailInvalid')]);
- return;
- }
-
- if($this->checkDataIsFromAnyAuthor($publication, 'email', $endorserEmail)) {
- http_response_code(400);
- header('Content-Type: application/json');
- echo json_encode(['errorMessage' => __('plugins.generic.plauditPreEndorsement.endorsementFromAuthor')]);
- return;
- }
-
- $endorserChanged = ($endorserEmail != $publication->getData('endorserEmail'));
-
- $publication->setData('endorserName', $endorserName);
- $publication->setData('endorserEmail', $endorserEmail);
- Repo::publication()->edit($publication, []);
-
- $plugin->sendEmailToEndorser($publication, $endorserChanged);
-
- return http_response_code(200);
- }
-
private function checkDataIsFromAnyAuthor($publication, $dataName, $dataValue): bool
{
$authors = $publication->getData('authors');
- foreach($authors as $author) {
- if($author->getData($dataName) == $dataValue) {
+ foreach ($authors as $author) {
+ if ($author->getData($dataName) == $dataValue) {
return true;
}
}
@@ -71,68 +31,21 @@ private function checkDataIsFromAnyAuthor($publication, $dataName, $dataValue):
return false;
}
- public function removeEndorsement($args, $request)
- {
- $submissionId = $request->getUserVar('submissionId');
- $submission = Repo::submission()->get($submissionId);
- $publication = $submission->getCurrentPublication();
-
- $endorsementFields = [
- 'endorserName',
- 'endorserEmail',
- 'endorsementStatus',
- 'endorserOrcid',
- 'endorserEmailToken',
- 'endorserEmailCount'
- ];
-
- foreach($endorsementFields as $field) {
- $publication->unsetData($field);
- }
-
- Repo::publication()->edit($publication, []);
-
- $plugin = PluginRegistry::getPlugin('generic', 'plauditpreendorsementplugin');
- $plugin->writeOnActivityLog($submission, 'plugins.generic.plauditPreEndorsement.log.endorsementRemoved');
-
- return http_response_code(200);
- }
-
- public function sendEndorsementManually($args, $request)
- {
- $submissionId = $request->getUserVar('submissionId');
- $submission = Repo::submission()->get($submissionId);
- $publication = $submission->getCurrentPublication();
- $plugin = PluginRegistry::getPlugin('generic', 'plauditpreendorsementplugin');
-
- $endorsementStatus = $publication->getData('endorsementStatus');
- $canSendEndorsementManually = $publication->getData('status') == Submission::STATUS_PUBLISHED
- && !$plugin->userAccessingIsAuthor($submission)
- && ($endorsementStatus == Endorsement::STATUS_CONFIRMED || $endorsementStatus == Endorsement::STATUS_COULDNT_COMPLETE);
-
- if($canSendEndorsementManually) {
- $endorsementService = new EndorsementService($request->getContext()->getId(), $plugin);
- $endorsementService->sendEndorsement($publication);
- return http_response_code(200);
- }
-
- return http_response_code(400);
- }
-
public function orcidVerify($args, $request)
{
$publication = Repo::publication()->get($request->getUserVar('state'));
$submission = Repo::submission()->get($publication->getData('submissionId'));
+ $endorsement = Repo::endorsement()->get($request->getUserVar('endorsementId'));
$plugin = PluginRegistry::getPlugin('generic', 'plauditpreendorsementplugin');
$contextId = $request->getContext()->getId();
- $statusAuth = $this->getStatusAuthentication($publication, $request);
+ $statusAuth = $this->getStatusAuthentication($endorsement, $request);
if ($statusAuth == self::AUTH_INVALID_TOKEN) {
$this->logMessageAndDisplayTemplate($submission, $request, 'plugins.generic.plauditPreEndorsement.log.invalidToken', ['errorType' => 'invalidToken']);
return;
} elseif ($statusAuth == self::AUTH_ACCESS_DENIED) {
- $this->setAccessDeniedEndorsement($publication);
+ $this->setAccessDeniedEndorsement($endorsement);
$this->logMessageAndDisplayTemplate($submission, $request, 'plugins.generic.plauditPreEndorsement.log.orcidAccessDenied', ['errorType' => 'denied']);
return;
}
@@ -151,18 +64,18 @@ public function orcidVerify($args, $request)
$orcidUri = ($isSandBox ? OrcidClient::ORCID_URL_SANDBOX : OrcidClient::ORCID_URL) . $orcid;
if (strlen($orcid) > 0) {
- if($this->checkDataIsFromAnyAuthor($publication, 'orcid', $orcidUri)) {
+ if ($this->checkDataIsFromAnyAuthor($publication, 'orcid', $orcidUri)) {
$this->logMessageAndDisplayTemplate($submission, $request, 'plugins.generic.plauditPreEndorsement.log.endorserOrcidFromAuthor', ['errorType' => 'orcidFromAuthor']);
return;
}
$endorsementService = new EndorsementService($contextId, $plugin);
- $endorsementService->updateEndorserNameFromOrcid($publication, $orcid);
+ $endorsementService->updateEndorsementNameFromOrcid($endorsement, $orcid);
- $this->setConfirmedEndorsementPublication($publication, $orcidUri);
+ $this->setConfirmedEndorsementPublication($endorsement, $orcidUri);
$this->logMessageAndDisplayTemplate($submission, $request, 'plugins.generic.plauditPreEndorsement.log.endorsementConfirmed', ['orcid' => $orcidUri]);
- if($publication->getData('status') == Submission::STATUS_PUBLISHED) {
+ if ($publication->getData('status') == Submission::STATUS_PUBLISHED) {
$endorsementService->sendEndorsement($publication);
}
}
@@ -180,24 +93,24 @@ private function logMessageAndDisplayTemplate($submission, $request, string $mes
$templateMgr->display($templatePath);
}
- private function setConfirmedEndorsementPublication($publication, $orcidUri)
+ private function setConfirmedEndorsementPublication($endorsement, $orcidUri)
{
- $publication->setData('endorserEmailToken', null);
- $publication->setData('endorserOrcid', $orcidUri);
- $publication->setData('endorsementStatus', Endorsement::STATUS_CONFIRMED);
- Repo::publication()->edit($publication, []);
+ $endorsement->setEmailToken(null);
+ $endorsement->setOrcid($orcidUri);
+ $endorsement->setStatus(Endorsement::STATUS_CONFIRMED);
+ Repo::endorsement()->edit($endorsement, []);
}
- private function setAccessDeniedEndorsement($publication)
+ private function setAccessDeniedEndorsement($endorsement)
{
- $publication->setData('endorserEmailToken', null);
- $publication->setData('endorsementStatus', Endorsement::STATUS_DENIED);
- Repo::publication()->edit($publication, []);
+ $endorsement->setEmailToken(null);
+ $endorsement->setStatus(Endorsement::STATUS_DENIED);
+ Repo::endorsement()->edit($endorsement, []);
}
- public function getStatusAuthentication($publication, $request)
+ public function getStatusAuthentication($endorsement, $request)
{
- if ($request->getUserVar('token') != $publication->getData('endorserEmailToken')) {
+ if ($request->getUserVar('token') != $endorsement->getEmailToken()) {
return self::AUTH_INVALID_TOKEN;
} elseif ($request->getUserVar('error') == 'access_denied') {
return self::AUTH_ACCESS_DENIED;
diff --git a/classes/SchemaBuilder.php b/classes/SchemaBuilder.php
new file mode 100644
index 0000000..8abd9db
--- /dev/null
+++ b/classes/SchemaBuilder.php
@@ -0,0 +1,27 @@
+action = $action;
-
- $this->addField(new FieldText('endorserName', [
- 'label' => __('plugins.generic.plauditPreEndorsement.endorserName'),
- 'value' => $publication->getData('endorserName'),
- ]));
-
- $this->addField(new FieldText('endorserEmail', [
- 'label' => __('plugins.generic.plauditPreEndorsement.endorserEmail'),
- 'value' => $publication->getData('endorserEmail'),
- 'inputType' => 'email'
- ]));
- }
-}
diff --git a/classes/endorsement/Collector.php b/classes/endorsement/Collector.php
new file mode 100644
index 0000000..431be7a
--- /dev/null
+++ b/classes/endorsement/Collector.php
@@ -0,0 +1,74 @@
+dao = $dao;
+ }
+
+ public function filterByContextIds(?array $contextIds): Collector
+ {
+ $this->contextIds = $contextIds;
+ return $this;
+ }
+
+ public function filterByPublicationIds(?array $publicationIds): Collector
+ {
+ $this->publicationIds = $publicationIds;
+ return $this;
+ }
+
+ public function filterByStatus(?array $status): Collector
+ {
+ $this->status = $status;
+ return $this;
+ }
+
+ public function getQueryBuilder(): Builder
+ {
+ $queryBuilder = DB::table($this->dao->table . ' as endorsements')
+ ->select(['endorsements.*']);
+
+ if (isset($this->contextIds)) {
+ $queryBuilder->whereIn('endorsements.context_id', $this->contextIds);
+ }
+
+ if (isset($this->publicationIds)) {
+ $queryBuilder->whereIn('endorsements.publication_id', $this->publicationIds);
+ }
+
+ if (isset($this->status)) {
+ $queryBuilder->whereIn('endorsements.status', $this->status);
+ }
+
+ return $queryBuilder;
+ }
+
+ public function getCount(): int
+ {
+ return $this->dao->getCount($this);
+ }
+
+ public function getIds(): Collection
+ {
+ return $this->dao->getIds($this);
+ }
+
+ public function getMany(): LazyCollection
+ {
+ return $this->dao->getMany($this);
+ }
+}
diff --git a/classes/endorsement/DAO.php b/classes/endorsement/DAO.php
new file mode 100644
index 0000000..9479e6e
--- /dev/null
+++ b/classes/endorsement/DAO.php
@@ -0,0 +1,89 @@
+ 'endorsement_id',
+ 'contextId' => 'context_id',
+ 'publicationId' => 'publication_id',
+ 'name' => 'name',
+ 'email' => 'email',
+ 'status' => 'status',
+ 'orcid' => 'orcid',
+ 'emailToken' => 'email_token',
+ 'emailCount' => 'email_count'
+ ];
+
+ public function getParentColumn(): string
+ {
+ return 'context_id';
+ }
+
+ public function newDataObject(): Endorsement
+ {
+ return app(Endorsement::class);
+ }
+
+ public function insert(Endorsement $endorsement): int
+ {
+ return parent::_insert($endorsement);
+ }
+
+ public function delete(Endorsement $endorsement)
+ {
+ return parent::_delete($endorsement);
+ }
+
+ public function update(Endorsement $endorsement)
+ {
+ return parent::_update($endorsement);
+ }
+
+ public function getCount(Collector $query): int
+ {
+ return $query
+ ->getQueryBuilder()
+ ->count();
+ }
+
+ public function getByEmail(string $email, int $publicationId, int $contextId): ?Endorsement
+ {
+ $row = DB::table($this->table)
+ ->where('email', $email)
+ ->where('publication_id', $publicationId)
+ ->where('context_id', $contextId)
+ ->get('endorsement_id')
+ ->first();
+ return $row ? $this->get($row->endorsement_id) : null;
+ }
+
+ public function getMany(Collector $query): LazyCollection
+ {
+ $rows = $query
+ ->getQueryBuilder()
+ ->get();
+
+ return LazyCollection::make(function () use ($rows) {
+ foreach ($rows as $row) {
+ yield $row->endorsement_id => $this->fromRow($row);
+ }
+ });
+ }
+
+ public function fromRow(object $row): Endorsement
+ {
+ return parent::fromRow($row);
+ }
+}
diff --git a/classes/endorsement/Endorsement.php b/classes/endorsement/Endorsement.php
new file mode 100644
index 0000000..86963e5
--- /dev/null
+++ b/classes/endorsement/Endorsement.php
@@ -0,0 +1,97 @@
+getData("id");
+ }
+
+ public function getContextId(): int
+ {
+ return $this->getData("contextId");
+ }
+
+ public function setContextId(int $contextId)
+ {
+ $this->setData("contextId", $contextId);
+ }
+
+ public function getPublicationId(): int
+ {
+ return $this->getData("publicationId");
+ }
+
+ public function setPublicationId(int $publicationId)
+ {
+ $this->setData("publicationId", $publicationId);
+ }
+
+ public function getName(): string
+ {
+ return $this->getData("name");
+ }
+
+ public function setName(string $name)
+ {
+ $this->setData("name", $name);
+ }
+
+ public function getEmail(): string
+ {
+ return $this->getData("email");
+ }
+
+ public function setEmail(string $email)
+ {
+ $this->setData("email", $email);
+ }
+
+ public function getStatus(): ?int
+ {
+ return $this->getData("status");
+ }
+
+ public function setStatus(int $status)
+ {
+ $this->setData("status", $status);
+ }
+
+ public function getOrcid(): ?string
+ {
+ return $this->getData("orcid");
+ }
+
+ public function setOrcid(string $orcid)
+ {
+ $this->setData("orcid", $orcid);
+ }
+
+ public function getEmailToken(): ?string
+ {
+ return $this->getData("emailToken");
+ }
+
+ public function setEmailToken(?string $emailToken)
+ {
+ $this->setData("emailToken", $emailToken);
+ }
+
+ public function getEmailCount(): ?int
+ {
+ return $this->getData("emailCount");
+ }
+
+ public function setEmailCount(int $emailCount)
+ {
+ $this->setData("emailCount", $emailCount);
+ }
+}
diff --git a/classes/endorsement/Repository.php b/classes/endorsement/Repository.php
new file mode 100644
index 0000000..194a819
--- /dev/null
+++ b/classes/endorsement/Repository.php
@@ -0,0 +1,63 @@
+dao = $dao;
+ }
+
+ public function newDataObject(array $params = []): Endorsement
+ {
+ $object = $this->dao->newDataObject();
+ if (!empty($params)) {
+ $object->setAllData($params);
+ }
+ return $object;
+ }
+
+ public function get(int $id, int $contextId = null): ?Endorsement
+ {
+ return $this->dao->get($id, $contextId);
+ }
+
+ public function add(Endorsement $endorsement): int
+ {
+ $id = $this->dao->insert($endorsement);
+ return $id;
+ }
+
+ public function edit(Endorsement $endorsement, array $params)
+ {
+ $newEndorsement = clone $endorsement;
+ $newEndorsement->setAllData(array_merge($newEndorsement->_data, $params));
+
+ $this->dao->update($newEndorsement);
+ }
+
+ public function delete(Endorsement $endorsement)
+ {
+ $this->dao->delete($endorsement);
+ }
+
+ public function exists(int $id, int $contextId = null): bool
+ {
+ return $this->dao->exists($id, $contextId);
+ }
+
+ public function getByEmail(string $email, int $publicationId, int $contextId): ?Endorsement
+ {
+ return $this->dao->getByEmail($email, $publicationId, $contextId);
+ }
+
+ public function getCollector(): Collector
+ {
+ return app(Collector::class);
+ }
+}
diff --git a/classes/facades/Repo.php b/classes/facades/Repo.php
new file mode 100644
index 0000000..9022479
--- /dev/null
+++ b/classes/facades/Repo.php
@@ -0,0 +1,13 @@
+bigInteger('endorsement_id')->autoIncrement();
+ $table->bigInteger('context_id');
+ $table->bigInteger('publication_id');
+ $table->string('name');
+ $table->string('email');
+ $table->integer('status')->nullable();
+ $table->string('orcid')->nullable();
+ $table->string('email_token')->nullable();
+ $table->integer('email_count')->default(0);
+
+ $table->foreign('context_id')
+ ->references('server_id')
+ ->on('servers')
+ ->onDelete('cascade');
+ $table->index(['context_id'], 'endorsers_context_id');
+
+ $table->foreign('publication_id')
+ ->references('publication_id')
+ ->on('publications')
+ ->onDelete('cascade');
+ $table->index(['context_id'], 'endorsers_publication_id');
+
+ $table->unique(['context_id', 'publication_id', 'email'], 'endorsement_pkey');
+ });
+ }
+
+ $upgradeMigration = new MoveLegacyEndorsementsToEndorsementsTable();
+ $upgradeMigration->up();
+ }
+
+ public function down(): void
+ {
+ throw new DowngradeNotSupportedException();
+ }
+}
diff --git a/classes/migration/upgrade/MoveLegacyEndorsementsToEndorsementsTable.php b/classes/migration/upgrade/MoveLegacyEndorsementsToEndorsementsTable.php
new file mode 100644
index 0000000..53051aa
--- /dev/null
+++ b/classes/migration/upgrade/MoveLegacyEndorsementsToEndorsementsTable.php
@@ -0,0 +1,82 @@
+getEndorsementsFromPublicationSettings();
+
+ if (!empty($endorsementSettings)) {
+ $legacyEndorsements = $this->getLegacyEndorsements($endorsementSettings);
+ $this->moveToEndorsementsTable($legacyEndorsements);
+ $this->deleteLegacyEndorsements();
+ }
+ }
+
+ public function down(): void
+ {
+ throw new DowngradeNotSupportedException();
+ }
+
+ private function getEndorsementsFromPublicationSettings()
+ {
+ return DB::table('publication_settings')
+ ->whereIn('setting_name', [
+ 'endorserName',
+ 'endorserEmail',
+ 'endorsementStatus',
+ 'endorserOrcid',
+ 'endorserEmailToken',
+ 'endorserEmailCount'
+ ])
+ ->get();
+ }
+
+ private function getLegacyEndorsements($endorsementSettings)
+ {
+ $legacyEndorsements = [];
+ foreach ($endorsementSettings as $endorsementSetting) {
+ $publicationId = $endorsementSetting->publication_id;
+ $legacyEndorsements[$publicationId][$endorsementSetting->setting_name] = $endorsementSetting->setting_value;
+ }
+ return $legacyEndorsements;
+ }
+
+ private function moveToEndorsementsTable($legacyEndorsements)
+ {
+ foreach ($legacyEndorsements as $publicationId => $settings) {
+ $submissionId = DB::table('publications')->where('publication_id', $publicationId)->value('submission_id');
+ $contextId = DB::table('submissions')->where('submission_id', $submissionId)->value('context_id');
+
+ DB::table('endorsements')->insert([
+ 'context_id' => $contextId,
+ 'publication_id' => $publicationId,
+ 'name' => $settings['endorserName'] ?? '',
+ 'email' => $settings['endorserEmail'] ?? '',
+ 'status' => $settings['endorsementStatus'] ?? null,
+ 'orcid' => $settings['endorserOrcid'] ?? '',
+ 'email_token' => $settings['endorserEmailToken'] ?? '',
+ 'email_count' => $settings['endorserEmailCount'] ?? 0,
+ ]);
+ }
+ }
+
+ private function deleteLegacyEndorsements()
+ {
+ DB::table('publication_settings')
+ ->whereIn('setting_name', [
+ 'endorserName',
+ 'endorserEmail',
+ 'endorsementStatus',
+ 'endorserOrcid',
+ 'endorserEmailToken',
+ 'endorserEmailCount'
+ ])->delete();
+ }
+}
diff --git a/classes/observers/listeners/SendEmailToEndorser.php b/classes/observers/listeners/SendEmailToEndorser.php
index 6851e6a..2507c20 100644
--- a/classes/observers/listeners/SendEmailToEndorser.php
+++ b/classes/observers/listeners/SendEmailToEndorser.php
@@ -5,6 +5,7 @@
use Illuminate\Events\Dispatcher;
use PKP\observers\events\SubmissionSubmitted;
use PKP\plugins\PluginRegistry;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
class SendEmailToEndorser
{
@@ -19,10 +20,17 @@ public function subscribe(Dispatcher $events): void
public function handle(SubmissionSubmitted $event): void
{
$publication = $event->submission->getCurrentPublication();
+ $contextId = $event->context->getId();
+ $endorsements = Repo::endorsement()->getCollector()
+ ->filterByContextIds([$contextId])
+ ->filterByPublicationIds([$publication->getId()])
+ ->getMany()
+ ->toArray();
- if (!empty($publication->getData('endorserEmail'))) {
- $plugin = PluginRegistry::getPlugin('generic', 'plauditpreendorsementplugin');
- $plugin->sendEmailToEndorser($publication);
+ $plugin = PluginRegistry::getPlugin('generic', 'plauditpreendorsementplugin');
+
+ foreach ($endorsements as $endorsement) {
+ $plugin->sendEmailToEndorser($publication, $endorsement);
}
}
}
diff --git a/classes/tasks/SendReadyEndorsements.php b/classes/tasks/SendReadyEndorsements.php
index 220f97d..cf4cfa5 100644
--- a/classes/tasks/SendReadyEndorsements.php
+++ b/classes/tasks/SendReadyEndorsements.php
@@ -5,8 +5,9 @@
use PKP\scheduledTask\ScheduledTask;
use PKP\plugins\PluginRegistry;
use APP\core\Application;
-use APP\plugins\generic\plauditPreEndorsement\classes\PlauditPreEndorsementDAO;
use APP\plugins\generic\plauditPreEndorsement\classes\EndorsementService;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
+use APP\plugins\generic\plauditPreEndorsement\classes\endorsement\Endorsement;
class SendReadyEndorsements extends ScheduledTask
{
@@ -14,14 +15,16 @@ public function executeActions()
{
PluginRegistry::loadCategory('generic');
$plugin = PluginRegistry::getPlugin('generic', 'plauditpreendorsementplugin');
- $preEndorsementDao = new PlauditPreEndorsementDAO();
$context = Application::get()->getRequest()->getContext();
+ $readyEndorsements = Repo::endorsement()->getCollector()
+ ->filterByContextIds([$context->getId()])
+ ->filterByStatus([Endorsement::STATUS_CONFIRMED])
+ ->getMany()
+ ->toArray();
- $readyPublications = $preEndorsementDao->getPublicationsWithEndorsementReadyToSend($context->getId());
-
- foreach($readyPublications as $publication) {
+ foreach($readyEndorsements as $endorsement) {
$endorsementService = new EndorsementService($context->getId(), $plugin);
- $endorsementService->sendEndorsement($publication, true);
+ $endorsementService->sendEndorsement($endorsement, true);
}
return true;
diff --git a/controllers/grid/EndorsementGridCellProvider.php b/controllers/grid/EndorsementGridCellProvider.php
new file mode 100644
index 0000000..282865e
--- /dev/null
+++ b/controllers/grid/EndorsementGridCellProvider.php
@@ -0,0 +1,51 @@
+getData();
+ switch ($column->getId()) {
+ case 'endorserName':
+ return array('label' => $element->getName(), 'orcid' => $element->getOrcid());
+ case 'endorserEmail':
+ return array('label' => $element->getEmail(), 'emailCount' => $element->getEmailCount());
+ case 'endorsementStatus':
+ return array(
+ 'label' => $this->getEndorsementStatusSuffix($element->getStatus()),
+ 'badgeClass' => $this->getEndorsementStatusBadge($element->getStatus())
+ );
+ }
+ }
+
+ private function getEndorsementStatusSuffix(?int $endorsementStatus): string
+ {
+ $mapStatusToSuffix = [
+ Endorsement::STATUS_NOT_CONFIRMED => __('plugins.generic.plauditPreEndorsement.endorsementNotConfirmed'),
+ Endorsement::STATUS_CONFIRMED => __('plugins.generic.plauditPreEndorsement.endorsementConfirmed'),
+ Endorsement::STATUS_DENIED => __('plugins.generic.plauditPreEndorsement.endorsementDenied'),
+ Endorsement::STATUS_COMPLETED => __('plugins.generic.plauditPreEndorsement.endorsementCompleted'),
+ Endorsement::STATUS_COULDNT_COMPLETE => __('plugins.generic.plauditPreEndorsement.endorsementCouldntComplete')
+ ];
+
+ return $mapStatusToSuffix[$endorsementStatus] ?? "";
+ }
+
+ private function getEndorsementStatusBadge(?int $endorsementStatus): string
+ {
+ $mapStatusToSuffix = [
+ Endorsement::STATUS_NOT_CONFIRMED => 'endorsementStatusCustomBadge',
+ Endorsement::STATUS_CONFIRMED => 'pkpBadge pkpBadge--isPrimary',
+ Endorsement::STATUS_DENIED => 'pkpBadge pkpBadge--isWarnable',
+ Endorsement::STATUS_COMPLETED => 'pkpBadge pkpBadge--isSuccess',
+ Endorsement::STATUS_COULDNT_COMPLETE => 'pkpBadge pkpBadge--isWarnable'
+ ];
+
+ return $mapStatusToSuffix[$endorsementStatus] ?? "";
+ }
+}
diff --git a/controllers/grid/EndorsementGridHandler.php b/controllers/grid/EndorsementGridHandler.php
new file mode 100644
index 0000000..9828f9e
--- /dev/null
+++ b/controllers/grid/EndorsementGridHandler.php
@@ -0,0 +1,212 @@
+addRoleAssignment(
+ array(Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_AUTHOR),
+ array('fetchGrid', 'fetchRow', 'addEndorsement', 'editEndorsement', 'updateEndorsement', 'deleteEndorsement', 'sendEndorsementManually')
+ );
+ $this->plugin = PluginRegistry::getPlugin('generic', PLAUDIT_PRE_ENDORSEMENT_PLUGIN_NAME);
+ }
+
+ public static function setPlugin($plugin)
+ {
+ $this->plugin = $plugin;
+ }
+
+ public function getSubmission()
+ {
+ return $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
+ }
+
+ public function authorize($request, &$args, $roleAssignments)
+ {
+ $this->addPolicy(new SubmissionAccessPolicy($request, $args, $roleAssignments));
+ return parent::authorize($request, $args, $roleAssignments);
+ }
+
+ public function initialize($request, $args = null)
+ {
+ parent::initialize($request, $args);
+
+ $submission = $this->getSubmission();
+ $submissionId = $submission->getId();
+ $publication = $submission->getCurrentPublication();
+
+ $this->setTitle('plugins.generic.plauditPreEndorsement.endorsement');
+ $this->setEmptyRowText('common.none');
+
+ $router = $request->getRouter();
+ $this->addAction(
+ new LinkAction(
+ 'addEndorsement',
+ new AjaxModal(
+ $router->url($request, null, null, 'addEndorsement', null, ['submissionId' => $submissionId]),
+ __('common.add'),
+ 'modal_add_item'
+ ),
+ __('common.add'),
+ 'add_item'
+ )
+ );
+
+ $cellProvider = new EndorsementGridCellProvider();
+ $this->addColumn(new GridColumn(
+ 'endorserName',
+ 'plugins.generic.plauditPreEndorsement.endorserName',
+ null,
+ $this->plugin->getTemplateResource('gridCells/endorserName.tpl'),
+ $cellProvider,
+ ['maxLength' => 40]
+ ));
+ $this->addColumn(new GridColumn(
+ 'endorserEmail',
+ 'plugins.generic.plauditPreEndorsement.emailColumnName',
+ null,
+ $this->plugin->getTemplateResource('gridCells/endorserEmail.tpl'),
+ $cellProvider,
+ ['maxLength' => 40]
+ ));
+
+ if (!$submission->getSubmissionProgress()) {
+ $this->addColumn(new GridColumn(
+ 'endorsementStatus',
+ 'plugins.generic.plauditPreEndorsement.endorsementStatus',
+ null,
+ $this->plugin->getTemplateResource('gridCells/endorsementStatus.tpl'),
+ $cellProvider
+ ));
+ }
+ }
+
+ protected function loadData($request, $filter)
+ {
+ $submission = $this->getSubmission();
+ $submissionId = $submission->getId();
+ $publication = $submission->getCurrentPublication();
+ $endorsements = Repo::endorsement()->getCollector()
+ ->filterByContextIds([$request->getContext()->getId()])
+ ->filterByPublicationIds([$publication->getId()])
+ ->getMany();
+ return $endorsements->toArray();
+ }
+
+ public function addEndorsement($args, $request)
+ {
+ return $this->editEndorsement($args, $request);
+ }
+
+ public function sendEndorsementManually($args, $request)
+ {
+ $contextId = $request->getContext()->getId();
+ $rowId = $request->getUserVar('rowId');
+ $endorsement = Repo::endorsement()->get((int)$rowId, $contextId);
+ $user = $request->getUser();
+
+ $endorsementService = new EndorsementService($contextId, $this->plugin);
+ $endorsementService->sendEndorsement($endorsement);
+
+ $notificationManager = new NotificationManager();
+ $notificationManager->createTrivialNotification(
+ $user->getId(),
+ NOTIFICATION_TYPE_SUCCESS,
+ array('contents' => __('plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditNotification'))
+ );
+
+ $json = new JSONMessage(true);
+ return $json->getString();
+ }
+
+ public function editEndorsement($args, $request)
+ {
+ $context = $request->getContext();
+ $submission = $this->getSubmission();
+ $submissionId = $submission->getId();
+ $rowId = $args['rowId'] ?? null;
+
+ $this->setupTemplate($request);
+
+ $endorsementForm = new EndorsementForm($context->getId(), $submissionId, $request, $this->plugin, $rowId);
+ $endorsementForm->initData();
+ $json = new JSONMessage(true, $endorsementForm->fetch($request));
+ return $json->getString();
+ }
+
+ public function updateEndorsement($args, $request)
+ {
+ $context = $request->getContext();
+ $submission = $this->getSubmission();
+ $submissionId = $submission->getId();
+ $rowId = $args['rowId'] ?? null;
+
+ $this->setupTemplate($request);
+
+ $endorsementForm = new EndorsementForm($context->getId(), $submissionId, $request, $this->plugin, $rowId);
+ $endorsementForm->readInputData();
+ if ($endorsementForm->validate()) {
+ $endorsementForm->execute();
+ $json = DAO::getDataChangedEvent($submissionId);
+ $json->setGlobalEvent('plugin:plauditPreEndorsement:endorsementAdded', ['submissionId' => $submissionId]);
+ return $json;
+ } else {
+ $json = new JSONMessage(true, $endorsementForm->fetch($request));
+ return $json->getString();
+ }
+ }
+
+ public function deleteEndorsement($args, $request)
+ {
+ $context = $request->getContext();
+ $submission = $this->getSubmission();
+ $submissionId = $submission->getId();
+ $rowId = $request->getUserVar('rowId');
+ $endorsement = Repo::endorsement()->get((int)$rowId, $context->getId());
+ Repo::endorsement()->delete($endorsement);
+ $this->plugin->writeOnActivityLog(
+ $submission,
+ 'plugins.generic.plauditPreEndorsement.log.endorsementRemoved',
+ ['endorserName' => $endorsement->getName(), 'endorserEmail' => $endorsement->getEmail()]
+ );
+ $json = DAO::getDataChangedEvent($submissionId);
+ $json->setGlobalEvent('plugin:plauditPreEndorsement:endorsementRemoved', ['submissionId' => $submissionId]);
+ return $json;
+ }
+
+ public function getJSHandler()
+ {
+ return '$.pkp.plugins.generic.plauditPreEndorsement.EndorsementGridHandler';
+ }
+
+ protected function getRowInstance()
+ {
+ return new EndorsementGridRow();
+ }
+}
+
+if (!PKP_STRICT_MODE) {
+ class_alias('\APP\plugins\generic\plauditPreEndorsement\controllers\grid\EndorsementGridHandler', '\EndorsementGridHandler');
+}
diff --git a/controllers/grid/EndorsementGridRow.php b/controllers/grid/EndorsementGridRow.php
new file mode 100644
index 0000000..ee2736a
--- /dev/null
+++ b/controllers/grid/EndorsementGridRow.php
@@ -0,0 +1,113 @@
+plugin = PluginRegistry::getPlugin('generic', PLAUDIT_PRE_ENDORSEMENT_PLUGIN_NAME);
+ }
+
+ public function initialize($request, $template = null)
+ {
+ parent::initialize($request, $template);
+ $submissionId = $request->getUserVar('submissionId');
+ $submission = Repo::submission()->get($submissionId);
+ $publication = $submission->getCurrentPublication();
+
+ $router = $request->getRouter();
+
+ $element = & $this->getData();
+
+ $rowId = $this->getId();
+
+ $canSendEndorsementManually = $publication->getData('status') == Submission::STATUS_PUBLISHED
+ && !$this->plugin->userAccessingIsAuthor($submission)
+ && (
+ $element->getStatus() == Endorsement::STATUS_CONFIRMED ||
+ $element->getStatus() == Endorsement::STATUS_COULDNT_COMPLETE
+ );
+
+ if ($canSendEndorsementManually) {
+ $this->addAction(
+ new LinkAction(
+ 'sendEndorsementManually',
+ new RemoteActionConfirmationModal(
+ $request->getSession(),
+ __('plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditConfirmationMessage'),
+ __('plugins.generic.plauditPreEndorsement.sendEndorsementToPlaudit'),
+ $router->url(
+ $request,
+ null,
+ null,
+ 'sendEndorsementManually',
+ null,
+ array('submissionId' => $submissionId, 'rowId' => $rowId)
+ ),
+ 'modal_delete'
+ ),
+ __('plugins.generic.plauditPreEndorsement.sendEndorsementToPlaudit'),
+ 'sendToPlaudit'
+ )
+ );
+ }
+
+ if ($element->getStatus() < Endorsement::STATUS_CONFIRMED) {
+ $this->addAction(
+ new LinkAction(
+ 'editEndorsementItem',
+ new AjaxModal(
+ $router->url(
+ $request,
+ null,
+ null,
+ 'editEndorsement',
+ null,
+ array('submissionId' => $submissionId, 'rowId' => $rowId)
+ ),
+ __('grid.action.edit'),
+ 'modal_edit',
+ true
+ ),
+ __('grid.action.edit'),
+ 'edit'
+ )
+ );
+ }
+
+ $this->addAction(
+ new LinkAction(
+ 'delete',
+ new RemoteActionConfirmationModal(
+ $request->getSession(),
+ __('common.confirmDelete'),
+ __('grid.action.delete'),
+ $router->url(
+ $request,
+ null,
+ null,
+ 'deleteEndorsement',
+ null,
+ array('submissionId' => $submissionId, 'rowId' => $rowId)
+ ),
+ 'modal_delete'
+ ),
+ __('grid.action.delete'),
+ 'delete'
+ )
+ );
+ }
+}
diff --git a/controllers/grid/form/EndorsementForm.php b/controllers/grid/form/EndorsementForm.php
new file mode 100644
index 0000000..46fa8a7
--- /dev/null
+++ b/controllers/grid/form/EndorsementForm.php
@@ -0,0 +1,88 @@
+contextId = $contextId;
+ $this->submissionId = $submissionId;
+ $this->request = $request ?? null;
+ $this->plugin = $plugin;
+ parent::__construct($plugin->getTemplateResource('addEndorsement.tpl'));
+ Validator::addValidations($this, $contextId, $submissionId, $rowId);
+ }
+
+ public function initData()
+ {
+ $this->setData('submissionId', $this->submissionId);
+ }
+
+ public function readInputData()
+ {
+ $this->readUserVars(array('endorserEmail', 'endorserName'));
+ }
+
+ public function fetch($request, $template = null, $display = false)
+ {
+ $templateMgr = TemplateManager::getManager();
+ $rowId = $this->request->getUserVar('rowId');
+ if ($rowId) {
+ $endorsement = Repo::endorsement()->get($rowId, $this->contextId);
+ $templateMgr->assign('endorserName', $endorsement->getName());
+ $templateMgr->assign('endorserEmail', $endorsement->getEmail());
+ }
+ $templateMgr->assign('rowId', $rowId);
+ $templateMgr->assign('submissionId', $this->submissionId);
+ return parent::fetch($request);
+ }
+
+ public function execute(...$functionArgs)
+ {
+ $rowId = $this->request->getUserVar('rowId');
+ $submission = Repo::submission()->get($this->submissionId);
+ $publication = $submission->getCurrentPublication();
+
+ if ($rowId) {
+ $endorsement = Repo::endorsement()->get((int)$rowId, $this->contextId);
+ $params = [
+ 'name' => $this->getData('endorserName'),
+ 'email' => $this->getData('endorserEmail')
+ ];
+
+ $endorserChanged = ($this->getData('endorserEmail') != $endorsement->getEmail());
+ Repo::endorsement()->edit($endorsement, $params);
+ $newEndorsement = Repo::endorsement()->get((int)$rowId, $this->contextId);
+ if (!$submission->getSubmissionProgress()) {
+ $this->plugin->sendEmailToEndorser($publication, $newEndorsement, $endorserChanged);
+ }
+ } else {
+ $params = [
+ 'contextId' => $this->contextId,
+ 'name' => $this->getData('endorserName'),
+ 'email' => $this->getData('endorserEmail'),
+ 'publicationId' => $publication->getId(),
+ ];
+ $endorsement = Repo::endorsement()->newDataObject($params);
+ Repo::endorsement()->add($endorsement);
+
+ if (!$submission->getSubmissionProgress()) {
+ $this->plugin->sendEmailToEndorser($publication, $endorsement);
+ }
+ }
+ }
+}
diff --git a/controllers/grid/form/Validator.php b/controllers/grid/form/Validator.php
new file mode 100644
index 0000000..24ddb92
--- /dev/null
+++ b/controllers/grid/form/Validator.php
@@ -0,0 +1,46 @@
+addCheck(new FormValidatorPost($form));
+ $form->addCheck(new FormValidatorCSRF($form));
+ $form->addCheck(new \PKP\form\validation\FormValidator($form, 'endorserName', 'required', 'validator.required'));
+ $form->addCheck(new \PKP\form\validation\FormValidatorEmail($form, 'endorserEmail', 'required', 'plugins.generic.plauditPreEndorsement.endorsementEmailInvalid'));
+ $form->addCheck(new \PKP\form\validation\FormValidatorCustom($form, 'endorserEmail', 'required', 'user.register.form.emailExists', function ($endorserEmail) use ($contextId, $submissionId, $rowId) {
+ $submission = Repo::submission()->get($submissionId);
+ $publication = $submission->getCurrentPublication();
+ $endorsement = Repo::endorsement()->getByEmail($endorserEmail, $publication->getId(), $contextId);
+
+ if (is_null($endorsement)) {
+ return true;
+ } else {
+ if ($rowId) {
+ return $rowId == $endorsement->getId();
+ }
+ return false;
+ }
+ }));
+ $form->addCheck(new \PKP\form\validation\FormValidatorCustom($form, 'endorserEmail', 'required', 'plugins.generic.plauditPreEndorsement.endorsementFromAuthor', function ($endorserEmail) use ($submissionId) {
+ $submission = Repo::submission()->get($submissionId);
+ $publication = $submission->getCurrentPublication();
+ $authors = $publication->getData('authors');
+
+ foreach ($authors as $author) {
+ if ($author->getData('email') == $endorserEmail) {
+ return false;
+ }
+ }
+ return true;
+ }));
+ }
+}
diff --git a/cypress/tests/Test1_endorserFieldsSubmission.cy.js b/cypress/tests/Test1_endorserFieldsSubmission.cy.js
index 17ddec2..0b77df0 100644
--- a/cypress/tests/Test1_endorserFieldsSubmission.cy.js
+++ b/cypress/tests/Test1_endorserFieldsSubmission.cy.js
@@ -20,12 +20,14 @@ describe("Plaudit Pre-Endorsement Plugin - Endorser fields in submission wizard"
title: "Killers of the Flower Moon",
abstract: 'A series of murders starts among native americans',
};
- dummyPdf = {
- 'file': 'dummy.pdf',
- 'fileName': 'dummy.pdf',
- 'mimeType': 'application/pdf',
- 'genre': 'Preprint Text'
- };
+ dummyPdf = [
+ {
+ 'file': 'dummy.pdf',
+ 'fileName': 'dummy.pdf',
+ 'mimeType': 'application/pdf',
+ 'genre': 'Preprint Text'
+ }
+ ];
endorsers = {
invalidEmail: {
name: 'John Wayne',
@@ -35,10 +37,14 @@ describe("Plaudit Pre-Endorsement Plugin - Endorser fields in submission wizard"
name: 'Catherine Kwantes',
email: 'ckwantes@mailinator.com'
},
- correct: {
+ firstEndorsement: {
name: 'Bong Joon-ho',
email: 'bong.joon-ho@email.kr'
- }
+ },
+ secondEndorsement: {
+ name: 'DummyEndorsement',
+ email: 'DummyEndorsement@mailinator.com'
+ },
};
});
@@ -47,44 +53,68 @@ describe("Plaudit Pre-Endorsement Plugin - Endorser fields in submission wizard"
cy.get('div#myQueue a:contains("New Submission")').click();
beginSubmission(submissionData);
- cy.setTinyMceContent('titleAbstract-abstract-control-en', submissionData.abstract);
cy.contains('h2', 'Endorsement');
cy.contains('Do you have the endorsement of an experienced researcher in the field of knowledge of the manuscript?');
cy.contains('If yes, please provide the name and e-mail address of the endorsing researcher. Endorsements can significantly speed up the moderation process.');
cy.contains('The endorsement cannot be given by one of the authors of the manuscript.');
+ cy.get('a[id^="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-addEndorsement-button-"]').contains("Add").click();
cy.get('input[name="endorserName"]').clear().type(endorsers.invalidEmail.name, {delay: 0});
cy.get('input[name="endorserEmail"]').clear().type(endorsers.invalidEmail.email, {delay: 0});
- cy.contains('button', 'Continue').click();
-
- cy.addSubmissionGalleys([dummyPdf]);
- cy.contains('button', 'Continue').click();
- cy.contains('button', 'Continue').click();
- cy.contains('button', 'Continue').click();
-
+ cy.get('form[id="endorsementForm"]').find('button[id^="submitFormButton-"]').click();
+ cy.contains('Errors occurred processing this form');
cy.contains('Please enter a valid endorser e-mail');
});
+
it("Validates endorser is not an author of the submission", function() {
cy.login('ckwantes', null, 'publicknowledge');
cy.findSubmission('myQueue', submissionData.title);
+ cy.get('a[id^="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-addEndorsement-button-"]').contains("Add").click();
cy.get('input[name="endorserName"]').clear().type(endorsers.isAuthor.name, {delay: 0});
cy.get('input[name="endorserEmail"]').clear().type(endorsers.isAuthor.email, {delay: 0});
- cy.contains('button', 'Continue').click();
- cy.contains('button', 'Continue').click();
- cy.contains('button', 'Continue').click();
- cy.contains('button', 'Continue').click();
+ cy.get('form[id="endorsementForm"]').find('button[id^="submitFormButton-"]').click();
cy.contains('The endorsement cannot be given by any of the authors of the manuscript');
});
- it("Finishes submission with correct endorsement", function() {
+
+ it("Add correct endorsements", function() {
+ cy.login('ckwantes', null, 'publicknowledge');
+ cy.findSubmission('myQueue', submissionData.title);
+
+ cy.get('a[id^="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-addEndorsement-button-"]').contains("Add").click();
+ cy.get('input[name="endorserName"]').clear().type(endorsers.firstEndorsement.name, {delay: 0});
+ cy.get('input[name="endorserEmail"]').clear().type(endorsers.firstEndorsement.email, {delay: 0});
+ cy.get('form[id="endorsementForm"]').find('button[id^="submitFormButton-"]').click();
+ cy.get('a[id^="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-addEndorsement-button-"]').contains("Add").click();
+ cy.get('input[name="endorserName"]').clear().type(endorsers.secondEndorsement.name, {delay: 0});
+ cy.get('input[name="endorserEmail"]').clear().type(endorsers.secondEndorsement.email, {delay: 0});
+ cy.get('form[id="endorsementForm"]').find('button[id^="submitFormButton-"]').click();
+ });
+
+ it("Validates endorsement email exists", function() {
+ cy.login('ckwantes', null, 'publicknowledge');
+ cy.findSubmission('myQueue', submissionData.title);
+
+ cy.get('a[id^="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-addEndorsement-button-"]').contains("Add").click();
+ cy.get('input[name="endorserName"]').clear().type(endorsers.firstEndorsement.name, {delay: 0});
+ cy.get('input[name="endorserEmail"]').clear().type(endorsers.firstEndorsement.email, {delay: 0});
+ cy.get('form[id="endorsementForm"]').find('button[id^="submitFormButton-"]').click();
+ cy.contains('Errors occurred processing this form');
+ cy.contains('The selected email address is already in use by another user.');
+ });
+
+ it("Finishes submission with correct endorsements", function() {
cy.login('ckwantes', null, 'publicknowledge');
cy.findSubmission('myQueue', submissionData.title);
+ cy.setTinyMceContent('titleAbstract-abstract-control-en', submissionData.abstract);
- cy.get('input[name="endorserName"]').clear().type(endorsers.correct.name, {delay: 0});
- cy.get('input[name="endorserEmail"]').clear().type(endorsers.correct.email, {delay: 0});
cy.contains('button', 'Continue').click();
+ cy.get('h2').contains('Upload Files');
+ cy.get('h2').contains('Files');
+ cy.addSubmissionGalleys(dummyPdf);
+
cy.contains('button', 'Continue').click();
cy.contains('button', 'Continue').click();
cy.contains('button', 'Continue').click();
@@ -96,4 +126,12 @@ describe("Plaudit Pre-Endorsement Plugin - Endorser fields in submission wizard"
cy.waitJQuery();
cy.contains('h1', 'Submission complete');
});
+
+ it("Check endorsements emails", function() {
+ cy.visit('localhost:8025');
+ cy.contains('Ramiro Vaca');
+ cy.contains('DummyEndorsement@mailinator.com');
+ cy.contains('bong.joon-ho@email.kr');
+ cy.contains('Endorsement confirmation');
+ });
});
\ No newline at end of file
diff --git a/cypress/tests/Test2_workflowFeatures.cy.js b/cypress/tests/Test2_workflowFeatures.cy.js
index 17bef10..9382580 100644
--- a/cypress/tests/Test2_workflowFeatures.cy.js
+++ b/cypress/tests/Test2_workflowFeatures.cy.js
@@ -9,56 +9,32 @@ describe("Plaudit Pre-Endorsement Plugin - Workflow features", function() {
cy.get("#publication-button").click();
cy.contains("Pre-Endorsement").click();
- cy.get('input[name="endorserNameWorkflow"]').should('have.value', 'Bong Joon-ho');
- cy.get('input[name="endorserEmailWorkflow"]').should('have.value', 'bong.joon-ho@email.kr');
- cy.contains('The endorsement has not yet been confirmed by the endorser');
- cy.contains("1 endorsement confirmation e-mail has been sent to the endorser");
- cy.get('#plauditPreEndorsement-button .pkpBadge:contains("1")');
- });
- it("E-mail sendings counting in workflow tab", function() {
- cy.login('ckwantes', null, 'publicknowledge');
- cy.findSubmission('myQueue', submissionTitle);
-
- cy.get("#publication-button").click();
- cy.contains("Pre-Endorsement").click();
- cy.contains("1 endorsement confirmation e-mail has been sent to the endorser");
- cy.get("#plauditPreEndorsement").contains("Save").click();
-
- cy.reload();
- cy.contains("2 endorsement confirmation e-mails have been sent to the endorser");
- cy.get('input[name="endorserNameWorkflow"]').clear().type("Lady Diana", { delay: 0 });
- cy.get('input[name="endorserEmailWorkflow"]').clear().type("lady.diana@gmail.com", { delay: 0 });
- cy.get("#plauditPreEndorsement").contains("Save").click();
-
- cy.reload();
- cy.contains("1 endorsement confirmation e-mail has been sent to the endorser");
+ cy.contains('Bong Joon-ho');
+ cy.contains('bong.joon-ho@email.kr');
+ cy.contains('DummyEndorsement');
+ cy.contains('DummyEndorsement@mailinator.com');
+ cy.contains('Awaiting confirmation');
+ cy.get('#plauditPreEndorsement-button .pkpBadge:contains("2")');
});
- it("Endorsement removal", function() {
- cy.login('ckwantes', null, 'publicknowledge');
- cy.findSubmission('myQueue', submissionTitle);
-
- cy.get("#publication-button").click();
- cy.contains("Pre-Endorsement").click();
- cy.contains('button', 'Remove endorsement').should('not.exist');
- cy.logout();
+ it("Endorsement removal", function() {
cy.login('dbarnes', null, 'publicknowledge');
cy.findSubmission('active', submissionTitle);
cy.get("#publication-button").click();
cy.contains("Pre-Endorsement").click();
- cy.contains('button', 'Remove endorsement').click();
- cy.on('window:confirm', () => true);
+ cy.get('[id*="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-row-"] > .first_column > .show_extras').first().click();
+ cy.get('[id*="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-row-"][id*="-delete-button-"]').first().click();
+ cy.get('.ok').click();
cy.reload();
- cy.get('input[name="endorserNameWorkflow"]').should('have.value', '');
- cy.get('input[name="endorserEmailWorkflow"]').should('have.value', '');
- cy.contains('The endorsement has not yet been confirmed by the endorser').should('not.exist');
- cy.contains("1 endorsement confirmation e-mail has been sent to the endorser").should('not.exist');
- cy.get('#plauditPreEndorsement-button .pkpBadge:contains("0")');
+ cy.contains('Bong Joon-ho').should('not.exist');
+ cy.contains("bong.joon-ho@email.kr").should('not.exist');
+ cy.get('#plauditPreEndorsement-button .pkpBadge:contains("1")');
});
+
it("Endorsement adding on workflow", function() {
- let newEndorserName = 'Francis Ford Coppola';
- let newEndorserEmail = 'francis.coppola@hollywood.com';
+ let newEndorsementName = 'Francis Ford Coppola';
+ let newEndorsementEmail = 'francis.coppola@hollywood.com';
cy.login('ckwantes', null, 'publicknowledge');
cy.findSubmission('myQueue', submissionTitle);
@@ -66,25 +42,33 @@ describe("Plaudit Pre-Endorsement Plugin - Workflow features", function() {
cy.get("#publication-button").click();
cy.contains("Pre-Endorsement").click();
- cy.get('input[name="endorserNameWorkflow"]').clear().type(newEndorserName, { delay: 0 });
- cy.get('input[name="endorserEmailWorkflow"]').clear().type(newEndorserEmail, { delay: 0 });
- cy.get("#plauditPreEndorsement").contains("Save").click();
+ cy.get('a[id^="component-plugins-generic-plauditpreendorsement-controllers-grid-endorsementgrid-addEndorsement-button-"]').contains("Add").click();
+ cy.get('input[name="endorserName"]').clear().type(newEndorsementName, {delay: 0});
+ cy.get('input[name="endorserEmail"]').clear().type(newEndorsementEmail, {delay: 0});
+ cy.get('form[id="endorsementForm"]').find('button[id^="submitFormButton-"]').click();
cy.reload();
- cy.get('input[name="endorserNameWorkflow"]').should('have.value', newEndorserName);
- cy.get('input[name="endorserEmailWorkflow"]').should('have.value', newEndorserEmail);
- cy.contains('The endorsement has not yet been confirmed by the endorser');
- cy.contains("1 endorsement confirmation e-mail has been sent to the endorser");
- cy.get('#plauditPreEndorsement-button .pkpBadge:contains("1")');
+ cy.contains(newEndorsementName);
+ cy.contains(newEndorsementEmail);
+ cy.get('#plauditPreEndorsement-button .pkpBadge:contains("2")');
});
+
it("Endorsement actions are written in submission's Activity Log", function() {
cy.login('dbarnes', null, 'publicknowledge');
cy.findSubmission('active', submissionTitle);
cy.contains('button', 'Activity Log').click();
cy.contains('An endorsement confirmation e-mail has been sent to Bong Joon-ho (bong.joon-ho@email.kr)');
- cy.contains('An endorsement confirmation e-mail has been sent to Lady Diana (lady.diana@gmail.com)');
- cy.contains('The submission endorsement has been removed');
+ cy.contains('A submission endorsement has been removed: Bong Joon-ho (bong.joon-ho@email.kr)');
cy.contains('An endorsement confirmation e-mail has been sent to Francis Ford Coppola (francis.coppola@hollywood.com)');
});
+
+ it("Check endorsements emails", function() {
+ cy.visit('localhost:8025');
+ cy.contains('Ramiro Vaca');
+ cy.contains('DummyEndorsement@mailinator.com');
+ cy.contains('bong.joon-ho@email.kr');
+ cy.contains('francis.coppola@hollywood.com');
+ cy.contains('Endorsement confirmation');
+ });
});
\ No newline at end of file
diff --git a/js/EndorsementGridHandler.js b/js/EndorsementGridHandler.js
new file mode 100644
index 0000000..87a9972
--- /dev/null
+++ b/js/EndorsementGridHandler.js
@@ -0,0 +1,59 @@
+(function($) {
+
+ /** @type {Object} */
+ $.pkp.plugins.generic.plauditPreEndorsement =
+ $.pkp.plugins.generic.plauditPreEndorsement ||
+ { js: { } };
+
+ /**
+ * @constructor
+ *
+ * @extends $.pkp.controllers.grid.CategoryGridHandler
+ *
+ * @param {jQueryObject} $grid The grid this handler is
+ * attached to.
+ * @param {Object} options Grid handler configuration.
+ */
+ $.pkp.plugins.generic.plauditPreEndorsement.EndorsementGridHandler =
+ function($grid, options) {
+ this.parent($grid, options);
+ };
+ $.pkp.classes.Helper.inherits(
+ $.pkp.plugins.generic.plauditPreEndorsement.EndorsementGridHandler,
+ $.pkp.controllers.grid.GridHandler);
+
+ //
+ // Public methods.
+ //
+
+ /**
+ * Refresh the whole grid.
+ *
+ * @protected
+ *
+ * @param {HTMLElement} sourceElement The element that
+ * issued the event.
+ * @param {Event} event The triggering event.
+ * @param {number|Object=} opt_elementId The submissionId
+ * @param {Boolean=} opt_fetchedAlready Flag that subclasses can send
+ * telling that a fetch operation was already handled there.
+ */
+ $.pkp.plugins.generic.plauditPreEndorsement.EndorsementGridHandler.prototype.refreshGridHandler =
+ function(sourceElement, event, opt_elementId, opt_fetchedAlready) {
+ var params;
+
+ params = this.getFetchExtraParams();
+
+ // Check if subclasses already handled the fetch of new elements.
+ if (!opt_fetchedAlready) {
+ params.submissionId = opt_elementId;
+ $.get(this.fetchGridUrl_, params,
+ this.callbackWrapper(this.replaceGridResponseHandler_), 'json');
+ }
+
+ // Let the calling context (page?) know that the grids are being redrawn.
+ this.trigger('gridRefreshRequested');
+ this.publishChangeEvents();
+ };
+
+}(jQuery));
\ No newline at end of file
diff --git a/locale/en/locale.po b/locale/en/locale.po
index f055c2a..9fb4980 100644
--- a/locale/en/locale.po
+++ b/locale/en/locale.po
@@ -32,20 +32,32 @@ msgstr "Endorser's email address"
msgid "plugins.generic.plauditPreEndorsement.endorserOrcid"
msgstr "Endorser's ORCID"
+msgid "plugins.generic.plauditPreEndorsement.endorsementStatus"
+msgstr "Status"
+
+msgid "plugins.generic.plauditPreEndorsement.emailColumnName"
+msgstr "Endorser's email address / Emails count"
+
msgid "plugins.generic.plauditPreEndorsement.endorsementConfirmed"
-msgstr "The endorsement has been confirmed by the endorser"
+msgstr "Confirmed by endorser"
msgid "plugins.generic.plauditPreEndorsement.endorsementNotConfirmed"
-msgstr "The endorsement has not yet been confirmed by the endorser"
+msgstr "Awaiting confirmation"
msgid "plugins.generic.plauditPreEndorsement.endorsementDenied"
-msgstr "The endorser denied access to his/her ORCID registry"
+msgstr "Access to ORCID denied"
msgid "plugins.generic.plauditPreEndorsement.endorsementCouldntComplete"
-msgstr "The submission of the endorsement to Plaudit could not be completed"
+msgstr "Error sending to Plaudit"
msgid "plugins.generic.plauditPreEndorsement.endorsementCompleted"
-msgstr "The endorsement was successfully sent to Plaudit"
+msgstr "Sent to Plaudit"
+
+msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditNotification"
+msgstr "Attempt to send endorsement to Plaudit completed. You can check the endorser's status or view the Activity Log for more details."
+
+msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditConfirmationMessage"
+msgstr "Do you want to send the endorsement of this submission to Plaudit?"
msgid "plugins.generic.plauditPreEndorsement.endorserEmailCount.one"
msgstr "1 endorsement confirmation e-mail has been sent to the endorser"
@@ -178,4 +190,4 @@ msgid "plugins.generic.plauditPreEndorsement.log.attemptSendingEndorsement"
msgstr "Attempt to send endorsement to Plaudit with DOI {$doi} and ORCID {$orcid}"
msgid "plugins.generic.plauditPreEndorsement.log.endorsementRemoved"
-msgstr "The submission endorsement has been removed"
\ No newline at end of file
+msgstr "A submission endorsement has been removed: {$endorserName} ({$endorserEmail})"
\ No newline at end of file
diff --git a/locale/es/locale.po b/locale/es/locale.po
index 5bd9f1a..334f360 100644
--- a/locale/es/locale.po
+++ b/locale/es/locale.po
@@ -32,20 +32,26 @@ msgstr "Dirección de correo electrónico del/a endosador/a"
msgid "plugins.generic.plauditPreEndorsement.endorserOrcid"
msgstr "ORCID del/a endosador/a"
+msgid "plugins.generic.plauditPreEndorsement.endorsementStatus"
+msgstr "Estado"
+
+msgid "plugins.generic.plauditPreEndorsement.emailColumnName"
+msgstr "Dirección de correo electrónico del endosante / Conteo de correos"
+
msgid "plugins.generic.plauditPreEndorsement.endorsementConfirmed"
-msgstr "El endoso fue confirmado por el/la endosador/a"
+msgstr "Confirmado por el endosante"
msgid "plugins.generic.plauditPreEndorsement.endorsementNotConfirmed"
-msgstr "El endoso aún no fue confirmado por el/la endosador/a"
+msgstr "Esperando confirmación"
msgid "plugins.generic.plauditPreEndorsement.endorsementDenied"
-msgstr "El/La endosador/a ha denegado el acceso a su registro ORCID"
+msgstr "Acceso a ORCID denegado"
msgid "plugins.generic.plauditPreEndorsement.endorsementCouldntComplete"
-msgstr "No se pudo completar el envío del endoso a Plaudit"
+msgstr "Error al enviar a Plaudit"
msgid "plugins.generic.plauditPreEndorsement.endorsementCompleted"
-msgstr "El endoso se ha enviado correctamente a Plaudit"
+msgstr "Enviado a Plaudit"
msgid "plugins.generic.plauditPreEndorsement.endorserEmailCount.one"
msgstr "Se ha enviado 1 correo electrónico de confirmación de endoso al endosante"
@@ -59,6 +65,12 @@ msgstr "Aprobación previa"
msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlaudit"
msgstr "Enviar endoso a Plaudit"
+msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditNotification"
+msgstr "Intento de envío del endoso a Plaudit completado. Puede verificar el estado del endosador o ver el Registro de actividad para más detalles."
+
+msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditConfirmationMessage"
+msgstr "¿Desea enviar el endoso de este envío a Plaudit?"
+
msgid "plugins.generic.plauditPreEndorsement.removeEndorsement"
msgstr "Eliminar endoso"
@@ -143,7 +155,6 @@ msgstr "El ORCID proporcionado para el endosante no debe ser el mismo que el de
msgid "plugins.generic.plauditPreEndorsement.failure.contact"
msgstr "Comuníquese con el administrador del servidor con su nombre, ORCID ID y detalles de envío"
-
msgid "plugins.generic.plauditPreEndorsement.log.sentEmailEndorser"
msgstr "Se ha enviado un correo electrónico de confirmación de endoso a {$endorserName} ({$endorserEmail})"
@@ -178,4 +189,4 @@ msgid "plugins.generic.plauditPreEndorsement.log.attemptSendingEndorsement"
msgstr "Intento de enviar endoso a Plaudit con DOI {$doi} y ORCID {$orcid}"
msgid "plugins.generic.plauditPreEndorsement.log.endorsementRemoved"
-msgstr "Se ha eliminado lo endoso del envío"
+msgstr "Se ha eliminado un endoso del envío: {$endorserName} ({$endorserEmail})"
\ No newline at end of file
diff --git a/locale/pt_BR/locale.po b/locale/pt_BR/locale.po
index 537fce2..3abe3cd 100644
--- a/locale/pt_BR/locale.po
+++ b/locale/pt_BR/locale.po
@@ -32,20 +32,26 @@ msgstr "Endereço de e-mail do(a) endossador(a)"
msgid "plugins.generic.plauditPreEndorsement.endorserOrcid"
msgstr "ORCID do(a) endossador(a)"
+msgid "plugins.generic.plauditPreEndorsement.endorsementStatus"
+msgstr "Situação"
+
+msgid "plugins.generic.plauditPreEndorsement.emailColumnName"
+msgstr "Endereço de email do endossador / Contagem de emails"
+
msgid "plugins.generic.plauditPreEndorsement.endorsementConfirmed"
-msgstr "O endosso foi confirmado pelo(a) endossador(a)"
+msgstr "Confirmado pelo(a) endossador(a)"
msgid "plugins.generic.plauditPreEndorsement.endorsementNotConfirmed"
-msgstr "O endosso ainda não foi confirmado pelo(a) endossador(a)"
+msgstr "Aguardando confirmação"
msgid "plugins.generic.plauditPreEndorsement.endorsementDenied"
-msgstr "O(A) endossador(a) negou acesso ao seu registro ORCID"
+msgstr "Acesso ao ORCID negado"
msgid "plugins.generic.plauditPreEndorsement.endorsementCouldntComplete"
-msgstr "O envio do endosso à Plaudit não pôde ser completado"
+msgstr "Erro no envio à Plaudit"
msgid "plugins.generic.plauditPreEndorsement.endorsementCompleted"
-msgstr "O endosso foi enviado com sucesso à Plaudit"
+msgstr "Enviado à Plaudit"
msgid "plugins.generic.plauditPreEndorsement.endorserEmailCount.one"
msgstr "Foi enviado 1 e-mail de confirmação do endosso para o(a) endossador(a)"
@@ -56,6 +62,12 @@ msgstr "Foram enviados {$numEmails} e-mails de confirmação do endosso para o(a
msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlaudit"
msgstr "Enviar endosso à Plaudit"
+msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditConfirmationMessage"
+msgstr "Deseja enviar o endosso desta submissão à Plaudit?"
+
+msgid "plugins.generic.plauditPreEndorsement.sendEndorsementToPlauditNotification"
+msgstr "Tentativa de envio do endosso à Plaudit concluída. Você pode checar o status do endossador ou verificar o Histórico de Atividades para mais detalhes."
+
msgid "plugins.generic.plauditPreEndorsement.removeEndorsement"
msgstr "Remover endosso"
@@ -143,7 +155,6 @@ msgstr "O ORCID informado para o(a) endossador(a) não pode ser o mesmo de um do
msgid "plugins.generic.plauditPreEndorsement.failure.contact"
msgstr "Por favor, entre em contato com o administrador do servidor, informando seu nome, ORCID ID e detalhes da submissão"
-
msgid "plugins.generic.plauditPreEndorsement.log.sentEmailEndorser"
msgstr "Foi enviado um e-mail de confirmação de endosso para {$endorserName} ({$endorserEmail})"
@@ -178,4 +189,4 @@ msgid "plugins.generic.plauditPreEndorsement.log.attemptSendingEndorsement"
msgstr "Tentativa de envio do endosso à Plaudit com DOI {$doi} e ORCID {$orcid}"
msgid "plugins.generic.plauditPreEndorsement.log.endorsementRemoved"
-msgstr "O endosso da submissão foi removido"
\ No newline at end of file
+msgstr "Um endosso de submissão foi removido: {$endorserName} ({$endorserEmail})"
\ No newline at end of file
diff --git a/schemas/endorsement.json b/schemas/endorsement.json
new file mode 100644
index 0000000..06d3ae2
--- /dev/null
+++ b/schemas/endorsement.json
@@ -0,0 +1,34 @@
+{
+ "title": "Endorsement",
+ "description": "An endorsement of a publication to be sent to Plaudit.",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "readOnly": true
+ },
+ "contextId": {
+ "type": "integer"
+ },
+ "publicationId": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "status": {
+ "type": "integer"
+ },
+ "orcid": {
+ "type": "string"
+ },
+ "emailToken": {
+ "type": "string"
+ },
+ "emailCount": {
+ "type": "integer"
+ }
+ }
+}
diff --git a/styles/endorserWorkflowStyleSheet.css b/styles/endorserWorkflowStyleSheet.css
index a68af07..cf85f3e 100644
--- a/styles/endorserWorkflowStyleSheet.css
+++ b/styles/endorserWorkflowStyleSheet.css
@@ -1,4 +1,4 @@
-#updateEndorserForm {
+#updateEndorsementForm {
padding: 0.875rem 1rem;
margin: 0 -2rem;
}
@@ -43,4 +43,22 @@
.formButtons {
text-align: right;
margin-top: 2rem;
+}
+
+.endorsementStatusCustomBadge {
+ display: inline-block;
+ padding: .25em 1em;
+ font-size: .75rem;
+ font-weight: 400;
+ line-height: 1.5em;
+ border: 1px solid #ddd;
+ border-radius: 1.2em;
+ color: #fff;
+ background-color: #e08914;
+}
+
+#plauditPreEndorsement-button {
+ span {
+ text-align: center;
+ }
}
\ No newline at end of file
diff --git a/templates/addEndorsement.tpl b/templates/addEndorsement.tpl
new file mode 100644
index 0000000..2726059
--- /dev/null
+++ b/templates/addEndorsement.tpl
@@ -0,0 +1,27 @@
+
+
+
+
+ {capture assign=actionUrl}{url router=$smarty.const.ROUTE_COMPONENT component="plugins.generic.plauditPreEndorsement.controllers.grid.EndorsementGridHandler" op="updateEndorsement" submissionId=$submissionId escape=false}{/capture}
+
+
\ No newline at end of file
diff --git a/templates/endorsementComponent.tpl b/templates/endorsementComponent.tpl
new file mode 100644
index 0000000..eadc9fe
--- /dev/null
+++ b/templates/endorsementComponent.tpl
@@ -0,0 +1,8 @@
+
+
+
+
+
+ {capture assign=endorsersGridUrl}{url router=$smarty.const.ROUTE_COMPONENT component="plugins.generic.plauditPreEndorsement.controllers.grid.EndorsementGridHandler" op="fetchGrid" submissionId=$submission->getId() escape=false}{/capture}
+ {load_url_in_div id="endorsersGridContainer"|uniqid url=$endorsersGridUrl inVueEl=true}
+
diff --git a/templates/endorserFieldWorkflow.tpl b/templates/endorserFieldWorkflow.tpl
deleted file mode 100644
index c588399..0000000
--- a/templates/endorserFieldWorkflow.tpl
+++ /dev/null
@@ -1,138 +0,0 @@
-{*
- * Copyright (c) 2022 - 2024 SciELO
- * Copyright (c) 2022 - 2024 Lepidus Tecnologia
- * Distributed under the GNU GPL v3. For full terms see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt
- *
- *}
-
-
-
-
-
-{if $canEditEndorsement}
-
-{/if}
-
-{if $canSendEndorsementManually}
-
-{/if}
-
-{if $canRemoveEndorsement}
-
-{/if}
\ No newline at end of file
diff --git a/templates/gridCells/endorsementStatus.tpl b/templates/gridCells/endorsementStatus.tpl
new file mode 100644
index 0000000..81fab30
--- /dev/null
+++ b/templates/gridCells/endorsementStatus.tpl
@@ -0,0 +1,17 @@
+{**
+ * templates/controllers/grid/gridCell.tpl
+ *
+ * Copyright (c) 2014-2021 Simon Fraser University
+ * Copyright (c) 2000-2021 John Willinsky
+ * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
+ *
+ * a regular grid cell (with or without actions)
+ *}
+{if $id}
+ {assign var=cellId value="cell-"|concat:$id}
+{else}
+ {assign var=cellId value=""}
+{/if}
+
+ {include file="controllers/grid/gridCellContents.tpl"}
+
diff --git a/templates/gridCells/endorserEmail.tpl b/templates/gridCells/endorserEmail.tpl
new file mode 100644
index 0000000..c58755f
--- /dev/null
+++ b/templates/gridCells/endorserEmail.tpl
@@ -0,0 +1,20 @@
+{**
+ * templates/controllers/grid/gridCell.tpl
+ *
+ * Copyright (c) 2014-2021 Simon Fraser University
+ * Copyright (c) 2000-2021 John Willinsky
+ * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
+ *
+ * a regular grid cell (with or without actions)
+ *}
+ {if $id}
+ {assign var=cellId value="cell-"|concat:$id}
+{else}
+ {assign var=cellId value=""}
+{/if}
+
+ {include file="controllers/grid/gridCellContents.tpl"}
+
+
+ {$emailCount}
+
diff --git a/templates/gridCells/endorserName.tpl b/templates/gridCells/endorserName.tpl
new file mode 100644
index 0000000..23b45a7
--- /dev/null
+++ b/templates/gridCells/endorserName.tpl
@@ -0,0 +1,25 @@
+{**
+ * templates/controllers/grid/gridCell.tpl
+ *
+ * Copyright (c) 2014-2021 Simon Fraser University
+ * Copyright (c) 2000-2021 John Willinsky
+ * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
+ *
+ * a regular grid cell (with or without actions)
+ *}
+{if $id}
+ {assign var=cellId value="cell-"|concat:$id}
+{else}
+ {assign var=cellId value=""}
+{/if}
+
+ {include file="controllers/grid/gridCellContents.tpl"}
+
+
+{if $orcid}
+
+
+
+
+
+{/if}
diff --git a/tests/EndorsementServiceTest.php b/tests/EndorsementServiceTest.php
index d7b97ff..ad0e309 100644
--- a/tests/EndorsementServiceTest.php
+++ b/tests/EndorsementServiceTest.php
@@ -5,15 +5,18 @@
use APP\publication\Publication;
use PKP\doi\Doi;
use APP\core\Application;
-use APP\facades\Repo;
use PKP\core\Core;
use APP\plugins\generic\plauditPreEndorsement\classes\CrossrefClient;
use APP\plugins\generic\plauditPreEndorsement\classes\OrcidClient;
use APP\plugins\generic\plauditPreEndorsement\classes\EndorsementService;
use APP\plugins\generic\plauditPreEndorsement\PlauditPreEndorsementPlugin;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
+use APP\plugins\generic\plauditPreEndorsement\tests\helpers\TestHelperTrait;
final class EndorsementServiceTest extends DatabaseTestCase
{
+ use TestHelperTrait;
+
private $endorsementService;
private $contextId = 1;
private $submissionId;
@@ -21,17 +24,20 @@ final class EndorsementServiceTest extends DatabaseTestCase
private $plugin;
private $doi = '10.1234/TestePublication.1234';
private $secretKey = 'a1b2c3d4-e5f6g7h8';
- private $endorserName = 'Caio Anjo';
- private $endorserOrcid = '0010-1010-1101-0001';
- private $endorserGivenNameOrcid = 'Caio';
- private $endorserFamilyNameOrcid = 'dos Anjos';
+ private $endorsementName = 'Caio Anjo';
+ private $endorsementOrcid = '0010-1010-1101-0001';
+ private $endorsementGivenNameOrcid = 'Caio';
+ private $endorsementFamilyNameOrcid = 'dos Anjos';
+ private $endorsementId;
public function setUp(): void
{
parent::setUp();
- $this->publication = $this->createEndorsedPublication();
+ $this->addSchemaFile('endorsement');
+ $this->publication = $this->createPublication();
$this->plugin = new PlauditPreEndorsementPlugin();
$this->endorsementService = new EndorsementService($this->contextId, $this->plugin);
+ $this->endorsementId = $this->createEndorsement();
}
public function tearDown(): void
@@ -46,10 +52,22 @@ public function tearDown(): void
protected function getAffectedTables(): array
{
- return ['event_log', 'event_log_settings'];
+ return ['event_log', 'event_log_settings', 'endorsements'];
+ }
+
+ private function createEndorsement()
+ {
+ $params = [
+ 'publicationId' => $this->publication->getId(),
+ 'contextId' => $this->contextId,
+ 'name' => 'Dummy',
+ 'email' => 'dummy@mailinator.com.br'
+ ];
+ $endorsement = Repo::endorsement()->newDataObject($params);
+ return Repo::endorsement()->add($endorsement);
}
- private function createEndorsedPublication(): Publication
+ private function createPublication(): Publication
{
$context = DAORegistry::getDAO('ServerDAO')->getById($this->contextId);
@@ -57,7 +75,6 @@ private function createEndorsedPublication(): Publication
$submission->setData('contextId', $this->contextId);
$publication = new Publication();
- $publication->setData('endorserName', $this->endorserName);
$this->submissionId = Repo::submission()->add($submission, $publication, $context);
@@ -91,15 +108,15 @@ private function getMockOrcidClient()
'value' => 1666816304613
],
'given-names' => [
- 'value' => $this->endorserGivenNameOrcid
+ 'value' => $this->endorsementGivenNameOrcid
],
'family-name' => [
- 'value' => $this->endorserFamilyNameOrcid
+ 'value' => $this->endorsementFamilyNameOrcid
],
'credit-name' => '',
'source' => '',
'visibility' => 'public',
- 'path' => $this->endorserOrcid
+ 'path' => $this->endorsementOrcid
]
]
];
@@ -107,10 +124,10 @@ private function getMockOrcidClient()
$mockOrcidClient = $this->createMock(OrcidClient::class);
$mockOrcidClient->method('getReadPublicAccessToken')->willReturn($fictionalAccessToken);
$mockOrcidClient->method('getOrcidRecord')->willReturnMap([
- [$this->endorserOrcid, $fictionalAccessToken, $testRecord]
+ [$this->endorsementOrcid, $fictionalAccessToken, $testRecord]
]);
$mockOrcidClient->method('getFullNameFromRecord')->willReturnMap([
- [$testRecord, $this->endorserGivenNameOrcid . ' ' . $this->endorserFamilyNameOrcid]
+ [$testRecord, $this->endorsementGivenNameOrcid . ' ' . $this->endorsementFamilyNameOrcid]
]);
return $mockOrcidClient;
@@ -150,15 +167,16 @@ public function testValidateEndorsementSending(): void
$this->assertEquals('ok', $validateResult);
}
- public function testUpdateEndorserName(): void
+ public function testUpdateEndorsementName(): void
{
+ $endorsement = Repo::endorsement()->get($this->endorsementId);
$mockOrcidClient = $this->getMockOrcidClient();
$this->endorsementService->setOrcidClient($mockOrcidClient);
- $this->publication = $this->endorsementService->updateEndorserNameFromOrcid($this->publication, $this->endorserOrcid);
- $expectedNewName = $this->endorserGivenNameOrcid . ' ' . $this->endorserFamilyNameOrcid;
+ $newEndorsement = $this->endorsementService->updateEndorsementNameFromOrcid($endorsement, $this->endorsementOrcid);
+ $expectedNewName = $this->endorsementGivenNameOrcid . ' ' . $this->endorsementFamilyNameOrcid;
- $this->assertEquals($expectedNewName, $this->publication->getData('endorserName'));
+ $this->assertEquals($expectedNewName, $newEndorsement->getName());
}
public function testMessageWasAlreadyLoggedToday(): void
diff --git a/tests/PlauditClientTest.php b/tests/PlauditClientTest.php
index 11ec831..f4ba40f 100644
--- a/tests/PlauditClientTest.php
+++ b/tests/PlauditClientTest.php
@@ -4,9 +4,10 @@
use APP\publication\Publication;
use PKP\doi\Doi;
-use APP\plugins\generic\plauditPreEndorsement\classes\Endorsement;
+use APP\plugins\generic\plauditPreEndorsement\classes\endorsement\Endorsement;
use APP\plugins\generic\plauditPreEndorsement\classes\PlauditClient;
use APP\plugins\generic\plauditPreEndorsement\tests\TestResponse;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
use PHPUnit\Framework\TestCase;
class PlauditClientTest extends TestCase
@@ -16,6 +17,7 @@ class PlauditClientTest extends TestCase
private $doi = '10.1590/LepidusPreprints.1535';
private $orcid = '0000-0001-5542-5100';
private $orcidX = '0000-0001-5542-510X';
+ private $endorsement;
public function setUp(): void
{
@@ -25,11 +27,22 @@ public function setUp(): void
$doiObject->setData('doi', $this->doi);
$this->publication = new Publication();
$this->publication->setData('doiObject', $doiObject);
- $this->publication->setData('endorserOrcid', $this->orcid);
+ $this->endorsement = $this->createEndorsement();
$this->plauditClient = new PlauditClient();
}
+ private function createEndorsement()
+ {
+ $params = [
+ 'name' => 'Dummy',
+ 'email' => 'dummy@mailinator.com.br',
+ 'orcid' => $this->orcid
+ ];
+ $endorsement = Repo::endorsement()->newDataObject($params);
+ return $endorsement;
+ }
+
public function testFilterOrcidNumbers(): void
{
$orcidUrlPrefix = 'https://orcid.org/';
@@ -48,7 +61,7 @@ public function testEndorsementStatusWhenRequestSucceed(): void
$bodyJson = "{\"endorsements\":[{\"doi\":\"$lowerCaseDoi\",\"orcid\":\"$this->orcid\",\"tags\":[]}]}";
$response = new TestResponse($statusOk, $bodyJson);
- $this->assertEquals(Endorsement::STATUS_COMPLETED, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication));
+ $this->assertEquals(Endorsement::STATUS_COMPLETED, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication, $this->endorsement));
}
public function testEndorsementStatusWhenRequestSucceedButDataDiffs(): void
@@ -57,13 +70,13 @@ public function testEndorsementStatusWhenRequestSucceedButDataDiffs(): void
$bodyJson = "{\"endorsements\":[{\"doi\":\"10.1590/lepiduspreprints.2022\",\"orcid\":\"$this->orcid\",\"tags\":[]}]}";
$response = new TestResponse($statusOk, $bodyJson);
- $this->assertEquals(Endorsement::STATUS_COULDNT_COMPLETE, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication));
+ $this->assertEquals(Endorsement::STATUS_COULDNT_COMPLETE, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication, $this->endorsement));
$lowerCaseDoi = strtolower($this->doi);
$bodyJson = "{\"endorsements\":[{\"doi\":\"$lowerCaseDoi\",\"orcid\":\"0000-0001-5542-1234\",\"tags\":[]}]}";
$response = new TestResponse($statusOk, $bodyJson);
- $this->assertEquals(Endorsement::STATUS_COULDNT_COMPLETE, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication));
+ $this->assertEquals(Endorsement::STATUS_COULDNT_COMPLETE, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication, $this->endorsement));
}
public function testEndorsementStatusWhenRequestFails(): void
@@ -72,6 +85,6 @@ public function testEndorsementStatusWhenRequestFails(): void
$bodyJson = "";
$response = new TestResponse($statusBadRequest, $bodyJson);
- $this->assertEquals(Endorsement::STATUS_COULDNT_COMPLETE, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication));
+ $this->assertEquals(Endorsement::STATUS_COULDNT_COMPLETE, $this->plauditClient->getEndorsementStatusByResponse($response, $this->publication, $this->endorsement));
}
}
diff --git a/tests/PlauditPreEndorsementHandlerTest.php b/tests/PlauditPreEndorsementHandlerTest.php
index e93e874..91fd025 100644
--- a/tests/PlauditPreEndorsementHandlerTest.php
+++ b/tests/PlauditPreEndorsementHandlerTest.php
@@ -2,42 +2,59 @@
use APP\publication\Publication;
use APP\core\Request;
-use APP\plugins\generic\plauditPreEndorsement\classes\Endorsement;
+use APP\plugins\generic\plauditPreEndorsement\classes\endorsement\Endorsement;
use APP\plugins\generic\plauditPreEndorsement\classes\PlauditPreEndorsementHandler;
use PHPUnit\Framework\TestCase;
+use APP\plugins\generic\plauditPreEndorsement\classes\facades\Repo;
final class PlauditPreEndorsementHandlerTest extends TestCase
{
private $publication;
- private $endorserEmail = 'endorser@email.com';
- private $endorserName = 'Endorser';
- private $endorserEmailToken;
+ private $firstEndorsement;
+ private $secondEndorsement;
+ private $endorsementEmailToken;
public function setUp(): void
{
parent::setUp();
- $this->endorserEmailToken = md5(microtime() . $this->endorserEmail);
+ $this->endorsementEmailToken = md5(microtime() . 'dummy@mailinator.com.br');
$this->publication = $this->createPublication();
+ [$this->firstEndorsement, $this->secondEndorsement] = $this->addEndorsements();
}
private function createPublication(): Publication
{
$this->publication = new Publication();
- $this->publication->setData('id', 1);
- $this->publication->setData('endorserEmail', $this->endorserEmail);
- $this->publication->setData('endorserName', $this->endorserName);
- $this->publication->setData('endorserEmailToken', $this->endorserEmailToken);
- $this->publication->setData('endorsementStatus', Endorsement::STATUS_NOT_CONFIRMED);
+ $this->publication->setData('id', rand());
return $this->publication;
}
- private function verifyEndorserAuth($token, $error = null): string
+ private function addEndorsements(): array
+ {
+ $firstEndorsementParams = [
+ 'name' => 'YvesDummy',
+ 'email' => 'dummy@mailinator.com.br',
+ 'emailToken' => $this->endorsementEmailToken
+ ];
+ $secondEndorsementParams = [
+ 'name' => 'JhonDummy',
+ 'email' => 'dummy2@mailinator.com.br',
+ 'emailToken' => md5(microtime() . 'dummy2@mailinator.com.br')
+ ];
+ $firstEndorsement = Repo::endorsement()->newDataObject($firstEndorsementParams);
+ $secondEndorsement = Repo::endorsement()->newDataObject($secondEndorsementParams);
+
+ return [$firstEndorsement, $secondEndorsement];
+ }
+
+ private function verifyEndorsementAuth($token, $endorsement, $error = null): string
{
$request = new Request();
$request->_requestVars = [
'state' => $this->publication->getId(),
- 'token' => $token
+ 'token' => $token,
+ 'endorsementId' => rand()
];
if ($error) {
@@ -45,25 +62,24 @@ private function verifyEndorserAuth($token, $error = null): string
}
$handler = new PlauditPreEndorsementHandler();
- return $handler->getStatusAuthentication($this->publication, $request);
+ return $handler->getStatusAuthentication($endorsement, $request);
}
- public function testEndorserAuthenticatesCorrectly(): void
+ public function testEndorsementAuthenticatesCorrectly(): void
{
- $result = $this->verifyEndorserAuth($this->endorserEmailToken);
+ $result = $this->verifyEndorsementAuth($this->endorsementEmailToken, $this->firstEndorsement);
$this->assertEquals(PlauditPreEndorsementHandler::AUTH_SUCCESS, $result);
}
- public function testEndorserTokenIsDifferent(): void
+ public function testEndorsementTokenIsDifferent(): void
{
- $diffToken = md5(microtime() . 'email@email.com');
- $result = $this->verifyEndorserAuth($diffToken);
+ $result = $this->verifyEndorsementAuth($this->endorsementEmailToken, $this->secondEndorsement);
$this->assertEquals(PlauditPreEndorsementHandler::AUTH_INVALID_TOKEN, $result);
}
- public function testEndorserAutheticationHasAccessDenied(): void
+ public function testEndorsementAutheticationHasAccessDenied(): void
{
- $result = $this->verifyEndorserAuth($this->endorserEmailToken, 'access_denied');
+ $result = $this->verifyEndorsementAuth($this->endorsementEmailToken, $this->firstEndorsement, 'access_denied');
$this->assertEquals(PlauditPreEndorsementHandler::AUTH_ACCESS_DENIED, $result);
}
}
diff --git a/tests/endorsement/DAOTest.php b/tests/endorsement/DAOTest.php
new file mode 100644
index 0000000..93d8d7f
--- /dev/null
+++ b/tests/endorsement/DAOTest.php
@@ -0,0 +1,109 @@
+endorsementDAO = app(DAO::class);
+ $this->contextId = $this->createServerMock();
+ $this->publicationId = $this->createPublicationMock();
+ $this->addSchemaFile('endorsement');
+ }
+
+ public function testNewDataObjectIsInstanceOfEndorsement(): void
+ {
+ $endorsement = $this->endorsementDAO->newDataObject();
+ self::assertInstanceOf(Endorsement::class, $endorsement);
+ }
+
+ public function testCreateEndorsement(): void
+ {
+ $fetchedEndorsement = $this->retrieveEndorsement();
+
+ self::assertEquals([
+ 'id' => $fetchedEndorsement->getId(),
+ 'contextId' => $this->contextId,
+ 'name' => 'DummyEndorsement',
+ 'email' => "DummyEndorsement@mailinator.com.br",
+ 'publicationId' => $this->publicationId,
+ 'status' => null,
+ 'orcid' => null,
+ 'emailToken' => null,
+ 'emailCount' => 0
+ ], $fetchedEndorsement->_data);
+ }
+
+ public function testDeleteEndorsement(): void
+ {
+ $fetchedEndorsement = $this->retrieveEndorsement();
+
+ $this->endorsementDAO->delete($fetchedEndorsement);
+ self::assertFalse($this->endorsementDAO->exists($fetchedEndorsement->getId(), $this->contextId));
+ }
+
+ public function testEditEndorsement(): void
+ {
+ $fetchedEndorsement = $this->retrieveEndorsement();
+
+ $updatedName = "Updated name";
+ $fetchedEndorsement->setName($updatedName);
+
+ $this->endorsementDAO->update($fetchedEndorsement);
+
+ $fetchedEndorsement = $this->retrieveEndorsement($fetchedEndorsement->getId());
+
+ self::assertEquals($fetchedEndorsement->getName(), $updatedName);
+ }
+
+ public function testGetEndorsementByEmail(): void
+ {
+ $endorsement = $this->retrieveEndorsement();
+
+ self::assertEquals(
+ $this->endorsementDAO->getByEmail(
+ $endorsement->getEmail(),
+ (int) $endorsement->getPublicationId(),
+ (int) $endorsement->getContextId()
+ ),
+ $endorsement
+ );
+ }
+
+ private function retrieveEndorsement($endorsementId = null)
+ {
+ $insertedEndorsementId = isset($endorsementId) ? $endorsementId : $this->createEndorsement();
+
+ return $this->endorsementDAO->get(
+ $insertedEndorsementId,
+ $this->contextId
+ );
+ }
+
+ private function createEndorsement()
+ {
+ $endorsementDataObject = $this->createEndorsementDataObject($this->contextId, $this->publicationId);
+ return $this->endorsementDAO->insert($endorsementDataObject);
+ }
+}
diff --git a/tests/endorsement/EndorsementTest.php b/tests/endorsement/EndorsementTest.php
new file mode 100644
index 0000000..0e9614b
--- /dev/null
+++ b/tests/endorsement/EndorsementTest.php
@@ -0,0 +1,70 @@
+endorsement = new Endorsement();
+ }
+
+ public function testEndorsementContextIdRetrieval()
+ {
+ $contextId = rand();
+ $this->endorsement->setContextId($contextId);
+ $this->assertEquals($this->endorsement->getContextId(), $contextId);
+ }
+
+ public function testEndorsementPublicationIdRetrieval()
+ {
+ $publicationId = rand();
+ $this->endorsement->setPublicationId($publicationId);
+ $this->assertEquals($this->endorsement->getPublicationId(), $publicationId);
+ }
+
+ public function testEndorsementNameRetrieval()
+ {
+ $this->endorsement->setName("DummyEndorsement");
+ $this->assertEquals($this->endorsement->getName(), "DummyEndorsement");
+ }
+
+ public function testEndorsementEmailRetrieval()
+ {
+ $this->endorsement->setEmail("DummyEndorsement@mailinator.com.br");
+ $this->assertEquals($this->endorsement->getEmail(), "DummyEndorsement@mailinator.com.br");
+ }
+
+ public function testEndorsementStatusRetrieval()
+ {
+ $this->endorsement->setStatus(Endorsement::STATUS_COMPLETED);
+ $this->assertEquals($this->endorsement->getStatus(), Endorsement::STATUS_COMPLETED);
+ }
+
+ public function testEndorsementOrcidRetrieval()
+ {
+ $dummyOrcid = "0009-0009-190X-Y612";
+ $this->endorsement->setOrcid($dummyOrcid);
+ $this->assertEquals($this->endorsement->getOrcid(), $dummyOrcid);
+ }
+
+ public function testEndorsementEmailTokenRetrieval()
+ {
+ $dummyEmailToken = "066235YTVa78273grv76ha8%¨$#@aiusd";
+ $this->endorsement->setEmailToken($dummyEmailToken);
+ $this->assertEquals($this->endorsement->getEmailToken(), $dummyEmailToken);
+ }
+
+ public function testEndorsementEmailCountRetrieval()
+ {
+ $emailCount = 2;
+ $this->endorsement->setEmailCount($emailCount);
+ $this->assertEquals($this->endorsement->getEmailCount(), $emailCount);
+ }
+}
diff --git a/tests/endorsement/RepositoryTest.php b/tests/endorsement/RepositoryTest.php
new file mode 100644
index 0000000..59c80b1
--- /dev/null
+++ b/tests/endorsement/RepositoryTest.php
@@ -0,0 +1,145 @@
+contextId = $this->createServerMock();
+ $this->publicationId = $this->createPublicationMock();
+ $this->params = [
+ 'contextId' => $this->contextId,
+ 'name' => 'DummyEndorsement',
+ 'email' => "DummyEndorsement@mailinator.com.br",
+ 'publicationId' => $this->publicationId,
+ 'status' => null,
+ 'orcid' => null,
+ 'emailToken' => null,
+ 'emailCount' => 0
+ ];
+ $this->addSchemaFile('endorsement');
+ }
+
+ public function testGetNewEndorsementObject(): void
+ {
+ $repository = app(Repository::class);
+ $endorsement = $repository->newDataObject();
+ self::assertInstanceOf(Endorsement::class, $endorsement);
+ $endorsement = $repository->newDataObject($this->params);
+ self::assertEquals($this->params, $endorsement->_data);
+ }
+
+ public function testCrud(): void
+ {
+ $repository = app(Repository::class);
+ $endorsement = $repository->newDataObject($this->params);
+ $insertedEndorsementId = $repository->add($endorsement);
+ $this->params['id'] = $insertedEndorsementId;
+
+ $fetchedEndorsement = $repository->get($insertedEndorsementId, $this->contextId);
+ self::assertEquals($this->params, $fetchedEndorsement->_data);
+
+ $this->params['emailToken'] = 'iuqwidub78a9qbkjabiao';
+ $this->params['emailCount'] += 1;
+ $repository->edit($endorsement, $this->params);
+
+ $fetchedEndorsement = $repository->get($endorsement->getId(), $this->contextId);
+ self::assertEquals($this->params, $fetchedEndorsement->_data);
+
+ $repository->delete($endorsement);
+ self::assertFalse($repository->exists($endorsement->getId()));
+ }
+
+ public function testCollectorFilterByContextAndPublicationId(): void
+ {
+ $repository = app(Repository::class);
+ $endorsement = $repository->newDataObject($this->params);
+
+ $repository->add($endorsement);
+
+ $endorsements = $repository->getCollector()
+ ->filterByContextIds([$this->contextId])
+ ->filterByPublicationIds([$this->publicationId])
+ ->getMany();
+ self::assertTrue(in_array($endorsement, $endorsements->all()));
+ }
+
+ public function testEmptyCollectorFilterByContextAndPublicationId(): void
+ {
+ $repository = app(Repository::class);
+ $endorsement = $repository->newDataObject($this->params);
+ $newMockPublicationId = 2;
+ $newPublicationId = $this->createPublicationMock($newMockPublicationId);
+ $endorsement->setPublicationId($newPublicationId);
+
+ $repository->add($endorsement);
+
+ $endorsements = $repository->getCollector()
+ ->filterByContextIds([$this->contextId])
+ ->filterByPublicationIds([$this->publicationId])
+ ->getMany();
+ self::assertFalse(in_array($endorsement, $endorsements->all()));
+ }
+
+ public function testCollectorFilterByContextAndStatus(): void
+ {
+ $repository = app(Repository::class);
+ $this->params['status'] = Endorsement::STATUS_CONFIRMED;
+ $endorsement = $repository->newDataObject($this->params);
+
+ $repository->add($endorsement);
+
+ $endorsements = $repository->getCollector()
+ ->filterByContextIds([$this->contextId])
+ ->filterByStatus([Endorsement::STATUS_CONFIRMED])
+ ->getMany();
+ self::assertTrue(in_array($endorsement, $endorsements->all()));
+ }
+
+ public function testEmptyCollectorFilterByContextAndStatus(): void
+ {
+ $repository = app(Repository::class);
+ $this->params['status'] = Endorsement::STATUS_CONFIRMED;
+ $endorsement = $repository->newDataObject($this->params);
+
+ $repository->add($endorsement);
+
+ $endorsements = $repository->getCollector()
+ ->filterByContextIds([$this->contextId])
+ ->filterByStatus([Endorsement::STATUS_NOT_CONFIRMED])
+ ->getMany();
+ self::assertFalse(in_array($endorsement, $endorsements->all()));
+ }
+
+ public function testGetEndorsementByEmail(): void
+ {
+ $repository = app(Repository::class);
+ $endorsement = $repository->newDataObject($this->params);
+ $repository->add($endorsement);
+
+ $fetchedEndorsement = $repository->getByEmail($this->params['email'], $endorsement->getPublicationId(), $endorsement->getContextId());
+ self::assertEquals($endorsement, $fetchedEndorsement);
+ }
+}
diff --git a/tests/helpers/TestHelperTrait.php b/tests/helpers/TestHelperTrait.php
new file mode 100644
index 0000000..e0fabbb
--- /dev/null
+++ b/tests/helpers/TestHelperTrait.php
@@ -0,0 +1,83 @@
+getMockBuilder(Server::class)
+ ->onlyMethods(['getId'])
+ ->getMock();
+
+ $server->expects($this->any())
+ ->method('getId')
+ ->will($this->returnValue(1));
+ $server->setName('server-title', "en");
+ $server->setData('publisherInstitution', 'server-publisher');
+ $server->setPrimaryLocale("en");
+ $server->setPath('server-path');
+ $server->setId(1);
+
+ return $server->getId();
+ }
+
+ private function createPublicationMock($mockPublicationId = null)
+ {
+ $publicationId = isset($mockPublicationId) ? $mockPublicationId : 1;
+ $publication = $this->getMockBuilder(Publication::class)
+ ->onlyMethods(['getId'])
+ ->getMock();
+
+ $publication->expects($this->any())
+ ->method('getId')
+ ->will($this->returnValue($publicationId));
+
+ return $publication->getId();
+ }
+
+ private function addSchemaFile(string $schemaName): void
+ {
+ Hook::add(
+ 'Schema::get::' . $schemaName,
+ function (string $hookName, array $args) use ($schemaName) {
+ $schema = &$args[0];
+
+ $schemaFile = sprintf(
+ '%s/plugins/generic/plauditPreEndorsement/schemas/%s.json',
+ BASE_SYS_DIR,
+ $schemaName
+ );
+ if (file_exists($schemaFile)) {
+ $schema = json_decode(file_get_contents($schemaFile));
+ if (!$schema) {
+ throw new \Exception(
+ 'Schema failed to decode. This usually means it is invalid JSON. Requested: '
+ . $schemaFile
+ . '. Last JSON error: '
+ . json_last_error()
+ );
+ }
+ }
+ return true;
+ }
+ );
+ }
+
+ private function createEndorsementDataObject($contextId, $publicationId)
+ {
+ $endorsement = $this->endorsementDAO->newDataObject();
+ $endorsement->setContextId($contextId);
+ $endorsement->setPublicationId($publicationId);
+ $endorsement->setName("DummyEndorsement");
+ $endorsement->setEmail("DummyEndorsement@mailinator.com.br");
+
+ return $endorsement;
+ }
+}