Skip to content
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
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ jobs:
php-version: ['8.1', '8.2', '8.3', '8.4']
steps:
- uses: actions/checkout@v5
- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: 20
cache: npm
- run: npm ci
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
"description": "A small PHP app demonstrating key Castle workflows on top of the Castle PHP SDK.",
"scripts": {
"build:css": "tailwindcss -i ./src/tailwind.css -o ./static/styles.css --minify",
"watch:css": "tailwindcss -i ./src/tailwind.css -o ./static/styles.css --watch"
"watch:css": "tailwindcss -i ./src/tailwind.css -o ./static/styles.css --watch",
"postinstall": "node scripts/ensure-castle-umd.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/castle/castle-php-example.git"
},
"license": "MIT",
"dependencies": {
"@castleio/castle-js": "^2.8.4"
"@castleio/castle-js": "^2.8.5"
},
"devDependencies": {
"tailwindcss": "^3.4.19"
Expand Down
15 changes: 15 additions & 0 deletions scripts/ensure-castle-umd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const fs = require('fs');
const path = require('path');

const dist = path.join(__dirname, '..', 'node_modules', '@castleio', 'castle-js', 'dist');
const dest = path.join(dist, 'castle.umd.js');
if (!fs.existsSync(dist) || fs.existsSync(dest)) {
process.exit(0);
}

const source = fs.readdirSync(dist).find((name) => (
name.startsWith('castle.') && name.endsWith('.js') && name !== 'castle.js'
));
if (source) {
fs.copyFileSync(path.join(dist, source), dest);
}
19 changes: 14 additions & 5 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,23 @@ function project_root(): string
return dirname(__DIR__);
}

// Serve the Castle browser SDK straight from the npm install (node_modules)
// instead of vendoring it into the repo.
function serve_castle_js(string $filename): void
function resolve_castle_js(string $filename): ?string
{
$dir = project_root() . '/node_modules/@castleio/castle-js/dist';
$dir = realpath(project_root() . '/node_modules/@castleio/castle-js/dist');
if ($dir === false) {
return null;
}
$path = realpath($dir . '/' . $filename);
if ($path !== false && str_starts_with($path, $dir . DIRECTORY_SEPARATOR) && is_file($path)) {
return $path;
}
return null;
}

if ($path === false || strpos($path, realpath($dir) ?: $dir) !== 0 || !is_file($path)) {
function serve_castle_js(string $filename): void
{
$path = resolve_castle_js($filename);
if ($path === null) {
http_response_code(404);
echo 'Not found';
return;
Expand Down
9 changes: 7 additions & 2 deletions static/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ async function postJSON(url, data) {

// Resolve a Castle request token, falling back gracefully if the browser SDK
// is unavailable (e.g. no publishable key configured).
function castleClient() {
return window.__castle || window.Castle;
}

function withRequestToken(callback) {
if (window.Castle && typeof Castle.createRequestToken === "function") {
Castle.createRequestToken()
var sdk = castleClient();
if (sdk && typeof sdk.createRequestToken === "function") {
sdk.createRequestToken()
.then(callback)
.catch(function (err) {
console.error("Castle.createRequestToken failed", err);
Expand Down
8 changes: 8 additions & 0 deletions tests/PagesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ public function testHomeRenders(): void
$html = render_page('home', default_params());
$this->assertStringContainsStringIgnoringCase('<html', $html);
$this->assertStringContainsString('Castle workflows demo', $html);
$this->assertStringContainsString('/vendor/castle-js/castle.umd.js', $html);
}

public function testResolveCastleJsServesNpmInstall(): void
{
$path = resolve_castle_js('castle.umd.js');
$this->assertNotNull($path);
$this->assertFileExists($path);
}

/**
Expand Down
12 changes: 10 additions & 2 deletions views/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="/static/styles.css" rel="stylesheet">

<script src="/vendor/castle-js/castle.browser.js"></script>
<script>
if (!window.Castle) {
window.exports = window.exports || {};
window.module = window.module || { exports: window.exports };
window.Castle = window.module.exports;
}
</script>
<script src="/vendor/castle-js/castle.umd.js"></script>
<script>
window.Castle = window.Castle || (window.module && window.module.exports) || window["@castleio/castle-js"];
if (window.Castle && "<?= h($castlePk) ?>") {
Castle.configure({ pk: "<?= h($castlePk) ?>" });
window.__castle = Castle.configure({ pk: "<?= h($castlePk) ?>" }) || window.Castle;
}
</script>
<script src="/static/app.js" defer></script>
Expand Down