Skip to content

Commit

Permalink
Use UserEntityInterface in feedback forms (#3613)
Browse files Browse the repository at this point in the history
- Also includes template rendering improvement in Email form handler.
  • Loading branch information
demiankatz committed Apr 24, 2024
1 parent b0a27a1 commit e28fea8
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 24 deletions.
17 changes: 9 additions & 8 deletions module/VuFind/src/VuFind/Controller/FeedbackController.php
Expand Up @@ -17,6 +17,7 @@

use Laminas\Log\LoggerAwareInterface;
use Laminas\View\Model\ViewModel;
use VuFind\Db\Entity\UserEntityInterface;
use VuFind\Form\Form;
use VuFind\Log\LoggerAwareTrait;

Expand Down Expand Up @@ -64,7 +65,7 @@ public function formAction()
$formId = 'FeedbackSite';
}

$user = $this->getUser();
$user = $this->getUser() ?: null;

$form = $this->serviceLocator->get($this->formClass);
$prefill = $this->params()->fromQuery();
Expand Down Expand Up @@ -102,7 +103,7 @@ public function formAction()
}

$primaryHandler = $form->getPrimaryHandler();
$success = $primaryHandler->handle($form, $params, $user ?: null);
$success = $primaryHandler->handle($form, $params, $user);
if ($success) {
$view->setVariable('successMessage', $form->getSubmitResponse());
$view->setTemplate('feedback/response');
Expand All @@ -115,7 +116,7 @@ public function formAction()
$handlers = $form->getSecondaryHandlers();
foreach ($handlers as $handler) {
try {
$handler->handle($form, $params, $user ?: null);
$handler->handle($form, $params, $user);
} catch (\Exception $e) {
$this->logError($e->getMessage());
}
Expand All @@ -127,18 +128,18 @@ public function formAction()
/**
* Prefill form sender fields for logged in users.
*
* @param Form $form Form
* @param array $user User
* @param Form $form Form
* @param ?UserEntityInterface $user User
*
* @return Form
*/
protected function prefillUserInfo($form, $user)
protected function prefillUserInfo(Form $form, ?UserEntityInterface $user)
{
if ($user) {
$form->setData(
[
'name' => $user->firstname . ' ' . $user->lastname,
'email' => $user['email'],
'name' => $user->getFirstname() . ' ' . $user->getLastname(),
'email' => $user->getEmail(),
]
);
}
Expand Down
7 changes: 4 additions & 3 deletions module/VuFind/src/VuFind/Form/Handler/Database.php
Expand Up @@ -32,6 +32,7 @@
namespace VuFind\Form\Handler;

use Laminas\Log\LoggerAwareInterface;
use VuFind\Db\Entity\UserEntityInterface;
use VuFind\Log\LoggerAwareTrait;

/**
Expand Down Expand Up @@ -80,22 +81,22 @@ public function __construct(
*
* @param \VuFind\Form\Form $form Submitted form
* @param \Laminas\Mvc\Controller\Plugin\Params $params Request params
* @param ?\VuFind\Db\Row\User $user Authenticated user
* @param ?UserEntityInterface $user Authenticated user
*
* @return bool
*/
public function handle(
\VuFind\Form\Form $form,
\Laminas\Mvc\Controller\Plugin\Params $params,
?\VuFind\Db\Row\User $user = null
?UserEntityInterface $user = null
): bool {
$fields = $form->mapRequestParamsToFieldValues($params->fromPost());
$fields = array_column($fields, 'value', 'name');

$formData = $fields;
unset($formData['message']);
$data = [
'user_id' => ($user) ? $user->id : null,
'user_id' => $user?->getId(),
'message' => $fields['message'] ?? '',
'form_data' => json_encode($formData),
'form_name' => $form->getFormId(),
Expand Down
21 changes: 10 additions & 11 deletions module/VuFind/src/VuFind/Form/Handler/Email.php
Expand Up @@ -35,6 +35,7 @@
use Laminas\Log\LoggerAwareInterface;
use Laminas\Mail\Address;
use Laminas\View\Renderer\RendererInterface;
use VuFind\Db\Entity\UserEntityInterface;
use VuFind\Exception\Mail as MailException;
use VuFind\Form\Form;
use VuFind\Log\LoggerAwareTrait;
Expand Down Expand Up @@ -96,17 +97,18 @@ public function __construct(
*
* @param \VuFind\Form\Form $form Submitted form
* @param \Laminas\Mvc\Controller\Plugin\Params $params Request params
* @param ?\VuFind\Db\Row\User $user Authenticated user
* @param ?UserEntityInterface $user Authenticated user
*
* @return bool
*/
public function handle(
\VuFind\Form\Form $form,
\Laminas\Mvc\Controller\Plugin\Params $params,
?\VuFind\Db\Row\User $user = null
?UserEntityInterface $user = null
): bool {
$fields = $form->mapRequestParamsToFieldValues($params->fromPost());
$emailMessage = $this->viewRenderer->partial(
$postParams = $params->fromPost();
$fields = $form->mapRequestParamsToFieldValues($postParams);
$emailMessage = $this->viewRenderer->render(
'Email/form.phtml',
compact('fields')
);
Expand All @@ -115,14 +117,11 @@ public function handle(

$replyToName = $params->fromPost(
'name',
$user ? trim($user->firstname . ' ' . $user->lastname) : null
$user ? trim($user->getFirstname() . ' ' . $user->getLastname()) : null
);
$replyToEmail = $params->fromPost(
'email',
$user ? $user->email : null
);
$recipients = $form->getRecipient($params->fromPost());
$emailSubject = $form->getEmailSubject($params->fromPost());
$replyToEmail = $params->fromPost('email', $user?->getEmail());
$recipients = $form->getRecipient($postParams);
$emailSubject = $form->getEmailSubject($postParams);

$result = true;
foreach ($recipients as $recipient) {
Expand Down
6 changes: 4 additions & 2 deletions module/VuFind/src/VuFind/Form/Handler/HandlerInterface.php
Expand Up @@ -31,6 +31,8 @@

namespace VuFind\Form\Handler;

use VuFind\Db\Entity\UserEntityInterface;

/**
* Interface HandlerInterface
*
Expand All @@ -47,13 +49,13 @@ interface HandlerInterface
*
* @param \VuFind\Form\Form $form Submitted form
* @param \Laminas\Mvc\Controller\Plugin\Params $params Request params
* @param ?\VuFind\Db\Row\User $user Authenticated user
* @param ?UserEntityInterface $user Authenticated user
*
* @return bool
*/
public function handle(
\VuFind\Form\Form $form,
\Laminas\Mvc\Controller\Plugin\Params $params,
?\VuFind\Db\Row\User $user = null
?UserEntityInterface $user = null
): bool;
}
@@ -0,0 +1,106 @@
<?php

/**
* Database Form Handler Test Class
*
* PHP version 8
*
* Copyright (C) Villanova University 2024.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* @category VuFind
* @package Tests
* @author Demian Katz <demian.katz@villanova.edu>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development:testing:unit_tests Wiki
*/

namespace VuFindTest\Form\Handler;

use Laminas\Mvc\Controller\Plugin\Params;
use VuFind\Db\Entity\UserEntityInterface;
use VuFind\Db\Table\Feedback;
use VuFind\Form\Form;
use VuFind\Form\Handler\Database;

/**
* Database Form Handler Test Class
*
* @category VuFind
* @package Tests
* @author Demian Katz <demian.katz@villanova.edu>
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License
* @link https://vufind.org/wiki/development:testing:unit_tests Wiki
*/
class DatabaseTest extends \PHPUnit\Framework\TestCase
{
/**
* Test success with a user.
*
* @return void
*/
public function testSuccessWithUser(): void
{
$feedback = $this->createMock(Feedback::class);
$callback = function ($data) {
$this->assertEquals(1234, $data['user_id']);
$this->assertEquals('', $data['message']);
$this->assertEquals('[]', $data['form_data']);
$this->assertEquals('formy-mcformface', $data['form_name']);
$this->assertEquals('http://foo', $data['site_url']);
$this->assertStringMatchesFormat('%d-%d-%d %d:%d:%d', $data['created']);
$this->assertStringMatchesFormat('%d-%d-%d %d:%d:%d', $data['updated']);
return true;
};
$feedback->expects($this->once())->method('insert')->with($this->callback($callback))->willReturn(true);
$handler = new Database($feedback, 'http://foo');
$form = $this->createMock(Form::class);
$form->expects($this->once())->method('mapRequestParamsToFieldValues')->willReturn([]);
$form->expects($this->once())->method('getFormId')->willReturn('formy-mcformface');
$params = $this->createMock(Params::class);
$params->expects($this->once())->method('fromPost')->willReturn([]);
$user = $this->createMock(UserEntityInterface::class);
$user->expects($this->once())->method('getId')->willReturn(1234);
$this->assertTrue($handler->handle($form, $params, $user));
}

/**
* Test success with no user.
*
* @return void
*/
public function testSuccessWithoutUser(): void
{
$feedback = $this->createMock(Feedback::class);
$callback = function ($data) {
$this->assertEquals(null, $data['user_id']);
$this->assertEquals('', $data['message']);
$this->assertEquals('[]', $data['form_data']);
$this->assertEquals('formy-mcformface', $data['form_name']);
$this->assertEquals('http://foo', $data['site_url']);
$this->assertStringMatchesFormat('%d-%d-%d %d:%d:%d', $data['created']);
$this->assertStringMatchesFormat('%d-%d-%d %d:%d:%d', $data['updated']);
return true;
};
$feedback->expects($this->once())->method('insert')->with($this->callback($callback))->willReturn(true);
$handler = new Database($feedback, 'http://foo');
$form = $this->createMock(Form::class);
$form->expects($this->once())->method('mapRequestParamsToFieldValues')->willReturn([]);
$form->expects($this->once())->method('getFormId')->willReturn('formy-mcformface');
$params = $this->createMock(Params::class);
$params->expects($this->once())->method('fromPost')->willReturn([]);
$this->assertTrue($handler->handle($form, $params, null));
}
}
Expand Up @@ -43,6 +43,7 @@
*/
class EmailTest extends \PHPUnit\Framework\TestCase
{
use \VuFindTest\Feature\WithConsecutiveTrait;
use \VuFindTest\Feature\ReflectionTrait;

/**
Expand Down Expand Up @@ -82,6 +83,63 @@ public function testDefaultEmailBehaviorWithConfig(): void
);
}

/**
* Test user object handling.
*
* @return void
*/
public function testExtractDataFromUserObject(): void
{
$handler = $this->getHandler();
$form = $this->createMock(Form::class);
$form->expects($this->once())->method('getRecipient')->willReturn([]);
$user = $this->createMock(\VuFind\Db\Entity\UserEntityInterface::class);
$user->expects($this->once())->method('getFirstname')->willReturn('First');
$user->expects($this->once())->method('getLastname')->willReturn('Last');
$user->expects($this->once())->method('getEmail')->willReturn('foo@example.com');
$params = $this->createMock(\Laminas\Mvc\Controller\Plugin\Params::class);
$this->expectConsecutiveCalls(
$params,
'fromPost',
[
[null],
['name', 'First Last'],
['email', 'foo@example.com'],
],
[
[], 'First Last', 'foo@example.com',
]
);
$this->assertTrue($handler->handle($form, $params, $user));
}

/**
* Test absent user object handling.
*
* @return void
*/
public function testHandleMissingUserObject(): void
{
$handler = $this->getHandler();
$form = $this->createMock(Form::class);
$form->expects($this->once())->method('getRecipient')->willReturn([]);
$user = null;
$params = $this->createMock(\Laminas\Mvc\Controller\Plugin\Params::class);
$this->expectConsecutiveCalls(
$params,
'fromPost',
[
[null],
['name', null],
['email', null],
],
[
[], null, null,
]
);
$this->assertTrue($handler->handle($form, $params, $user));
}

/**
* Get a handler configured for testing.
*
Expand Down

0 comments on commit e28fea8

Please sign in to comment.