Skip to content

Instantly share code, notes, and snippets.

@levacic
Created December 21, 2020 23:30
Show Gist options
  • Save levacic/2f3cc01ac21199c064d5d3165bdde783 to your computer and use it in GitHub Desktop.
Save levacic/2f3cc01ac21199c064d5d3165bdde783 to your computer and use it in GitHub Desktop.
Form request for failed validation redirect with hash
<?php
declare(strict_types=1);
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
abstract class Request extends FormRequest
{
/**
* Adds an optional hash which will be appended to the auto-generated
* redirect URL.
*
* This is useful when a form is not on top of the page to which the user is
* being redirected, so that the browser will automatically scroll down to
* the correct location in the page and the user can see the form and its
* error messages.
*
* Do not prefix this value with the actual hash symbol "#", e.g. if you
* want to redirect the user to "http://example.com/foo#bar", just set this
* value to "bar".
*/
protected ?string $redirectHash = null;
/**
* @inheritDoc
*/
protected function getRedirectUrl(): string
{
$redirectUrl = parent::getRedirectUrl();
if ($this->redirectHash) {
$redirectUrl .= "#{$this->redirectHash}";
}
return $redirectUrl;
}
/**
* Returns the configured redirect hash.
*
* Useful to keep things DRY in case of, for example, a controller using
* this request needs to redirect to the same hash in the case of successful
* form submission.
*
* @return string|null
*/
public function getRedirectHash(): ?string
{
return $this->redirectHash;
}
}
<?php
declare(strict_types=1);
namespace Tests\App\Unit\Http\Requests;
use App\Http\Requests\Request;
class RequestDummyWithHash extends Request
{
/**
* @inheritDoc
*/
protected ?string $redirectHash = 'bar';
/**
* @inheritDoc
*/
public function getRedirectUrl(): string
{
return parent::getRedirectUrl();
}
}
<?php
declare(strict_types=1);
namespace Tests\App\Unit\Http\Requests;
use App\Http\Requests\Request;
class RequestDummyWithoutHash extends Request
{
/**
* @inheritDoc
*/
public function getRedirectUrl(): string
{
return parent::getRedirectUrl();
}
}
<?php
declare(strict_types=1);
namespace Tests\App\Unit\Http\Requests;
use Illuminate\Routing\Redirector;
use Illuminate\Routing\UrlGenerator;
use Tests\App\TestCase;
use Tests\App\Unit\Http\Requests\RequestDummyWithHash;
use Tests\App\Unit\Http\Requests\RequestDummyWithoutHash;
class RequestTest extends TestCase
{
/**
* Tests whether redirect URLs get generated correctly when a redirect hash
* is configured on the FormRequest class.
*
* @return void
*/
public function testRedirectWithHash(): void
{
$requestWithHash = new RequestDummyWithHash();
$requestWithHash->setRedirector($this->getRedirectorForPreviousUrl('http://localhost/foo'));
$this->assertEquals('http://localhost/foo#bar', $requestWithHash->getRedirectUrl());
}
/**
* Tests whether redirect URLs still get generated correctly when a redirect
* hash isn't configured on the FormRequest class.
*
* @return void
*/
public function testRedirectWithoutHash(): void
{
$requestWithoutHash = new RequestDummyWithoutHash();
$requestWithoutHash->setRedirector($this->getRedirectorForPreviousUrl('http://localhost/foo'));
$this->assertEquals('http://localhost/foo', $requestWithoutHash->getRedirectUrl());
}
/**
* Returns a Redirector whose UrlGenerator returns the passed URL when asked
* for the previous URL.
*
* @param string $url The URL which should be returned.
*
* @return Redirector
*/
protected function getRedirectorForPreviousUrl(string $url): Redirector
{
$urlGenerator = $this->getMockBuilder(UrlGenerator::class)
->disableOriginalConstructor()
->setMethods(['previous'])
->getMock()
;
$urlGenerator
->expects($this->any())
->method('previous')
->willReturn($url)
;
$redirector = $this->getMockBuilder(Redirector::class)
->disableOriginalConstructor()
->setMethods(['getUrlGenerator'])
->getMock()
;
$redirector
->expects($this->any())
->method('getUrlGenerator')
->willReturn($urlGenerator)
;
return $redirector;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment