From e34802557966ffd4ade1775d4e849a1b23b133e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Enes=20Yak=C4=B1=C5=9Ft=C4=B1r?=
Date: Wed, 13 May 2026 09:10:43 +0300
Subject: [PATCH] Major upgrade v2.0.0
---
.env.example | 1 +
.gitignore | 6 +
LICENSE | 21 +++
README.md | 96 ++++++++++++
bin/a11y | 16 ++
composer.json | 49 ++++++
demo/broken.html | 20 +++
demo/dynamic_preview.html | 195 ++++++++++++++++++++++++
demo/fixed_preview.html | 112 ++++++++++++++
demo/fixed_preview_with_widget.html | 23 +++
demo/index.php | 70 +++++++++
demo/index_fixed.php | 75 +++++++++
demo/static_preview.html | 102 +++++++++++++
demo/views-fixed/contact.php | 32 ++++
demo/views-fixed/home.php | 36 +++++
demo/views-fixed/layout.php | 75 +++++++++
demo/views/contact.php | 31 ++++
demo/views/home.php | 36 +++++
demo/views/layout.php | 74 +++++++++
src/AI/GeminiFixer.php | 52 +++++++
src/Console/Command/FixCommand.php | 136 +++++++++++++++++
src/Console/Command/ScanCommand.php | 113 ++++++++++++++
src/Core/Config.php | 29 ++++
src/Core/RuleEngine.php | 24 +++
src/Core/Scanner.php | 63 ++++++++
src/Core/Severity.php | 21 +++
src/Core/Violation.php | 29 ++++
src/Core/WCAGStandard.php | 10 ++
src/Reporting/HtmlDashboardReporter.php | 84 ++++++++++
src/Rules/AbstractRule.php | 28 ++++
src/Rules/ButtonName.php | 30 ++++
src/Rules/EmptyLink.php | 38 +++++
src/Rules/FieldsetLegend.php | 30 ++++
src/Rules/FormLabel.php | 55 +++++++
src/Rules/HeadingOrder.php | 40 +++++
src/Rules/HtmlHasLang.php | 29 ++++
src/Rules/ImgAltText.php | 35 +++++
src/Rules/MetaViewport.php | 30 ++++
src/Rules/RuleInterface.php | 12 ++
src/Rules/StandardRuleSet.php | 23 +++
src/Source/SourceLocator.php | 158 +++++++++++++++++++
41 files changed, 2139 insertions(+)
create mode 100644 .env.example
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 README.md
create mode 100644 bin/a11y
create mode 100644 composer.json
create mode 100644 demo/broken.html
create mode 100644 demo/dynamic_preview.html
create mode 100644 demo/fixed_preview.html
create mode 100644 demo/fixed_preview_with_widget.html
create mode 100644 demo/index.php
create mode 100644 demo/index_fixed.php
create mode 100644 demo/static_preview.html
create mode 100644 demo/views-fixed/contact.php
create mode 100644 demo/views-fixed/home.php
create mode 100644 demo/views-fixed/layout.php
create mode 100644 demo/views/contact.php
create mode 100644 demo/views/home.php
create mode 100644 demo/views/layout.php
create mode 100644 src/AI/GeminiFixer.php
create mode 100644 src/Console/Command/FixCommand.php
create mode 100644 src/Console/Command/ScanCommand.php
create mode 100644 src/Core/Config.php
create mode 100644 src/Core/RuleEngine.php
create mode 100644 src/Core/Scanner.php
create mode 100644 src/Core/Severity.php
create mode 100644 src/Core/Violation.php
create mode 100644 src/Core/WCAGStandard.php
create mode 100644 src/Reporting/HtmlDashboardReporter.php
create mode 100644 src/Rules/AbstractRule.php
create mode 100644 src/Rules/ButtonName.php
create mode 100644 src/Rules/EmptyLink.php
create mode 100644 src/Rules/FieldsetLegend.php
create mode 100644 src/Rules/FormLabel.php
create mode 100644 src/Rules/HeadingOrder.php
create mode 100644 src/Rules/HtmlHasLang.php
create mode 100644 src/Rules/ImgAltText.php
create mode 100644 src/Rules/MetaViewport.php
create mode 100644 src/Rules/RuleInterface.php
create mode 100644 src/Rules/StandardRuleSet.php
create mode 100644 src/Source/SourceLocator.php
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..f0d664a
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+GEMINI_API_KEY=your_api_key_here
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9805767
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+/vendor/
+/.env
+/composer.lock
+/rapor.html
+/.phpunit.result.cache
+/phpstan-baseline.neon
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..288f9dd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 YakNet Bilişim
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..22ecfdb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,96 @@
+# YakNet Accessibility Console 2.0 (AI-Powered)
+
+[](https://php.net)
+[](LICENSE)
+[](https://gemini.google.com)
+
+**YakNet Accessibility Console**, web projelerinizdeki erişilebilirlik (WCAG 2.1) hatalarını sadece tespit etmekle kalmayan, aynı zamanda **Yapay Zeka (AI)** desteğiyle bu hataları otomatik olarak düzeltebilen (Self-Healing) profesyonel bir PHP kütüphanesidir.
+
+## 🌟 Öne Çıkan Özellikler
+
+- **🤖 AI Self-Healing:** Tespit edilen WCAG hataları için Google Gemini AI üzerinden akıllı çözüm önerileri alır ve isterseniz kaynak kodunuzu (Blade, Twig, PHP) otomatik olarak tamir eder.
+- **⚡ Modern CLI:** Rust/Vite tarzı şık bir komut satırı arayüzü ile saniyeler içinde tarama ve düzeltme yapın.
+- **📊 Görsel Dashboard:** Tarama sonuçlarını modern ve şık bir HTML raporu olarak dışarı aktarın.
+- **🔍 Akıllı Kaynak Tespiti:** Hataları projenizdeki tam dosya yolu ve satır numarası ile eşleştirir.
+- **🛠️ Geliştirici Dostu:** PSR-4 uyumlu, modern PHP 8.2+ mimarisi ve genişletilebilir kural motoru.
+
+## 📦 Kurulum
+
+Composer ile projenize hemen dahil edin:
+
+```bash
+composer require yaknet/accessibility-console
+```
+
+## 🚀 CLI Kullanımı
+
+Kütüphane, `vendor/bin/a11y` (veya kütüphane dizininde `bin/a11y`) üzerinden kullanılabilir.
+
+### 1. Standart Tarama
+Bir URL'yi veya yerel bir HTML dosyasını tarayın:
+```bash
+bin/a11y scan https://test-siteniz.com
+```
+
+### 2. AI Destekli Tarama ve Raporlama
+Yapay zeka önerileriyle birlikte tarama yapın ve sonucu HTML olarak kaydedin:
+```bash
+bin/a11y scan https://test-siteniz.com --ai --report=sonuc.html
+```
+
+### 3. Otomatik Düzeltme (Self-Healing) - **DEVRİMSEL**
+Tespit edilen hataları yapay zekaya düzelttirin ve dosyalarınızı güncelleyin:
+```bash
+bin/a11y fix https://test-siteniz.com --project-path=/var/www/projeniz
+```
+
+## 💻 Kütüphane Olarak Kullanım
+
+Kendi PHP uygulamalarınızın içine entegre edin:
+
+```php
+use YakNet\AccessibilityConsole\Core\Scanner;
+use YakNet\AccessibilityConsole\Rules\StandardRuleSet;
+
+// 1. Scanner'ı ve Kuralları Hazırla
+$scanner = new Scanner();
+foreach (StandardRuleSet::all() as $rule) {
+ $scanner->addRule($rule);
+}
+
+// 2. HTML İçeriğini Tara
+$html = file_get_contents('view.html');
+$violations = $scanner->scan($html);
+
+// 3. Sonuçları İşle
+foreach ($violations as $v) {
+ echo "Hata: {$v->message} (Kural: {$v->ruleId})\n";
+}
+```
+
+## ⚙️ Yapılandırma
+
+AI özelliklerini kullanabilmek için projenizin kök dizininde bir `.env` dosyası oluşturun ve **Google Gemini API** anahtarınızı ekleyin:
+
+```env
+GEMINI_API_KEY=AIzaSyA...your_key_here
+```
+
+## 🛠️ Mevcut Kurallar (WCAG 2.1)
+
+- **A11Y_VIEWPORT:** Zoom engelleme kontrolü.
+- **WCAG_1_1_1_ALT:** Görsel alt metin kontrolü.
+- **WCAG_1_3_1_LABEL:** Form etiketi kontrolü.
+- **WCAG_1_3_1_FIELDSET:** Fieldset/Legend kontrolü.
+- **WCAG_1_3_1_HEADING:** Başlık hiyerarşisi kontrolü.
+- **WCAG_2_4_4_LINK_TEXT:** Boş link kontrolü.
+- **WCAG_3_1_1_LANG:** HTML dil etiketi kontrolü.
+- **WCAG_4_1_2_BUTTON:** Boş buton kontrolü.
+
+## 🤝 Katkıda Bulunma
+
+Bu proje açık kaynaklıdır ve katkılarınıza açıktır. Lütfen hata bildirimleri için `Issue` açmaktan veya yeni özellikler için `Pull Request` göndermekten çekinmeyin.
+
+## 📜 Lisans
+
+Bu yazılım **YakNet Bilişim** tarafından geliştirilmiştir ve **MIT Lisansı** altında lisanslanmıştır. Detaylar için [LICENSE](LICENSE) dosyasına göz atabilirsiniz.
\ No newline at end of file
diff --git a/bin/a11y b/bin/a11y
new file mode 100644
index 0000000..c447cb0
--- /dev/null
+++ b/bin/a11y
@@ -0,0 +1,16 @@
+#!/usr/bin/env php
+add(new ScanCommand());
+$application->add(new FixCommand());
+
+$application->run();
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..0db6a3e
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,49 @@
+{
+ "name": "yaknet/accessibility-console",
+ "description": "A professional AI-powered WCAG 2.1 accessibility scanner with self-healing capabilities.",
+ "keywords": [
+ "accessibility",
+ "wcag",
+ "a11y",
+ "scanner",
+ "ai",
+ "gemini",
+ "self-healing",
+ "yaknet"
+ ],
+ "homepage": "https://forum.yak.net.tr",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "YakNet Bilişim",
+ "email": "dev@yak.net.tr",
+ "role": "Developer"
+ }
+ ],
+ "require": {
+ "php": "^8.2",
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0",
+ "monolog/monolog": "^3.0",
+ "vlucas/phpdotenv": "^5.6",
+ "google-gemini-php/client": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.5",
+ "phpstan/phpstan": "^1.10"
+ },
+ "autoload": {
+ "psr-4": {
+ "YakNet\\AccessibilityConsole\\": "src/"
+ }
+ },
+ "bin": [
+ "bin/a11y"
+ ],
+ "minimum-stability": "stable",
+ "prefer-stable": true
+}
\ No newline at end of file
diff --git a/demo/broken.html b/demo/broken.html
new file mode 100644
index 0000000..d39825b
--- /dev/null
+++ b/demo/broken.html
@@ -0,0 +1,20 @@
+
+
+
+ Broken Page
+
+
+ Welcome to a broken page
+
+
+
+
+
+
+
+
+
+
+ This page has multiple accessibility issues.
+
+
diff --git a/demo/dynamic_preview.html b/demo/dynamic_preview.html
new file mode 100644
index 0000000..5a6eed5
--- /dev/null
+++ b/demo/dynamic_preview.html
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+ YakNet Dynamic Demo
+
+
+
+
+
+
+
+ Latest Products
+ Welcome to our dynamic product catalog. (Intentionally filled with errors)
+
+
+
+
+
+
+
Super Gadget
+
$99
+
Buy Now
+
+
+
+
+
+
Mega Widget
+
$49
+
Buy Now
+
+
+
+
+
+
Ultra Thing
+
$199
+
Buy Now
+
+
+
+
+
+
+ Sponsors
+
+
+
+
+
+
+
+
+
+
+ ⚠️ Accessibility: 5 Errors
+
+
+
+
+
+
+
+
+ FATAL
+ ERROR
+ Accessibility Violations Detected
+
+ ×
+
+
+
+
+
+
+ #
+ Violation / Message
+ Source File
+
+
+
+
+ 1
+
+ Image
+ is missing alt attribute.
+ Rule:
+ img-alt-text
+
+ <img src="images/gadget.jpg" width="100">
+
+
+ Fix: Add an alt="" attribute
+ describing the image, or alt="" if decorative.
+
+
+
+
+ home.php:14
+
+
+
+
+ 2
+
+ Image
+ is missing alt attribute.
+ Rule:
+ img-alt-text
+
+ <img src="images/widget.png" width="100">
+
+
+ Fix: Add an alt="" attribute
+ describing the image, or alt="" if decorative.
+
+
+
+
+ home.php:14
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/fixed_preview.html b/demo/fixed_preview.html
new file mode 100644
index 0000000..9c4c3bc
--- /dev/null
+++ b/demo/fixed_preview.html
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+ YakNet Dynamic Demo (Fixed)
+
+
+
+
+
+
+
+ Latest Products
+ Welcome to our accessible product catalog.
+
+
+
+
+
+
+
Super Gadget
+
$99
+
Buy Now
+
+
+
+
+
Mega Widget
+
$49
+
Buy Now
+
+
+
+
+
Ultra Thing
+
$199
+
Buy Now
+
+
+
+
+
+ Sponsors
+
+
+
+
+
+
+
+
+
+ ✅ Accessibility: 0 Errors
+
+
+
\ No newline at end of file
diff --git a/demo/fixed_preview_with_widget.html b/demo/fixed_preview_with_widget.html
new file mode 100644
index 0000000..7984a99
--- /dev/null
+++ b/demo/fixed_preview_with_widget.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ YakNet Dynamic Demo (Fixed)
+
+
+
+
+
+ My Dynamic Site (Accessible)
+ Success widget demonstration.
+
+
+
+ ✅ Accessibility: 0 Errors
+
+
+
+
\ No newline at end of file
diff --git a/demo/index.php b/demo/index.php
new file mode 100644
index 0000000..51eace3
--- /dev/null
+++ b/demo/index.php
@@ -0,0 +1,70 @@
+addRule(new ImgAltText());
+$scanner->addRule(new FormLabel());
+$scanner->addRule(new \YakNet\AccessibilityConsole\Rules\HtmlHasLang());
+$scanner->addRule(new \YakNet\AccessibilityConsole\Rules\EmptyLink());
+
+// Scan the captured HTML
+$violations = $scanner->scan($html);
+
+if (!empty($violations)) {
+ // Locate Sources
+ // We point it to the 'views' directory so it knows where to look for the error source
+ $locator = new SourceLocator(__DIR__ . '/views');
+
+ foreach ($violations as $violation) {
+ $location = $locator->locate($violation->snippet);
+ if ($location) {
+ $violation->setSourceLocation($location['file'], $location['line']);
+ }
+ }
+
+ // Render Report
+ $reporter = new HtmlReporter();
+ $reportHtml = $reporter->render($violations);
+
+ // Inject into body
+ $html = str_replace('
+ Accessibility Console Preview
+ This is a static preview of how the error console looks.
+ Click the "Accessibility: 2 Errors" button in the bottom right.
+
+
+
+ ⚠️ Accessibility: 2 Errors
+
+
+
+
+
+
+
+ FATAL
+ ERROR
+ Accessibility Violations Detected
+
+ ×
+
+
+
+
+
+
+ #
+ Violation / Message
+ Source File
+
+
+
+
+ 1
+
+ Image
+ is missing alt attribute.
+ Rule:
+ img-alt-text
+
+
+ <img src="logo.png" />
+
+
+ Fix: Add an alt="" attribute
+ describing the image, or alt="" if decorative.
+
+
+
+
+ C:\Users\User\Project\views\header.php:42
+
+
+
+
+ 2
+
+ Form
+ field <input> missing label.
+ Rule:
+ form-label
+
+
+ <input type="text" name="username" />
+
+
+ Fix: Associate a <label>
+ via "for" attribute, wrap in <label>, or use "aria-label".
+
+
+
+
+ C:\Users\User\Project\views\login.php:15
+
+
+
+
+
+
+
+
+', $reportHtml . '', $html);
+}
+
+// 7. Output Final HTML
+echo $html;
diff --git a/demo/index_fixed.php b/demo/index_fixed.php
new file mode 100644
index 0000000..e15d0db
--- /dev/null
+++ b/demo/index_fixed.php
@@ -0,0 +1,75 @@
+addRule(new ImgAltText());
+$scanner->addRule(new FormLabel());
+$scanner->addRule(new HtmlHasLang());
+$scanner->addRule(new EmptyLink());
+
+$violations = $scanner->scan($html);
+
+if (!empty($violations)) {
+ // Locate Sources
+ $locator = new SourceLocator(__DIR__ . '/views-fixed');
+
+ foreach ($violations as $violation) {
+ $location = $locator->locate($violation->snippet);
+ if ($location) {
+ $violation->setSourceLocation($location['file'], $location['line']);
+ }
+ }
+
+ $reporter = new HtmlReporter();
+ // Enable success widget for this demo
+ $reporter->setShowSuccess(true);
+
+ $reportHtml = $reporter->render($violations);
+ $html = str_replace('', $reportHtml . '', $html);
+} else {
+ // Violations is empty, but render() will return the success widget because we set it to true
+ $reporter = new HtmlReporter();
+ $reporter->setShowSuccess(true);
+ $reportHtml = $reporter->render($violations);
+
+ $html = str_replace('', $reportHtml . '', $html);
+}
+
+echo $html;
diff --git a/demo/static_preview.html b/demo/static_preview.html
new file mode 100644
index 0000000..9c475e2
--- /dev/null
+++ b/demo/static_preview.html
@@ -0,0 +1,102 @@
+
+
+
+