initial: bootstrap from BukidBountyApp base

This commit is contained in:
Jonathan Sykes
2026-06-06 18:43:00 +08:00
commit eb4a5731fb
5674 changed files with 160857 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
namespace App\Support;
/**
* RouteArgumentParser handles parsing URL arguments in format: "page-name--h:HASHKEY" or "page-name--e:ENCODED_PAYLOAD"
*/
class RouteArgumentParser
{
/**
* Parse a route argument string into its components
*
* @param string $argument The route argument string (e.g., "edituser--h:USER_HASH123")
* @return array {slug: string, type?: 'hash'|'payload', value?: string} Array with parsed components
*/
public function parseArgument($argument)
{
if (!is_string($argument) || empty($argument)) {
return [
'slug' => $argument,
'type' => null,
'value' => null
];
}
// Check for hash format: --h:HASHKEY
if (preg_match('/^(.*?)--h:(.*)$/', $argument, $matches)) {
return [
'slug' => $matches[1],
'type' => 'hash',
'value' => $this->decodeHashValue($matches[2])
];
}
// Check for payload format: --e:ENCODED_PAYLOAD
if (preg_match('/^(.*?)--e:(.*)$/', $argument, $matches)) {
return [
'slug' => $matches[1],
'type' => 'payload',
'value' => $this->decodePayloadValue($matches[2])
];
}
// Backward compatibility: Check for hash format without colon: --hHASHKEY
if (preg_match('/^(.*?)--h([^:].*)$/', $argument, $matches)) {
return [
'slug' => $matches[1],
'type' => 'hash',
'value' => $this->decodeHashValue($matches[2])
];
}
// No hash/payload found - just return the slug
return [
'slug' => $argument,
'type' => null,
'value' => null
];
}
/**
* Decode a hash value from URL format (base64 encoded)
*/
private function decodeHashValue($encodedValue)
{
if (!is_string($encodedValue) || empty($encodedValue)) {
return $encodedValue;
}
try {
// Remove base64 encoding and decode
$decoded = base64_decode($encodedValue, true);
// If it's valid UTF-8 string representation of the hashkey
if (is_string($decoded) && mb_check_encoding($decoded, 'utf-8')) {
// Frontend encodes as btoa(encodeURIComponent(hashkey)),
// so we need to urldecode after base64_decode
return urldecode($decoded);
}
return $encodedValue; // Return original if decoding fails
} catch (\Exception $e) {
error_log('[RouteArgumentParser] Error decoding hash: ' . $e->getMessage());
return null;
}
}
/**
* Decode a payload value from URL format (base64 encoded JSON)
*/
private function decodePayloadValue($encodedValue)
{
if (!is_string($encodedValue) || empty($encodedValue)) {
return null;
}
try {
// Remove base64 encoding and decode
$decoded = base64_decode($encodedValue, true);
// Decode URI components if it was encoded on frontend
if ($decoded) {
$decoded = urldecode($decoded);
}
// Parse JSON
$jsonData = json_decode($decoded, true);
if (json_last_error() === JSON_ERROR_NONE) {
return $jsonData;
}
return null;
} catch (\Exception $e) {
error_log('[RouteArgumentParser] Error decoding payload: ' . $e->getMessage());
return null;
}
}
/**
* Check if argument contains hash format
*/
public function isHashFormat($argument)
{
return (bool) preg_match('/^(.*?)--h:?(.*)$/', $argument, $matches);
}
/**
* Check if argument contains payload format
*/
public function isPayloadFormat($argument)
{
return (bool) preg_match('/^(.*?)--e:(.*)$/', $argument, $matches);
}
}