From 3a19c1c5347c9fcfc9ccf02597339e9031e9a6f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enes=20Yak=C4=B1=C5=9Ft=C4=B1r?= Date: Wed, 13 May 2026 12:46:26 +0300 Subject: [PATCH] Fix model name to gemini-1.5-flash v2.2.3 --- src/AI/GeminiFixer.php | 17 +++- src/Console/Command/ScanCommand.php | 1 + src/Core/RuleEngine.php | 28 ++++++- src/Core/Scanner.php | 5 ++ src/Core/Violation.php | 2 +- src/Reporting/HtmlDashboardReporter.php | 4 + test_report.html | 101 ++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 test_report.html diff --git a/src/AI/GeminiFixer.php b/src/AI/GeminiFixer.php index 1ee4a39..7ba4573 100644 --- a/src/AI/GeminiFixer.php +++ b/src/AI/GeminiFixer.php @@ -11,15 +11,23 @@ class GeminiFixer public function __construct(private readonly ?string $apiKey) { - if ($this->apiKey && class_exists(Gemini::class)) { - $this->client = Gemini::client($this->apiKey); + if ($this->apiKey) { + try { + $this->client = \Gemini::client($this->apiKey); + } catch (\Throwable) { + $this->client = null; + } } } public function suggestFix(Violation $violation): ?string { + if (!$this->apiKey) { + return "Hata: GEMINI_API_KEY bulunamadı."; + } + if (!$this->client) { - return null; + return "Hata: Gemini istemcisi başlatılamadı. Kütüphane eksik olabilir."; } $prompt = <<client->generativeModel('gemini-2.5-flash')->generateContent($prompt); + // Stable model: gemini-1.5-flash + $result = $this->client->generativeModel('gemini-1.5-flash')->generateContent($prompt); $suggestion = trim($result->text()); // Clean up if AI included markdown blocks anyway diff --git a/src/Console/Command/ScanCommand.php b/src/Console/Command/ScanCommand.php index fa4e9d1..5aff13e 100644 --- a/src/Console/Command/ScanCommand.php +++ b/src/Console/Command/ScanCommand.php @@ -83,6 +83,7 @@ class ScanCommand extends Command $io->write(" AI Fix Suggestion: "); $suggestion = $fixer->suggestFix($violation); if ($suggestion) { + $violation->fixSuggestion = $suggestion; $io->writeln("" . htmlspecialchars($suggestion) . ""); } else { $io->writeln("Could not generate suggestion (check API key)"); diff --git a/src/Core/RuleEngine.php b/src/Core/RuleEngine.php index 4d8c234..d92e121 100644 --- a/src/Core/RuleEngine.php +++ b/src/Core/RuleEngine.php @@ -4,10 +4,10 @@ namespace YakNet\AccessibilityConsole\Core; class RuleEngine { - /** @var AbstractRule[] */ + /** @var array */ private array $rules = []; - public function addRule(AbstractRule $rule): void + public function addRule(mixed $rule): void { $this->rules[] = $rule; } @@ -19,8 +19,28 @@ class RuleEngine { $allViolations = []; foreach ($this->rules as $rule) { - $violations = $rule->check($doc); - $allViolations = array_merge($allViolations, $violations); + if (method_exists($rule, 'check')) { + // Determine if it's a document-level rule or element-level rule + $reflection = new \ReflectionMethod($rule, 'check'); + $params = $reflection->getParameters(); + + if (isset($params[0]) && $params[0]->getType() && $params[0]->getType()->getName() === 'DOMDocument') { + // Document-level rule (Core\AbstractRule style) + $violations = $rule->check($doc); + $allViolations = array_merge($allViolations, $violations); + } else { + // Element-level rule (Rules\RuleInterface style) + // We need to iterate over all elements + $xpath = new \DOMXPath($doc); + $elements = $xpath->query('//*'); + foreach ($elements as $element) { + $violation = $rule->check($element); + if ($violation) { + $allViolations[] = $violation; + } + } + } + } } return $allViolations; } diff --git a/src/Core/Scanner.php b/src/Core/Scanner.php index ed71214..405ccc5 100644 --- a/src/Core/Scanner.php +++ b/src/Core/Scanner.php @@ -11,6 +11,11 @@ class Scanner } } + public function addRule(mixed $rule): void + { + $this->engine->addRule($rule); + } + /** * Scan HTML content for accessibility violations. * diff --git a/src/Core/Violation.php b/src/Core/Violation.php index 8036f3b..2690ee1 100644 --- a/src/Core/Violation.php +++ b/src/Core/Violation.php @@ -2,7 +2,7 @@ namespace YakNet\AccessibilityConsole\Core; -readonly class Violation +class Violation { public function __construct( public string $ruleId, diff --git a/src/Reporting/HtmlDashboardReporter.php b/src/Reporting/HtmlDashboardReporter.php index 21f7efa..23f5d0a 100644 --- a/src/Reporting/HtmlDashboardReporter.php +++ b/src/Reporting/HtmlDashboardReporter.php @@ -22,6 +22,7 @@ class HtmlDashboardReporter {$v->ruleId} {$v->message}
" . htmlspecialchars($v->htmlSnippet) . "
+ " . ($v->fixSuggestion ? "
" . htmlspecialchars($v->fixSuggestion) . "
" : "Manual fix required") . " " . ($v->location ? "{$v->location['file']}:{$v->location['line']}" : 'N/A') . " "; } @@ -43,8 +44,10 @@ class HtmlDashboardReporter th, td { text-align: left; padding: 12px; border-bottom: 1px solid #eee; } th { background: #f8f9fa; } pre { background: #272822; color: #f8f8f2; padding: 10px; border-radius: 4px; overflow-x: auto; font-size: 12px; } + .ai-fix { border-left: 4px solid #2ecc71; background: #1e1e1e; } .badge { background: #34495e; color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; } .severity-error { background: #fff5f5; } + .text-muted { color: #95a5a6; font-size: 0.9em; font-style: italic; } @@ -69,6 +72,7 @@ class HtmlDashboardReporter Rule ID Issue Code Snippet + AI Recommendation Source Location diff --git a/test_report.html b/test_report.html new file mode 100644 index 0000000..053e61d --- /dev/null +++ b/test_report.html @@ -0,0 +1,101 @@ + + + + + A11y Report - demo/broken.html + + + +
+

Accessibility Report

+

Target: demo/broken.html | Generated: 2026-05-13 09:46:04

+ +
+
+

4

+

Violations Found

+
+
+

WCAG 2.1

+

Standard Level

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rule IDIssueCode SnippetAI RecommendationSource Location
WCAG_3_1_1_LANGThe html element must have a lang attribute.
<html>
+<head>
+    <title>Broken Page</title>
+</head>
+<body>
+    <h1>Welcome to a broken page</h1>
+    
+    <!-- Missing alt attribute -->
+    <img src="logo.png">
+    
+    <!-- Empty link -->
+    <a href="https://google.com"></a>
+    
+    <!-- Empty button -->
+    <button type="submit"></button>
+    
+    <p>This page has multiple accessibility issues.</p>
+</body>
+</html>
Hata: GEMINI_API_KEY bulunamadı.
N/A
WCAG_1_1_1_ALTImages must have an alt attribute.
<img src="logo.png">
Hata: GEMINI_API_KEY bulunamadı.
N/A
WCAG_2_4_4_LINK_TEXTLinks must have discernible text.
<a href="https://google.com"></a>
Hata: GEMINI_API_KEY bulunamadı.
N/A
WCAG_4_1_2_BUTTONButtons must have discernible text.
<button type="submit"></button>
Hata: GEMINI_API_KEY bulunamadı.
N/A
+
+ + \ No newline at end of file