From 0a479ed5a2eb70503d8c1eb48dc096f80a1889d8 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 10 Dec 2025 05:49:23 +0000 Subject: [PATCH] Use short class names for framework models to enable overrides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../ModelFqcnReference_CodeQualityRule.php | 189 ++++++++++++++++++ .../Rsx_Formdata_Generator_Controller.php | 2 +- 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100755 app/RSpade/CodeQuality/Rules/PHP/ModelFqcnReference_CodeQualityRule.php diff --git a/app/RSpade/CodeQuality/Rules/PHP/ModelFqcnReference_CodeQualityRule.php b/app/RSpade/CodeQuality/Rules/PHP/ModelFqcnReference_CodeQualityRule.php new file mode 100755 index 000000000..7f1571b02 --- /dev/null +++ b/app/RSpade/CodeQuality/Rules/PHP/ModelFqcnReference_CodeQualityRule.php @@ -0,0 +1,189 @@ +get_id() . '-EXCEPTION')) { + return; + } + + $lines = explode("\n", $contents); + + foreach ($lines as $line_number => $line) { + $actual_line_number = $line_number + 1; + + // Skip if line has exception comment + if (str_contains($line, '@' . $this->get_id() . '-EXCEPTION')) { + continue; + } + + // Skip use statements - those are fine + if (preg_match('/^\s*use\s+/', $line)) { + continue; + } + + // Skip namespace declarations + if (preg_match('/^\s*namespace\s+/', $line)) { + continue; + } + + // Skip comments + $trimmed = trim($line); + if (str_starts_with($trimmed, '//') || str_starts_with($trimmed, '*') || str_starts_with($trimmed, '/*')) { + continue; + } + + // Look for inline FQCN references to App\RSpade\Core\Models\ + // Pattern 1: \App\RSpade\Core\Models\Something (backslash-prefixed) + // Pattern 2: 'App\RSpade\Core\Models\Something' or "..." (string references) + + // Check for backslash-prefixed FQCN in code + if (preg_match('/\\\\App\\\\RSpade\\\\Core\\\\Models\\\\(\w+)/', $line, $matches)) { + $model_name = $matches[1]; + $this->add_violation( + $file_path, + $actual_line_number, + "Inline FQCN reference to framework model '\\App\\RSpade\\Core\\Models\\{$model_name}' prevents model overrides", + trim($line), + $this->build_suggestion($model_name), + 'high' + ); + continue; + } + + // Check for string references (for dynamic class usage) + if (preg_match('/[\'"]App\\\\RSpade\\\\Core\\\\Models\\\\(\w+)[\'"]/', $line, $matches)) { + $model_name = $matches[1]; + $this->add_violation( + $file_path, + $actual_line_number, + "String FQCN reference to framework model 'App\\RSpade\\Core\\Models\\{$model_name}' prevents model overrides", + trim($line), + $this->build_suggestion($model_name, true), + 'high' + ); + } + } + } + + /** + * Build suggestion for fixing the violation + */ + private function build_suggestion(string $model_name, bool $is_string = false): string + { + $suggestions = []; + $suggestions[] = "Framework models should be referenced by short class name to allow developer overrides."; + $suggestions[] = ""; + + if ($is_string) { + $suggestions[] = "Change:"; + $suggestions[] = " \$class = 'App\\RSpade\\Core\\Models\\{$model_name}';"; + $suggestions[] = ""; + $suggestions[] = "To:"; + $suggestions[] = " \$class = '{$model_name}';"; + } else { + $suggestions[] = "Change:"; + $suggestions[] = " \\App\\RSpade\\Core\\Models\\{$model_name}::method()"; + $suggestions[] = ""; + $suggestions[] = "To:"; + $suggestions[] = " \\{$model_name}::method()"; + } + + $suggestions[] = ""; + $suggestions[] = "This allows developers to override {$model_name} by creating:"; + $suggestions[] = " /rsx/models/" . strtolower(str_replace('_Model', '', $model_name)) . "_model.php"; + $suggestions[] = ""; + $suggestions[] = "Note: 'use App\\RSpade\\Core\\Models\\{$model_name};' statements are allowed"; + $suggestions[] = "because PHP resolves them at parse time before the override system."; + + return implode("\n", $suggestions); + } +} diff --git a/app/RSpade/Core/Testing/Rsx_Formdata_Generator_Controller.php b/app/RSpade/Core/Testing/Rsx_Formdata_Generator_Controller.php index 9dda02619..5b12bc237 100755 --- a/app/RSpade/Core/Testing/Rsx_Formdata_Generator_Controller.php +++ b/app/RSpade/Core/Testing/Rsx_Formdata_Generator_Controller.php @@ -39,7 +39,7 @@ class Rsx_Formdata_Generator_Controller extends Rsx_Controller_Abstract } // Require developer role - if (!Permission::has_role(\App\RSpade\Core\Models\User_Model::ROLE_DEVELOPER)) { + if (!Permission::has_role(\User_Model::ROLE_DEVELOPER)) { return response_unauthorized('Developer access required'); }