Skip to content

Commit 70be111

Browse files
committed
Initial release
0 parents  commit 70be111

File tree

8 files changed

+183
-0
lines changed

8 files changed

+183
-0
lines changed

Diff for: .github/workflows/ci.yml

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
tests:
11+
if: "!contains(github.event.head_commit.message, 'skip ci')"
12+
name: PHP ${{ matrix.php-versions }} on ${{ matrix.os }}
13+
runs-on: ${{ matrix.os }}
14+
continue-on-error: ${{ matrix.php-versions >= '8.3' }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
php-versions: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
19+
os: [ubuntu-latest, windows-latest]
20+
21+
steps:
22+
- name: Configure git
23+
if: runner.os == 'Windows'
24+
run: git config --system core.autocrlf false; git config --system core.eol lf
25+
26+
- name: Checkout
27+
uses: actions/checkout@v3
28+
29+
- name: Set up PHP ${{ matrix.php-versions }}
30+
uses: shivammathur/setup-php@v2
31+
with:
32+
php-version: ${{ matrix.php-versions }}
33+
ini-values: date.timezone=Europe/Berlin
34+
35+
- name: Validate composer.json and composer.lock
36+
run: composer validate
37+
38+
- name: Get Composer Cache Directory
39+
id: composer-cache
40+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
41+
42+
- name: Cache dependencies
43+
uses: actions/cache@v3
44+
with:
45+
path: ${{ steps.composer-cache.outputs.dir }}
46+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
47+
restore-keys: ${{ runner.os }}-composer-
48+
49+
- name: Install dependencies
50+
run: >
51+
curl -sSL https://baltocdn.com/xp-framework/xp-runners/distribution/downloads/e/entrypoint/xp-run-8.7.0.sh > xp-run &&
52+
composer install --prefer-dist &&
53+
echo "vendor/autoload.php" > composer.pth
54+
55+
- name: Run test suite
56+
run: sh xp-run xp.test.Runner -r Dots src/test/php

Diff for: ChangeLog.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
HTMX for XP web frontends change log
2+
====================================
3+
4+
## ?.?.? / ????-??-??
5+
6+
## 0.1.0 / 2024-01-28
7+
8+
* First public release - @thekid

Diff for: README.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
HTMX for XP web frontends
2+
=========================
3+
4+
[![Build status on GitHub](https://github.com/xp-forge/htmx/workflows/Tests/badge.svg)](https://github.com/xp-forge/htmx/actions)
5+
[![XP Framework Module](https://raw.githubusercontent.com/xp-framework/web/master/static/xp-framework-badge.png)](https://github.com/xp-framework/core)
6+
[![BSD Licence](https://raw.githubusercontent.com/xp-framework/web/master/static/licence-bsd.png)](https://github.com/xp-framework/core/blob/master/LICENCE.md)
7+
[![Requires PHP 7.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-7_0plus.svg)](http://php.net/)
8+
[![Supports PHP 8.0+](https://raw.githubusercontent.com/xp-framework/web/master/static/php-8_0plus.svg)](http://php.net/)
9+
[![Latest Stable Version](https://poser.pugx.org/xp-forge/htmx/version.png)](https://packagist.org/packages/xp-forge/htmx)
10+
11+
HTMX Integration
12+
13+
Authentication
14+
--------------
15+
Wrap any authentication flow in a *HtmxFlow* to ensure authentication does not redirect but instead yields an error code and triggers an event:
16+
17+
```diff
18+
+ use web\frontend\HtmxFlow;
19+
20+
- $auth= new SessionBased($flow, $sessions);
21+
+ $auth= new SessionBased(new HtmxFlow($flow), $sessions);
22+
```
23+
24+
Handle this inside JavaScript with something along the lines of the following:
25+
26+
```javascript
27+
window.addEventListener('authenticationexpired', e => {
28+
if (confirm('Authentication expired. Do you want to re-authenticate?')) {
29+
window.location.reload();
30+
}
31+
});
32+
````

Diff for: class.pth

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
src/main/php/
2+
src/test/php/
3+
src/test/php/

Diff for: composer.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name" : "xp-forge/htmx",
3+
"type" : "library",
4+
"homepage" : "http://xp-framework.net/",
5+
"license" : "BSD-3-Clause",
6+
"description" : "HTMX integration for XP web frontends",
7+
"keywords": ["module", "xp"],
8+
"require" : {
9+
"xp-framework/core": "^11.0 | ^10.0",
10+
"xp-forge/frontend": "^6.0 | ^5.0",
11+
"xp-forge/web-auth": "^3.7",
12+
"php": ">=7.0.0"
13+
},
14+
"require-dev" : {
15+
"xp-framework/test": "^1.0"
16+
},
17+
"autoload" : {
18+
"files" : ["src/main/php/autoload.php"]
19+
}
20+
}

Diff for: src/main/php/autoload.php

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php namespace xp;
2+
3+
\lang\ClassLoader::registerPath(__DIR__);

Diff for: src/main/php/web/frontend/HtmxFlow.class.php

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php namespace web\frontend;
2+
3+
use web\auth\Flow;
4+
5+
/**
6+
* Wraps around any authentication flow and ensures that if there is the
7+
* need to (re-)authenticate HTMX requests, a 401 error is sent back and
8+
* an `authenticationexpired` event is triggered instead of redirecting.
9+
*
10+
* @see https://htmx.org/reference/#headers
11+
*/
12+
class HtmxFlow extends Flow {
13+
private $delegate;
14+
15+
/** Creates a new instance, wrapping around a given flow */
16+
public function __construct(Flow $delegate) { $this->delegate= $delegate; }
17+
18+
/**
19+
* Refreshes access token given a refresh token if necessary.
20+
*
21+
* @param [:var] $claims
22+
* @return ?web.auth.Authorization
23+
* @throws lang.IllegalStateException
24+
*/
25+
public function refresh(array $claims) { return $this->delegate->refresh($claims); }
26+
27+
/**
28+
* Executes authentication flow, returning the authentication result
29+
*
30+
* @param web.Request $request
31+
* @param web.Response $response
32+
* @param web.session.Session $session
33+
* @return var
34+
*/
35+
public function authenticate($request, $response, $session) {
36+
if ('true' === $request->header('Hx-Request')) {
37+
$response->answer(401);
38+
$response->header('HX-Trigger', 'authenticationexpired');
39+
return null;
40+
}
41+
42+
return $this->delegate->authenticate($request, $response, $session);
43+
}
44+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php namespace web\frontend\unittest;
2+
3+
use test\{Assert, Test};
4+
use web\auth\Flow;
5+
use web\frontend\HtmxFlow;
6+
7+
class HtmxFlowTest {
8+
9+
#[Test]
10+
public function can_create() {
11+
new HtmxFlow(new class() extends Flow {
12+
public function authenticate($request, $response, $session) {
13+
// NOOP
14+
}
15+
});
16+
}
17+
}

0 commit comments

Comments
 (0)