Skip to content

Commit d3c6cb6

Browse files
committed
fix: Disable save previous URL
1 parent 463a474 commit d3c6cb6

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

src/CodeIgniter.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace Michalsn\CodeIgniterHtmx;
4+
5+
use CodeIgniter\CodeIgniter as BaseCodeIgniter;
6+
use CodeIgniter\HTTP\CLIRequest;
7+
use CodeIgniter\HTTP\DownloadResponse;
8+
use CodeIgniter\HTTP\IncomingRequest;
9+
use CodeIgniter\HTTP\RedirectResponse;
10+
use CodeIgniter\HTTP\URI;
11+
use Michalsn\CodeIgniterHtmx\HTTP\IncomingRequest as HTMXIncomingRequest;
12+
13+
/**
14+
* @property CLIRequest|HTMXIncomingRequest|IncomingRequest|null $request
15+
*/
16+
class CodeIgniter extends BaseCodeIgniter
17+
{
18+
/**
19+
* Web access?
20+
*/
21+
private function isWeb(): bool
22+
{
23+
return $this->context === 'web';
24+
}
25+
26+
/**
27+
* If we have a session object to use, store the current URI
28+
* as the previous URI. This is called just prior to sending the
29+
* response to the client, and will make it available next request.
30+
*
31+
* This helps provider safer, more reliable previous_url() detection.
32+
*
33+
* @param string|URI $uri
34+
*
35+
* @return void
36+
*/
37+
public function storePreviousURL($uri)
38+
{
39+
// Ignore CLI requests
40+
if (! $this->isWeb()) {
41+
return;
42+
}
43+
44+
// Ignore AJAX and HTMX requests
45+
if ((method_exists($this->request, 'isHTMX') && $this->request->isHTMX()) || (method_exists($this->request, 'isAJAX') && $this->request->isAJAX())) {
46+
return;
47+
}
48+
49+
// Ignore unroutable responses
50+
if ($this->response instanceof DownloadResponse || $this->response instanceof RedirectResponse) {
51+
return;
52+
}
53+
54+
// Ignore non-HTML responses
55+
if (! str_contains($this->response->getHeaderLine('Content-Type'), 'text/html')) {
56+
return;
57+
}
58+
59+
// This is mainly needed during testing...
60+
if (is_string($uri)) {
61+
$uri = service('uri', $uri, false);
62+
}
63+
64+
if (isset($_SESSION)) {
65+
session()->set('_ci_previous_url', URI::createURIString(
66+
$uri->getScheme(),
67+
$uri->getAuthority(),
68+
$uri->getPath(),
69+
$uri->getQuery(),
70+
$uri->getFragment()
71+
));
72+
}
73+
}
74+
}

src/Config/Services.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Config\Services as AppServices;
1212
use Config\Toolbar as ToolbarConfig;
1313
use Config\View as ViewConfig;
14+
use Michalsn\CodeIgniterHtmx\CodeIgniter;
1415
use Michalsn\CodeIgniterHtmx\Debug\Toolbar;
1516
use Michalsn\CodeIgniterHtmx\HTTP\IncomingRequest;
1617
use Michalsn\CodeIgniterHtmx\HTTP\RedirectResponse;
@@ -19,6 +20,22 @@
1920

2021
class Services extends BaseService
2122
{
23+
/**
24+
* CodeIgniter, the core of the framework.
25+
*
26+
* @return CodeIgniter
27+
*/
28+
public static function codeigniter(?App $config = null, bool $getShared = true)
29+
{
30+
if ($getShared) {
31+
return static::getSharedInstance('codeigniter', $config);
32+
}
33+
34+
$config ??= config(App::class);
35+
36+
return new CodeIgniter($config);
37+
}
38+
2239
/**
2340
* The Renderer class is the class that actually displays a file to the user.
2441
* The default View class within CodeIgniter is intentionally simple, but this

tests/CodeIgniterTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests;
6+
7+
use CodeIgniter\Test\CIUnitTestCase;
8+
9+
/**
10+
* @internal
11+
*/
12+
final class CodeIgniterTest extends CIUnitTestCase
13+
{
14+
protected function setUp(): void
15+
{
16+
parent::setUp();
17+
18+
$this->resetServices();
19+
}
20+
21+
protected function tearDown(): void
22+
{
23+
parent::tearDown();
24+
25+
$this->resetServices();
26+
}
27+
28+
public function testIsHTMXNotSavePreviousURL(): void
29+
{
30+
// Default request behavior
31+
$uri = service('uri');
32+
$request = service('incomingrequest');
33+
34+
$uri->setPath('/')->setQuery('previous=original');
35+
36+
ob_start();
37+
service('codeigniter', null, false)->setContext('web')->run();
38+
ob_get_clean();
39+
40+
$this->assertArrayHasKey('_ci_previous_url', $_SESSION);
41+
$this->assertSame('https://example.com/index.php/?previous=original', $_SESSION['_ci_previous_url']);
42+
43+
// HTMX request
44+
$uri->setPath('/')->setQuery('previous=htmx');
45+
$request->appendHeader('HX-Request', 'true');
46+
47+
ob_start();
48+
service('codeigniter', null, false)->setContext('web')->run();
49+
ob_get_clean();
50+
51+
$this->assertTrue($request->isHTMX());
52+
$this->assertArrayHasKey('_ci_previous_url', $_SESSION);
53+
$this->assertSame('https://example.com/index.php/?previous=original', $_SESSION['_ci_previous_url']);
54+
}
55+
}

0 commit comments

Comments
 (0)