Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkp/pkp-lib#9658 send and accept invitation views and php integrations #10558

Merged
merged 7 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions classes/components/forms/invitation/AcceptUserDetailsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php
/**
* @file classes/components/forms/invitation/AcceptUserDetailsForm.php
*
* Copyright (c) 2014-2024 Simon Fraser University
* Copyright (c) 2000-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class AcceptUserDetailsForm
*
*
* @brief Handles accept invitation user details form
*/

namespace PKP\components\forms\invitation;

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

class AcceptUserDetailsForm extends FormComponent
{
public const ACCEPT_FORM_USER_DETAILS = 'acceptUserDetails';
/** @copydoc FormComponent::$id */
public $id = self::ACCEPT_FORM_USER_DETAILS;

/** @copydoc FormComponent::$method */
public $method = 'POST';

/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct($action, $locales)
{
$this->action = $action;
$this->locales = $locales;

$countries = [];
foreach (Locale::getCountries() as $country) {
$countries[] = [
'value' => $country->getAlpha2(),
'label' => $country->getLocalName()
];
}

usort($countries, function ($a, $b) {
return strcmp($a['label'], $b['label']);
});

$this->addField(new FieldText('givenName', [
'label' => __('user.givenName'),
'description' => __('acceptInvitation.userDetailsForm.givenName.description'),
'isRequired' => true,
'isMultilingual' => true,
'size' => 'large',
'value' => ''
]))
->addField(new FieldText('familyName', [
'label' => __('user.familyName'),
'description' => __('acceptInvitation.userDetailsForm.familyName.description'),
'isRequired' => false,
'isMultilingual' => true,
'size' => 'large',
'value' => ''
]))
->addField(new FieldText('affiliation', [
'label' => __('user.affiliation'),
'description' => __('acceptInvitation.userDetailsForm.affiliation.description'),
'isMultilingual' => true,
'isRequired' => false,
'size' => 'large',

]))
->addField(new FieldSelect('userCountry', [
'label' => __('acceptInvitation.userDetailsForm.countryOfAffiliation.label'),
'description' => __('acceptInvitation.userDetailsForm.countryOfAffiliation.description'),
'options' => $countries,
'isRequired' => true,
'size' => 'large',
]));

}
}
68 changes: 68 additions & 0 deletions classes/components/forms/invitation/UserDetailsForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* @file classes/components/forms/invitation/UserDetailsForm.php
*
* Copyright (c) 2014-2024 Simon Fraser University
* Copyright (c) 2000-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class AcceptUserDetailsForm
*
*
* @brief Handles send invitation user details form
*/

namespace PKP\components\forms\invitation;

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

