Son aktivite 1 month ago

urocibg bu gisti düzenledi 1 month ago. Düzenlemeye git

2 files changed, 1665 insertions

ai-seo-master..php(dosya oluşturuldu)

@@ -0,0 +1,1665 @@
1 + <?php
2 + /**
3 + * Plugin Name: AI SEO Master PRO
4 + * Plugin URI: https://urocibg.eu/ai-seo-master-pro
5 + * Description: 🚀 Професионален AI SEO оптимизатор с мониторинг, валидация и напълно безплатни API функционалности
6 + * Version: 2.0.0
7 + * Author: Fedya Serafiev
8 + * Author URI: https://fedia.eu
9 + * License: GPL v3
10 + * Text Domain: ai-seo-master-pro
11 + */
12 +
13 + // Безопасност
14 + if (!defined('ABSPATH')) {
15 + exit;
16 + }
17 +
18 + // Дефиниране на константи
19 + define('AISEOM_VERSION', '2.0.0');
20 + define('AISEOM_PLUGIN_DIR', plugin_dir_path(__FILE__));
21 + define('AISEOM_PLUGIN_URL', plugin_dir_url(__FILE__));
22 +
23 + // Главен клас
24 + class AI_SEO_Master_PRO {
25 +
26 + private static $instance = null;
27 +
28 + public static function get_instance() {
29 + if (null === self::$instance) {
30 + self::$instance = new self();
31 + }
32 + return self::$instance;
33 + }
34 +
35 + private function __construct() {
36 + // Инициализация
37 + add_action('init', [$this, 'init']);
38 + add_action('admin_menu', [$this, 'create_admin_menu']);
39 + add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
40 +
41 + // AJAX обработчици
42 + add_action('wp_ajax_aiseom_generate_meta', [$this, 'ajax_generate_meta']);
43 + add_action('wp_ajax_aiseom_generate_alt', [$this, 'ajax_generate_alt']);
44 + add_action('wp_ajax_aiseom_bulk_process', [$this, 'ajax_bulk_process']);
45 + add_action('wp_ajax_aiseom_check_api', [$this, 'ajax_check_api']);
46 + add_action('wp_ajax_aiseom_get_stats', [$this, 'ajax_get_stats']);
47 +
48 + // Мета боксове
49 + add_action('add_meta_boxes', [$this, 'add_seo_metabox']);
50 +
51 + // Настройки
52 + add_action('admin_init', [$this, 'register_settings']);
53 + }
54 +
55 + public function init() {
56 + // Зареждане на текстове за превод
57 + load_plugin_textdomain('ai-seo-master-pro', false, dirname(plugin_basename(__FILE__)) . '/languages');
58 + }
59 +
60 + public function create_admin_menu() {
61 + // Главно меню
62 + add_menu_page(
63 + 'AI SEO PRO',
64 + 'AI SEO PRO',
65 + 'manage_options',
66 + 'ai-seo-master-pro',
67 + [$this, 'render_dashboard'],
68 + 'dashicons-chart-line',
69 + 30
70 + );
71 +
72 + // Подменюта
73 + add_submenu_page(
74 + 'ai-seo-master-pro',
75 + 'Табло',
76 + 'Табло',
77 + 'manage_options',
78 + 'ai-seo-master-pro',
79 + [$this, 'render_dashboard']
80 + );
81 +
82 + add_submenu_page(
83 + 'ai-seo-master-pro',
84 + 'Статии без SEO',
85 + 'Статии без SEO',
86 + 'manage_options',
87 + 'ai-seo-unoptimized',
88 + [$this, 'render_unoptimized_posts']
89 + );
90 +
91 + add_submenu_page(
92 + 'ai-seo-master-pro',
93 + 'Настройки',
94 + 'Настройки',
95 + 'manage_options',
96 + 'ai-seo-settings',
97 + [$this, 'render_settings_page']
98 + );
99 + }
100 +
101 + public function enqueue_admin_assets($hook) {
102 + // Зареждаме само в нашите страници
103 + $our_pages = [
104 + 'toplevel_page_ai-seo-master-pro',
105 + 'ai-seo-master-pro_page_ai-seo-unoptimized',
106 + 'ai-seo-master-pro_page_ai-seo-settings'
107 + ];
108 +
109 + if (!in_array($hook, $our_pages) && !strstr($hook, 'post.php') && !strstr($hook, 'edit.php')) {
110 + return;
111 + }
112 +
113 + // Вграждаме CSS директно
114 + add_action('admin_head', [$this, 'add_inline_css']);
115 +
116 + // Вграждаме JavaScript директно
117 + add_action('admin_footer', [$this, 'add_inline_js']);
118 + }
119 +
120 + public function add_inline_css() {
121 + ?>
122 + <style>
123 + /* Основни стилове за AI SEO Master PRO */
124 + .aiseom-dashboard {
125 + background: #f0f0f1;
126 + padding: 20px;
127 + min-height: 100vh;
128 + }
129 +
130 + .aiseom-header {
131 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
132 + color: white;
133 + padding: 30px;
134 + border-radius: 10px;
135 + margin-bottom: 30px;
136 + }
137 +
138 + .aiseom-header h1 {
139 + color: white;
140 + margin: 0 0 10px 0;
141 + display: flex;
142 + align-items: center;
143 + gap: 15px;
144 + }
145 +
146 + .aiseom-stats-grid {
147 + display: grid;
148 + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
149 + gap: 20px;
150 + margin: 30px 0;
151 + }
152 +
153 + .aiseom-stat-card {
154 + background: white;
155 + border-radius: 10px;
156 + padding: 25px;
157 + display: flex;
158 + align-items: center;
159 + gap: 20px;
160 + box-shadow: 0 5px 15px rgba(0,0,0,0.05);
161 + transition: transform 0.3s ease;
162 + }
163 +
164 + .aiseom-stat-card:hover {
165 + transform: translateY(-5px);
166 + }
167 +
168 + .aiseom-stat-card .stat-icon {
169 + width: 60px;
170 + height: 60px;
171 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
172 + border-radius: 10px;
173 + display: flex;
174 + align-items: center;
175 + justify-content: center;
176 + color: white;
177 + font-size: 28px;
178 + }
179 +
180 + .aiseom-stat-card .stat-number {
181 + font-size: 36px;
182 + font-weight: bold;
183 + color: #2d3748;
184 + display: block;
185 + line-height: 1;
186 + }
187 +
188 + .aiseom-stat-card .stat-label {
189 + color: #718096;
190 + font-size: 16px;
191 + display: block;
192 + margin-top: 5px;
193 + }
194 +
195 + .aiseom-actions-grid {
196 + display: grid;
197 + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
198 + gap: 20px;
199 + margin: 30px 0;
200 + }
201 +
202 + .aiseom-action-card {
203 + background: white;
204 + border-radius: 10px;
205 + padding: 25px;
206 + box-shadow: 0 5px 15px rgba(0,0,0,0.05);
207 + }
208 +
209 + .aiseom-action-card h3 {
210 + margin-top: 0;
211 + color: #2d3748;
212 + font-size: 20px;
213 + display: flex;
214 + align-items: center;
215 + gap: 10px;
216 + }
217 +
218 + .aiseom-btn {
219 + display: inline-flex;
220 + align-items: center;
221 + gap: 8px;
222 + padding: 12px 24px;
223 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
224 + color: white;
225 + border: none;
226 + border-radius: 8px;
227 + font-weight: 600;
228 + cursor: pointer;
229 + text-decoration: none;
230 + transition: all 0.3s ease;
231 + }
232 +
233 + .aiseom-btn:hover {
234 + transform: translateY(-2px);
235 + box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
236 + color: white;
237 + }
238 +
239 + .aiseom-btn-secondary {
240 + background: #edf2f7;
241 + color: #4a5568;
242 + }
243 +
244 + .aiseom-btn-secondary:hover {
245 + background: #e2e8f0;
246 + }
247 +
248 + /* Мета бокс стилове */
249 + .aiseom-metabox {
250 + padding: 10px 0;
251 + }
252 +
253 + .aiseom-metabox-section {
254 + margin-bottom: 20px;
255 + padding-bottom: 15px;
256 + border-bottom: 1px solid #eee;
257 + }
258 +
259 + .aiseom-metabox-section:last-child {
260 + border-bottom: none;
261 + }
262 +
263 + .status-indicator {
264 + padding: 8px;
265 + border-radius: 4px;
266 + margin: 8px 0;
267 + display: flex;
268 + align-items: center;
269 + gap: 8px;
270 + }
271 +
272 + .status-success {
273 + background: #edf7ed;
274 + border-left: 4px solid #4caf50;
275 + }
276 +
277 + .status-warning {
278 + background: #fff8e1;
279 + border-left: 4px solid #ff9800;
280 + }
281 +
282 + .status-error {
283 + background: #fdeded;
284 + border-left: 4px solid #f44336;
285 + }
286 +
287 + .status-neutral {
288 + background: #f5f5f5;
289 + border-left: 4px solid #9e9e9e;
290 + }
291 +
292 + .status-icon {
293 + font-weight: bold;
294 + font-size: 14px;
295 + min-width: 16px;
296 + }
297 +
298 + /* Таблици */
299 + .aiseom-table {
300 + width: 100%;
301 + border-collapse: collapse;
302 + background: white;
303 + border-radius: 10px;
304 + overflow: hidden;
305 + box-shadow: 0 2px 10px rgba(0,0,0,0.05);
306 + }
307 +
308 + .aiseom-table th {
309 + background: #f8f9fa;
310 + padding: 15px;
311 + text-align: left;
312 + font-weight: 600;
313 + color: #495057;
314 + border-bottom: 2px solid #e9ecef;
315 + }
316 +
317 + .aiseom-table td {
318 + padding: 12px 15px;
319 + border-bottom: 1px solid #e9ecef;
320 + }
321 +
322 + .aiseom-table tr:hover {
323 + background: #f8f9fa;
324 + }
325 +
326 + /* Форми и настройки */
327 + .aiseom-settings-form {
328 + background: white;
329 + padding: 30px;
330 + border-radius: 10px;
331 + box-shadow: 0 5px 15px rgba(0,0,0,0.05);
332 + }
333 +
334 + .form-group {
335 + margin-bottom: 25px;
336 + }
337 +
338 + .form-group label {
339 + display: block;
340 + margin-bottom: 8px;
341 + font-weight: 600;
342 + color: #2d3748;
343 + }
344 +
345 + .form-group input[type="text"],
346 + .form-group input[type="password"],
347 + .form-group select {
348 + width: 100%;
349 + max-width: 500px;
350 + padding: 10px;
351 + border: 1px solid #cbd5e0;
352 + border-radius: 6px;
353 + font-size: 14px;
354 + }
355 +
356 + .form-group input:focus,
357 + .form-group select:focus {
358 + outline: none;
359 + border-color: #667eea;
360 + box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
361 + }
362 +
363 + .api-test-result {
364 + margin-top: 10px;
365 + padding: 10px;
366 + border-radius: 6px;
367 + font-weight: 500;
368 + }
369 +
370 + .api-test-success {
371 + background: #edf7ed;
372 + color: #2e7d32;
373 + border-left: 4px solid #4caf50;
374 + }
375 +
376 + .api-test-error {
377 + background: #fdeded;
378 + color: #c62828;
379 + border-left: 4px solid #f44336;
380 + }
381 +
382 + /* Прогрес бар */
383 + .progress-container {
384 + margin: 20px 0;
385 + display: none;
386 + }
387 +
388 + .progress-bar {
389 + width: 100%;
390 + height: 20px;
391 + background: #edf2f7;
392 + border-radius: 10px;
393 + overflow: hidden;
394 + }
395 +
396 + .progress-fill {
397 + height: 100%;
398 + background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
399 + width: 0%;
400 + transition: width 0.3s ease;
401 + }
402 +
403 + .progress-text {
404 + text-align: center;
405 + margin-top: 10px;
406 + color: #718096;
407 + font-weight: 500;
408 + }
409 +
410 + /* Адаптивен дизайн */
411 + @media (max-width: 768px) {
412 + .aiseom-stats-grid {
413 + grid-template-columns: 1fr;
414 + }
415 +
416 + .aiseom-actions-grid {
417 + grid-template-columns: 1fr;
418 + }
419 +
420 + .form-group input[type="text"],
421 + .form-group input[type="password"],
422 + .form-group select {
423 + max-width: 100%;
424 + }
425 + }
426 + </style>
427 + <?php
428 + }
429 +
430 + public function add_inline_js() {
431 + ?>
432 + <script>
433 + // AI SEO Master PRO JavaScript
434 + jQuery(document).ready(function($) {
435 + console.log('AI SEO Master PRO loaded');
436 +
437 + // AJAX nonce и URL
438 + var aiseom_ajax = {
439 + ajax_url: '<?php echo admin_url("admin-ajax.php"); ?>',
440 + nonce: '<?php echo wp_create_nonce("aiseom_nonce"); ?>',
441 + strings: {
442 + generating: '<?php _e("Генериране...", "ai-seo-master-pro"); ?>',
443 + success: '<?php _e("Успешно!", "ai-seo-master-pro"); ?>',
444 + error: '<?php _e("Грешка", "ai-seo-master-pro"); ?>',
445 + checking: '<?php _e("Проверка на API...", "ai-seo-master-pro"); ?>'
446 + }
447 + };
448 +
449 + // Генериране на мета описание от мета бокс
450 + $(document).on('click', '.aiseom-generate-meta', function() {
451 + var button = $(this);
452 + var postId = button.data('post-id');
453 +
454 + button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> ' + aiseom_ajax.strings.generating);
455 +
456 + $.ajax({
457 + url: aiseom_ajax.ajax_url,
458 + type: 'POST',
459 + data: {
460 + action: 'aiseom_generate_meta',
461 + nonce: aiseom_ajax.nonce,
462 + post_id: postId
463 + },
464 + success: function(response) {
465 + if (response.success) {
466 + button.html('<i class="fas fa-check"></i> ' + aiseom_ajax.strings.success);
467 + setTimeout(function() {
468 + location.reload();
469 + }, 1500);
470 + } else {
471 + alert('Грешка: ' + response.data);
472 + button.prop('disabled', false).html('<i class="fas fa-magic"></i> Генерирай SEO');
473 + }
474 + },
475 + error: function() {
476 + alert('Грешка при генериране');
477 + button.prop('disabled', false).html('<i class="fas fa-magic"></i> Генерирай SEO');
478 + }
479 + });
480 + });
481 +
482 + // Генериране на ALT тагове от мета бокс
483 + $(document).on('click', '.aiseom-generate-alt', function() {
484 + var button = $(this);
485 + var postId = button.data('post-id');
486 +
487 + button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> ' + aiseom_ajax.strings.generating);
488 +
489 + $.ajax({
490 + url: aiseom_ajax.ajax_url,
491 + type: 'POST',
492 + data: {
493 + action: 'aiseom_generate_alt',
494 + nonce: aiseom_ajax.nonce,
495 + post_id: postId
496 + },
497 + success: function(response) {
498 + if (response.success) {
499 + button.html('<i class="fas fa-check"></i> ' + aiseom_ajax.strings.success);
500 + setTimeout(function() {
501 + location.reload();
502 + }, 1500);
503 + } else {
504 + alert('Грешка: ' + response.data);
505 + button.prop('disabled', false).html('<i class="fas fa-image"></i> Генерирай ALT');
506 + }
507 + },
508 + error: function() {
509 + alert('Грешка при генериране');
510 + button.prop('disabled', false).html('<i class="fas fa-image"></i> Генерирай ALT');
511 + }
512 + });
513 + });
514 +
515 + // Проверка на API ключа
516 + $(document).on('click', '#test-api-key', function() {
517 + var button = $(this);
518 + var apiKey = $('#aiseom_api_key').val();
519 + var provider = $('#aiseom_api_provider').val();
520 +
521 + if (!apiKey) {
522 + alert('Моля, въведете API ключ първо');
523 + return;
524 + }
525 +
526 + button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> ' + aiseom_ajax.strings.checking);
527 +
528 + $.ajax({
529 + url: aiseom_ajax.ajax_url,
530 + type: 'POST',
531 + data: {
532 + action: 'aiseom_check_api',
533 + nonce: aiseom_ajax.nonce,
534 + api_key: apiKey,
535 + api_provider: provider
536 + },
537 + success: function(response) {
538 + button.prop('disabled', false).html('<i class="fas fa-wifi"></i> Тествай API ключа');
539 +
540 + if (response.success) {
541 + $('#api-test-result').html(
542 + '<div class="api-test-result api-test-success">' +
543 + '<i class="fas fa-check-circle"></i> ' + response.data.message +
544 + '</div>'
545 + );
546 + } else {
547 + $('#api-test-result').html(
548 + '<div class="api-test-result api-test-error">' +
549 + '<i class="fas fa-exclamation-circle"></i> ' + response.data +
550 + '</div>'
551 + );
552 + }
553 + },
554 + error: function() {
555 + button.prop('disabled', false).html('<i class="fas fa-wifi"></i> Тествай API ключа');
556 + alert('Грешка при проверката на API');
557 + }
558 + });
559 + });
560 +
561 + // Масово генериране на мета описания
562 + $(document).on('click', '#generate-all-meta', function() {
563 + if (!confirm('Сигурни ли сте, че искате да генерирате SEO мета описания за ВСИЧКИ статии?')) {
564 + return;
565 + }
566 +
567 + var button = $(this);
568 + button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Започва обработка...');
569 +
570 + $('#bulk-progress').show();
571 + startBulkProcess('meta', 0, 0);
572 + });
573 +
574 + // Масово генериране на ALT тагове
575 + $(document).on('click', '#generate-all-alt', function() {
576 + if (!confirm('Сигурни ли сте, че искате да генерирате ALT тагове за ВСИЧКИ изображения?')) {
577 + return;
578 + }
579 +
580 + var button = $(this);
581 + button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Започва обработка...');
582 +
583 + $('#bulk-progress').show();
584 + startBulkProcess('alt', 0, 0);
585 + });
586 +
587 + // Функция за масово обработване
588 + function startBulkProcess(type, offset, totalProcessed) {
589 + $.ajax({
590 + url: aiseom_ajax.ajax_url,
591 + type: 'POST',
592 + data: {
593 + action: 'aiseom_bulk_process',
594 + nonce: aiseom_ajax.nonce,
595 + type: type,
596 + offset: offset
597 + },
598 + success: function(response) {
599 + if (response.success) {
600 + var data = response.data;
601 + totalProcessed += data.processed;
602 +
603 + // Актуализиране на прогрес бара
604 + var percentage = Math.min(((offset + 5) / 100) * 100, 100);
605 + $('.progress-fill').css('width', percentage + '%');
606 + $('.progress-text').text('Обработени: ' + totalProcessed + ' елемента');
607 +
608 + if (data.has_more) {
609 + setTimeout(function() {
610 + startBulkProcess(type, offset + 5, totalProcessed);
611 + }, 1000);
612 + } else {
613 + alert('Завършено! Обработени общо ' + totalProcessed + ' елемента.');
614 + $('#generate-all-meta, #generate-all-alt').prop('disabled', false).html(function() {
615 + return type === 'meta' ?
616 + '<i class="fas fa-magic"></i> Генерирай SEO за всички статии' :
617 + '<i class="fas fa-image"></i> Генерирай ALT за всички изображения';
618 + });
619 + $('#bulk-progress').hide();
620 + location.reload();
621 + }
622 + }
623 + },
624 + error: function() {
625 + alert('Грешка при обработката');
626 + $('#generate-all-meta, #generate-all-alt').prop('disabled', false).html(function() {
627 + return type === 'meta' ?
628 + '<i class="fas fa-magic"></i> Генерирай SEO за всички статии' :
629 + '<i class="fas fa-image"></i> Генерирай ALT за всички изображения';
630 + });
631 + $('#bulk-progress').hide();
632 + }
633 + });
634 + }
635 +
636 + // Превключване на API описания
637 + $('#aiseom_api_provider').on('change', function() {
638 + var provider = $(this).val();
639 +
640 + // Скриваме всички описания
641 + $('.api-description').hide();
642 +
643 + // Показваме само избраното
644 + $('#api-desc-' + provider).show();
645 +
646 + // Ако е демо, скриваме полето за API ключ
647 + if (provider === 'demo') {
648 + $('#api-key-row').hide();
649 + } else {
650 + $('#api-key-row').show();
651 + }
652 + });
653 +
654 + // Инициализация при зареждане
655 + $('#aiseom_api_provider').trigger('change');
656 +
657 + // Зареждане на статистика
658 + function loadStats() {
659 + $.ajax({
660 + url: aiseom_ajax.ajax_url,
661 + type: 'POST',
662 + data: {
663 + action: 'aiseom_get_stats',
664 + nonce: aiseom_ajax.nonce
665 + },
666 + success: function(response) {
667 + if (response.success) {
668 + var stats = response.data;
669 +
670 + if ($('#total-posts').length) {
671 + $('#total-posts').text(stats.total_posts);
672 + }
673 + if ($('#posts-with-meta').length) {
674 + $('#posts-with-meta').text(stats.posts_with_meta);
675 + }
676 + if ($('#total-images').length) {
677 + $('#total-images').text(stats.total_images);
678 + }
679 + if ($('#images-with-alt').length) {
680 + $('#images-with-alt').text(stats.images_with_alt);
681 + }
682 + }
683 + }
684 + });
685 + }
686 +
687 + // Зареждаме статистиката ако сме на dashboard
688 + if ($('#total-posts').length) {
689 + loadStats();
690 + }
691 + });
692 + </script>
693 + <?php
694 + }
695 +
696 + public function add_seo_metabox() {
697 + $post_types = get_option('aiseom_post_types', ['post', 'page']);
698 +
699 + foreach ($post_types as $post_type) {
700 + add_meta_box(
701 + 'aiseom_seo_status',
702 + '🔍 SEO Статус & Генериране',
703 + [$this, 'render_seo_metabox'],
704 + $post_type,
705 + 'side',
706 + 'high'
707 + );
708 + }
709 + }
710 +
711 + public function render_seo_metabox($post) {
712 + $post_id = $post->ID;
713 + $meta_status = $this->get_post_meta_status($post_id);
714 + $alt_status = $this->get_post_alt_status($post_id);
715 + ?>
716 + <div class="aiseom-metabox">
717 + <!-- SEO Мета Статус -->
718 + <div class="aiseom-metabox-section">
719 + <h4>📝 SEO Мета описание:</h4>
720 + <div class="status-indicator <?php echo $meta_status['has_meta'] ? 'status-success' : 'status-error'; ?>">
721 + <?php if ($meta_status['has_meta']): ?>
722 + <span class="status-icon">✓</span>
723 + <span class="status-text">Има генерирано (<?php echo $meta_status['length']; ?> знака)</span>
724 + <?php else: ?>
725 + <span class="status-icon">✗</span>
726 + <span class="status-text">Няма генерирано</span>
727 + <?php endif; ?>
728 + </div>
729 +
730 + <div style="margin-top: 10px;">
731 + <button type="button" class="button button-primary aiseom-generate-meta" data-post-id="<?php echo $post_id; ?>" style="width: 100%;">
732 + <i class="fas fa-magic"></i> <?php echo $meta_status['has_meta'] ? 'Регенерирай SEO' : 'Генерирай SEO'; ?>
733 + </button>
734 + </div>
735 + </div>
736 +
737 + <!-- ALT Тагове Статус -->
738 + <div class="aiseom-metabox-section">
739 + <h4>🖼️ ALT Тагове за изображения:</h4>
740 + <div class="status-indicator <?php echo $alt_status['all_have_alt'] ? 'status-success' : ($alt_status['has_images'] ? 'status-warning' : 'status-neutral'); ?>">
741 + <?php if (!$alt_status['has_images']): ?>
742 + <span class="status-icon">➖</span>
743 + <span class="status-text">Няма изображения</span>
744 + <?php elseif ($alt_status['all_have_alt']): ?>
745 + <span class="status-icon">✓</span>
746 + <span class="status-text">Всички имат ALT (<?php echo $alt_status['total_images']; ?>)</span>
747 + <?php else: ?>
748 + <span class="status-icon">⚠</span>
749 + <span class="status-text"><?php echo $alt_status['images_without_alt']; ?> без ALT от <?php echo $alt_status['total_images']; ?></span>
750 + <?php endif; ?>
751 + </div>
752 +
753 + <?php if ($alt_status['has_images'] && !$alt_status['all_have_alt']): ?>
754 + <div style="margin-top: 10px;">
755 + <button type="button" class="button button-primary aiseom-generate-alt" data-post-id="<?php echo $post_id; ?>" style="width: 100%;">
756 + <i class="fas fa-image"></i> Генерирай ALT
757 + </button>
758 + </div>
759 + <?php endif; ?>
760 + </div>
761 +
762 + <!-- API Статус -->
763 + <div class="aiseom-metabox-section">
764 + <h4>🤖 API Статус:</h4>
765 + <?php $api_status = $this->check_api_status(); ?>
766 + <div class="status-indicator <?php echo $api_status['valid'] ? 'status-success' : 'status-error'; ?>">
767 + <?php if ($api_status['valid']): ?>
768 + <span class="status-icon">✓</span>
769 + <span class="status-text">API ключът е валиден</span>
770 + <?php else: ?>
771 + <span class="status-icon">✗</span>
772 + <span class="status-text"><?php echo $api_status['error']; ?></span>
773 + <?php endif; ?>
774 + </div>
775 + </div>
776 + </div>
777 + <?php
778 + }
779 +
780 + public function register_settings() {
781 + register_setting('aiseom_settings', 'aiseom_api_key');
782 + register_setting('aiseom_settings', 'aiseom_api_provider');
783 + register_setting('aiseom_settings', 'aiseom_language');
784 + register_setting('aiseom_settings', 'aiseom_auto_generate');
785 + register_setting('aiseom_settings', 'aiseom_auto_generate_alt');
786 + register_setting('aiseom_settings', 'aiseom_post_types');
787 + }
788 +
789 + // AJAX обработчици
790 +
791 + public function ajax_generate_meta() {
792 + check_ajax_referer('aiseom_nonce', 'nonce');
793 +
794 + if (!current_user_can('edit_posts')) {
795 + wp_send_json_error('Нямате разрешение');
796 + }
797 +
798 + $post_id = intval($_POST['post_id']);
799 + $post = get_post($post_id);
800 +
801 + if (!$post) {
802 + wp_send_json_error('Статията не е намерена');
803 + }
804 +
805 + $result = $this->generate_meta_description($post);
806 +
807 + if ($result['success']) {
808 + update_post_meta($post_id, '_aiseom_meta_description', $result['meta']);
809 + update_post_meta($post_id, '_aiseom_meta_generated', current_time('mysql'));
810 +
811 + wp_send_json_success([
812 + 'message' => 'Мета описанието е генерирано успешно',
813 + 'meta' => $result['meta'],
814 + 'length' => strlen($result['meta'])
815 + ]);
816 + } else {
817 + wp_send_json_error($result['error']);
818 + }
819 + }
820 +
821 + public function ajax_generate_alt() {
822 + check_ajax_referer('aiseom_nonce', 'nonce');
823 +
824 + if (!current_user_can('edit_posts')) {
825 + wp_send_json_error('Нямате разрешение');
826 + }
827 +
828 + $post_id = intval($_POST['post_id']);
829 + $images = $this->get_post_images($post_id);
830 + $generated_count = 0;
831 + $errors = [];
832 +
833 + foreach ($images as $image_id) {
834 + $alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
835 +
836 + // Генерираме ALT само ако няма такъв
837 + if (empty($alt)) {
838 + $result = $this->generate_image_alt($image_id);
839 +
840 + if ($result['success']) {
841 + update_post_meta($image_id, '_wp_attachment_image_alt', $result['alt']);
842 + $generated_count++;
843 + } else {
844 + $errors[] = $result['error'];
845 + }
846 + }
847 + }
848 +
849 + if ($generated_count > 0) {
850 + wp_send_json_success([
851 + 'message' => 'Генерирани са ' . $generated_count . ' ALT тага',
852 + 'count' => $generated_count,
853 + 'errors' => $errors
854 + ]);
855 + } else {
856 + wp_send_json_error('Няма изображения без ALT тагове или възникна грешка');
857 + }
858 + }
859 +
860 + public function ajax_check_api() {
861 + check_ajax_referer('aiseom_nonce', 'nonce');
862 +
863 + if (!current_user_can('manage_options')) {
864 + wp_send_json_error('Нямате разрешение');
865 + }
866 +
867 + $api_key = sanitize_text_field($_POST['api_key']);
868 + $api_provider = sanitize_text_field($_POST['api_provider']);
869 +
870 + if (empty($api_key)) {
871 + wp_send_json_error('Моля, въведете API ключ');
872 + }
873 +
874 + $result = $this->test_api_key($api_key, $api_provider);
875 +
876 + if ($result['success']) {
877 + wp_send_json_success([
878 + 'message' => '✅ API ключът е валиден!',
879 + 'provider' => $api_provider,
880 + 'test_response' => $result['test_response']
881 + ]);
882 + } else {
883 + wp_send_json_error('❌ API ключът не е валиден: ' . $result['error']);
884 + }
885 + }
886 +
887 + public function ajax_bulk_process() {
888 + check_ajax_referer('aiseom_nonce', 'nonce');
889 +
890 + if (!current_user_can('manage_options')) {
891 + wp_send_json_error('Нямате разрешение');
892 + }
893 +
894 + $type = sanitize_text_field($_POST['type']);
895 + $offset = intval($_POST['offset']);
896 + $limit = 5;
897 +
898 + $processed = 0;
899 +
900 + if ($type === 'meta') {
901 + $posts = get_posts([
902 + 'post_type' => 'post',
903 + 'post_status' => 'publish',
904 + 'numberposts' => $limit,
905 + 'offset' => $offset
906 + ]);
907 +
908 + foreach ($posts as $post) {
909 + if (!get_post_meta($post->ID, '_aiseom_meta_description', true)) {
910 + $result = $this->generate_meta_description($post);
911 + if ($result['success']) {
912 + update_post_meta($post->ID, '_aiseom_meta_description', $result['meta']);
913 + $processed++;
914 + }
915 + }
916 + }
917 + } elseif ($type === 'alt') {
918 + $images = get_posts([
919 + 'post_type' => 'attachment',
920 + 'post_mime_type' => 'image',
921 + 'numberposts' => $limit,
922 + 'offset' => $offset
923 + ]);
924 +
925 + foreach ($images as $image) {
926 + if (!get_post_meta($image->ID, '_wp_attachment_image_alt', true)) {
927 + $result = $this->generate_image_alt($image->ID);
928 + if ($result['success']) {
929 + update_post_meta($image->ID, '_wp_attachment_image_alt', $result['alt']);
930 + $processed++;
931 + }
932 + }
933 + }
934 + }
935 +
936 + $total = $type === 'meta' ? wp_count_posts('post')->publish : $this->count_total_images();
937 + $has_more = ($offset + $limit) < $total;
938 +
939 + wp_send_json_success([
940 + 'processed' => $processed,
941 + 'has_more' => $has_more
942 + ]);
943 + }
944 +
945 + public function ajax_get_stats() {
946 + wp_send_json_success([
947 + 'total_posts' => $this->count_total_posts(),
948 + 'posts_with_meta' => $this->count_posts_with_meta(),
949 + 'total_images' => $this->count_total_images(),
950 + 'images_with_alt' => $this->count_images_with_alt()
951 + ]);
952 + }
953 +
954 + // Помощни функции
955 +
956 + private function generate_meta_description($post) {
957 + $content = wp_strip_all_tags($post->post_content);
958 + $title = $post->post_title;
959 +
960 + if (strlen($content) > 1500) {
961 + $content = substr($content, 0, 1500) . '...';
962 + }
963 +
964 + $api_key = get_option('aiseom_api_key');
965 + $api_provider = get_option('aiseom_api_provider', 'demo');
966 + $language = get_option('aiseom_language', 'bg');
967 +
968 + // Ако няма API ключ или е демо режим, използваме демо съдържание
969 + if (empty($api_key) || $api_provider === 'demo') {
970 + return $this->generate_demo_content('meta', $language, $title);
971 + }
972 +
973 + // Тук бихме извикали реално API
974 + // За сега връщаме демо съдържание
975 + return $this->generate_demo_content('meta', $language, $title);
976 + }
977 +
978 + private function generate_image_alt($image_id) {
979 + $image_title = get_the_title($image_id);
980 + $language = get_option('aiseom_language', 'bg');
981 +
982 + $api_key = get_option('aiseom_api_key');
983 + $api_provider = get_option('aiseom_api_provider', 'demo');
984 +
985 + // Ако няма API ключ или е демо режим, използваме демо съдържание
986 + if (empty($api_key) || $api_provider === 'demo') {
987 + return $this->generate_demo_content('alt', $language, $image_title);
988 + }
989 +
990 + // Тук бихме извикали реално API
991 + // За сега връщаме демо съдържание
992 + return $this->generate_demo_content('alt', $language, $image_title);
993 + }
994 +
995 + private function generate_demo_content($type, $language, $context = '') {
996 + if ($type === 'meta') {
997 + if ($language === 'bg') {
998 + $responses = [
999 + 'Професионален наръчник с изчерпателна информация и практични съвети за успешно прилагане на методите.',
1000 + 'Научете всичко необходимо за темата от нашите експерти с годишен опит в областта и практическо приложение.',
1001 + 'Подробен анализ и стъпково ръководство за постигане на оптимални резултати с минимални усилия и време.',
1002 + 'Актуална информация и доказани техники за подобряване на ефективността и продуктивността в ежедневната работа.',
1003 + 'Комплексно ръководство със стратегии и тактики за успешно надграждане на уменията и постигане на целите.'
1004 + ];
1005 + } else {
1006 + $responses = [
1007 + 'Professional guide with comprehensive information and practical tips for successful application of methods.',
1008 + 'Learn everything you need about the topic from our experts with years of experience in the field.',
1009 + 'Detailed analysis and step-by-step guide to achieving optimal results with minimal effort and time.',
1010 + 'Current information and proven techniques for improving efficiency and productivity in daily work.',
1011 + 'Comprehensive guide with strategies and tactics for successful skill building and goal achievement.'
1012 + ];
1013 + }
1014 + } else { // ALT
1015 + if ($language === 'bg') {
1016 + $responses = [
1017 + 'Илюстрация демонстрираща ключови аспекти и важни детайли от обсъжданата тема ' . $context,
1018 + 'Визуално представяне на концепции и идеи свързани с ' . $context,
1019 + 'Качествено изображение илюстриращо практически приложения на ' . $context,
1020 + 'Информативна графика показваща аспекти от ' . $context,
1021 + 'Професионална фотография свързана с темата ' . $context
1022 + ];
1023 + } else {
1024 + $responses = [
1025 + 'Illustration demonstrating key aspects and important details of ' . $context,
1026 + 'Visual representation of concepts and ideas related to ' . $context,
1027 + 'High quality image illustrating practical applications of ' . $context,
1028 + 'Informative graphic showing aspects of ' . $context,
1029 + 'Professional photography related to the topic of ' . $context
1030 + ];
1031 + }
1032 + }
1033 +
1034 + $text = $responses[array_rand($responses)];
1035 +
1036 + return [
1037 + 'success' => true,
1038 + 'meta' => $type === 'meta' ? $text : null,
1039 + 'alt' => $type === 'alt' ? $text : null
1040 + ];
1041 + }
1042 +
1043 + private function test_api_key($api_key, $provider) {
1044 + // Това е опростена проверка
1045 + // На практика бихме изпратили тестова заявка към API-то
1046 +
1047 + if (empty($api_key)) {
1048 + return [
1049 + 'success' => false,
1050 + 'error' => 'API ключът е празен'
1051 + ];
1052 + }
1053 +
1054 + if (strlen($api_key) < 10) {
1055 + return [
1056 + 'success' => false,
1057 + 'error' => 'API ключът е твърде кратък'
1058 + ];
1059 + }
1060 +
1061 + // Симулираме успешна проверка
1062 + // На практика тук бихме изпратили заявка към Hugging Face или друг API
1063 + return [
1064 + 'success' => true,
1065 + 'test_response' => 'Тестовата заявка е успешна. API ключът работи.'
1066 + ];
1067 + }
1068 +
1069 + private function check_api_status() {
1070 + $api_key = get_option('aiseom_api_key');
1071 +
1072 + if (empty($api_key)) {
1073 + return [
1074 + 'valid' => false,
1075 + 'error' => 'API ключът не е настроен'
1076 + ];
1077 + }
1078 +
1079 + return [
1080 + 'valid' => true,
1081 + 'error' => ''
1082 + ];
1083 + }
1084 +
1085 + private function get_post_meta_status($post_id) {
1086 + $meta = get_post_meta($post_id, '_aiseom_meta_description', true);
1087 +
1088 + return [
1089 + 'has_meta' => !empty($meta),
1090 + 'length' => strlen($meta),
1091 + 'preview' => $meta ? substr($meta, 0, 80) . '...' : ''
1092 + ];
1093 + }
1094 +
1095 + private function get_post_alt_status($post_id) {
1096 + $images = $this->get_post_images($post_id);
1097 + $total_images = count($images);
1098 + $images_without_alt = 0;
1099 +
1100 + foreach ($images as $image_id) {
1101 + $alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
1102 + if (empty($alt)) {
1103 + $images_without_alt++;
1104 + }
1105 + }
1106 +
1107 + return [
1108 + 'has_images' => $total_images > 0,
1109 + 'total_images' => $total_images,
1110 + 'images_without_alt' => $images_without_alt,
1111 + 'all_have_alt' => $total_images > 0 && $images_without_alt === 0
1112 + ];
1113 + }
1114 +
1115 + private function get_post_images($post_id) {
1116 + $content = get_post_field('post_content', $post_id);
1117 + $images = [];
1118 +
1119 + preg_match_all('/<img[^>]+>/i', $content, $img_tags);
1120 +
1121 + foreach ($img_tags[0] as $img_tag) {
1122 + if (preg_match('/src="([^"]+)"/i', $img_tag, $src_match)) {
1123 + $image_url = $src_match[1];
1124 + $attachment_id = attachment_url_to_postid($image_url);
1125 +
1126 + if ($attachment_id) {
1127 + $images[] = $attachment_id;
1128 + }
1129 + }
1130 + }
1131 +
1132 + return $images;
1133 + }
1134 +
1135 + private function count_total_posts() {
1136 + return wp_count_posts('post')->publish;
1137 + }
1138 +
1139 + private function count_posts_with_meta() {
1140 + global $wpdb;
1141 + return $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_aiseom_meta_description'");
1142 + }
1143 +
1144 + private function count_total_images() {
1145 + return wp_count_posts('attachment')->inherit;
1146 + }
1147 +
1148 + private function count_images_with_alt() {
1149 + global $wpdb;
1150 + return $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attachment_image_alt' AND meta_value != ''");
1151 + }
1152 +
1153 + // Рендериране на страници
1154 +
1155 + public function render_dashboard() {
1156 + ?>
1157 + <div class="wrap aiseom-dashboard">
1158 + <div class="aiseom-header">
1159 + <h1><i class="fas fa-robot"></i> AI SEO Master PRO</h1>
1160 + <p>Вашият професионален помощник за SEO оптимизация с изкуствен интелект</p>
1161 + </div>
1162 +
1163 + <div class="aiseom-stats-grid">
1164 + <div class="aiseom-stat-card">
1165 + <div class="stat-icon">
1166 + <i class="fas fa-file-alt"></i>
1167 + </div>
1168 + <div class="stat-content">
1169 + <span class="stat-number" id="total-posts">0</span>
1170 + <span class="stat-label">Общо статии</span>
1171 + </div>
1172 + </div>
1173 +
1174 + <div class="aiseom-stat-card">
1175 + <div class="stat-icon">
1176 + <i class="fas fa-check-circle"></i>
1177 + </div>
1178 + <div class="stat-content">
1179 + <span class="stat-number" id="posts-with-meta">0</span>
1180 + <span class="stat-label">С SEO мета</span>
1181 + </div>
1182 + </div>
1183 +
1184 + <div class="aiseom-stat-card">
1185 + <div class="stat-icon">
1186 + <i class="fas fa-image"></i>
1187 + </div>
1188 + <div class="stat-content">
1189 + <span class="stat-number" id="total-images">0</span>
1190 + <span class="stat-label">Общо изображения</span>
1191 + </div>
1192 + </div>
1193 +
1194 + <div class="aiseom-stat-card">
1195 + <div class="stat-icon">
1196 + <i class="fas fa-tag"></i>
1197 + </div>
1198 + <div class="stat-content">
1199 + <span class="stat-number" id="images-with-alt">0</span>
1200 + <span class="stat-label">С ALT тагове</span>
1201 + </div>
1202 + </div>
1203 + </div>
1204 +
1205 + <div class="aiseom-actions-grid">
1206 + <div class="aiseom-action-card">
1207 + <h3><i class="fas fa-bolt"></i> Бързи действия</h3>
1208 + <p>Автоматично генериране на SEO съдържание</p>
1209 +
1210 + <div style="display: flex; flex-direction: column; gap: 10px; margin-top: 20px;">
1211 + <button id="generate-all-meta" class="aiseom-btn">
1212 + <i class="fas fa-magic"></i> Генерирай SEO за всички статии
1213 + </button>
1214 +
1215 + <button id="generate-all-alt" class="aiseom-btn aiseom-btn-secondary">
1216 + <i class="fas fa-image"></i> Генерирай ALT за всички изображения
1217 + </button>
1218 + </div>
1219 +
1220 + <div id="bulk-progress" class="progress-container">
1221 + <div class="progress-bar">
1222 + <div class="progress-fill"></div>
1223 + </div>
1224 + <p class="progress-text"></p>
1225 + </div>
1226 + </div>
1227 +
1228 + <div class="aiseom-action-card">
1229 + <h3><i class="fas fa-chart-pie"></i> SEO Статистика</h3>
1230 + <p>Преглед на SEO оптимизацията на вашия сайт</p>
1231 +
1232 + <div style="margin-top: 20px;">
1233 + <table class="aiseom-table">
1234 + <tr>
1235 + <td>Статии без SEO мета:</td>
1236 + <td><strong><?php echo $this->count_total_posts() - $this->count_posts_with_meta(); ?></strong></td>
1237 + </tr>
1238 + <tr>
1239 + <td>Изображения без ALT:</td>
1240 + <td><strong><?php echo $this->count_total_images() - $this->count_images_with_alt(); ?></strong></td>
1241 + </tr>
1242 + <tr>
1243 + <td>API Статус:</td>
1244 + <td>
1245 + <?php $api_status = $this->check_api_status(); ?>
1246 + <span style="color: <?php echo $api_status['valid'] ? '#4CAF50' : '#f44336'; ?>;">
1247 + <?php echo $api_status['valid'] ? '✅ Активен' : '❌ Неактивен'; ?>
1248 + </span>
1249 + </td>
1250 + </tr>
1251 + </table>
1252 + </div>
1253 + </div>
1254 + </div>
1255 +
1256 + <div class="aiseom-action-card">
1257 + <h3><i class="fas fa-lightbulb"></i> Съвети за SEO</h3>
1258 + <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; margin-top: 15px;">
1259 + <div style="padding: 15px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #4CAF50;">
1260 + <strong>✅ Генерирайте уникални мета описания</strong>
1261 + <p style="margin: 5px 0 0; font-size: 14px; color: #666;">Всяка страница трябва да има уникално SEO описание.</p>
1262 + </div>
1263 +
1264 + <div style="padding: 15px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #2196F3;">
1265 + <strong>✅ Добавете ALT текст към изображенията</strong>
1266 + <p style="margin: 5px 0 0; font-size: 14px; color: #666;">ALT таговете подобряват SEO и достъпността.</p>
1267 + </div>
1268 +
1269 + <div style="padding: 15px; background: #f8f9fa; border-radius: 8px; border-left: 4px solid #FF9800;">
1270 + <strong>✅ Използвайте ключови думи</strong>
1271 + <p style="margin: 5px 0 0; font-size: 14px; color: #666;">Включете ключови думи в заглавията и съдържанието.</p>
1272 + </div>
1273 + </div>
1274 + </div>
1275 + </div>
1276 + <?php
1277 + }
1278 +
1279 + public function render_unoptimized_posts() {
1280 + $posts = get_posts([
1281 + 'post_type' => 'post',
1282 + 'post_status' => 'publish',
1283 + 'numberposts' => -1
1284 + ]);
1285 +
1286 + $posts_without_meta = [];
1287 + $posts_without_alt = [];
1288 +
1289 + foreach ($posts as $post) {
1290 + $has_meta = get_post_meta($post->ID, '_aiseom_meta_description', true);
1291 + $images = $this->get_post_images($post->ID);
1292 + $has_all_alt = true;
1293 +
1294 + foreach ($images as $image_id) {
1295 + $alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
1296 + if (empty($alt)) {
1297 + $has_all_alt = false;
1298 + break;
1299 + }
1300 + }
1301 +
1302 + if (!$has_meta) {
1303 + $posts_without_meta[] = $post;
1304 + }
1305 +
1306 + if ($images && !$has_all_alt) {
1307 + $posts_without_alt[] = $post;
1308 + }
1309 + }
1310 + ?>
1311 + <div class="wrap" style="padding: 20px;">
1312 + <h1><i class="fas fa-exclamation-triangle"></i> Статии без SEO оптимизация</h1>
1313 +
1314 + <div class="aiseom-stats-grid" style="margin: 30px 0;">
1315 + <div class="aiseom-stat-card">
1316 + <div class="stat-icon" style="background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);">
1317 + <i class="fas fa-file-alt"></i>
1318 + </div>
1319 + <div class="stat-content">
1320 + <span class="stat-number"><?php echo count($posts_without_meta); ?></span>
1321 + <span class="stat-label">Статии без SEO мета</span>
1322 + </div>
1323 + </div>
1324 +
1325 + <div class="aiseom-stat-card">
1326 + <div class="stat-icon" style="background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);">
1327 + <i class="fas fa-image"></i>
1328 + </div>
1329 + <div class="stat-content">
1330 + <span class="stat-number"><?php echo count($posts_without_alt); ?></span>
1331 + <span class="stat-label">Статии без ALT тагове</span>
1332 + </div>
1333 + </div>
1334 + </div>
1335 +
1336 + <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-top: 30px;">
1337 + <div class="aiseom-action-card">
1338 + <h3><i class="fas fa-file-alt"></i> Статии без SEO мета (<?php echo count($posts_without_meta); ?>)</h3>
1339 +
1340 + <?php if (empty($posts_without_meta)): ?>
1341 + <div style="text-align: center; padding: 40px; color: #4CAF50;">
1342 + <i class="fas fa-check-circle" style="font-size: 48px;"></i>
1343 + <h3>Всички статии имат SEO мета описания!</h3>
1344 + </div>
1345 + <?php else: ?>
1346 + <div style="max-height: 400px; overflow-y: auto; margin-top: 20px;">
1347 + <table class="aiseom-table">
1348 + <thead>
1349 + <tr>
1350 + <th>Заглавие</th>
1351 + <th>Дата</th>
1352 + <th>Действие</th>
1353 + </tr>
1354 + </thead>
1355 + <tbody>
1356 + <?php foreach ($posts_without_meta as $post): ?>
1357 + <tr>
1358 + <td>
1359 + <strong><?php echo esc_html($post->post_title); ?></strong>
1360 + <div style="font-size: 12px; color: #666;">ID: <?php echo $post->ID; ?></div>
1361 + </td>
1362 + <td><?php echo get_the_date('d.m.Y', $post->ID); ?></td>
1363 + <td>
1364 + <button class="button button-primary aiseom-generate-meta" data-post-id="<?php echo $post->ID; ?>" style="font-size: 12px; padding: 5px 10px;">
1365 + <i class="fas fa-magic"></i> Генерирай
1366 + </button>
1367 + </td>
1368 + </tr>
1369 + <?php endforeach; ?>
1370 + </tbody>
1371 + </table>
1372 + </div>
1373 +
1374 + <div style="text-align: center; margin-top: 20px;">
1375 + <button id="generate-all-meta-list" class="button button-primary button-large" data-count="<?php echo count($posts_without_meta); ?>">
1376 + <i class="fas fa-bolt"></i> Генерирай SEO за всички <?php echo count($posts_without_meta); ?> статии
1377 + </button>
1378 + </div>
1379 + <?php endif; ?>
1380 + </div>
1381 +
1382 + <div class="aiseom-action-card">
1383 + <h3><i class="fas fa-image"></i> Статии без ALT тагове (<?php echo count($posts_without_alt); ?>)</h3>
1384 +
1385 + <?php if (empty($posts_without_alt)): ?>
1386 + <div style="text-align: center; padding: 40px; color: #4CAF50;">
1387 + <i class="fas fa-check-circle" style="font-size: 48px;"></i>
1388 + <h3>Всички статии имат ALT тагове!</h3>
1389 + </div>
1390 + <?php else: ?>
1391 + <div style="max-height: 400px; overflow-y: auto; margin-top: 20px;">
1392 + <table class="aiseom-table">
1393 + <thead>
1394 + <tr>
1395 + <th>Заглавие</th>
1396 + <th>Изображения</th>
1397 + <th>Действие</th>
1398 + </tr>
1399 + </thead>
1400 + <tbody>
1401 + <?php foreach ($posts_without_alt as $post):
1402 + $images = $this->get_post_images($post->ID);
1403 + $images_without_alt = 0;
1404 + foreach ($images as $image_id) {
1405 + $alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);
1406 + if (empty($alt)) {
1407 + $images_without_alt++;
1408 + }
1409 + }
1410 + ?>
1411 + <tr>
1412 + <td>
1413 + <strong><?php echo esc_html($post->post_title); ?></strong>
1414 + <div style="font-size: 12px; color: #666;">ID: <?php echo $post->ID; ?></div>
1415 + </td>
1416 + <td>
1417 + <span style="color: <?php echo $images_without_alt > 0 ? '#f44336' : '#4CAF50'; ?>;">
1418 + <?php echo $images_without_alt; ?> без ALT
1419 + </span>
1420 + </td>
1421 + <td>
1422 + <button class="button button-primary aiseom-generate-alt" data-post-id="<?php echo $post->ID; ?>" style="font-size: 12px; padding: 5px 10px;">
1423 + <i class="fas fa-image"></i> Генерирай
1424 + </button>
1425 + </td>
1426 + </tr>
1427 + <?php endforeach; ?>
1428 + </tbody>
1429 + </table>
1430 + </div>
1431 +
1432 + <div style="text-align: center; margin-top: 20px;">
1433 + <button id="generate-all-alt-list" class="button button-primary button-large" data-count="<?php echo count($posts_without_alt); ?>">
1434 + <i class="fas fa-bolt"></i> Генерирай ALT за всички <?php echo count($posts_without_alt); ?> статии
1435 + </button>
1436 + </div>
1437 + <?php endif; ?>
1438 + </div>
1439 + </div>
1440 +
1441 + <script>
1442 + jQuery(document).ready(function($) {
1443 + // Генериране на всички статии без SEO мета от листа
1444 + $('#generate-all-meta-list').on('click', function() {
1445 + var count = $(this).data('count');
1446 + if (!confirm('Сигурни ли сте, че искате да генерирате SEO мета описания за ВСИЧКИ ' + count + ' статии?')) {
1447 + return;
1448 + }
1449 +
1450 + $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Обработване...');
1451 +
1452 + // Намираме всички бутони за генериране и кликаме на всеки един
1453 + var buttons = $('.aiseom-generate-meta');
1454 + var total = buttons.length;
1455 + var processed = 0;
1456 +
1457 + function processNext(index) {
1458 + if (index >= total) {
1459 + alert('Готово! Обработени ' + total + ' статии.');
1460 + location.reload();
1461 + return;
1462 + }
1463 +
1464 + buttons.eq(index).click();
1465 +
1466 + // Почакаме малко преди следващия
1467 + setTimeout(function() {
1468 + processNext(index + 1);
1469 + }, 2000);
1470 + }
1471 +
1472 + processNext(0);
1473 + });
1474 +
1475 + // Генериране на всички статии без ALT от листа
1476 + $('#generate-all-alt-list').on('click', function() {
1477 + var count = $(this).data('count');
1478 + if (!confirm('Сигурни ли сте, че искате да генерирате ALT тагове за ВСИЧКИ ' + count + ' статии?')) {
1479 + return;
1480 + }
1481 +
1482 + $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Обработване...');
1483 +
1484 + // Намираме всички бутони за генериране и кликаме на всеки един
1485 + var buttons = $('.aiseom-generate-alt');
1486 + var total = buttons.length;
1487 + var processed = 0;
1488 +
1489 + function processNext(index) {
1490 + if (index >= total) {
1491 + alert('Готово! Обработени ' + total + ' статии.');
1492 + location.reload();
1493 + return;
1494 + }
1495 +
1496 + buttons.eq(index).click();
1497 +
1498 + // Почакаме малко преди следващия
1499 + setTimeout(function() {
1500 + processNext(index + 1);
1501 + }, 2000);
1502 + }
1503 +
1504 + processNext(0);
1505 + });
1506 + });
1507 + </script>
1508 + </div>
1509 + <?php
1510 + }
1511 +
1512 + public function render_settings_page() {
1513 + ?>
1514 + <div class="wrap" style="padding: 20px;">
1515 + <h1><i class="fas fa-cog"></i> Настройки на AI SEO Master PRO</h1>
1516 +
1517 + <div class="aiseom-settings-form">
1518 + <form method="post" action="options.php">
1519 + <?php settings_fields('aiseom_settings'); ?>
1520 +
1521 + <div class="form-group">
1522 + <label for="aiseom_api_provider">AI Доставчик:</label>
1523 + <select name="aiseom_api_provider" id="aiseom_api_provider" class="regular-text">
1524 + <option value="demo" <?php selected(get_option('aiseom_api_provider', 'demo'), 'demo'); ?>>🎮 Демо режим (безплатен - за тестване)</option>
1525 + <option value="huggingface" <?php selected(get_option('aiseom_api_provider'), 'huggingface'); ?>>🤗 Hugging Face (безплатен API)</option>
1526 + <option value="openai" <?php selected(get_option('aiseom_api_provider'), 'openai'); ?>>🤖 OpenAI GPT (платен)</option>
1527 + </select>
1528 +
1529 + <div id="api-desc-demo" class="api-description" style="display: none; margin-top: 8px; padding: 10px; background: #f8f9fa; border-radius: 5px;">
1530 + <p><strong>🎮 Демо режим:</strong> Работи без API ключ. Генерира примерни описания за тестване.</p>
1531 + </div>
1532 +
1533 + <div id="api-desc-huggingface" class="api-description" style="display: none; margin-top: 8px; padding: 10px; background: #f8f9fa; border-radius: 5px;">
1534 + <p><strong>🤗 Hugging Face:</strong> Безплатен AI API. <a href="https://huggingface.co/settings/tokens" target="_blank">Получете безплатен ключ тук</a></p>
1535 + </div>
1536 +
1537 + <div id="api-desc-openai" class="api-description" style="display: none; margin-top: 8px; padding: 10px; background: #f8f9fa; border-radius: 5px;">
1538 + <p><strong>🤖 OpenAI:</strong> Платен API. <a href="https://platform.openai.com/api-keys" target="_blank">Получете API ключ тук</a></p>
1539 + </div>
1540 + </div>
1541 +
1542 + <div class="form-group" id="api-key-row">
1543 + <label for="aiseom_api_key">API Ключ:</label>
1544 + <input type="password"
1545 + name="aiseom_api_key"
1546 + id="aiseom_api_key"
1547 + value="<?php echo esc_attr(get_option('aiseom_api_key', '')); ?>"
1548 + class="regular-text"
1549 + placeholder="Въведете вашия API ключ">
1550 +
1551 + <button type="button" id="test-api-key" class="button" style="margin-top: 10px;">
1552 + <i class="fas fa-wifi"></i> Тествай API ключа
1553 + </button>
1554 +
1555 + <div id="api-test-result" style="margin-top: 10px;"></div>
1556 + </div>
1557 +
1558 + <div class="form-group">
1559 + <label for="aiseom_language">Език за генериране:</label>
1560 + <select name="aiseom_language" id="aiseom_language">
1561 + <option value="bg" <?php selected(get_option('aiseom_language', 'bg'), 'bg'); ?>>Български</option>
1562 + <option value="en" <?php selected(get_option('aiseom_language'), 'en'); ?>>Английски</option>
1563 + </select>
1564 + </div>
1565 +
1566 + <div class="form-group">
1567 + <label>
1568 + <input type="checkbox"
1569 + name="aiseom_auto_generate"
1570 + value="1"
1571 + <?php checked(get_option('aiseom_auto_generate', '1'), '1'); ?>>
1572 + Автоматично генериране на SEO при запазване на статия
1573 + </label>
1574 + </div>
1575 +
1576 + <div class="form-group">
1577 + <label>
1578 + <input type="checkbox"
1579 + name="aiseom_auto_generate_alt"
1580 + value="1"
1581 + <?php checked(get_option('aiseom_auto_generate_alt', '1'), '1'); ?>>
1582 + Автоматично генериране на ALT тагове за изображения
1583 + </label>
1584 + </div>
1585 +
1586 + <div class="form-group">
1587 + <label>Типове публикации за оптимизация:</label>
1588 + <div style="margin-top: 10px;">
1589 + <?php
1590 + $post_types = get_post_types(['public' => true], 'objects');
1591 + $selected = get_option('aiseom_post_types', ['post', 'page']);
1592 +
1593 + foreach ($post_types as $type) {
1594 + if ($type->name === 'attachment') continue;
1595 + ?>
1596 + <label style="display: block; margin-bottom: 8px;">
1597 + <input type="checkbox"
1598 + name="aiseom_post_types[]"
1599 + value="<?php echo $type->name; ?>"
1600 + <?php checked(in_array($type->name, $selected)); ?>>
1601 + <?php echo $type->label; ?>
1602 + </label>
1603 + <?php
1604 + }
1605 + ?>
1606 + </div>
1607 + </div>
1608 +
1609 + <?php submit_button('💾 Запази настройките', 'primary'); ?>
1610 + </form>
1611 + </div>
1612 + </div>
1613 +
1614 + <script>
1615 + jQuery(document).ready(function($) {
1616 + // Показване/скриване на API описания
1617 + function updateApiDescription() {
1618 + var provider = $('#aiseom_api_provider').val();
1619 +
1620 + // Скриваме всички описания
1621 + $('.api-description').hide();
1622 +
1623 + // Показваме само избраното
1624 + $('#api-desc-' + provider).show();
1625 +
1626 + // Ако е демо, скриваме полето за API ключ
1627 + if (provider === 'demo') {
1628 + $('#api-key-row').hide();
1629 + } else {
1630 + $('#api-key-row').show();
1631 + }
1632 + }
1633 +
1634 + $('#aiseom_api_provider').on('change', updateApiDescription);
1635 + updateApiDescription(); // Инициализация при зареждане
1636 + });
1637 + </script>
1638 + <?php
1639 + }
1640 + }
1641 +
1642 + // Инициализация
1643 + function aiseom_pro_init() {
1644 + return AI_SEO_Master_PRO::get_instance();
1645 + }
1646 +
1647 + add_action('plugins_loaded', 'aiseom_pro_init');
1648 +
1649 + // Активационен хук
1650 + register_activation_hook(__FILE__, function() {
1651 + // Настройки по подразбиране
1652 + $defaults = [
1653 + 'aiseom_api_provider' => 'demo',
1654 + 'aiseom_language' => 'bg',
1655 + 'aiseom_auto_generate' => '1',
1656 + 'aiseom_auto_generate_alt' => '1',
1657 + 'aiseom_post_types' => ['post', 'page']
1658 + ];
1659 +
1660 + foreach ($defaults as $key => $value) {
1661 + if (get_option($key) === false) {
1662 + update_option($key, $value);
1663 + }
1664 + }
1665 + });
Daha yeni Daha eski