Implement JQHTML function cache ID system and fix bundle compilation Implement underscore prefix for system tables Fix JS syntax linter to support decorators and grant exception to Task system SPA: Update planning docs and wishlists with remaining features SPA: Document Navigation API abandonment and future enhancements Implement SPA browser integration with History API (Phase 1) Convert contacts view page to SPA action Convert clients pages to SPA actions and document conversion procedure SPA: Merge GET parameters and update documentation Implement SPA route URL generation in JavaScript and PHP Implement SPA bootstrap controller architecture Add SPA routing manual page (rsx:man spa) Add SPA routing documentation to CLAUDE.md Phase 4 Complete: Client-side SPA routing implementation Update get_routes() consumers for unified route structure Complete SPA Phase 3: PHP-side route type detection and is_spa flag Restore unified routes structure and Manifest_Query class Refactor route indexing and add SPA infrastructure Phase 3 Complete: SPA route registration in manifest Implement SPA Phase 2: Extract router code and test decorators Rename Jqhtml_Component to Component and complete SPA foundation setup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
153 lines
4.8 KiB
PHP
Executable File
153 lines
4.8 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* CODING CONVENTION:
|
|
* This file follows the coding convention where variable_names and function_names
|
|
* use snake_case (underscore_wherever_possible).
|
|
*/
|
|
|
|
// @ROUTE-EXISTS-01-EXCEPTION
|
|
|
|
namespace App\RSpade\CodeQuality\Rules\PHP;
|
|
|
|
use App\RSpade\CodeQuality\Rules\CodeQualityRule_Abstract;
|
|
|
|
/**
|
|
* RouteQueryConcatenation_CodeQualityRule - Detect query string concatenation onto Rsx::Route()
|
|
*
|
|
* This rule detects patterns where query strings are concatenated onto Rsx::Route() calls:
|
|
* - Rsx::Route(...) . '?param=value'
|
|
* - Rsx::Route(...) . "?param=value"
|
|
*
|
|
* Query parameters should be passed as the third argument to Rsx::Route() as an array.
|
|
*/
|
|
class RouteQueryConcatenation_CodeQualityRule extends CodeQualityRule_Abstract
|
|
{
|
|
/**
|
|
* Get the unique identifier for this rule
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_id(): string
|
|
{
|
|
return 'PHP-ROUTE-QUERY-01';
|
|
}
|
|
|
|
/**
|
|
* Get the default severity level
|
|
*
|
|
* @return string One of: critical, high, medium, low, convention
|
|
*/
|
|
public function get_default_severity(): string
|
|
{
|
|
return 'high';
|
|
}
|
|
|
|
/**
|
|
* Get the file patterns this rule applies to
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_file_patterns(): array
|
|
{
|
|
return ['*.php'];
|
|
}
|
|
|
|
/**
|
|
* Get the display name for this rule
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_name(): string
|
|
{
|
|
return 'Route Query String Concatenation Detection';
|
|
}
|
|
|
|
/**
|
|
* Get the description of what this rule checks
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_description(): string
|
|
{
|
|
return 'Detects query strings concatenated onto Rsx::Route() calls and suggests using the third parameter array instead';
|
|
}
|
|
|
|
/**
|
|
* Check if this rule should be called during manifest scan
|
|
*
|
|
* This rule runs at manifest-time to catch incorrect Rsx::Route() usage
|
|
* immediately, preventing routes with malformed query strings from being used.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function is_called_during_manifest_scan(): bool
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check the file contents for violations
|
|
*
|
|
* @param string $file_path The path to the file being checked
|
|
* @param string $contents The contents of the file
|
|
* @param array $metadata Additional metadata about the file
|
|
* @return void
|
|
*/
|
|
public function check(string $file_path, string $contents, array $metadata = []): void
|
|
{
|
|
// Only check files in rsx/ directory
|
|
if (!str_contains($file_path, '/rsx/')) {
|
|
return;
|
|
}
|
|
|
|
$lines = explode("\n", $contents);
|
|
|
|
foreach ($lines as $line_num => $line) {
|
|
// Pattern to match: Rsx::Route(...) . '?' or Rsx::Route(...) . "?"
|
|
// This regex matches:
|
|
// - Rsx::Route
|
|
// - Opening parenthesis
|
|
// - Any content (including nested parentheses)
|
|
// - Closing parenthesis
|
|
// - Optional whitespace
|
|
// - Concatenation operator (.)
|
|
// - Optional whitespace
|
|
// - Single or double quote
|
|
// - Question mark
|
|
|
|
// Use a simpler pattern that looks for the specific sequence
|
|
// We need to match Rsx::Route(...) followed by . '? or . "?
|
|
|
|
// First, check if line contains both "Rsx::Route" and concatenation with query
|
|
if (!str_contains($line, 'Rsx::Route')) {
|
|
continue;
|
|
}
|
|
|
|
// Look for the pattern: Rsx::Route(...) . '?' or Rsx::Route(...) . "?"
|
|
// This is a complex pattern because we need to match nested parentheses
|
|
|
|
// Strategy: Find all occurrences of Rsx::Route on the line, then check what follows
|
|
$pattern = '/Rsx::Route\s*\([^)]*(?:\([^)]*\)[^)]*)*\)\s*\.\s*[\'"][?]/';
|
|
|
|
if (preg_match($pattern, $line, $matches, PREG_OFFSET_CAPTURE)) {
|
|
$matched_text = $matches[0][0];
|
|
$position = $matches[0][1];
|
|
|
|
// Add violation
|
|
$this->add_violation(
|
|
$file_path,
|
|
$line_num + 1,
|
|
"Query string concatenated onto Rsx::Route() call",
|
|
$line,
|
|
"Query parameters should be passed as the third argument to Rsx::Route() as an array.\n\n" .
|
|
"WRONG:\n" .
|
|
" Rsx::Route('Controller::method') . '?param=value&other=test'\n\n" .
|
|
"CORRECT:\n" .
|
|
" Rsx::Route('Controller::method', ['param' => 'value', 'other' => 'test'])\n\n" .
|
|
"The framework will automatically URL-encode the parameters and construct the query string properly."
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|