$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); } }