$file_metadata) { // Only check PHP files with classes in ./rsx directory if (!isset($file_metadata['class'])) { continue; } if (!str_starts_with($file, 'rsx/')) { continue; } // Check if this class directly extends "Controller" $extends = $file_metadata['extends'] ?? null; if ($extends !== 'Controller') { continue; } // Found violation - RSX controller extending Laravel's Controller // Find line number of class declaration $line = $this->find_class_line($file, $file_metadata['class']); $this->add_violation( $file, $line, "RSX controller class '{$file_metadata['class']}' extends Laravel's Controller class. " . "RSX controllers must extend Rsx_Controller_Abstract or one of its subclasses to access " . "RSX-specific functionality and follow framework conventions.", "class {$file_metadata['class']} extends Controller", "Change the parent class from 'Controller' to 'Rsx_Controller_Abstract':\n" . " class {$file_metadata['class']} extends Rsx_Controller_Abstract", 'high' ); } } /** * Find the line number where a class is declared */ private function find_class_line(string $file_path, string $class_name): int { $absolute_path = base_path($file_path); if (!file_exists($absolute_path)) { return 1; } $contents = file_get_contents($absolute_path); $lines = explode("\n", $contents); foreach ($lines as $index => $line) { if (preg_match('/^\s*(?:abstract\s+)?class\s+' . preg_quote($class_name) . '\b/', $line)) { return $index + 1; } } return 1; } }