Plugin Directory

Changeset 3431166


Ignore:
Timestamp:
01/02/2026 05:26:53 PM (12 days ago)
Author:
saeidafshari
Message:

Release version 1.2.0 with new UI and animations

Location:
kabook-auto-rank-math-snippet
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • kabook-auto-rank-math-snippet/trunk/assets/css/admin-style.css

    r3413121 r3431166  
    1 /* Kabook ARMS Admin Styles */
    2 
    3 /* Tab Navigation Styles */
    4 .karms-settings-wrap .nav-tab-wrapper {
    5     margin-bottom: 20px;
    6     border-bottom: 1px solid #c3c4c7;
    7 }
    8 
    9 /* Form Table Spacing */
    10 .form-table th {
    11     padding: 20px 10px 20px 0;
    12     width: 220px;
    13 }
    14 
    15 /* Small Input Fields (Numbers) */
    16 input.small-text {
    17     width: 80px;
    18     text-align: center;
    19 }
    20 
    21 /* Color Picker Container Alignment */
    22 .wp-picker-container {
    23     display: inline-block;
    24     vertical-align: middle;
    25 }
    26 
    27 /* Reset Button Styles */
     1/**
     2 * Admin Stylesheet for Kabook Auto Schema & Accordion
     3 * * Handles the visual presentation of the plugin settings page within the WordPress admin area.
     4 * Supports both LTR and RTL directions automatically based on WordPress core classes.
     5 *
     6 * @package Kabook Auto Rank Math Snippet
     7 * @version 1.2.0
     8 */
     9
     10/* -----------------------------------------------------------------------------
     11 * 1. Main Wrapper & Container
     12 * ----------------------------------------------------------------------------- */
     13.karms-admin-wrapper {
     14    background: #fff;
     15    padding: 0;
     16    border-radius: 16px;
     17    box-shadow: 0 5px 25px rgba(0, 0, 0, 0.05);
     18    max-width: 1100px;
     19    margin: 30px auto;
     20    border: 1px solid #e0e0e0;
     21    position: relative;
     22    overflow: hidden;
     23    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
     24    direction: ltr; /* Default LTR orientation */
     25}
     26
     27/* RTL Support */
     28body.rtl .karms-admin-wrapper {
     29    direction: rtl;
     30}
     31
     32/* -----------------------------------------------------------------------------
     33 * 2. Header Section
     34 * ----------------------------------------------------------------------------- */
     35.karms-header {
     36    background: linear-gradient(135deg, #005bea 0%, #00c6fb 100%);
     37    color: #fff;
     38    padding: 25px 40px;
     39    display: flex;
     40    align-items: center;
     41    justify-content: space-between;
     42}
     43
     44body.rtl .karms-header {
     45    flex-direction: row-reverse;
     46}
     47
     48.karms-header h1 {
     49    color: #fff !important;
     50    margin: 0 !important;
     51    font-size: 22px !important;
     52    font-weight: 800 !important;
     53}
     54
     55.karms-logo {
     56    width: 45px;
     57    height: 45px;
     58    background: #fff;
     59    border-radius: 50%;
     60    display: flex;
     61    align-items: center;
     62    justify-content: center;
     63    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
     64}
     65
     66.karms-logo img {
     67    max-width: 80%;
     68    height: auto;
     69}
     70
     71/* -----------------------------------------------------------------------------
     72 * 3. Navigation Tabs
     73 * ----------------------------------------------------------------------------- */
     74.karms-inner-content {
     75    padding: 30px;
     76}
     77
     78.karms-nav-tab-wrapper {
     79    border-bottom: 1px solid #f0f0f0 !important;
     80    padding-bottom: 20px !important;
     81    margin-bottom: 35px !important;
     82    display: flex;
     83    gap: 12px;
     84}
     85
     86body.rtl .karms-nav-tab-wrapper {
     87    justify-content: flex-start;
     88}
     89
     90.karms-nav-tab {
     91    background: #f5f7fa !important;
     92    border: none !important;
     93    padding: 12px 30px !important;
     94    border-radius: 50px !important;
     95    color: #607d8b !important;
     96    font-weight: 600 !important;
     97    text-decoration: none;
     98    transition: all 0.3s ease;
     99    font-size: 14px;
     100}
     101
     102.karms-nav-tab-active {
     103    background: #005bea !important;
     104    color: #fff !important;
     105    box-shadow: 0 4px 12px rgba(0, 91, 234, 0.25);
     106}
     107
     108/* -----------------------------------------------------------------------------
     109 * 4. Settings Field Rows
     110 * ----------------------------------------------------------------------------- */
     111.karms-settings-section-wrap h2 {
     112    font-size: 1.3em;
     113    color: #005bea;
     114    margin: 40px 0 20px;
     115    padding-bottom: 10px;
     116    border-bottom: 2px solid #f8f9fa;
     117}
     118
     119.karms-field-row {
     120    display: flex;
     121    align-items: center;
     122    padding: 22px 0;
     123    border-bottom: 1px solid #f8f9fa;
     124    gap: 40px;
     125}
     126
     127/* Flex direction handles RTL automatically via parent context */
     128body.rtl .karms-field-row {
     129    flex-direction: row;
     130}
     131
     132.karms-field-label {
     133    flex: 0 0 280px;
     134    text-align: left;
     135}
     136
     137body.rtl .karms-field-label {
     138    text-align: right;
     139}
     140
     141.karms-field-label label {
     142    font-weight: 700;
     143    color: #2c3338;
     144    font-size: 15px;
     145}
     146
     147.karms-field-input {
     148    flex: 1;
     149}
     150
     151.karms-field-input .description {
     152    display: block;
     153    margin-top: 8px;
     154    font-size: 13px;
     155    color: #646970;
     156    line-height: 1.6;
     157}
     158
     159/* -----------------------------------------------------------------------------
     160 * 5. Inputs & Form Controls
     161 * ----------------------------------------------------------------------------- */
     162.karms-admin-wrapper input[type="text"],
     163.karms-admin-wrapper input[type="number"],
     164.karms-admin-wrapper select {
     165    border: 1px solid #d1d5db;
     166    border-radius: 10px;
     167    height: 44px;
     168    padding: 0 15px;
     169    width: 100%;
     170    max-width: 400px;
     171    background-color: #fdfdfd;
     172}
     173
     174.karms-admin-wrapper input:focus {
     175    border-color: #005bea;
     176    box-shadow: 0 0 0 3px rgba(0, 91, 234, 0.08);
     177    outline: none;
     178}
     179
     180.karms-admin-wrapper input[type="checkbox"] {
     181    width: 20px;
     182    height: 20px;
     183    margin: 0 8px;
     184    border-radius: 6px;
     185}
     186
     187/* -----------------------------------------------------------------------------
     188 * 6. Footer Actions
     189 * ----------------------------------------------------------------------------- */
     190.karms-submit-area {
     191    margin-top: 40px;
     192    padding-top: 25px;
     193    border-top: 1px solid #eee;
     194    display: flex;
     195    justify-content: space-between;
     196    align-items: center;
     197}
     198
     199body.rtl .karms-submit-area {
     200    flex-direction: row-reverse;
     201}
     202
     203.button-primary.karms-save-btn {
     204    background: #005bea !important;
     205    border: none !important;
     206    height: 48px !important;
     207    padding: 0 40px !important;
     208    border-radius: 12px !important;
     209    font-weight: 700 !important;
     210    font-size: 15px !important;
     211    box-shadow: 0 4px 15px rgba(0, 91, 234, 0.2) !important;
     212}
     213
    28214#karms_reset_btn {
    29     margin-top: 10px;
     215    border-radius: 10px;
     216    color: #d63638;
    30217    border-color: #d63638;
    31     color: #d63638;
    32218}
    33219
    34220#karms_reset_btn:hover {
    35     background: #d63638;
    36     color: #fff;
    37     border-color: #d63638;
    38 }
    39 
    40 /* Field Descriptions */
    41 .description {
    42     color: #646970;
    43     font-style: italic;
    44     margin-left: 5px;
    45 }
     221    background: #fcf2f2;
     222}
  • kabook-auto-rank-math-snippet/trunk/assets/css/frontend-counter.css

    r3413121 r3431166  
    1 /* Kabook ARMS Counter Styles (Fixed RTL & Icon Conflict) */
     1/**
     2 * Frontend Counter Stylesheet for Kabook Auto Schema & Accordion
     3 * * Manages the automatic numbering of accordion items using CSS counters.
     4 * Handles both LTR and RTL layouts correctly.
     5 *
     6 * @package Kabook Auto Rank Math Snippet
     7 * @version 1.2.0
     8 */
    29
    3 /* 1. Initialize Counter */
    4 #rank-math-faq .rank-math-list-item {
    5     counter-increment: karms-question-counter;
     10/* -----------------------------------------------------------------------------
     11 * 1. Initialize Counter Scope
     12 * ----------------------------------------------------------------------------- */
     13#rank-math-faq {
     14    counter-reset: karms-counter;
    615}
    716
    8 /* 2. Number Styling (::before pseudo-element) */
     17#rank-math-faq .rank-math-list-item {
     18    counter-increment: karms-counter;
     19}
     20
     21/* -----------------------------------------------------------------------------
     22 * 2. Number Styling & Positioning
     23 * ----------------------------------------------------------------------------- */
    924#rank-math-faq .rm-faq-question-btn::before {
    10     content: counter(karms-question-counter) ".";
     25    content: counter(karms-counter) ".";
    1126    position: absolute;
    1227    top: 50%;
    13     width: 25px;
     28    transform: translateY(-50%);
     29    font-weight: bold;
     30    opacity: 0.8;
     31    color: inherit;
     32    width: 30px; /* Width reserved for the number */
    1433    text-align: center;
    15     color: inherit;
    16     font-weight: bold;
    17     transform: translateY(-50%);
    18     opacity: 0.7;
    19     z-index: 1;
    2034}
    2135
    22 /* =========================================
    23    LTR Styles (Default/English)
    24    ========================================= */
    25 #rank-math-faq .rank-math-question {
    26     /* Right padding: Icon space | Left padding: Number space */
    27     padding: 15px 54px 15px 35px !important;
    28 }
    29 
    30 /* Position number on the left */
     36/* -----------------------------------------------------------------------------
     37 * 3. LTR Positioning (Default)
     38 * ----------------------------------------------------------------------------- */
    3139#rank-math-faq .rm-faq-question-btn::before {
    3240    left: 10px;
     
    3442}
    3543
    36 /* =========================================
    37    RTL Styles (Persian/Arabic) - Final Fix
    38    ========================================= */
    39 
    40 /* A) Fix Padding (Swap spaces) */
    41 body.rtl #rank-math-faq .rank-math-question,
    42 [dir="rtl"] #rank-math-faq .rank-math-question {
    43     /* Right padding: Number space | Left padding: Icon space */
    44     padding: 15px 35px 15px 54px !important;
     44/* Adjust padding to prevent text overlap with the number */
     45#rank-math-faq .rank-math-question {
     46    padding-left: 45px !important; /* Space for number on the left */
    4547}
    4648
    47 /* B) Fix Number Positioning (Move to right) */
     49/* -----------------------------------------------------------------------------
     50 * 4. RTL Positioning (Right-to-Left Support)
     51 * ----------------------------------------------------------------------------- */
    4852body.rtl #rank-math-faq .rm-faq-question-btn::before,
    4953[dir="rtl"] #rank-math-faq .rm-faq-question-btn::before {
    50     left: auto !important;
    51     right: 10px !important;
     54    left: auto;
     55    right: 10px;
    5256}
    5357
    54 /* C) Fix +/- Icon Positioning (Move to left) */
    55 /* This resolves the overlap conflict between the number and the icon */
    56 body.rtl #rank-math-faq .rank-math-question::after,
    57 [dir="rtl"] #rank-math-faq .rank-math-question::after {
    58     right: auto !important; /* Remove from right */
    59     left: 0 !important;     /* Move to left */
     58/* Adjust padding for RTL layouts */
     59body.rtl #rank-math-faq .rank-math-question {
     60    padding-left: 54px !important; /* Space for the toggle icon on the left */
     61    padding-right: 45px !important; /* Space for the number on the right */
    6062}
  • kabook-auto-rank-math-snippet/trunk/assets/css/frontend-style.css

    r3413121 r3431166  
     1/**
     2 * Frontend Stylesheet for Kabook Auto Schema & Accordion
     3 * * Controls the visual appearance of the accordion, including layout, colors,
     4 * typography, and animations. Supports dynamic CSS variables injected by PHP.
     5 *
     6 * @package Kabook Auto Rank Math Snippet
     7 * @version 1.2.0
     8 */
     9
     10/* -----------------------------------------------------------------------------
     11 * 1. Global Variables & Defaults
     12 * ----------------------------------------------------------------------------- */
     13:root {
     14    --karms-anim-speed: 300ms;
     15}
     16
     17/* -----------------------------------------------------------------------------
     18 * 2. Container Styles
     19 * ----------------------------------------------------------------------------- */
    120#rank-math-faq .rank-math-list-item {
    221    border: var(--karms-border-width) var(--karms-border-style) var(--karms-border-color);
    3     border-radius: var(--karms-border-radius);
     22    border-radius: var(--karms-border-radius) !important;
    423    margin-bottom: 20px;
    5     position: relative;
    6     overflow: hidden;
     24    overflow: hidden; /* Ensures content doesn't overflow rounded corners */
    725}
    826
     27/* -----------------------------------------------------------------------------
     28 * 3. Question Block Styles
     29 * ----------------------------------------------------------------------------- */
    930#rank-math-faq .rank-math-question {
    1031    display: block;
     
    1637    background-color: var(--karms-question-bg-color);
    1738    margin: 0 !important;
    18     padding: 15px 54px 15px 12px;
     39    padding: 15px 54px 15px 15px !important; /* Default LTR padding (Icon on right) */
    1940    position: relative;
    2041    cursor: pointer;
     
    2243}
    2344
    24 #rank-math-faq .rank-math-question.rm-faq-question-active {
    25     border-bottom: var(--karms-border-width) var(--karms-border-style) var(--karms-border-color);
    26 }
    27 
     45/* Toggle Icon (+/-) Positioning */
    2846#rank-math-faq .rank-math-question::after {
    2947    content: "+";
     
    3351    width: 54px;
    3452    text-align: center;
    35     font-weight: 700;
    36     color: inherit;
    3753    font-size: 20px;
    3854    transform: translateY(-50%);
     55    transition: transform 0.3s ease;
    3956}
    4057
     58/* Active State Icon */
    4159#rank-math-faq .rank-math-question.rm-faq-question-active::after {
    4260    content: "-";
    4361}
    4462
     63/* Accessibility Button Reset */
     64#rank-math-faq .rm-faq-question-btn {
     65    all: unset !important;
     66    width: 100%;
     67    display: block;
     68}
     69
     70/* -----------------------------------------------------------------------------
     71 * 4. RTL Support (Right-to-Left)
     72 * ----------------------------------------------------------------------------- */
     73body.rtl #rank-math-faq .rank-math-question,
     74[dir="rtl"] #rank-math-faq .rank-math-question {
     75    padding: 15px 15px 15px 54px !important; /* Swap padding for icon on left */
     76}
     77
     78body.rtl #rank-math-faq .rank-math-question::after,
     79[dir="rtl"] #rank-math-faq .rank-math-question::after {
     80    right: auto;
     81    left: 0;
     82}
     83
     84/* -----------------------------------------------------------------------------
     85 * 5. Answer Block Styles
     86 * ----------------------------------------------------------------------------- */
    4587#rank-math-faq .rank-math-answer {
     88    display: none;
    4689    font-size: var(--karms-answer-font-size);
    47     line-height: 1.4 !important;
     90    line-height: 1.6 !important;
    4891    text-align: var(--karms-answer-text-align);
    4992    color: var(--karms-answer-color);
    5093    background-color: var(--karms-answer-bg-color);
    51     margin: 0;
    52     padding: 12px;
    53     display: none;
     94    padding: 15px;
     95    border-top: var(--karms-border-width) var(--karms-border-style) var(--karms-border-color);
    5496}
    5597
    56 #rank-math-faq .rank-math-answer p {
    57     margin-bottom: .5em;
     98/* -----------------------------------------------------------------------------
     99 * 6. Animations
     100 * ----------------------------------------------------------------------------- */
     101
     102/* Fade Animation Class */
     103.karms-animate-fade {
     104    animation: karmsFadeIn var(--karms-anim-speed, 300ms) ease-out forwards;
    58105}
    59106
    60 #rank-math-faq .rm-faq-question-btn {
    61     all: unset !important;
     107/* Zoom Animation Class */
     108.karms-animate-zoom {
     109    animation: karmsZoomIn var(--karms-anim-speed, 300ms) cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
    62110}
     111
     112/* Keyframes: Fade In */
     113@keyframes karmsFadeIn {
     114    from { opacity: 0; }
     115    to { opacity: 1; }
     116}
     117
     118/* Keyframes: Zoom In (with bounce effect) */
     119@keyframes karmsZoomIn {
     120    from {
     121        opacity: 0;
     122        transform: scale(0.85);
     123    }
     124    to {
     125        opacity: 1;
     126        transform: scale(1);
     127    }
     128}
  • kabook-auto-rank-math-snippet/trunk/assets/js/admin-script.js

    r3413121 r3431166  
     1/**
     2 * Admin Script for Kabook Auto Schema & Accordion
     3 *
     4 * Handles administrative interface interactions, specifically the WordPress
     5 * Color Picker initialization and the AJAX-based settings reset functionality.
     6 *
     7 * @package Kabook Auto Rank Math Snippet
     8 * @version 1.2.0
     9 */
     10
    111jQuery(document).ready(function($) {
    2     // Initialize WordPress Color Picker
     12    'use strict';
     13
     14    /**
     15     * Initialize WordPress Color Picker.
     16     * Applies to all inputs with the .karms-color-picker class.
     17     */
    318    $('.karms-color-picker').wpColorPicker();
    419
    5     // Handle Reset Button Click
     20    /**
     21     * Handle Reset Button Click.
     22     * Sends an AJAX request to reset all plugin settings to defaults.
     23     */
    624    $('#karms_reset_btn').on('click', function(e) {
    725        e.preventDefault();
    826       
    9         // Use localized confirmation message
    10         if (confirm(karms_vars.confirm)) {
     27        // Ensure localization object exists to prevent errors
     28        if (typeof karms_vars === 'undefined') {
     29            console.error('KARMS: Localization variable "karms_vars" not found.');
     30            return;
     31        }
     32
     33        // Define fallback messages just in case PHP didn't pass them
     34        const msgConfirm = karms_vars.confirm || 'Are you sure you want to reset all settings?';
     35        const msgSuccess = karms_vars.msg_success || 'Settings reset successfully.';
     36        const msgError   = karms_vars.msg_error || 'Error resetting settings.';
     37
     38        // 1. Confirm the action using localized text
     39        if (confirm(msgConfirm)) {
     40           
     41            // Disable button to prevent multiple clicks during request
     42            const $btn = $(this);
     43            $btn.prop('disabled', true);
     44
    1145            $.ajax({
    12                 url: ajaxurl,
     46                url: ajaxurl, // Global WordPress AJAX URL
    1347                type: 'POST',
    1448                data: {
    1549                    action: 'karms_reset_settings',
    16                     security: karms_vars.nonce // SECURITY TOKEN
     50                    security: karms_vars.nonce // Security Token
    1751                },
    1852                success: function(response) {
    1953                    if (response.success) {
    20                         alert('Settings reset to default. Please refresh the page.');
     54                        // 2. Show success message (Localized) and reload
     55                        alert(msgSuccess);
    2156                        location.reload();
    2257                    } else {
    23                         alert('Error resetting settings.');
     58                        // 3. Show error message (Localized)
     59                        alert(msgError);
     60                        $btn.prop('disabled', false);
    2461                    }
     62                },
     63                error: function() {
     64                    // Handle network/server errors
     65                    alert(msgError);
     66                    $btn.prop('disabled', false);
    2567                }
    2668            });
  • kabook-auto-rank-math-snippet/trunk/assets/js/frontend-script.js

    r3414326 r3431166  
     1/**
     2 * Frontend Script for Kabook Auto Schema & Accordion
     3 * Handles the accordion functionality, ARIA accessibility attributes,
     4 * and animation logic for the Rank Math FAQ schema.
     5 *
     6 * @package Kabook Auto Rank Math Snippet
     7 */
     8
    19document.addEventListener('DOMContentLoaded', function() {
     10    'use strict';
     11
    212    const faqItems = document.querySelectorAll('#rank-math-faq .rank-math-list-item');
    313    if (!faqItems.length) return;
    414
    5     // 1. Setup Structure (Buttons & Attributes)
     15    // Counter to ensure unique IDs without Math.random collision risk
     16    let uniqueIdCounter = 0;
     17
     18    /**
     19     * 1. Initialize Button Structure & ARIA Attributes
     20     * Wraps the question text in a button for better accessibility.
     21     */
    622    faqItems.forEach(item => {
    7         const questionHeader = item.querySelector('h3');
     23        const questionHeader = item.querySelector('.rank-math-question');
    824        if (!questionHeader) return;
    925
    10         // Generate unique ID
    11         let idSuffix = item.id ? item.id.split('-')[2] : Math.floor(Math.random() * 1000);
    12         if (!idSuffix) idSuffix = Math.floor(Math.random() * 1000);
     26        // Increment counter for each item
     27        uniqueIdCounter++;
     28        const btnId = 'rm-accordion-' + uniqueIdCounter;
     29        const panelId = 'rm-accordion-panel-' + uniqueIdCounter;
    1330
    14         const btnId = 'rm-accordion-' + idSuffix;
    15         const panelId = 'rm-accordion-panel-' + idSuffix;
    16 
    17         // Convert H3 content to Button
    1831        const innerHTML = questionHeader.innerHTML;
    1932        questionHeader.innerHTML = `<button class="rm-faq-question-btn" type="button" id="${btnId}" aria-controls="${panelId}" aria-expanded="false">${innerHTML}</button>`;
    2033
    21         // Setup Panel
    2234        const answerDiv = item.querySelector('.rank-math-answer');
    2335        if (answerDiv) {
    2436            answerDiv.id = panelId;
    2537            answerDiv.setAttribute('aria-labelledby', btnId);
    26             // Initial styling for JS toggle
    2738            answerDiv.style.display = 'none';
    28             answerDiv.style.overflow = 'hidden';
    2939        }
    3040    });
    3141
    32     // 2. Handle Click Events
    3342    const questions = document.querySelectorAll('#rank-math-faq .rank-math-question');
     43    // Ensure config object is safe
     44    const config = (typeof karms_settings !== 'undefined') ? karms_settings : { animation: 'slide', initial_expand_first: 0 };
    3445   
    3546    questions.forEach(question => {
    3647        question.addEventListener('click', function(e) {
    37             // Prevent triggering if clicking inside the answer
     48            // Prevent triggering when clicking inside the answer content
    3849            if (e.target.closest('.rank-math-answer')) return;
    3950
     
    4152            const currentBtn = currentItem.querySelector('button');
    4253            const currentAnswer = currentItem.nextElementSibling;
    43 
    4454            const isActive = currentItem.classList.contains('rm-faq-question-active');
    4555
    46             // Close all others
     56            /**
     57             * 2. Accordion Mode: Close other items
     58             * Loops through all questions and closes them if they are not the current item.
     59             */
    4760            questions.forEach(q => {
    48                 if (q !== currentItem) {
     61                if (q !== currentItem && q.classList.contains('rm-faq-question-active')) {
    4962                    q.classList.remove('rm-faq-question-active');
    5063                    const btn = q.querySelector('button');
    51                     if(btn) btn.setAttribute('aria-expanded', 'false');
     64                    if (btn) btn.setAttribute('aria-expanded', 'false');
    5265                   
    5366                    const ans = q.nextElementSibling;
    54                     if (ans && ans.classList.contains('rank-math-answer')) {
    55                         ans.classList.remove('rm-faq-answer-active');
     67                    if (ans) {
    5668                        ans.style.display = 'none';
     69                        ans.classList.remove('karms-animate-fade', 'karms-animate-zoom');
    5770                    }
    5871                }
    5972            });
    6073
    61             // Toggle current
    62             if (isActive) {
    63                 currentItem.classList.remove('rm-faq-question-active');
    64                 if(currentBtn) currentBtn.setAttribute('aria-expanded', 'false');
    65                 currentAnswer.classList.remove('rm-faq-answer-active');
    66                 currentAnswer.style.display = 'none';
    67             } else {
    68                 currentItem.classList.add('rm-faq-question-active');
    69                 if(currentBtn) currentBtn.setAttribute('aria-expanded', 'true');
    70                 currentAnswer.classList.add('rm-faq-answer-active');
    71                 currentAnswer.style.display = 'block';
    72                 // Simple height animation can be added via CSS if needed
     74            if (currentAnswer) {
     75                /**
     76                 * 3. Reset Animation
     77                 * Removes animation classes and forces a reflow to restart the animation.
     78                 */
     79                currentAnswer.classList.remove('karms-animate-fade', 'karms-animate-zoom');
     80                void currentAnswer.offsetWidth; // Force Reflow
     81
     82                if (isActive) {
     83                    // Close the current item
     84                    currentItem.classList.remove('rm-faq-question-active');
     85                    if (currentBtn) currentBtn.setAttribute('aria-expanded', 'false');
     86                    currentAnswer.style.display = 'none';
     87                } else {
     88                    // Open the current item
     89                    currentItem.classList.add('rm-faq-question-active');
     90                    if (currentBtn) currentBtn.setAttribute('aria-expanded', 'true');
     91
     92                    // Apply animation based on admin settings
     93                    if (config.animation === 'fade') {
     94                        currentAnswer.classList.add('karms-animate-fade');
     95                    } else if (config.animation === 'zoom') {
     96                        currentAnswer.classList.add('karms-animate-zoom');
     97                    }
     98                   
     99                    currentAnswer.style.display = 'block';
     100                }
    73101            }
    74102        });
    75103    });
    76104
    77     // 3. Initial Expand Logic
    78     if (typeof karms_settings !== 'undefined' && karms_settings.initial_expand_first === '1') {
    79         const firstQuestion = questions[0];
    80         if (firstQuestion) {
    81             firstQuestion.classList.add('rm-faq-question-active');
    82             const btn = firstQuestion.querySelector('button');
    83             if(btn) btn.setAttribute('aria-expanded', 'true');
    84            
    85             const firstAnswer = firstQuestion.nextElementSibling;
    86             if (firstAnswer) {
    87                 firstAnswer.classList.add('rm-faq-answer-active');
    88                 firstAnswer.style.display = 'block';
    89             }
    90         }
     105    /**
     106     * 4. Initial State
     107     * Expand the first item if the option is enabled in settings.
     108     */
     109    if (String(config.initial_expand_first) === '1' && questions[0]) {
     110        // Use a small timeout to ensure DOM is fully ready for the click simulation
     111        setTimeout(() => {
     112            const firstBtn = questions[0].querySelector('button');
     113            if (firstBtn) firstBtn.click();
     114        }, 50);
    91115    }
    92116});
  • kabook-auto-rank-math-snippet/trunk/kabook-auto-rank-math-snippet.php

    r3414326 r3431166  
    33 * Plugin Name: Kabook Auto Schema & Accordion for Rank Math
    44 * Description: Automatically injects Rank Math FAQ schema and converts it to a stylish, customizable accordion.
    5  * Version:     1.1.0
     5 * Version:     1.2.0
    66 * Author:      Kabook (Saeid Afshari)
    7  * Author URI:  https://kabook.ir/
     7 * Author URI:  https://www.kabook.ir/
    88 * License:     GPL-2.0+
    99 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
     
    1111 * Domain Path: /languages
    1212 * Requires at least: 5.6
    13  * Requires PHP: 8.0
    14  *
    15  * Credits:
    16  * This plugin utilizes styling logic inspired by the "Convert Rank Math FAQ to Accordion" plugin.
     13 * Requires PHP: 7.4
    1714 */
    1815
    1916if ( ! defined( 'ABSPATH' ) ) {
    20     exit;
     17    exit;
    2118}
    2219
     
    2421// 1. CONSTANTS
    2522// -----------------------------------------------------------------------------
    26 define( 'KARMS_VERSION', '1.1.0' );
     23define( 'KARMS_VERSION', '1.2.0' );
    2724define( 'KARMS_PATH', plugin_dir_path( __FILE__ ) );
    2825define( 'KARMS_URL', plugin_dir_url( __FILE__ ) );
     
    3229// -----------------------------------------------------------------------------
    3330class KARMS_Loader {
    34     public static function init() {
    35         // Note: load_plugin_textdomain is removed to comply with WP.org standards.
    36         // WordPress automatically loads translations defined in the "Domain Path" header.
    37 
    38         // Core & Frontend
    39         add_action( 'init', [ 'KARMS_Core', 'init' ] );
    40         add_action( 'wp_enqueue_scripts', [ 'KARMS_Accordion', 'enqueue_assets' ] );
    41        
    42         // Admin Hooks
    43         add_action( 'admin_menu', [ 'KARMS_Admin', 'add_settings_page' ] );
    44         add_action( 'admin_init', [ 'KARMS_Admin', 'register_settings' ] );
    45         add_action( 'admin_enqueue_scripts', [ 'KARMS_Admin', 'enqueue_assets' ] );
    46         add_action( 'wp_ajax_karms_reset_settings', [ 'KARMS_Admin', 'ajax_reset_settings' ] );
    47         add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), [ __CLASS__, 'add_settings_link' ] );
    48        
    49         // Dependency Check Notice
    50         add_action( 'admin_notices', [ __CLASS__, 'check_rank_math_dependency' ] );
    51 
    52         // Meta Box Hooks
    53         add_action( 'add_meta_boxes', [ 'KARMS_MetaBox', 'add_meta_box' ] );
    54         add_action( 'save_post', [ 'KARMS_MetaBox', 'save_meta_box' ] );
    55     }
    56 
    57     public static function check_rank_math_dependency() {
    58         if ( ! defined( 'RANK_MATH_PRO_FILE' ) ) {
    59             ?>
    60             <div class="notice notice-error is-dismissible">
    61                 <p>
    62                     <?php
    63                     echo wp_kses_post(
    64                         sprintf(
    65                             /* translators: %s: Plugin Name */
    66                             __( '%s requires Rank Math SEO PRO to be installed and active.', 'kabook-auto-rank-math-snippet' ),
    67                             '<strong>Kabook Auto Schema & Accordion</strong>'
    68                         )
    69                     );
    70                     ?>
    71                 </p>
    72             </div>
    73             <?php
    74         }
    75     }
    76 
    77     public static function activate_plugin() {
    78         if ( get_option( 'karms_options' ) === false ) {
    79             update_option( 'karms_options', KARMS_Admin::get_default_options() );
    80         }
    81     }
    82 
    83     public static function add_settings_link( $links ) {
    84         $settings_link = '<a href="options-general.php?page=karms-settings">' . esc_html__( 'Settings', 'kabook-auto-rank-math-snippet' ) . '</a>';
    85         array_unshift( $links, $settings_link );
    86         return $links;
    87     }
    88 }
     31
     32    public static function init() {
     33        add_action( 'init', [ 'KARMS_Core', 'init' ] );
     34        add_action( 'wp_enqueue_scripts', [ 'KARMS_Accordion', 'enqueue_assets' ] );
     35        add_action( 'admin_menu', [ 'KARMS_Admin', 'add_settings_page' ] );
     36        add_action( 'admin_init', [ 'KARMS_Admin', 'register_settings' ] );
     37        add_action( 'admin_enqueue_scripts', [ 'KARMS_Admin', 'enqueue_assets' ] );
     38        add_action( 'wp_ajax_karms_reset_settings', [ 'KARMS_Admin', 'ajax_reset_settings' ] );
     39        add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), [ __CLASS__, 'add_settings_link' ] );
     40        add_action( 'admin_notices', [ __CLASS__, 'check_rank_math_dependency' ] );
     41        add_action( 'add_meta_boxes', [ 'KARMS_MetaBox', 'add_meta_box' ] );
     42        add_action( 'save_post', [ 'KARMS_MetaBox', 'save_meta_box' ] );
     43    }
     44
     45    public static function check_rank_math_dependency() {
     46        if ( ! defined( 'RANK_MATH_PRO_FILE' ) ) {
     47            $msg = sprintf(
     48                /* translators: 1: Plugin Name, 2: Dependency Name */
     49                esc_html__( '%1$s requires %2$s to be installed and active.', 'kabook-auto-rank-math-snippet' ),
     50                '<strong>' . esc_html__( 'Kabook Auto Schema & Accordion', 'kabook-auto-rank-math-snippet' ) . '</strong>',
     51                '<strong>' . esc_html__( 'Rank Math SEO PRO', 'kabook-auto-rank-math-snippet' ) . '</strong>'
     52            );
     53            ?>
     54            <div class="notice notice-error is-dismissible">
     55                <p><?php echo wp_kses_post( $msg ); ?></p>
     56            </div>
     57            <?php
     58        }
     59    }
     60
     61    public static function activate_plugin() {
     62        if ( get_option( 'karms_options' ) === false ) {
     63            update_option( 'karms_options', KARMS_Admin::get_default_options() );
     64        }
     65    }
     66
     67    public static function add_settings_link( $links ) {
     68        $label = esc_html__( 'Settings', 'kabook-auto-rank-math-snippet' );
     69        $settings_link = '<a href="options-general.php?page=karms-settings">' . $label . '</a>';
     70        array_unshift( $links, $settings_link );
     71        return $links;
     72    }
     73}
     74
    8975// -----------------------------------------------------------------------------
    9076// 3. CORE LOGIC CLASS
    9177// -----------------------------------------------------------------------------
    9278class KARMS_Core {
    93     public static function init() {
    94         add_filter( 'the_content', [ __CLASS__, 'maybe_inject_shortcode' ], 999 );
    95     }
    96 
    97     public static function maybe_inject_shortcode( $content ) {
    98         // Dependency Check
    99         if ( ! defined( 'RANK_MATH_PRO_FILE' ) ) { return $content; }
    100        
    101         // Context Check
    102         if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { return $content; }
    103         if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) { return $content; }
    104 
    105         global $post;
    106         if ( ! $post instanceof WP_Post ) { return $content; }
    107 
    108         // Check Meta Box Control & Global Settings
    109         if ( ! self::should_inject( $post->ID ) ) {
    110             return $content;
    111         }
    112 
    113         // 1. Check rendered content (Safety)
    114         if ( has_shortcode( $content, 'rank_math_rich_snippet' ) ) {
    115             return $content;
    116         }
    117 
    118         // 2. Check RAW post content (Anti-Duplication)
    119         if ( has_shortcode( $post->post_content, 'rank_math_rich_snippet' ) ) {
    120             return $content;
    121         }
    122 
    123         // 3. String check fallback
    124         if ( strpos( $post->post_content, '[rank_math_rich_snippet' ) !== false ) {
    125             return $content;
    126         }
    127 
    128         // Logic: Try specific ID, fallback to generic
    129         $shortcode = self::get_shortcode_for_post( $post->ID );
    130         if ( $shortcode ) {
    131             $content .= "\n\n" . do_shortcode( $shortcode );
    132         }
    133         return $content;
    134     }
    135 
    136     protected static function should_inject( $post_id ) {
    137         // 1. Check Local Override First
    138         $local_override = get_post_meta( $post_id, '_karms_auto_inject_override', true );
    139 
    140         if ( 'enabled' === $local_override ) return true;
    141         if ( 'disabled' === $local_override ) return false;
    142 
    143         // 2. Fallback to Global Settings
    144         $options = get_option( 'karms_options' );
    145         return isset( $options['auto_insert'] ) && $options['auto_insert'] == 1;
    146     }
    147 
    148     protected static function get_shortcode_for_post( $post_id ) {
    149         $schema_id = get_post_meta( $post_id, 'rank_math_schema_id', true );
    150         if ( $schema_id ) {
    151             return '[rank_math_rich_snippet id="' . esc_attr( $schema_id ) . '"]';
    152         }
    153         return '[rank_math_rich_snippet]';
    154     }
     79
     80    public static function init() {
     81        add_filter( 'the_content', [ __CLASS__, 'maybe_inject_shortcode' ], 999 );
     82    }
     83
     84    public static function maybe_inject_shortcode( $content ) {
     85        if ( ! defined( 'RANK_MATH_PRO_FILE' ) ) { return $content; }
     86        if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { return $content; }
     87        if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) { return $content; }
     88
     89        global $post;
     90        if ( ! $post instanceof WP_Post ) { return $content; }
     91        if ( ! self::should_inject( $post->ID ) ) { return $content; }
     92
     93        // Check if shortcode already exists to avoid duplication
     94        if ( has_shortcode( $content, 'rank_math_rich_snippet' ) ||
     95             has_shortcode( $post->post_content, 'rank_math_rich_snippet' ) ||
     96             strpos( $post->post_content, '[rank_math_rich_snippet' ) !== false ) {
     97            return $content;
     98        }
     99
     100        $shortcode = self::get_shortcode_for_post( $post->ID );
     101        if ( $shortcode ) {
     102            $content .= "\n\n" . do_shortcode( $shortcode );
     103        }
     104        return $content;
     105    }
     106
     107    protected static function should_inject( $post_id ) {
     108        $local_override = get_post_meta( $post_id, '_karms_auto_inject_override', true );
     109        if ( 'enabled' === $local_override ) return true;
     110        if ( 'disabled' === $local_override ) return false;
     111        $options = get_option( 'karms_options' );
     112        return isset( $options['auto_insert'] ) && $options['auto_insert'] == 1;
     113    }
     114
     115    protected static function get_shortcode_for_post( $post_id ) {
     116        $schema_id = get_post_meta( $post_id, 'rank_math_schema_id', true );
     117        if ( $schema_id ) {
     118            return '[rank_math_rich_snippet id="' . esc_attr( $schema_id ) . '"]';
     119        }
     120        return '[rank_math_rich_snippet]';
     121    }
    155122}
    156123
     
    159126// -----------------------------------------------------------------------------
    160127class KARMS_Accordion {
    161     public static function enqueue_assets() {
    162         $options = get_option( 'karms_options' );
    163         if ( ! $options || ! is_array( $options ) ) {
    164             $options = KARMS_Admin::get_default_options();
    165         }
    166 
    167         if ( empty( $options['accordion_enabled'] ) ) {
    168             return;
    169         }
    170 
    171         wp_enqueue_style( 'karms-frontend-style', KARMS_URL . 'assets/css/frontend-style.css', [], KARMS_VERSION );
    172        
    173         // Vanilla JS - Loading in footer
    174         wp_enqueue_script( 'karms-frontend-script', KARMS_URL . 'assets/js/frontend-script.js', [], KARMS_VERSION, true );
    175 
    176         $js_settings = [
    177             'initial_expand_first' => isset( $options['initial_expand_first'] ) ? $options['initial_expand_first'] : 0,
    178         ];
    179         wp_localize_script( 'karms-frontend-script', 'karms_settings', $js_settings );
    180 
    181         if ( ! empty( $options['counter_enabled'] ) ) {
    182             wp_enqueue_style( 'karms-frontend-counter', KARMS_URL . 'assets/css/frontend-counter.css', [], KARMS_VERSION );
    183         }
    184 
    185         self::add_inline_styles( $options );
    186     }
    187 
    188     private static function add_inline_styles( $opts ) {
    189         $defaults = KARMS_Admin::get_default_options();
    190         $get_opt = function( $key ) use ( $opts, $defaults ) {
    191             return isset( $opts[ $key ] ) && $opts[ $key ] !== '' ? $opts[ $key ] : $defaults[ $key ];
    192         };
    193 
    194         // Mapping options to CSS Variables
    195         $css_vars = [
    196             'border-color'  => $get_opt( 'border_color' ),
    197             'border-width'  => absint( $get_opt( 'border_width' ) ),
    198             'border-style'  => $get_opt( 'border_style' ),
    199             'border-radius' => absint( $get_opt( 'border_radius' ) ),
    200             'question-font-size' => absint( $get_opt( 'question_font_size' ) ),
    201             'question-color'     => $get_opt( 'question_color' ),
    202             'question-bg-color'  => $get_opt( 'question_background_color' ),
    203             'question-text-align'=> $get_opt( 'question_text_align' ),
    204             'answer-font-size'   => absint( $get_opt( 'answer_font_size' ) ),
    205             'answer-color'       => $get_opt( 'answer_color' ),
    206             'answer-bg-color'    => $get_opt( 'answer_background_color' ),
    207             'answer-text-align'  => $get_opt( 'answer_text_align' ),
    208         ];
    209 
    210         $custom_css = ":root {";
    211         foreach( $css_vars as $key => $val ) {
    212             if( strpos($key, 'width') !== false || strpos($key, 'size') !== false || strpos($key, 'radius') !== false ) {
    213                 $val .= 'px';
    214             }
    215             $custom_css .= sprintf( '--karms-%s: %s;', esc_attr( $key ), esc_attr( $val ) );
    216         }
    217         $custom_css .= "}";
    218        
    219         wp_add_inline_style( 'karms-frontend-style', $custom_css );
    220     }
     128
     129    public static function enqueue_assets() {
     130        if ( ! is_singular() ) { return; }
     131        global $post;
     132        if ( ! $post ) { return; }
     133
     134        $options = get_option( 'karms_options', KARMS_Admin::get_default_options() );
     135        if ( empty( $options['accordion_enabled'] ) ) { return; }
     136
     137        $has_shortcode = has_shortcode( $post->post_content, 'rank_math_rich_snippet' );
     138        $auto_inject   = isset( $options['auto_insert'] ) && $options['auto_insert'] == 1;
     139
     140        if ( ! $has_shortcode && ! $auto_inject ) { return; }
     141
     142        wp_enqueue_style( 'karms-frontend-style', KARMS_URL . 'assets/css/frontend-style.css', [], KARMS_VERSION );
     143        wp_enqueue_script( 'karms-frontend-script', KARMS_URL . 'assets/js/frontend-script.js', [], KARMS_VERSION, true );
     144
     145        $js_settings = [
     146            'initial_expand_first' => isset( $options['initial_expand_first'] ) ? $options['initial_expand_first'] : 0,
     147            'animation'            => isset( $options['accordion_animation'] ) ? $options['accordion_animation'] : 'slide',
     148        ];
     149        wp_localize_script( 'karms-frontend-script', 'karms_settings', $js_settings );
     150
     151        if ( ! empty( $options['counter_enabled'] ) ) {
     152            wp_enqueue_style( 'karms-frontend-counter', KARMS_URL . 'assets/css/frontend-counter.css', [], KARMS_VERSION );
     153        }
     154
     155        self::add_inline_styles( $options );
     156    }
     157
     158    private static function add_inline_styles( $opts ) {
     159        $defaults = KARMS_Admin::get_default_options();
     160        $get_opt = function( $key ) use ( $opts, $defaults ) {
     161            return isset( $opts[ $key ] ) && $opts[ $key ] !== '' ? $opts[ $key ] : $defaults[ $key ];
     162        };
     163
     164        $css_vars = [
     165            'border-color'        => $get_opt( 'border_color' ),
     166            'border-width'        => absint( $get_opt( 'border_width' ) ),
     167            'border-style'        => $get_opt( 'border_style' ),
     168            'border-radius'       => absint( $get_opt( 'border_radius' ) ),
     169            'question-font-size'  => absint( $get_opt( 'question_font_size' ) ),
     170            'question-color'      => $get_opt( 'question_color' ),
     171            'question-bg-color'   => $get_opt( 'question_background_color' ),
     172            'question-text-align' => $get_opt( 'question_text_align' ),
     173            'answer-font-size'    => absint( $get_opt( 'answer_font_size' ) ),
     174            'answer-color'        => $get_opt( 'answer_color' ),
     175            'answer-bg-color'     => $get_opt( 'answer_background_color' ),
     176            'answer-text-align'   => $get_opt( 'answer_text_align' ),
     177        ];
     178
     179        $custom_css = ":root {";
     180        foreach( $css_vars as $key => $val ) {
     181            if( strpos($key, 'width') !== false || strpos($key, 'size') !== false || strpos($key, 'radius') !== false ) {
     182                $val .= 'px';
     183            }
     184            $custom_css .= sprintf( '--karms-%s: %s;', esc_attr( $key ), esc_attr( $val ) );
     185        }
     186        $custom_css .= sprintf( '--karms-anim-speed: %dms;', absint( $get_opt( 'accordion_speed' ) ) );
     187        $custom_css .= "}";
     188        wp_add_inline_style( 'karms-frontend-style', $custom_css );
     189    }
    221190}
    222191
     
    225194// -----------------------------------------------------------------------------
    226195class KARMS_MetaBox {
    227     public static function add_meta_box() {
    228         $options = get_option( 'karms_options' );
    229         if ( empty( $options['show_meta_box'] ) ) {
    230             return;
    231         }
    232 
    233         $screens = [ 'post', 'page', 'product' ];
    234         foreach ( $screens as $screen ) {
    235             add_meta_box(
    236                 'karms_injection_metabox',
    237                 esc_html__( 'Schema Injection Settings', 'kabook-auto-rank-math-snippet' ),
    238                 [ __CLASS__, 'render_meta_box' ],
    239                 $screen,
    240                 'side',
    241                 'default'
    242             );
    243         }
    244     }
    245 
    246     public static function render_meta_box( $post ) {
    247         $value = get_post_meta( $post->ID, '_karms_auto_inject_override', true );
    248         if ( empty( $value ) ) {
    249             $value = 'default';
    250         }
    251        
    252         wp_nonce_field( 'karms_save_meta_box_data', 'karms_meta_box_nonce' );
    253        
    254         echo '<label for="karms_auto_inject_override">';
    255         esc_html_e( 'Auto Inject Schema for this post:', 'kabook-auto-rank-math-snippet' );
    256         echo '</label><br>';
    257        
    258         echo '<select name="karms_auto_inject_override" id="karms_auto_inject_override" style="width:100%; margin-top:5px;">';
    259         echo '<option value="default" ' . selected( $value, 'default', false ) . '>' . esc_html__( 'Default (Global Settings)', 'kabook-auto-rank-math-snippet' ) . '</option>';
    260         echo '<option value="enabled" ' . selected( $value, 'enabled', false ) . '>' . esc_html__( 'Enable / Force Inject', 'kabook-auto-rank-math-snippet' ) . '</option>';
    261         echo '<option value="disabled" ' . selected( $value, 'disabled', false ) . '>' . esc_html__( 'Disable', 'kabook-auto-rank-math-snippet' ) . '</option>';
    262         echo '</select>';
    263        
    264         echo '<p class="description" style="margin-top: 8px;">';
    265         esc_html_e( 'Override the global auto-injection setting for this specific post.', 'kabook-auto-rank-math-snippet' );
    266         echo '</p>';
    267     }
    268 
    269     public static function save_meta_box( $post_id ) {
    270         if ( ! isset( $_POST['karms_meta_box_nonce'] ) ) { return; }
    271        
    272         $nonce = sanitize_text_field( wp_unslash( $_POST['karms_meta_box_nonce'] ) );
    273         if ( ! wp_verify_nonce( $nonce, 'karms_save_meta_box_data' ) ) { return; }
    274        
    275         if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; }
    276         if ( ! current_user_can( 'edit_post', $post_id ) ) { return; }
    277 
    278         if ( isset( $_POST['karms_auto_inject_override'] ) ) {
    279             $new_val = sanitize_key( $_POST['karms_auto_inject_override'] );
    280             if ( in_array( $new_val, [ 'default', 'enabled', 'disabled' ] ) ) {
    281                 update_post_meta( $post_id, '_karms_auto_inject_override', $new_val );
    282             }
    283         }
    284     }
    285 }
    286 
    287 // -----------------------------------------------------------------------------
    288 // 6. ADMIN CLASS
     196
     197    public static function add_meta_box() {
     198        $options = get_option( 'karms_options' );
     199        if ( empty( $options['show_meta_box'] ) ) { return; }
     200
     201        $screens = [ 'post', 'page', 'product' ];
     202        foreach ( $screens as $screen ) {
     203            add_meta_box(
     204                'karms_injection_metabox',
     205                esc_html__( 'Schema Injection Settings', 'kabook-auto-rank-math-snippet' ),
     206                [ __CLASS__, 'render_meta_box' ],
     207                $screen,
     208                'side',
     209                'default'
     210            );
     211        }
     212    }
     213
     214    public static function render_meta_box( $post ) {
     215        $value = get_post_meta( $post->ID, '_karms_auto_inject_override', true );
     216        if ( empty( $value ) ) { $value = 'default'; }
     217       
     218        wp_nonce_field( 'karms_save_meta_box_data', 'karms_meta_box_nonce' );
     219       
     220        echo '<label for="karms_auto_inject_override">';
     221        esc_html_e( 'Auto Inject Schema for this post:', 'kabook-auto-rank-math-snippet' );
     222        echo '</label><br>';
     223       
     224        echo '<select name="karms_auto_inject_override" id="karms_auto_inject_override" style="width:100%; margin-top:5px;">';
     225        echo '<option value="default" ' . selected( $value, 'default', false ) . '>' . esc_html__( 'Default (Global Settings)', 'kabook-auto-rank-math-snippet' ) . '</option>';
     226        echo '<option value="enabled" ' . selected( $value, 'enabled', false ) . '>' . esc_html__( 'Enable / Force Inject', 'kabook-auto-rank-math-snippet' ) . '</option>';
     227        echo '<option value="disabled" ' . selected( $value, 'disabled', false ) . '>' . esc_html__( 'Disable', 'kabook-auto-rank-math-snippet' ) . '</option>';
     228        echo '</select>';
     229       
     230        echo '<p class="description" style="margin-top: 8px;">';
     231        esc_html_e( 'Override the global auto-injection setting for this specific post.', 'kabook-auto-rank-math-snippet' );
     232        echo '</p>';
     233    }
     234
     235    public static function save_meta_box( $post_id ) {
     236        if ( ! isset( $_POST['karms_meta_box_nonce'] ) ) { return; }
     237        if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['karms_meta_box_nonce'] ) ), 'karms_save_meta_box_data' ) ) { return; }
     238        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; }
     239        if ( ! current_user_can( 'edit_post', $post_id ) ) { return; }
     240
     241        if ( isset( $_POST['karms_auto_inject_override'] ) ) {
     242            $new_val = sanitize_key( $_POST['karms_auto_inject_override'] );
     243            if ( in_array( $new_val, [ 'default', 'enabled', 'disabled' ] ) ) {
     244                update_post_meta( $post_id, '_karms_auto_inject_override', $new_val );
     245            }
     246        }
     247    }
     248}
     249
     250// -----------------------------------------------------------------------------
     251// 6. ADMIN SETTINGS CLASS
    289252// -----------------------------------------------------------------------------
    290253class KARMS_Admin {
    291     public static function get_default_options() {
    292         return [
    293             'auto_insert'               => 1,
    294             'show_meta_box'             => 0,
    295             'accordion_enabled'         => 1,
    296             'counter_enabled'           => 0,
    297             'initial_expand_first'      => 0,
    298             'question_font_size'        => 18,
    299             'question_color'            => '#003952',
    300             'question_background_color' => '#e2f6ff',
    301             'question_text_align'       => 'left',
    302             'answer_font_size'          => 16,
    303             'answer_color'              => '#003952',
    304             'answer_background_color'   => '#f3fbff',
    305             'answer_text_align'         => 'left',
    306             'border_width'              => 1,
    307             'border_style'              => 'solid',
    308             'border_color'              => '#c1ecff',
    309             'border_radius'             => 4,
    310         ];
    311     }
    312 
    313     public static function add_settings_page() {
    314         add_options_page(
    315             esc_html__( 'Settings for Rank Math Snippet', 'kabook-auto-rank-math-snippet' ),
    316             esc_html__( 'Kabook RM Snippet', 'kabook-auto-rank-math-snippet' ),
    317             'manage_options',
    318             'karms-settings',
    319             [ __CLASS__, 'render_settings_page' ]
    320         );
    321     }
    322 
    323     public static function enqueue_assets( $hook ) {
    324         if ( 'settings_page_karms-settings' !== $hook ) { return; }
    325        
    326         wp_enqueue_style( 'wp-color-picker' );
    327         wp_enqueue_style( 'karms-admin-css', KARMS_URL . 'assets/css/admin-style.css', [], KARMS_VERSION );
    328         wp_enqueue_script( 'karms-admin-js', KARMS_URL . 'assets/js/admin-script.js', [ 'jquery', 'wp-color-picker' ], KARMS_VERSION, true );
    329 
    330         wp_localize_script( 'karms-admin-js', 'karms_vars', [
    331             'nonce'   => wp_create_nonce( 'karms_reset_nonce_action' ),
    332             'confirm' => esc_html__( 'Are you sure you want to reset all settings to default?', 'kabook-auto-rank-math-snippet' )
    333         ]);
    334     }
    335 
    336     public static function register_settings() {
    337         register_setting( 'karms_options_group', 'karms_options', [ __CLASS__, 'sanitize_options' ] );
    338 
    339         add_settings_section( 'karms_general_section', esc_html__( 'General Settings', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-general' );
    340        
    341         add_settings_field( 'auto_insert', esc_html__( 'Auto Inject Schema', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [
    342             'label_for' => 'auto_insert',
    343             'desc'      => esc_html__( 'Automatically add [rank_math_rich_snippet] to posts if missing.', 'kabook-auto-rank-math-snippet' ) .
    344                            '<br><br><span style="color:#d63638; font-weight:600;">' . esc_html__( 'Important:', 'kabook-auto-rank-math-snippet' ) . '</span> ' .
    345                            esc_html__( 'If you use other schemas like "HowTo" in a specific post, please DISABLE auto-injection for that post using the "Injection Control Meta Box" (in the post editor) and insert shortcodes manually to avoid conflicts.', 'kabook-auto-rank-math-snippet' ),
    346         ] );
    347 
    348         add_settings_field( 'show_meta_box', esc_html__( 'Show Injection Control Meta Box', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [
    349             'label_for' => 'show_meta_box',
    350             'desc'      => esc_html__( 'Display a meta box in the post editor to manually Enable/Disable injection per post.', 'kabook-auto-rank-math-snippet' ),
    351         ] );
    352 
    353         add_settings_field( 'accordion_enabled', esc_html__( 'Enable Accordion Style', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [
    354             'label_for' => 'accordion_enabled',
    355             'desc'      => esc_html__( 'Convert the FAQ schema into an accordion style.', 'kabook-auto-rank-math-snippet' ),
    356         ] );
    357         add_settings_field( 'counter_enabled', esc_html__( 'Enable Numbering', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'counter_enabled' ] );
    358         add_settings_field( 'initial_expand_first', esc_html__( 'Expand First Item', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'initial_expand_first' ] );
    359 
    360         add_settings_section( 'karms_style_question', esc_html__( 'Question Styling', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
    361         add_settings_field( 'question_font_size', esc_html__( 'Font Size (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_question', [ 'label_for' => 'question_font_size' ] );
    362         add_settings_field( 'question_color', esc_html__( 'Text Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_question', [ 'label_for' => 'question_color' ] );
    363         add_settings_field( 'question_background_color', esc_html__( 'Background Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_question', [ 'label_for' => 'question_background_color' ] );
    364         add_settings_field( 'question_text_align', esc_html__( 'Text Align', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_select_align' ], 'karms-settings-style', 'karms_style_question', [ 'label_for' => 'question_text_align' ] );
    365 
    366         add_settings_section( 'karms_style_answer', esc_html__( 'Answer Styling', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
    367         add_settings_field( 'answer_font_size', esc_html__( 'Font Size (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_answer', [ 'label_for' => 'answer_font_size' ] );
    368         add_settings_field( 'answer_color', esc_html__( 'Text Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_answer', [ 'label_for' => 'answer_color' ] );
    369         add_settings_field( 'answer_background_color', esc_html__( 'Background Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_answer', [ 'label_for' => 'answer_background_color' ] );
    370         add_settings_field( 'answer_text_align', esc_html__( 'Text Align', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_select_align' ], 'karms-settings-style', 'karms_style_answer', [ 'label_for' => 'answer_text_align' ] );
    371 
    372         add_settings_section( 'karms_style_border', esc_html__( 'Border Styling', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
    373         add_settings_field( 'border_width', esc_html__( 'Width (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_width' ] );
    374         add_settings_field( 'border_style', esc_html__( 'Style', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_select_border' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_style' ] );
    375         add_settings_field( 'border_color', esc_html__( 'Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_color' ] );
    376         add_settings_field( 'border_radius', esc_html__( 'Radius (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_radius' ] );
    377     }
    378 
    379     public static function render_settings_page() {
    380         if ( ! current_user_can( 'manage_options' ) ) { return; }
    381        
    382         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    383         $active_tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : 'general';
    384         $base_url    = admin_url( 'options-general.php?page=karms-settings' );
    385        
    386         ?>
    387         <div class="wrap karms-settings-wrap" style="position: relative;">
    388             <h1 style="margin-bottom: 20px;"><?php esc_html_e( 'Kabook Auto Schema & Accordion for Rank Math', 'kabook-auto-rank-math-snippet' ); ?></h1>
    389            
    390             <div style="border-bottom: 1px solid #c3c4c7; margin-bottom: 20px; padding-bottom: 0; position: relative; z-index: 99;">
    391                 <?php
    392                 $tab_style_base   = 'text-decoration: none; padding: 10px 15px; border: 1px solid #c3c4c7; border-bottom: none; margin-left: 5px; display: inline-block; background: #e5e5e5; color: #50575e; font-weight: 500; font-size: 14px;';
    393                 $tab_style_active = 'background: #f0f0f1; border-bottom: 1px solid #f0f0f1; color: #000; margin-bottom: -1px;';
    394                 ?>
    395                 <a href="<?php echo esc_url( $base_url . '&tab=general' ); ?>" style="<?php echo esc_attr( $tab_style_base . ( $active_tab == 'general' ? $tab_style_active : '' ) ); ?>">
    396                     <?php esc_html_e( 'General', 'kabook-auto-rank-math-snippet' ); ?>
    397                 </a>
    398                 <a href="<?php echo esc_url( $base_url . '&tab=style' ); ?>" style="<?php echo esc_attr( $tab_style_base . ( $active_tab == 'style'   ? $tab_style_active : '' ) ); ?>">
    399                     <?php esc_html_e( 'Accordion Styles', 'kabook-auto-rank-math-snippet' ); ?>
    400                 </a>
    401             </div>
    402 
    403             <form action="options.php" method="post">
    404                 <?php
    405                 settings_fields( 'karms_options_group' );
    406                 echo '<input type="hidden" name="karms_current_tab_context" value="' . esc_attr( $active_tab ) . '">';
    407 
    408                 if ( $active_tab == 'general' ) {
    409                     do_settings_sections( 'karms-settings-general' );
    410                 } else {
    411                     do_settings_sections( 'karms-settings-style' );
    412                 }
    413                 submit_button();
    414                 ?>
    415                 <div style="margin-top: 20px; border-top: 1px solid #ccc; padding-top: 20px;">
    416                     <button type="button" id="karms_reset_btn" class="button button-secondary" style="color: #a00; border-color: #a00;">
    417                         <?php esc_html_e( 'Reset to Defaults', 'kabook-auto-rank-math-snippet' ); ?>
    418                     </button>
    419                 </div>
    420             </form>
    421         </div>
    422         <?php
    423     }
    424 
    425     public static function sanitize_options( $input ) {
    426         $current_options = get_option( 'karms_options', self::get_default_options() );
    427         if ( ! is_array( $current_options ) ) { $current_options = self::get_default_options(); }
    428 
    429         $defaults = self::get_default_options();
    430         $new_input = $current_options;
    431        
    432         // phpcs:ignore WordPress.Security.NonceVerification.Missing
    433         $context = isset( $_POST['karms_current_tab_context'] ) ? sanitize_text_field( wp_unslash( $_POST['karms_current_tab_context'] ) ) : 'general';
    434        
    435         $general_keys = [ 'auto_insert', 'show_meta_box', 'accordion_enabled', 'counter_enabled', 'initial_expand_first' ];
    436 
    437         if ( $context === 'general' ) {
    438             foreach ( $general_keys as $key ) {
    439                 $new_input[ $key ] = isset( $input[ $key ] ) ? 1 : 0;
    440             }
    441         } else {
    442             foreach ( $defaults as $key => $default ) {
    443                 if ( ! in_array( $key, $general_keys, true ) ) {
    444                     if ( isset( $input[ $key ] ) ) {
    445                         if ( strpos( $key, 'color' ) !== false ) {
    446                             $new_input[ $key ] = sanitize_hex_color( $input[ $key ] );
    447                         } elseif ( is_numeric( $default ) ) {
    448                             $new_input[ $key ] = absint( $input[ $key ] );
    449                         } else {
    450                             $new_input[ $key ] = sanitize_text_field( $input[ $key ] );
    451                         }
    452                     }
    453                 }
    454             }
    455         }
    456         return $new_input;
    457     }
    458 
    459     public static function field_checkbox( $args ) {
    460         $options = get_option( 'karms_options', self::get_default_options() );
    461         $key     = $args['label_for'];
    462         $checked = isset( $options[ $key ] ) ? $options[ $key ] : 0;
    463         echo '<input type="checkbox" name="karms_options[' . esc_attr( $key ) . ']" value="1" ' . checked( 1, $checked, false ) . ' /> ';
    464         if ( ! empty( $args['desc'] ) ) {
    465             echo '<span class="description">' . wp_kses_post( $args['desc'] ) . '</span>';
    466         }
    467     }
    468     public static function field_number( $args ) {
    469         $options = get_option( 'karms_options', self::get_default_options() );
    470         $key     = $args['label_for'];
    471         $val     = isset( $options[ $key ] ) ? $options[ $key ] : '';
    472         echo '<input type="number" name="karms_options[' . esc_attr( $key ) . ']" value="' . esc_attr( $val ) . '" class="small-text" />';
    473     }
    474     public static function field_color( $args ) {
    475         $options  = get_option( 'karms_options', self::get_default_options() );
    476         $key      = $args['label_for'];
    477         $val      = isset( $options[ $key ] ) ? $options[ $key ] : '';
    478         $defaults = self::get_default_options();
    479         $def      = isset( $defaults[ $key ] ) ? $defaults[ $key ] : '';
    480         echo '<input type="text" name="karms_options[' . esc_attr( $key ) . ']" value="' . esc_attr( $val ) . '" class="karms-color-picker" data-default-color="' . esc_attr( $def ) . '" />';
    481     }
    482     public static function field_select_align( $args ) {
    483         $options = get_option( 'karms_options', self::get_default_options() );
    484         $key     = $args['label_for'];
    485         $val     = isset( $options[ $key ] ) ? $options[ $key ] : 'left';
    486         echo '<select name="karms_options[' . esc_attr( $key ) . ']">';
    487         foreach ( [ 'left', 'center', 'right' ] as $item ) {
    488             echo '<option value="' . esc_attr( $item ) . '" ' . selected( $item, $val, false ) . '>' . esc_html( ucfirst( $item ) ) . '</option>';
    489         }
    490         echo '</select>';
    491     }
    492     public static function field_select_border( $args ) {
    493         $options = get_option( 'karms_options', self::get_default_options() );
    494         $key     = $args['label_for'];
    495         $val     = isset( $options[ $key ] ) ? $options[ $key ] : 'solid';
    496         echo '<select name="karms_options[' . esc_attr( $key ) . ']">';
    497         foreach ( [ 'solid', 'dashed', 'dotted', 'none' ] as $item ) {
    498             echo '<option value="' . esc_attr( $item ) . '" ' . selected( $item, $val, false ) . '>' . esc_html( ucfirst( $item ) ) . '</option>';
    499         }
    500         echo '</select>';
    501     }
    502 
    503     public static function ajax_reset_settings() {
    504         check_ajax_referer( 'karms_reset_nonce_action', 'security' );
    505         if ( ! current_user_can( 'manage_options' ) ) {
    506             wp_send_json_error();
    507         }
    508         remove_filter( 'sanitize_option_karms_options', [ __CLASS__, 'sanitize_options' ] );
    509         update_option( 'karms_options', self::get_default_options() );
    510         wp_send_json_success();
    511     }
    512 }
    513 
    514 // -----------------------------------------------------------------------------
    515 // 7. INIT
     254
     255    public static function get_default_options() {
     256        return [
     257            'auto_insert'             => 1,
     258            'show_meta_box'           => 0,
     259            'accordion_enabled'       => 1,
     260            'counter_enabled'         => 0,
     261            'initial_expand_first'    => 0,
     262            'accordion_animation'     => 'slide',
     263            'accordion_speed'         => 300,
     264            'question_font_size'      => 18,
     265            'question_color'          => '#003952',
     266            'question_background_color' => '#e2f6ff',
     267            'question_text_align'     => 'left',
     268            'answer_font_size'        => 16,
     269            'answer_color'            => '#003952',
     270            'answer_background_color' => '#f3fbff',
     271            'answer_text_align'       => 'left',
     272            'border_width'            => 1,
     273            'border_style'            => 'solid',
     274            'border_color'            => '#c1ecff',
     275            'border_radius'           => 12,
     276        ];
     277    }
     278
     279    public static function add_settings_page() {
     280        add_options_page(
     281            esc_html__( 'Kabook Auto Schema Settings', 'kabook-auto-rank-math-snippet' ),
     282            esc_html__( 'Kabook RM Snippet', 'kabook-auto-rank-math-snippet' ),
     283            'manage_options',
     284            'karms-settings',
     285            [ __CLASS__, 'render_settings_page' ]
     286        );
     287    }
     288
     289    public static function enqueue_assets( $hook ) {
     290        if ( 'settings_page_karms-settings' !== $hook ) { return; }
     291       
     292        wp_enqueue_style( 'wp-color-picker' );
     293        wp_enqueue_style( 'karms-admin-css', KARMS_URL . 'assets/css/admin-style.css', [], KARMS_VERSION );
     294        wp_enqueue_script( 'karms-admin-js', KARMS_URL . 'assets/js/admin-script.js', [ 'jquery', 'wp-color-picker' ], KARMS_VERSION, true );
     295       
     296        wp_localize_script( 'karms-admin-js', 'karms_vars', [
     297            'nonce'       => wp_create_nonce( 'karms_reset_nonce_action' ),
     298            'confirm'     => esc_html__( 'Are you sure you want to reset all settings to default?', 'kabook-auto-rank-math-snippet' ),
     299            'msg_success' => esc_html__( 'Settings reset successfully. Reloading...', 'kabook-auto-rank-math-snippet' ),
     300            'msg_error'   => esc_html__( 'Error resetting settings. Please try again.', 'kabook-auto-rank-math-snippet' ),
     301        ]);
     302    }
     303
     304    public static function register_settings() {
     305        register_setting( 'karms_options_group', 'karms_options', [ __CLASS__, 'sanitize_options' ] );
     306
     307        // TAB 1: General Settings
     308        add_settings_section( 'karms_general_section', esc_html__( 'General Settings', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-general' );
     309        add_settings_field( 'auto_insert', esc_html__( 'Auto Inject Schema', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'auto_insert', 'desc' => esc_html__( 'Automatically add [rank_math_rich_snippet] to posts if missing.', 'kabook-auto-rank-math-snippet' ) ] );
     310        add_settings_field( 'show_meta_box', esc_html__( 'Show Meta Box', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'show_meta_box', 'desc' => esc_html__( 'Show per-post injection control.', 'kabook-auto-rank-math-snippet' ) ] );
     311        add_settings_field( 'accordion_enabled', esc_html__( 'Enable Accordion', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'accordion_enabled' ] );
     312        add_settings_field( 'counter_enabled', esc_html__( 'Enable Numbering', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'counter_enabled' ] );
     313        add_settings_field( 'initial_expand_first', esc_html__( 'Expand First Item', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_checkbox' ], 'karms-settings-general', 'karms_general_section', [ 'label_for' => 'initial_expand_first' ] );
     314
     315        // TAB 2: Styles & Animations
     316        add_settings_section( 'karms_style_main', esc_html__( 'Animation Settings', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
     317        add_settings_field( 'accordion_animation', esc_html__( 'Opening Animation', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_select_animation' ], 'karms-settings-style', 'karms_style_main', [ 'label_for' => 'accordion_animation' ] );
     318        add_settings_field( 'accordion_speed', esc_html__( 'Animation Speed (ms)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_main', [ 'label_for' => 'accordion_speed', 'desc' => esc_html__( 'e.g. 300 for fast, 1200 for slow.', 'kabook-auto-rank-math-snippet' ) ] );
     319
     320        add_settings_section( 'karms_style_q', esc_html__( 'Question Styles', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
     321        add_settings_field( 'question_font_size', esc_html__( 'Font Size (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_q', [ 'label_for' => 'question_font_size' ] );
     322        add_settings_field( 'question_color', esc_html__( 'Text Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_q', [ 'label_for' => 'question_color' ] );
     323        add_settings_field( 'question_background_color', esc_html__( 'Background Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_q', [ 'label_for' => 'question_background_color' ] );
     324        add_settings_field( 'question_text_align', esc_html__( 'Text Alignment', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_select_align' ], 'karms-settings-style', 'karms_style_q', [ 'label_for' => 'question_text_align' ] );
     325
     326        add_settings_section( 'karms_style_a', esc_html__( 'Answer Styles', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
     327        add_settings_field( 'answer_font_size', esc_html__( 'Font Size (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_a', [ 'label_for' => 'answer_font_size' ] );
     328        add_settings_field( 'answer_color', esc_html__( 'Text Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_a', [ 'label_for' => 'answer_color' ] );
     329        add_settings_field( 'answer_background_color', esc_html__( 'Background Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_a', [ 'label_for' => 'answer_background_color' ] );
     330        add_settings_field( 'answer_text_align', esc_html__( 'Text Alignment', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_select_align' ], 'karms-settings-style', 'karms_style_a', [ 'label_for' => 'answer_text_align' ] );
     331
     332        add_settings_section( 'karms_style_border', esc_html__( 'Border & Radius', 'kabook-auto-rank-math-snippet' ), null, 'karms-settings-style' );
     333        add_settings_field( 'border_width', esc_html__( 'Border Width (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_width' ] );
     334        add_settings_field( 'border_radius', esc_html__( 'Corner Radius (px)', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_number' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_radius' ] );
     335        add_settings_field( 'border_color', esc_html__( 'Border Color', 'kabook-auto-rank-math-snippet' ), [ __CLASS__, 'field_color' ], 'karms-settings-style', 'karms_style_border', [ 'label_for' => 'border_color' ] );
     336    }
     337
     338    public static function render_settings_page() {
     339        if ( ! current_user_can( 'manage_options' ) ) { return; }
     340       
     341        $raw_tab    = filter_input( INPUT_GET, 'tab' );
     342        $active_tab = $raw_tab ? sanitize_key( $raw_tab ) : 'general';
     343       
     344        $base_url   = admin_url( 'options-general.php?page=karms-settings' );
     345        $logo_url   = KARMS_URL . 'assets/images/icon-kabook.png';
     346        ?>
     347        <div class="karms-admin-wrapper">
     348            <header class="karms-header">
     349                <h1><?php esc_html_e( 'Kabook Auto Schema Settings', 'kabook-auto-rank-math-snippet' ); ?></h1>
     350                <div class="karms-logo"><img src="<?php echo esc_url( $logo_url ); ?>" alt="Kabook"></div>
     351            </header>
     352            <div class="karms-inner-content">
     353                <nav class="karms-nav-tab-wrapper">
     354                    <a href="<?php echo esc_url( $base_url . '&tab=general' ); ?>" class="karms-nav-tab <?php echo $active_tab == 'general' ? 'karms-nav-tab-active' : ''; ?>"><?php esc_html_e( 'General System', 'kabook-auto-rank-math-snippet' ); ?></a>
     355                    <a href="<?php echo esc_url( $base_url . '&tab=style' ); ?>" class="karms-nav-tab <?php echo $active_tab == 'style' ? 'karms-nav-tab-active' : ''; ?>"><?php esc_html_e( 'Accordion Styles', 'kabook-auto-rank-math-snippet' ); ?></a>
     356                </nav>
     357                <form action="options.php" method="post">
     358                    <?php
     359                    settings_fields( 'karms_options_group' );
     360                    echo '<input type="hidden" name="karms_current_tab_context" value="' . esc_attr( $active_tab ) . '">';
     361                   
     362                    echo '<div class="karms-settings-section-wrap">';
     363                    if ( $active_tab == 'general' ) { self::render_custom_section( 'karms-settings-general' ); }
     364                    else { self::render_custom_section( 'karms-settings-style' ); }
     365                    echo '</div>';
     366                    ?>
     367                    <div class="karms-submit-area">
     368                        <?php submit_button( __( 'Save Changes', 'kabook-auto-rank-math-snippet' ), 'primary karms-save-btn' ); ?>
     369                        <button type="button" id="karms_reset_btn" class="button"><?php esc_html_e( 'Reset Defaults', 'kabook-auto-rank-math-snippet' ); ?></button>
     370                    </div>
     371                </form>
     372            </div>
     373        </div>
     374        <?php
     375    }
     376
     377    private static function render_custom_section( $page_slug ) {
     378        global $wp_settings_sections, $wp_settings_fields;
     379        if ( ! isset( $wp_settings_sections[ $page_slug ] ) ) { return; }
     380       
     381        foreach ( (array) $wp_settings_sections[ $page_slug ] as $section ) {
     382            if ( $section['title'] ) { echo "<h2>" . esc_html( $section['title'] ) . "</h2>"; }
     383            if ( ! isset( $wp_settings_fields[ $page_slug ][ $section['id'] ] ) ) { continue; }
     384            foreach ( (array) $wp_settings_fields[ $page_slug ][ $section['id'] ] as $field ) {
     385                echo '<div class="karms-field-row">';
     386                echo '<div class="karms-field-label"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['title'] ) . '</label></div>';
     387                echo '<div class="karms-field-input">';
     388                call_user_func( $field['callback'], $field['args'] );
     389                echo '</div></div>';
     390            }
     391        }
     392    }
     393
     394    public static function sanitize_options( $input ) {
     395        // SECURITY CHECK: Verify nonce for options.php form submission
     396        if ( isset( $_POST['_wpnonce'] ) ) {
     397            if ( ! wp_verify_nonce( sanitize_key( $_POST['_wpnonce'] ), 'karms_options_group-options' ) ) {
     398                add_settings_error( 'karms_options', 'invalid_nonce', esc_html__( 'Security check failed. Please try again.', 'kabook-auto-rank-math-snippet' ) );
     399                return get_option( 'karms_options', self::get_default_options() );
     400            }
     401        }
     402
     403        $current_options = get_option( 'karms_options', self::get_default_options() );
     404        $defaults = self::get_default_options();
     405        $new_input = is_array( $current_options ) ? $current_options : $defaults;
     406
     407        $context = filter_input( INPUT_POST, 'karms_current_tab_context' );
     408        if ( $context ) {
     409            $context = sanitize_key( $context );
     410        }
     411
     412        foreach ( $defaults as $key => $default ) {
     413            if ( isset( $input[$key] ) ) {
     414                if ( strpos( $key, 'color' ) !== false ) {
     415                    $new_input[$key] = sanitize_hex_color( $input[$key] );
     416                }
     417                elseif ( is_numeric( $default ) ) {
     418                    $new_input[$key] = absint( $input[$key] );
     419                }
     420                else {
     421                    $new_input[$key] = sanitize_text_field( $input[$key] );
     422                }
     423            } else {
     424                $tab_checkboxes = ($context === 'general') ? ['auto_insert', 'show_meta_box', 'accordion_enabled', 'counter_enabled', 'initial_expand_first'] : [];
     425                if ( in_array($key, $tab_checkboxes) ) {
     426                    $new_input[$key] = 0;
     427                }
     428            }
     429        }
     430        return $new_input;
     431    }
     432
     433    public static function field_checkbox( $args ) {
     434        $options = get_option( 'karms_options', self::get_default_options() );
     435        $key = $args['label_for'];
     436        $checked = isset( $options[ $key ] ) ? $options[ $key ] : 0;
     437        echo '<input type="checkbox" name="karms_options[' . esc_attr( $key ) . ']" id="' . esc_attr( $key ) . '" value="1" ' . checked( 1, $checked, false ) . ' /> ';
     438        if ( ! empty( $args['desc'] ) ) { echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>'; }
     439    }
     440
     441    public static function field_select_align( $args ) {
     442        $options = get_option( 'karms_options', self::get_default_options() );
     443        $key = $args['label_for'];
     444        $val = isset( $options[$key] ) ? $options[$key] : 'left';
     445       
     446        $alignments = [
     447            'left'   => esc_html__( 'Left', 'kabook-auto-rank-math-snippet' ),
     448            'center' => esc_html__( 'Center', 'kabook-auto-rank-math-snippet' ),
     449            'right'  => esc_html__( 'Right', 'kabook-auto-rank-math-snippet' ),
     450        ];
     451
     452        echo '<select name="karms_options[' . esc_attr( $key ) . ']" id="' . esc_attr( $key ) . '">';
     453        foreach ( $alignments as $value => $label ) {
     454            echo '<option value="' . esc_attr( $value ) . '" ' . selected( $value, $val, false ) . '>' . esc_html( $label ) . '</option>';
     455        }
     456        echo '</select>';
     457    }
     458
     459    public static function field_select_animation( $args ) {
     460        $options = get_option( 'karms_options', self::get_default_options() );
     461        $key = $args['label_for'];
     462        $val = isset( $options[$key] ) ? $options[$key] : 'slide';
     463        echo '<select name="karms_options[' . esc_attr( $key ) . ']" id="' . esc_attr( $key ) . '">';
     464        echo '<option value="slide" ' . selected( 'slide', $val, false ) . '>' . esc_html__( 'Slide Down', 'kabook-auto-rank-math-snippet' ) . '</option>';
     465        echo '<option value="fade" ' . selected( 'fade', $val, false ) . '>' . esc_html__( 'Fade In', 'kabook-auto-rank-math-snippet' ) . '</option>';
     466        echo '<option value="zoom" ' . selected( 'zoom', $val, false ) . '>' . esc_html__( 'Zoom In', 'kabook-auto-rank-math-snippet' ) . '</option>';
     467        echo '</select>';
     468    }
     469
     470    public static function field_number( $args ) {
     471        $options = get_option( 'karms_options', self::get_default_options() );
     472        $key = $args['label_for'];
     473        $val = isset( $options[ $key ] ) ? $options[ $key ] : '';
     474        echo '<input type="number" name="karms_options[' . esc_attr( $key ) . ']" id="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" />';
     475        if ( ! empty( $args['desc'] ) ) { echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>'; }
     476    }
     477
     478    public static function field_color( $args ) {
     479        $options = get_option( 'karms_options', self::get_default_options() );
     480        $key = $args['label_for'];
     481        $val = isset( $options[ $key ] ) ? $options[ $key ] : '';
     482        echo '<input type="text" name="karms_options[' . esc_attr( $key ) . ']" id="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" class="karms-color-picker" />';
     483    }
     484
     485    public static function ajax_reset_settings() {
     486        check_ajax_referer( 'karms_reset_nonce_action', 'security' );
     487        if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error(); }
     488        update_option( 'karms_options', self::get_default_options() );
     489        wp_send_json_success();
     490    }
     491}
     492
     493// -----------------------------------------------------------------------------
     494// 7. INITIALIZATION
    516495// -----------------------------------------------------------------------------
    517496KARMS_Loader::init();
  • kabook-auto-rank-math-snippet/trunk/languages/kabook-auto-rank-math-snippet-fa_IR.po

    r3414326 r3431166  
    11msgid ""
    22msgstr ""
    3 "Project-Id-Version: Kabook Auto Schema & Accordion for Rank Math 1.1.0\n"
    4 "Report-Msgid-Bugs-To: https://kabook.ir/contact/\n"
    5 "POT-Creation-Date: 2025-12-08 15:27+0330\n"
    6 "PO-Revision-Date: 2025-12-08 15:30+0330\n"
    7 "Last-Translator: Saeid Afshari <info@kabook.ir>\n"
    8 "Language-Team: Kabook Dev Team <admin@kabook.ir>\n"
     3"Project-Id-Version: Kabook Auto Schema & Accordion for Rank Math\n"
     4"POT-Creation-Date: 2026-01-02 19:51+0330\n"
     5"PO-Revision-Date: 2026-01-02 19:52+0330\n"
     6"Last-Translator: Saeid Afshari <admin@kabook.ir>\n"
     7"Language-Team: Kabook Team <https://www.kabook.ir>\n"
    98"Language: fa_IR\n"
    109"MIME-Version: 1.0\n"
    1110"Content-Type: text/plain; charset=UTF-8\n"
    1211"Content-Transfer-Encoding: 8bit\n"
    13 "X-Generator: Poedit 3.5\n"
    14 "X-Domain: kabook-auto-rank-math-snippet\n"
    15 #. translators: %s: Plugin Name
    16 #: kabook-auto-rank-math-snippet.php:73
     12"Plural-Forms: nplurals=2; plural=(n==0 || n==1);\n"
     13"X-Generator: Poedit 3.7\n"
     14"X-Poedit-Basepath: ..\n"
     15"X-Poedit-Flags-xgettext: --add-comments=translators:\n"
     16"X-Poedit-WPHeader: kabook-auto-rank-math-snippet.php\n"
     17"X-Poedit-SourceCharset: UTF-8\n"
     18"X-Poedit-KeywordsList: "
     19"__;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
     20"X-Poedit-SearchPath-0: .\n"
     21"X-Poedit-SearchPathExcluded-0: *.js\n"
     22
     23#. translators: 1: Plugin Name, 2: Dependency Name
     24#: kabook-auto-rank-math-snippet.php:49
    1725#, php-format
    18 msgid "%s requires Rank Math SEO PRO to be installed and active."
    19 msgstr "افزونه %s نیاز دارد که Rank Math SEO PRO نصب و فعال باشد."
    20 
    21 #: kabook-auto-rank-math-snippet.php:91
     26msgid "%1$s requires %2$s to be installed and active."
     27msgstr "افزونه %1$s نیاز دارد که %2$s نصب و فعال باشد."
     28
     29#: kabook-auto-rank-math-snippet.php:50
     30msgid "Kabook Auto Schema & Accordion"
     31msgstr "اسکیما و آکاردئون خودکار کابوک"
     32
     33#: kabook-auto-rank-math-snippet.php:51
     34msgid "Rank Math SEO PRO"
     35msgstr "Rank Math SEO PRO"
     36
     37#: kabook-auto-rank-math-snippet.php:68
    2238msgid "Settings"
    2339msgstr "تنظیمات"
    2440
    25 #: kabook-auto-rank-math-snippet.php:243
     41#: kabook-auto-rank-math-snippet.php:205
    2642msgid "Schema Injection Settings"
    27 msgstr "تنظیمات درج اسکیما"
    28 
    29 #: kabook-auto-rank-math-snippet.php:261
     43msgstr "تنظیمات افزودن اسکیما"
     44
     45#: kabook-auto-rank-math-snippet.php:221
    3046msgid "Auto Inject Schema for this post:"
    31 msgstr "درج خودکار اسکیما برای این نوشته:"
    32 
    33 #: kabook-auto-rank-math-snippet.php:265
     47msgstr "افزودن خودکار اسکیما برای این نوشته:"
     48
     49#: kabook-auto-rank-math-snippet.php:225
    3450msgid "Default (Global Settings)"
    3551msgstr "پیش‌فرض (تنظیمات سراسری)"
    3652
    37 #: kabook-auto-rank-math-snippet.php:266
     53#: kabook-auto-rank-math-snippet.php:226
    3854msgid "Enable / Force Inject"
    39 msgstr "فعال‌سازی / درج اجباری"
    40 
    41 #: kabook-auto-rank-math-snippet.php:267
     55msgstr "فعال‌سازی / اجبار به افزودن"
     56
     57#: kabook-auto-rank-math-snippet.php:227
    4258msgid "Disable"
    4359msgstr "غیرفعال‌سازی"
    4460
    45 #: kabook-auto-rank-math-snippet.php:271
     61#: kabook-auto-rank-math-snippet.php:231
    4662msgid "Override the global auto-injection setting for this specific post."
    47 msgstr "بازنویسی تنظیمات سراسری درج خودکار برای این نوشته خاص."
    48 
    49 #: kabook-auto-rank-math-snippet.php:319
    50 msgid "Settings for Rank Math Snippet"
    51 msgstr "تنظیمات اسنیپت رنک‌مث"
    52 
    53 #: kabook-auto-rank-math-snippet.php:320
     63msgstr "بازنویسی تنظیمات سراسری افزودن خودکار برای این نوشته خاص."
     64
     65#: kabook-auto-rank-math-snippet.php:281 kabook-auto-rank-math-snippet.php:349
     66msgid "Kabook Auto Schema Settings"
     67msgstr "تنظیمات اسکیما خودکار کابوک"
     68
     69#: kabook-auto-rank-math-snippet.php:282
    5470msgid "Kabook RM Snippet"
    5571msgstr "اسنیپت Kabook RM"
    5672
    57 #: kabook-auto-rank-math-snippet.php:336
     73#: kabook-auto-rank-math-snippet.php:298
    5874msgid "Are you sure you want to reset all settings to default?"
    5975msgstr "آیا مطمئن هستید که می‌خواهید تمام تنظیمات را به حالت پیش‌فرض بازگردانید؟"
    6076
    61 #: kabook-auto-rank-math-snippet.php:343
     77#: kabook-auto-rank-math-snippet.php:299
     78msgid "Settings reset successfully. Reloading..."
     79msgstr "تنظیمات با موفقیت بازنشانی شدند. در حال بارگیری مجدد..."
     80
     81#: kabook-auto-rank-math-snippet.php:300
     82msgid "Error resetting settings. Please try again."
     83msgstr "خطا در بازنشانی تنظیمات. لطفا دوباره امتحان کنید."
     84
     85#: kabook-auto-rank-math-snippet.php:308
    6286msgid "General Settings"
    6387msgstr "تنظیمات عمومی"
    6488
    65 #: kabook-auto-rank-math-snippet.php:346
     89#: kabook-auto-rank-math-snippet.php:309
    6690msgid "Auto Inject Schema"
    67 msgstr "درج خودکار اسکیما"
    68 
    69 #: kabook-auto-rank-math-snippet.php:348
     91msgstr "افزودن خودکار اسکیما"
     92
     93#: kabook-auto-rank-math-snippet.php:309
    7094msgid "Automatically add [rank_math_rich_snippet] to posts if missing."
    71 msgstr "افزودن خودکار شورت‌کد [rank_math_rich_snippet] به نوشته‌ها در صورت موجود نبودن."
    72 
    73 #: kabook-auto-rank-math-snippet.php:349
    74 msgid "Important:"
    75 msgstr "مهم:"
    76 
    77 #: kabook-auto-rank-math-snippet.php:350
    78 msgid ""
    79 "If you use other schemas like \"HowTo\" in a specific post, please DISABLE "
    80 "auto-injection for that post using the \"Injection Control Meta Box\" (in "
    81 "the post editor) and insert shortcodes manually to avoid conflicts."
    8295msgstr ""
    83 "اگر از اسکیماهای دیگر مانند \"HowTo\" در یک نوشته خاص استفاده می‌کنید، لطفاً "
    84 "درج خودکار را برای آن نوشته از طریق «متاباکس کنترل درج» (در ویرایشگر نوشته) "
    85 "غیرفعال کرده و شورت‌کدها را دستی وارد کنید تا از تداخل جلوگیری شود."
    86 
    87 #: kabook-auto-rank-math-snippet.php:353
    88 msgid "Show Injection Control Meta Box"
    89 msgstr "نمایش متاباکس کنترل درج"
    90 
    91 #: kabook-auto-rank-math-snippet.php:355
    92 msgid ""
    93 "Display a meta box in the post editor to manually Enable/Disable injection "
    94 "per post."
    95 msgstr ""
    96 "نمایش یک متاباکس در ویرایشگر نوشته برای فعال یا غیرفعال کردن دستی عملیات درج "
    97 "برای هر نوشته."
    98 
    99 #: kabook-auto-rank-math-snippet.php:358
    100 msgid "Enable Accordion Style"
    101 msgstr "فعال‌سازی استایل آکاردئونی"
    102 
    103 #: kabook-auto-rank-math-snippet.php:360
    104 msgid "Convert the FAQ schema into an accordion style."
    105 msgstr "تبدیل اسکیمای سوالات متداول (FAQ) به استایل آکاردئونی."
    106 
    107 #: kabook-auto-rank-math-snippet.php:362
     96"افزودن خودکار شورت‌کد [rank_math_rich_snippet] به نوشته‌ها در صورت عدم وجود."
     97
     98#: kabook-auto-rank-math-snippet.php:310
     99msgid "Show Meta Box"
     100msgstr "نمایش متاباکس"
     101
     102#: kabook-auto-rank-math-snippet.php:310
     103msgid "Show per-post injection control."
     104msgstr "نمایش کنترل افزودن اسکیما در هر نوشته."
     105
     106#: kabook-auto-rank-math-snippet.php:311
     107msgid "Enable Accordion"
     108msgstr "فعال‌سازی آکاردئون"
     109
     110#: kabook-auto-rank-math-snippet.php:312
    108111msgid "Enable Numbering"
    109112msgstr "فعال‌سازی شماره‌گذاری"
    110113
    111 #: kabook-auto-rank-math-snippet.php:363
     114#: kabook-auto-rank-math-snippet.php:313
    112115msgid "Expand First Item"
    113116msgstr "باز بودن اولین آیتم"
    114117
    115 #: kabook-auto-rank-math-snippet.php:365
    116 msgid "Question Styling"
    117 msgstr "استایل‌دهی سوال"
    118 
    119 #: kabook-auto-rank-math-snippet.php:366 kabook-auto-rank-math-snippet.php:372
     118#: kabook-auto-rank-math-snippet.php:316
     119msgid "Animation Settings"
     120msgstr "تنظیمات انیمیشن"
     121
     122#: kabook-auto-rank-math-snippet.php:317
     123msgid "Opening Animation"
     124msgstr "انیمیشن باز شدن"
     125
     126#: kabook-auto-rank-math-snippet.php:318
     127msgid "Animation Speed (ms)"
     128msgstr "سرعت انیمیشن (میلی‌ثانیه)"
     129
     130#: kabook-auto-rank-math-snippet.php:318
     131msgid "e.g. 300 for fast, 1200 for slow."
     132msgstr "مثلاً ۳۰۰ برای سریع، ۱۲۰۰ برای کند."
     133
     134#: kabook-auto-rank-math-snippet.php:320
     135msgid "Question Styles"
     136msgstr "استایل‌های سوال"
     137
     138#: kabook-auto-rank-math-snippet.php:321 kabook-auto-rank-math-snippet.php:327
    120139msgid "Font Size (px)"
    121140msgstr "اندازه فونت (پیکسل)"
    122141
    123 #: kabook-auto-rank-math-snippet.php:367 kabook-auto-rank-math-snippet.php:373
     142#: kabook-auto-rank-math-snippet.php:322 kabook-auto-rank-math-snippet.php:328
    124143msgid "Text Color"
    125144msgstr "رنگ متن"
    126145
    127 #: kabook-auto-rank-math-snippet.php:368 kabook-auto-rank-math-snippet.php:374
     146#: kabook-auto-rank-math-snippet.php:323 kabook-auto-rank-math-snippet.php:329
    128147msgid "Background Color"
    129148msgstr "رنگ پس‌زمینه"
    130149
    131 #: kabook-auto-rank-math-snippet.php:369 kabook-auto-rank-math-snippet.php:375
    132 msgid "Text Align"
     150#: kabook-auto-rank-math-snippet.php:324 kabook-auto-rank-math-snippet.php:330
     151msgid "Text Alignment"
    133152msgstr "تراز متن"
    134153
    135 #: kabook-auto-rank-math-snippet.php:371
    136 msgid "Answer Styling"
    137 msgstr "استایل‌دهی پاسخ"
    138 
    139 #: kabook-auto-rank-math-snippet.php:377
    140 msgid "Border Styling"
    141 msgstr "استایل‌دهی حاشیه (Border)"
    142 
    143 #: kabook-auto-rank-math-snippet.php:378
    144 msgid "Width (px)"
    145 msgstr "عرض (پیکسل)"
    146 
    147 #: kabook-auto-rank-math-snippet.php:379
    148 msgid "Style"
    149 msgstr "نوع استایل"
    150 
    151 #: kabook-auto-rank-math-snippet.php:380
    152 msgid "Color"
    153 msgstr "رنگ"
    154 
    155 #: kabook-auto-rank-math-snippet.php:381
    156 msgid "Radius (px)"
    157 msgstr "شعاع گردی (پیکسل)"
     154#: kabook-auto-rank-math-snippet.php:326
     155msgid "Answer Styles"
     156msgstr "استایل‌های پاسخ"
     157
     158#: kabook-auto-rank-math-snippet.php:332
     159msgid "Border & Radius"
     160msgstr "حاشیه و شعاع گردی"
     161
     162#: kabook-auto-rank-math-snippet.php:333
     163msgid "Border Width (px)"
     164msgstr "عرض حاشیه (پیکسل)"
     165
     166#: kabook-auto-rank-math-snippet.php:334
     167msgid "Corner Radius (px)"
     168msgstr "شعاع گوشه‌ها (پیکسل)"
     169
     170#: kabook-auto-rank-math-snippet.php:335
     171msgid "Border Color"
     172msgstr "رنگ حاشیه"
     173
     174#: kabook-auto-rank-math-snippet.php:354
     175msgid "General System"
     176msgstr "سیستم عمومی"
     177
     178#: kabook-auto-rank-math-snippet.php:355
     179msgid "Accordion Styles"
     180msgstr "استایل‌های آکاردئون"
     181
     182#: kabook-auto-rank-math-snippet.php:368
     183msgid "Save Changes"
     184msgstr "ذخیره تغییرات"
     185
     186#: kabook-auto-rank-math-snippet.php:369
     187msgid "Reset Defaults"
     188msgstr "بازنشانی به پیش‌فرض‌ها"
     189
     190#: kabook-auto-rank-math-snippet.php:398
     191msgid "Security check failed. Please try again."
     192msgstr "بررسی امنیتی با شکست مواجه شد. لطفاً دوباره تلاش کنید."
     193
     194#: kabook-auto-rank-math-snippet.php:447
     195msgid "Left"
     196msgstr "چپ"
     197
     198#: kabook-auto-rank-math-snippet.php:448
     199msgid "Center"
     200msgstr "وسط"
     201
     202#: kabook-auto-rank-math-snippet.php:449
     203msgid "Right"
     204msgstr "راست"
     205
     206#: kabook-auto-rank-math-snippet.php:464
     207msgid "Slide Down"
     208msgstr "کشویی به پایین"
     209
     210#: kabook-auto-rank-math-snippet.php:465
     211msgid "Fade In"
     212msgstr "محو شدن (Fade)"
     213
     214#: kabook-auto-rank-math-snippet.php:466
     215msgid "Zoom In"
     216msgstr "بزرگنمایی (Zoom)"
    158217
    159218#. Plugin Name of the plugin/theme
    160 #: kabook-auto-rank-math-snippet.php:393
    161219msgid "Kabook Auto Schema & Accordion for Rank Math"
    162220msgstr "اسکیما و آکاردئون خودکار کابوک برای رنک‌مث"
    163221
    164 #: kabook-auto-rank-math-snippet.php:401
    165 msgid "General"
    166 msgstr "عمومی"
    167 
    168 #: kabook-auto-rank-math-snippet.php:404
    169 msgid "Accordion Styles"
    170 msgstr "استایل‌های آکاردئون"
    171 
    172 #: kabook-auto-rank-math-snippet.php:422
    173 msgid "Reset to Defaults"
    174 msgstr "بازنشانی به پیش‌فرض‌ها"
    175 
    176222#. Description of the plugin/theme
    177223msgid ""
    178 "Automatically injects Rank Math FAQ schema and converts it to a stylish "
    179 "accordion."
     224"Automatically injects Rank Math FAQ schema and converts it to a stylish, "
     225"customizable accordion."
    180226msgstr ""
    181 "درج خودکار اسکیمای سوالات متداول (FAQ) رنک‌مث و تبدیل آن به یک آکاردئون شیک."
     227"افزودن خودکار اسکیمای سوالات متداول (FAQ) رنک‌مث و تبدیل آن به یک آکاردئون شیک "
     228"و قابل شخصی‌سازی."
    182229
    183230#. Author of the plugin/theme
     
    186233
    187234#. Author URI of the plugin/theme
    188 msgid "https://kabook.ir/"
    189 msgstr "https://kabook.ir/"
     235msgid "https://www.kabook.ir/"
     236msgstr "https://www.kabook.ir/"
  • kabook-auto-rank-math-snippet/trunk/languages/kabook-auto-rank-math-snippet.pot

    r3414326 r3431166  
     1#, fuzzy
    12msgid ""
    23msgstr ""
    3 "Project-Id-Version: Kabook Auto Schema & Accordion for Rank Math 1.1.0\n"
    4 "Report-Msgid-Bugs-To: https://kabook.ir/contact/\n"
    5 "POT-Creation-Date: 2025-12-08 15:27+0330\n"
    6 "PO-Revision-Date: 2025-12-08 15:30+0330\n"
    7 "Last-Translator: Saeid Afshari <info@kabook.ir>\n"
    8 "Language-Team: Kabook Dev Team <admin@kabook.ir>\n"
    9 "Language: fa_IR\n"
     4"Project-Id-Version: Kabook Auto Schema & Accordion for Rank Math\n"
     5"POT-Creation-Date: 2026-01-02 19:51+0330\n"
     6"PO-Revision-Date: 2026-01-02 19:20+0330\n"
     7"Last-Translator: \n"
     8"Language-Team: \n"
    109"MIME-Version: 1.0\n"
    1110"Content-Type: text/plain; charset=UTF-8\n"
    1211"Content-Transfer-Encoding: 8bit\n"
    13 "X-Generator: Poedit 3.5\n"
    14 "X-Domain: kabook-auto-rank-math-snippet\n"
    15 
    16 #. translators: %s: Plugin Name
    17 #: kabook-auto-rank-math-snippet.php:73
     12"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
     13"X-Generator: Poedit 3.7\n"
     14"X-Poedit-Basepath: ..\n"
     15"X-Poedit-Flags-xgettext: --add-comments=translators:\n"
     16"X-Poedit-WPHeader: kabook-auto-rank-math-snippet.php\n"
     17"X-Poedit-SourceCharset: UTF-8\n"
     18"X-Poedit-KeywordsList: "
     19"__;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
     20"X-Poedit-SearchPath-0: .\n"
     21"X-Poedit-SearchPathExcluded-0: *.js\n"
     22
     23#. translators: 1: Plugin Name, 2: Dependency Name
     24#: kabook-auto-rank-math-snippet.php:49
    1825#, php-format
    19 msgid "%s requires Rank Math SEO PRO to be installed and active."
    20 msgstr ""
    21 
    22 #: kabook-auto-rank-math-snippet.php:91
     26msgid "%1$s requires %2$s to be installed and active."
     27msgstr ""
     28
     29#: kabook-auto-rank-math-snippet.php:50
     30msgid "Kabook Auto Schema & Accordion"
     31msgstr ""
     32
     33#: kabook-auto-rank-math-snippet.php:51
     34msgid "Rank Math SEO PRO"
     35msgstr ""
     36
     37#: kabook-auto-rank-math-snippet.php:68
    2338msgid "Settings"
    2439msgstr ""
    2540
    26 #: kabook-auto-rank-math-snippet.php:243
     41#: kabook-auto-rank-math-snippet.php:205
    2742msgid "Schema Injection Settings"
    2843msgstr ""
    2944
    30 #: kabook-auto-rank-math-snippet.php:261
     45#: kabook-auto-rank-math-snippet.php:221
    3146msgid "Auto Inject Schema for this post:"
    3247msgstr ""
    3348
    34 #: kabook-auto-rank-math-snippet.php:265
     49#: kabook-auto-rank-math-snippet.php:225
    3550msgid "Default (Global Settings)"
    3651msgstr ""
    3752
    38 #: kabook-auto-rank-math-snippet.php:266
     53#: kabook-auto-rank-math-snippet.php:226
    3954msgid "Enable / Force Inject"
    4055msgstr ""
    4156
    42 #: kabook-auto-rank-math-snippet.php:267
     57#: kabook-auto-rank-math-snippet.php:227
    4358msgid "Disable"
    4459msgstr ""
    4560
    46 #: kabook-auto-rank-math-snippet.php:271
     61#: kabook-auto-rank-math-snippet.php:231
    4762msgid "Override the global auto-injection setting for this specific post."
    4863msgstr ""
    4964
    50 #: kabook-auto-rank-math-snippet.php:319
    51 msgid "Settings for Rank Math Snippet"
     65#: kabook-auto-rank-math-snippet.php:281 kabook-auto-rank-math-snippet.php:349
     66msgid "Kabook Auto Schema Settings"
     67msgstr ""
     68
     69#: kabook-auto-rank-math-snippet.php:282
     70msgid "Kabook RM Snippet"
     71msgstr ""
     72
     73#: kabook-auto-rank-math-snippet.php:298
     74msgid "Are you sure you want to reset all settings to default?"
     75msgstr ""
     76
     77#: kabook-auto-rank-math-snippet.php:299
     78msgid "Settings reset successfully. Reloading..."
     79msgstr ""
     80
     81#: kabook-auto-rank-math-snippet.php:300
     82msgid "Error resetting settings. Please try again."
     83msgstr ""
     84
     85#: kabook-auto-rank-math-snippet.php:308
     86msgid "General Settings"
     87msgstr ""
     88
     89#: kabook-auto-rank-math-snippet.php:309
     90msgid "Auto Inject Schema"
     91msgstr ""
     92
     93#: kabook-auto-rank-math-snippet.php:309
     94msgid "Automatically add [rank_math_rich_snippet] to posts if missing."
     95msgstr ""
     96
     97#: kabook-auto-rank-math-snippet.php:310
     98msgid "Show Meta Box"
     99msgstr ""
     100
     101#: kabook-auto-rank-math-snippet.php:310
     102msgid "Show per-post injection control."
     103msgstr ""
     104
     105#: kabook-auto-rank-math-snippet.php:311
     106msgid "Enable Accordion"
     107msgstr ""
     108
     109#: kabook-auto-rank-math-snippet.php:312
     110msgid "Enable Numbering"
     111msgstr ""
     112
     113#: kabook-auto-rank-math-snippet.php:313
     114msgid "Expand First Item"
     115msgstr ""
     116
     117#: kabook-auto-rank-math-snippet.php:316
     118msgid "Animation Settings"
     119msgstr ""
     120
     121#: kabook-auto-rank-math-snippet.php:317
     122msgid "Opening Animation"
     123msgstr ""
     124
     125#: kabook-auto-rank-math-snippet.php:318
     126msgid "Animation Speed (ms)"
     127msgstr ""
     128
     129#: kabook-auto-rank-math-snippet.php:318
     130msgid "e.g. 300 for fast, 1200 for slow."
    52131msgstr ""
    53132
    54133#: kabook-auto-rank-math-snippet.php:320
    55 msgid "Kabook RM Snippet"
    56 msgstr ""
    57 
    58 #: kabook-auto-rank-math-snippet.php:336
    59 msgid "Are you sure you want to reset all settings to default?"
    60 msgstr ""
    61 
    62 #: kabook-auto-rank-math-snippet.php:343
    63 msgid "General Settings"
    64 msgstr ""
    65 
    66 #: kabook-auto-rank-math-snippet.php:346
    67 msgid "Auto Inject Schema"
    68 msgstr ""
    69 
    70 #: kabook-auto-rank-math-snippet.php:348
    71 msgid "Automatically add [rank_math_rich_snippet] to posts if missing."
    72 msgstr ""
    73 
    74 #: kabook-auto-rank-math-snippet.php:349
    75 msgid "Important:"
    76 msgstr ""
    77 
    78 #: kabook-auto-rank-math-snippet.php:350
    79 msgid ""
    80 "If you use other schemas like \"HowTo\" in a specific post, please DISABLE "
    81 "auto-injection for that post using the \"Injection Control Meta Box\" (in "
    82 "the post editor) and insert shortcodes manually to avoid conflicts."
    83 msgstr ""
    84 
    85 #: kabook-auto-rank-math-snippet.php:353
    86 msgid "Show Injection Control Meta Box"
     134msgid "Question Styles"
     135msgstr ""
     136
     137#: kabook-auto-rank-math-snippet.php:321 kabook-auto-rank-math-snippet.php:327
     138msgid "Font Size (px)"
     139msgstr ""
     140
     141#: kabook-auto-rank-math-snippet.php:322 kabook-auto-rank-math-snippet.php:328
     142msgid "Text Color"
     143msgstr ""
     144
     145#: kabook-auto-rank-math-snippet.php:323 kabook-auto-rank-math-snippet.php:329
     146msgid "Background Color"
     147msgstr ""
     148
     149#: kabook-auto-rank-math-snippet.php:324 kabook-auto-rank-math-snippet.php:330
     150msgid "Text Alignment"
     151msgstr ""
     152
     153#: kabook-auto-rank-math-snippet.php:326
     154msgid "Answer Styles"
     155msgstr ""
     156
     157#: kabook-auto-rank-math-snippet.php:332
     158msgid "Border & Radius"
     159msgstr ""
     160
     161#: kabook-auto-rank-math-snippet.php:333
     162msgid "Border Width (px)"
     163msgstr ""
     164
     165#: kabook-auto-rank-math-snippet.php:334
     166msgid "Corner Radius (px)"
     167msgstr ""
     168
     169#: kabook-auto-rank-math-snippet.php:335
     170msgid "Border Color"
     171msgstr ""
     172
     173#: kabook-auto-rank-math-snippet.php:354
     174msgid "General System"
    87175msgstr ""
    88176
    89177#: kabook-auto-rank-math-snippet.php:355
    90 msgid ""
    91 "Display a meta box in the post editor to manually Enable/Disable injection "
    92 "per post."
    93 msgstr ""
    94 
    95 #: kabook-auto-rank-math-snippet.php:358
    96 msgid "Enable Accordion Style"
    97 msgstr ""
    98 
    99 #: kabook-auto-rank-math-snippet.php:360
    100 msgid "Convert the FAQ schema into an accordion style."
    101 msgstr ""
    102 
    103 #: kabook-auto-rank-math-snippet.php:362
    104 msgid "Enable Numbering"
    105 msgstr ""
    106 
    107 #: kabook-auto-rank-math-snippet.php:363
    108 msgid "Expand First Item"
    109 msgstr ""
    110 
    111 #: kabook-auto-rank-math-snippet.php:365
    112 msgid "Question Styling"
    113 msgstr ""
    114 
    115 #: kabook-auto-rank-math-snippet.php:366 kabook-auto-rank-math-snippet.php:372
    116 msgid "Font Size (px)"
    117 msgstr ""
    118 
    119 #: kabook-auto-rank-math-snippet.php:367 kabook-auto-rank-math-snippet.php:373
    120 msgid "Text Color"
    121 msgstr ""
    122 
    123 #: kabook-auto-rank-math-snippet.php:368 kabook-auto-rank-math-snippet.php:374
    124 msgid "Background Color"
    125 msgstr ""
    126 
    127 #: kabook-auto-rank-math-snippet.php:369 kabook-auto-rank-math-snippet.php:375
    128 msgid "Text Align"
    129 msgstr ""
    130 
    131 #: kabook-auto-rank-math-snippet.php:371
    132 msgid "Answer Styling"
    133 msgstr ""
    134 
    135 #: kabook-auto-rank-math-snippet.php:377
    136 msgid "Border Styling"
    137 msgstr ""
    138 
    139 #: kabook-auto-rank-math-snippet.php:378
    140 msgid "Width (px)"
    141 msgstr ""
    142 
    143 #: kabook-auto-rank-math-snippet.php:379
    144 msgid "Style"
    145 msgstr ""
    146 
    147 #: kabook-auto-rank-math-snippet.php:380
    148 msgid "Color"
    149 msgstr ""
    150 
    151 #: kabook-auto-rank-math-snippet.php:381
    152 msgid "Radius (px)"
     178msgid "Accordion Styles"
     179msgstr ""
     180
     181#: kabook-auto-rank-math-snippet.php:368
     182msgid "Save Changes"
     183msgstr ""
     184
     185#: kabook-auto-rank-math-snippet.php:369
     186msgid "Reset Defaults"
     187msgstr ""
     188
     189#: kabook-auto-rank-math-snippet.php:398
     190msgid "Security check failed. Please try again."
     191msgstr ""
     192
     193#: kabook-auto-rank-math-snippet.php:447
     194msgid "Left"
     195msgstr ""
     196
     197#: kabook-auto-rank-math-snippet.php:448
     198msgid "Center"
     199msgstr ""
     200
     201#: kabook-auto-rank-math-snippet.php:449
     202msgid "Right"
     203msgstr ""
     204
     205#: kabook-auto-rank-math-snippet.php:464
     206msgid "Slide Down"
     207msgstr ""
     208
     209#: kabook-auto-rank-math-snippet.php:465
     210msgid "Fade In"
     211msgstr ""
     212
     213#: kabook-auto-rank-math-snippet.php:466
     214msgid "Zoom In"
    153215msgstr ""
    154216
    155217#. Plugin Name of the plugin/theme
    156 #: kabook-auto-rank-math-snippet.php:393
    157218msgid "Kabook Auto Schema & Accordion for Rank Math"
    158 msgstr ""
    159 
    160 #: kabook-auto-rank-math-snippet.php:401
    161 msgid "General"
    162 msgstr ""
    163 
    164 #: kabook-auto-rank-math-snippet.php:404
    165 msgid "Accordion Styles"
    166 msgstr ""
    167 
    168 #: kabook-auto-rank-math-snippet.php:422
    169 msgid "Reset to Defaults"
    170219msgstr ""
    171220
    172221#. Description of the plugin/theme
    173222msgid ""
    174 "Automatically injects Rank Math FAQ schema and converts it to a stylish "
    175 "accordion."
     223"Automatically injects Rank Math FAQ schema and converts it to a stylish, "
     224"customizable accordion."
    176225msgstr ""
    177226
     
    181230
    182231#. Author URI of the plugin/theme
    183 msgid "https://kabook.ir/"
    184 msgstr ""
     232msgid "https://www.kabook.ir/"
     233msgstr ""
  • kabook-auto-rank-math-snippet/trunk/readme.txt

    r3414326 r3431166  
    11=== Kabook Auto Schema & Accordion for Rank Math ===
    22Contributors: saeidafshari
    3 Tags: rank math, schema, faq, accordion, seo
     3Tags: rank math, schema, faq, accordion, schema-injection
    44Requires at least: 5.6
    55Tested up to: 6.9
    6 Requires PHP: 8.0
    7 Stable tag: 1.1.0
     6Requires PHP: 7.4
     7Stable tag: 1.2.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1010
    11 Automatically injects Rank Math FAQ schema and converts it to a stylish, customizable accordion on the frontend.
     11Automatically injects Rank Math FAQ schema and converts it to a stylish, customizable accordion with smooth animations.
    1212
    1313== Description ==
    1414
    1515This plugin is a power-up for **Rank Math SEO PRO** users.
    16 It solves two common problems:
    17 1.  Forgetting to insert the FAQ schema shortcode into posts.
    18 2.  The default, plain look of the FAQ schema output.
     16It solves common SEO and UX problems by ensuring your FAQ Schema is always present and looks professional.
    1917
    2018**Key Features:**
    2119
    2220* **Auto Injection:** Automatically adds the `[rank_math_rich_snippet]` shortcode to your single posts if you have defined an FAQ schema but forgot to insert the block.
    23 * **Per-Post Control:** (New) Manually enable or disable schema injection for specific posts via a simple checkbox in the editor.
    24 * **Smart Detection:** Checks the raw database content to ensure the shortcode is never duplicated if you manually added it.
     21* **New: Animation Effects:** Choose between Slide, Fade, or Zoom effects for your accordion opening.
     22* **New: Speed Control:** Fully customize the animation duration (ms) to match your site's feel.
     23* **Per-Post Control:** Manually enable or disable schema injection for specific posts via a simple checkbox in the editor.
     24* **Smart Detection:** Checks the raw database content to ensure the shortcode is never duplicated.
    2525* **Stylish Accordion:** Converts the boring list format into a beautiful, interactive accordion.
    26 * **Fully Customizable:** Change colors, fonts, borders, and alignment via a simple settings panel.
    27 * **Lightweight:** Rebuilt with Vanilla JS (No jQuery) for maximum performance.
    28 * **RTL Support:** Fully supports Right-to-Left languages like Persian and Arabic.
     26* **Fully Customizable:** Change colors, fonts, borders, and alignment via a modern "Blue Harmony" settings panel.
     27* **Ultra Lightweight:** Rebuilt with Vanilla JS (No jQuery) for maximum performance.
     28* **Perfect RTL Support:** Deep integration for Right-to-Left languages like Persian and Arabic.
    2929
    3030**Note:** This plugin relies on the schema data generated by the **Rank Math SEO PRO** plugin.
     
    3333== Installation ==
    3434
    35 1.  Upload the plugin files to the `/wp-content/plugins/kabook-auto-rank-math-snippet` directory, or install the plugin through the WordPress plugins screen directly.
    36 2.  Activate the plugin through the 'Plugins' screen in WordPress.
    37 3.  Go to **Settings > Kabook RM Snippet** to configure the styling options.
    38 4.  (Optional) Enable the "Injection Control Meta Box" in settings to control injection on a per-post basis.
     351. Upload the plugin files to the `/wp-content/plugins/kabook-auto-rank-math-snippet` directory.
     362. Activate the plugin through the 'Plugins' screen in WordPress.
     373. Go to **Settings > Kabook RM Snippet** to configure the styling and animation options.
    3938
    4039== Frequently Asked Questions ==
    4140
    4241= Does this plugin work without Rank Math PRO? =
    43 No. This plugin acts as an add-on.
    44 It depends on the schema data generated by the Rank Math SEO PRO plugin to function.
     42No. This plugin acts as an add-on and depends on the schema data generated by the Rank Math SEO PRO plugin.
     43
     44= Can I change the opening speed of the accordion? =
     45Yes! In version 1.2.0, we added an "Animation Speed" setting where you can define the speed in milliseconds (e.g., 300ms for fast or 1200ms for slow).
     46
     47= Does it load scripts on every page? =
     48No. To ensure maximum performance, the plugin only loads its CSS and JS files on pages where an FAQ schema or shortcode is actually detected.
    4549
    4650= Will it slow down my site? =
    47 No. The plugin is highly optimized (Vanilla JS) and only loads assets on pages where an FAQ schema is detected.
     51Absolutely not. The plugin uses Vanilla JS instead of jQuery, making it extremely fast and lightweight.
    4852
    4953== Screenshots ==
    5054
    51 1.  **General Settings:** Enable or disable auto-injection and the new meta box feature.
    52 2.  **Style Customization:** Easily change colors and styles to match your theme.
    53 3.  **Frontend Example:** How the FAQ Accordion looks to your visitors.
    54 4.  **RTL Support:** Full support for Persian/Arabic layouts.
     551. **General Settings:** The new "Blue Harmony" UI for managing global plugin options and auto-injection.
     562. **Animation Controls:** Choose your desired opening effect (Slide, Fade, Zoom) and set the animation speed.
     573. **Style Customization:** Full control over colors, typography, borders, and corner radius to match your theme.
     584. **Frontend Example (LTR):** A beautiful, animated FAQ accordion as seen on an English site.
     595. **RTL Support (Persian):** Perfect alignment and styling for Right-to-Left languages.
    5560
    5661== Changelog ==
    5762
     63= 1.2.0 =
     64* New: Added Opening Animations (Slide, Fade, Zoom).
     65* New: Added Animation Speed control setting.
     66* New: Brand new "Blue Harmony" Admin UI for better user experience.
     67* Improvement: Optimized Asset Loading (scripts only load when needed).
     68* Improvement: Enhanced RTL support for both Admin and Frontend.
     69* Security: Implemented Nonce verification and better output escaping for WP.org standards.
     70* Compatibility: PHP requirement lowered to 7.4 for better compatibility.
     71
    5872= 1.1.0 =
    59 * New: Added "Injection Control Meta Box" to Enable/Disable auto-injection per post.
    60 * New: Added option to show/hide the Meta Box in plugin settings.
    61 * New: Added helpful notice in settings regarding schema conflicts.
    62 * Improvement: Rewrote frontend logic in Vanilla JS (removed jQuery dependency) for better performance.
    63 * Improvement: Added uninstall.php for proper data cleanup.
    64 * Security: Fixed non-sanitized input variable warnings (Plugin Check standards).
    65 * Compatibility: Tested up to WordPress 6.9.
     73* New: Added "Injection Control Meta Box" per post.
     74* Improvement: Rewrote frontend logic in Vanilla JS (removed jQuery).
     75* Security: Fixed non-sanitized input variable warnings.
    6676
    6777= 1.0.0 =
  • kabook-auto-rank-math-snippet/trunk/uninstall.php

    r3414326 r3431166  
    33 * Fired when the plugin is uninstalled.
    44 *
    5  * @package Kabook_Auto_Rank_Math_Snippet
     5 * Removes all settings and database entries created by the plugin
     6 * to ensure a clean uninstallation process.
     7 *
     8 * @package Kabook Auto Rank Math Snippet
    69 */
    710
    811if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
    9     exit;
     12    exit;
    1013}
    1114
    12 // 1. Delete Options
     15// 1. Delete Plugin Options
    1316delete_option( 'karms_options' );
    1417
    15 // 2. Clean up post meta (Uncommented for full cleanup)
     18// 2. Clean up Post Meta (Database cleanup)
    1619global $wpdb;
     20
    1721// phpcs:ignore WordPress.DB.DirectDatabaseQuery
    1822$wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_karms_auto_inject_override'" );
Note: See TracChangeset for help on using the changeset viewer.