class UserDetailsForm extends FormComponent
{
public const FORM_USER_DETAILS = 'userDetails';
/** @copydoc FormComponent::$id */
public $id = self::FORM_USER_DETAILS;

/** @copydoc FormComponent::$method */
public $method = 'POST';

/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct(string $action, array $locales)
{
$this->action = $action;
$this->locales = $locales;

$this->addField(new FieldText('inviteeEmail', [
'label' => __('user.email'),
'description' => __('invitation.email.description'),
'isRequired' => true,
'size' => 'large',
]))
->addField(new FieldHTML('orcid', [
'label' => __('user.orcid'),
'description' => __('invitation.orcid.description'),
'isRequired' => false,
'size' => 'large',
]))
->addField(new FieldText('givenName', [
'label' => __('user.givenName'),
'description' => __('invitation.givenName.description'),
'isRequired' => false,
'isMultilingual' => true,
'size' => 'large',
]))
->addField(new FieldText('familyName', [
'label' => __('user.familyName'),
'description' => __('invitation.familyName.description'),
'isRequired' => false,
'isMultilingual' => true,
'size' => 'large',
]));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@

use APP\core\Request;
use APP\template\TemplateManager;
use PKP\core\PKPApplication;
use PKP\invitation\core\enums\InvitationAction;
use PKP\invitation\core\enums\InvitationStatus;
use PKP\invitation\core\InvitationActionRedirectController;
use PKP\invitation\invitations\userRoleAssignment\UserRoleAssignmentInvite;
use PKP\invitation\stepTypes\AcceptInvitationStep;
use APP\facades\Repo;

class UserRoleAssignmentInviteRedirectController extends InvitationActionRedirectController
{
Expand All @@ -26,17 +30,62 @@ public function getInvitation(): UserRoleAssignmentInvite
return $this->invitation;
}

/**
* Redirect to accept invitation page
* @param Request $request
* @return void
* @throws \Exception
*/
public function acceptHandle(Request $request): void
{
$templateMgr = TemplateManager::getManager($request);

$templateMgr->assign('invitation', $this->invitation);
$templateMgr->display('frontend/pages/invitations.tpl');
$context = $request->getContext();
$steps = new AcceptInvitationStep();
$invitationModel = $this->invitation->invitationModel->toArray();
$user = $invitationModel['userId'] ?Repo::user()->get($invitationModel['userId']) : null;
$templateMgr->setState([
'steps' => $steps->getSteps($this->invitation,$context,$user),
'primaryLocale' => $context->getData('primaryLocale'),
'pageTitle' => __('invitation.wizard.pageTitle'),
'invitationId' => (int)$request->getUserVar('id') ?: null,
'invitationKey' => $request->getUserVar('key') ?: null,
'pageTitleDescription' => __('invitation.wizard.pageTitleDescription'),
]);
$templateMgr->assign([
'pageComponent' => 'PageOJS',
]);
$templateMgr->display('invitation/acceptInvitation.tpl');
}

/**
* Redirect to login page after decline invitation
* @param Request $request
* @return void
* @throws \Exception
*/
public function declineHandle(Request $request): void
{
return;
if ($this->invitation->getStatus() !== InvitationStatus::PENDING) {
$request->getDispatcher()->handle404('The link is deactivated as the invitation was cancelled');
}

$context = $request->getContext();

$url = PKPApplication::get()->getDispatcher()->url(
PKPApplication::get()->getRequest(),
PKPApplication::ROUTE_PAGE,
$context->getData('urlPath'),
'login',
null,
null,
[
]
);

$this->getInvitation()->decline();

$request->redirectUrl($url);
}

public function preRedirectActions(InvitationAction $action)
Expand Down
109 changes: 109 additions & 0 deletions classes/invitation/sections/Email.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* @file classes/invitation/sections/Email.php
*
* Copyright (c) 2014-2024 Simon Fraser University
* Copyright (c) 2000-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Email
*
* @brief A section in an invitation workflow that shows an email composer.
*/

namespace PKP\invitation\sections;

use APP\core\Application;
use APP\facades\Repo;
use Exception;
use PKP\emailTemplate\EmailTemplate;
use PKP\facades\Locale;
use PKP\mail\Mailable;
use PKP\user\User;
use stdClass;

class Email extends Section
{
public bool $anonymousRecipients = false;
public array $locales;
public Mailable $mailable;
public array $recipients;
public string $type = 'email';

/**
* @param array<User> $recipients One or more User objects who are the recipients of this email
* @param Mailable $mailable The mailable that will be used to send this email
*
* @throws Exception
*/
public function __construct(string $id, string $name, string $description, array $recipients, Mailable $mailable, array $locales)
{
parent::__construct($id, $name, $description);
$this->locales = $locales;
$this->mailable = $mailable;
$this->recipients = $recipients;
}

/**
* @inheritDoc
*/
public function getState(): stdClass
ipula marked this conversation as resolved.
Show resolved Hide resolved
{
$config = parent::getState();
$config->canChangeRecipients = false;
$config->canSkip = false;
$config->emailTemplates = $this->getEmailTemplates();
$config->initialTemplateKey = $this->mailable::getEmailTemplateKey();
$config->recipientOptions = $this->getRecipientOptions();
$config->anonymousRecipients = $this->anonymousRecipients;
$config->variables = [];
$config->locale = Locale::getLocale();
$config->locales = [];
return $config;
}

/**
* Get all email recipients for email composer
* @return array
*/
protected function getRecipientOptions(): array
ipula marked this conversation as resolved.
Show resolved Hide resolved
{
$recipientOptions = [];
foreach ($this->recipients as $user) {
$names = [];
foreach ($this->locales as $locale) {
$names[$locale] = $user->getFullName(true, false, $locale);
}
$recipientOptions[] = [
'value' => $user->getId(),
'label' => $names,
];
}
return $recipientOptions;
}

/**
* Get all email templates for email composer
* @return array
*/
protected function getEmailTemplates(): array
ipula marked this conversation as resolved.
Show resolved Hide resolved
{
$request = Application::get()->getRequest();
$context = $request->getContext();

$emailTemplates = collect();
if ($this->mailable::getEmailTemplateKey()) {
$emailTemplate = Repo::emailTemplate()->getByKey($context->getId(), $this->mailable::getEmailTemplateKey());
if ($emailTemplate) {
$emailTemplates->add($emailTemplate);
}
Repo::emailTemplate()
->getCollector($context->getId())
->alternateTo([$this->mailable::getEmailTemplateKey()])
->getMany()
->each(fn (EmailTemplate $e) => $emailTemplates->add($e));
}

return Repo::emailTemplate()->getSchemaMap()->mapMany($emailTemplates)->toArray();
}
}
49 changes: 49 additions & 0 deletions classes/invitation/sections/Form.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/**
* @file classes/invitation/sections/Form.php
*
* Copyright (c) 2014-2024 Simon Fraser University
* Copyright (c) 2000-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Form
*
* @brief A section in an invitation workflow that shows a form.
*/
namespace PKP\invitation\sections;

use Exception;
use PKP\components\forms\FormComponent;
use stdClass;

class Form extends Section
{
public string $type = 'form';
public FormComponent $form;

/**
* @param FormComponent $form The form to show in this step
*
* @throws Exception
*/
public function __construct(string $id, string $name, string $description, FormComponent $form)
{
parent::__construct($id, $name, $description);
$this->form = $form;
}

/**
* @inheritDoc
* @throws Exception
*/
public function getState(): stdClass
ipula marked this conversation as resolved.
Show resolved Hide resolved
{
$config = parent::getState();
foreach ($this->form->getConfig() as $key => $value) {
$config->$key = $value;
}
unset($config->pages[0]['submitButton']);

return $config;
}
}
Loading