Plugin Directory

Changeset 3524967


Ignore:
Timestamp:
05/07/2026 03:44:00 AM (6 months ago)
Author:
mryudha
Message:

Update to version 1.0.4 from GitHub

Location:
foureyed-shortcode-control
Files:
6 added
2 deleted
56 edited
1 copied

Legend:

Unmodified
Added
Removed
  • foureyed-shortcode-control/tags/1.0.4/foureyed-shortcode-control.php

    r3523952 r3524967  
    44 * Plugin URI:        https://wordpress.org/plugins/foureyed-shortcode-control/
    55 * Description:       A WordPress admin plugin that discovers, lists, toggles, scans, and creates shortcodes.
    6  * Version:           1.0.3
     6 * Version:           1.0.4
    77 * Author:            Muhammad Yudha - DJ
    88 * Author URI:        https://profiles.wordpress.org/mryudha/
    … …  
    1818}
    1919
    20 define('FOUREYED_SHORTCODE_CONTROL_VERSION', '1.0.3');
     20define('FOUREYED_SHORTCODE_CONTROL_VERSION', '1.0.4');
    2121define('FOUREYED_SHORTCODE_CONTROL_PATH', plugin_dir_path(__FILE__));
    2222define('FOUREYED_SHORTCODE_CONTROL_URL', plugin_dir_url(__FILE__));
  • foureyed-shortcode-control/tags/1.0.4/includes/Bootstrap.php

    r3523935 r3524967  
    1212use FoureyedShortcodeControl\Features\Scanner\Rest\ScannerRestController;
    1313use FoureyedShortcodeControl\Features\ShortcodeManager\Rest\ShortcodesRestController;
     14use FoureyedShortcodeControl\Services\DismissedNotices;
    1415
    1516if (!defined('ABSPATH')) {
    … …  
    4445                (new ScannerRestController())->register_routes();
    4546                (new ShortcodesRestController())->register_routes();
     47
     48                // Shared: dismiss notice
     49                register_rest_route('shortcode-control/v1', '/dismiss-notice', [
     50                        'methods'             => \WP_REST_Server::CREATABLE,
     51                        'callback'            => [DismissedNotices::class, 'handle_rest'],
     52                        'permission_callback' => [DismissedNotices::class, 'permissions_check'],
     53                        'args'                => [
     54                                'key' => ['type' => 'string', 'required' => true],
     55                        ],
     56                ]);
    4657        }
    4758
    … …  
    116127                }
    117128
     129                // Enqueue shared assets (applies to all SCC pages)
     130                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
     131                wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     132                wp_localize_script('foureyed-shortcode-control-shared-ui', 'sccSharedData', [
     133                        'restUrl' => esc_url_raw(rest_url('shortcode-control/v1')),
     134                        'nonce'   => wp_create_nonce('wp_rest'),
     135                ]);
     136
    118137                // Enqueue global tooltip system
    119                         wp_enqueue_style('foureyed-shortcode-control-tooltip-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    120                         wp_enqueue_script('foureyed-shortcode-control-tooltip', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     138                wp_enqueue_style('foureyed-shortcode-control-tooltip-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
     139                wp_enqueue_script('foureyed-shortcode-control-tooltip', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    121140        }
    122141}
  • foureyed-shortcode-control/tags/1.0.4/includes/DataRegistry.php

    r3523935 r3524967  
    2626        // ─── Options: Settings ────────────────────────────────────────────────────
    2727
    28         public const OPTION_DELETE_ON_UNINSTALL = 'foureyed_shortcode_control_delete_data_on_uninstall'; // bool
    29         public const OPTION_HIDE_CORE           = 'foureyed_shortcode_control_hide_core';                // bool
    30         public const OPTION_SCAN_BATCH_SIZE     = 'foureyed_shortcode_control_scan_batch_size';          // 10|50|100|500
     28        public const OPTION_DELETE_ON_UNINSTALL    = 'foureyed_shortcode_control_delete_data_on_uninstall'; // bool
     29        public const OPTION_HIDE_CORE              = 'foureyed_shortcode_control_hide_core';                // bool
     30        public const OPTION_SCAN_BATCH_SIZE        = 'foureyed_shortcode_control_scan_batch_size';          // 10|50|100|500
     31        public const OPTION_SCAN_EXCLUDED_BLOCKS   = 'foureyed_shortcode_control_scan_excluded_blocks';     // string[] of wp block names e.g. ['html','code']
    3132
    3233        /** For batch delete/reset. */
    … …  
    3536                self::OPTION_HIDE_CORE,
    3637                self::OPTION_SCAN_BATCH_SIZE,
     38                self::OPTION_SCAN_EXCLUDED_BLOCKS,
    3739        ];
    3840
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/AdminUi/ScannerPageController.php

    r3523935 r3524967  
    1919        public function render_page()
    2020        {
    21                 // Show adoption success notice when redirected back after a successful adoption.
    22                 if (!empty($_GET['adopted'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    23                         $adopted_tag = sanitize_key(wp_unslash($_GET['adopted'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    24                         printf(
    25                                 '<div class="notice notice-success is-dismissible"><p>%s</p></div>',
    26                                 wp_kses_post(
    27                                         sprintf(
    28                                                 /* translators: %s: shortcode tag name */
    29                                                 __('Successfully adopted shortcode &ldquo;%s&rdquo;. It is now <strong>disabled</strong> by default. You can manage it in the &ldquo;Manually Adopted&rdquo; section of your Shortcodes page.', 'foureyed-shortcode-control'),
    30                                                 esc_html($adopted_tag)
    31                                         )
    32                                 )
    33                         );
    34                 }
    35 
    3621                // Get enriched data with counts
    3722                $data = ScannerDataProvider::get_prepared_data();
    … …  
    7560                );
    7661
    77                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    78                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     62                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    7963                wp_enqueue_style('foureyed-shortcode-control-scanner-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/Scanner/AdminUi/scanner.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    8064
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/AdminUi/ScannerTemplate.php

    r3523935 r3524967  
    4444        </div>
    4545
     46        <?php if (!\FoureyedShortcodeControl\Services\DismissedNotices::is_dismissed('scanner')) : ?>
    4647        <div class="scc-helper-card" data-dismiss-key="scanner">
    4748                <strong><?php esc_html_e('Quick Guide:', 'foureyed-shortcode-control'); ?></strong>
    4849                <?php esc_html_e('Run a scan, review orphaned findings first, then click Manage to jump directly into Shortcode Manager for that shortcode tag.', 'foureyed-shortcode-control'); ?>
    4950        </div>
     51        <?php endif; ?>
    5052
    5153        <?php /* Status banner — shown by JS on interruption, hidden by default */ ?>
    … …  
    103105        </div>
    104106
    105         <div class="scc-stats">
    106                 <div class="scc-stat-card">
    107                         <div class="scc-stat-label"><?php esc_html_e('Total', 'foureyed-shortcode-control'); ?></div>
    108                         <div class="scc-stat-number" id="scc-stat-total"><?php echo esc_html($total_findings); ?></div>
    109                 </div>
    110                 <div class="scc-stat-card">
    111                         <div class="scc-stat-label"><?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?></div>
    112                         <div class="scc-stat-number" id="scc-stat-active"><?php echo esc_html($active_findings); ?></div>
    113                 </div>
    114                 <div class="scc-stat-card">
    115                         <div class="scc-stat-label"><?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?></div>
    116                         <div class="scc-stat-number" id="scc-stat-disabled"><?php echo esc_html($disabled_findings); ?></div>
    117                 </div>
    118                 <div class="scc-stat-card">
    119                         <div class="scc-stat-label"><?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?></div>
    120                         <div class="scc-stat-number" id="scc-stat-orphaned"><?php echo esc_html($orphaned_findings); ?></div>
    121                 </div>
    122         </div>
    123 
    124107        <div class="scc-toolbar">
    125108                <div class="scc-toolbar-main">
     109                        <input type="hidden" id="scc-filter-status" value="all">
     110
     111                        <div class="scc-filter-tabs">
     112                                <button type="button" class="scc-scan-filter-tab scc-filter-tab-active" data-filter="all">
     113                                        <?php esc_html_e('All', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-total"><?php echo esc_html($total_findings); ?></span>)
     114                                </button>
     115                                <button type="button" class="scc-scan-filter-tab" data-filter="active">
     116                                        <?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-active"><?php echo esc_html($active_findings); ?></span>)
     117                                </button>
     118                                <button type="button" class="scc-scan-filter-tab" data-filter="disabled">
     119                                        <?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-disabled"><?php echo esc_html($disabled_findings); ?></span>)
     120                                </button>
     121                                <button type="button" class="scc-scan-filter-tab" data-filter="orphaned">
     122                                        <?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-orphaned"><?php echo esc_html($orphaned_findings); ?></span>)
     123                                </button>
     124                        </div>
     125
    126126                        <div class="scc-search-wrap" style="display: flex; gap: 8px;">
    127127                                <label class="screen-reader-text" for="scc-search-posts"><?php esc_html_e('Search findings:', 'foureyed-shortcode-control'); ?></label>
    … …  
    129129                                        placeholder="<?php esc_attr_e('Search by post title or shortcode tag...', 'foureyed-shortcode-control'); ?>">
    130130                                <button type="button" id="scc-clear-search" class="button" style="display: none;"><?php esc_html_e('Clear Filter', 'foureyed-shortcode-control'); ?></button>
    131                         </div>
    132 
    133                         <input type="hidden" id="scc-filter-status" value="all">
    134 
    135                         <div class="scc-filter-tabs">
    136                                 <button type="button" class="scc-scan-filter-tab scc-filter-tab-active" data-filter="all"
    137                                 >
    138                                         <?php esc_html_e('All', 'foureyed-shortcode-control'); ?>
    139                                 </button>
    140                                 <button type="button" class="scc-scan-filter-tab" data-filter="active"
    141                                 >
    142                                         <?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?>
    143                                 </button>
    144                                 <button type="button" class="scc-scan-filter-tab" data-filter="disabled"
    145                                 >
    146                                         <?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?>
    147                                 </button>
    148                                 <button type="button" class="scc-scan-filter-tab" data-filter="orphaned"
    149                                 >
    150                                         <?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?>
    151                                 </button>
    152131                        </div>
    153132                </div>
    … …  
    171150                                        <?php
    172151                                        $live_status = isset($row->live_status) ? $row->live_status : 'orphaned';
    173                                         $is_adopted  = isset($row->is_adopted) ? $row->is_adopted : false;
    174152                                        $source_type = isset($row->source_type) ? $row->source_type : 'unknown';
    175153
    … …  
    191169                                        $item['wporg_status'] = $item['wporg_status'] ?? 'not_applicable';
    192170
    193                                         // Special case for unmanaged orphans which only exist in the Scanner until adopted
    194                                         if ($live_status === 'orphaned' && !$is_adopted) {
    195                                                 $status_badges = '<span class="scc-status-badge scc-status-orphaned">' . esc_html__('Orphaned', 'foureyed-shortcode-control') . '</span>';
    196                                                 $source_html   = '<span class="scc-muted-italic" style="color:#a7aaad;">' . esc_html__('Unknown', 'foureyed-shortcode-control') . '</span>';
     171                                        // Orphaned tags have no source data, so we render a static badge instead
     172                                        if ($live_status === 'orphaned') {
     173                                                if (($row->granular_status ?? '') === 'hidden') {
     174                                                        $status_badges = '<span class="scc-status-badge scc-status-hidden">' . esc_html__('Silenced', 'foureyed-shortcode-control') . '</span>';
     175                                                } else {
     176                                                        $status_badges = '<span class="scc-status-badge scc-status-orphaned">' . esc_html__('Orphaned', 'foureyed-shortcode-control') . '</span>';
     177                                                }
     178                                                $source_html = '<span class="scc-muted-italic" style="color:#a7aaad;">' . esc_html__('Unknown', 'foureyed-shortcode-control') . '</span>';
    197179                                        } else {
    198180                                                $status_badges = $renderer->render_status($item);
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/AdminUi/scanner.css

    r3523935 r3524967  
    11/* Scanner admin styles */
    2 
    3 .scc-stats {
    4     display: flex;
    5     background: #fff;
    6     border: 1px solid #c3c4c7;
    7     border-radius: 6px;
    8     margin-bottom: 16px;
    9     overflow: hidden;
    10 }
    11 
    12 .scc-stat-card {
    13     flex: 1;
    14     padding: 16px 20px;
    15     border: none;
    16     border-right: 1px solid #c3c4c7;
    17     border-radius: 0;
    18     background: transparent;
    19 }
    20 
    21 .scc-stat-card:last-child {
    22     border-right: none;
    23 }
    24 
    25 .scc-stat-label {
    26     color: #646970;
    27     margin-bottom: 4px;
    28 }
    29 
    30 .scc-stat-number {
    31     font-size: 18px;
    32     line-height: 1.2;
    33     font-weight: 600;
    34     color: #1d2327;
    35 }
    362
    373.scc-toolbar {
    … …  
    4612    display: flex;
    4713    align-items: center;
     14    justify-content: space-between;
    4815    gap: 8px;
    4916    width: 100%;
    … …  
    5118
    5219.scc-search-wrap {
    53     flex: 0 0 220px;
    54     /* fixed narrow width on the right */
    55     order: 2;
    56     /* always rendered after the tabs */
     20    flex: 0 0 240px;
    5721    min-width: 0;
    5822}
    … …  
    6428.scc-filter-tabs {
    6529    display: inline-flex;
    66     /* shrinks to content width — no stretching */
    67     order: 1;
    6830    border: 1px solid #c3c4c7;
    6931    border-radius: 4px;
    … …  
    13294}
    13395
    134 .scc-status-adopted {
    135     background: #d9edf7;
    136     color: #31708f;
     96.scc-status-hidden {
     97    background: #e5e5e5;
     98    color: #555555;
    13799}
    138100
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/Api/ScannerApi.php

    r3523935 r3524967  
    2626                return ScannerDataProvider::get_prepared_data();
    2727        }
     28
     29        /**
     30         * Get scanner result counts.
     31         * Single source of truth for scan stat cards (Start Here, etc.).
     32         *
     33         * Counts use live status (recalculated against current registry), not stored DB values.
     34         *
     35         * @return array{total: int, active: int, disabled: int, orphaned: int}
     36         */
     37        public static function get_stats(): array
     38        {
     39                return ScannerDataProvider::get_prepared_data()['counts'];
     40        }
    2841}
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/Core/ScanDataProvider.php

    r3523935 r3524967  
    3434                          AND (l.post_id IS NULL OR l.last_scanned_at < p.post_modified)
    3535                ");
    36         }
    37 
    38         /**
    39          * Fetch a batch of published posts that have been modified since their last scan.
    40          * Legacy method — retained for use by the save_post lifecycle hook.
    41          *
    42          * @param int $limit  Number of posts to fetch
    43          * @param int $offset Starting position
    44          * @return array Array of post objects
    45          */
    46         public static function get_posts_batch(int $limit, int $offset): array
    47         {
    48                 global $wpdb;
    49                 $log_table = $wpdb->prefix . DataRegistry::TABLE_SCAN_LOG;
    50                 return $wpdb->get_results($wpdb->prepare("
    51                         SELECT p.ID, p.post_type, p.post_content, p.post_modified
    52                         FROM {$wpdb->posts} p
    53                         LEFT JOIN {$log_table} l ON p.ID = l.post_id
    54                         WHERE p.post_status = 'publish'
    55                           AND p.post_type IN ('post', 'page')
    56                           AND (l.post_id IS NULL OR l.last_scanned_at < p.post_modified)
    57                         ORDER BY p.ID ASC
    58                         LIMIT %d OFFSET %d
    59                 ", $limit, $offset));
    6036        }
    6137
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/Core/ScanLifecycleHooks.php

    r3523935 r3524967  
    1717        {
    1818                add_action('deleted_post', [__CLASS__, 'on_deleted_post'], 10, 1);
     19
     20                // When the excluded-blocks setting changes, wipe the scan log so all posts
     21                // are treated as unscanned on the next run. Old results stay until overwritten.
     22                add_action('update_option_' . DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, [__CLASS__, 'on_excluded_blocks_changed'], 10, 2);
     23        }
     24
     25        /**
     26         * Fires when the excluded blocks setting is updated.
     27         * Only clears the log when the value actually changed.
     28         */
     29        public static function on_excluded_blocks_changed($old_value, $new_value)
     30        {
     31                if ($old_value === $new_value) {
     32                        return;
     33                }
     34
     35                global $wpdb;
     36                $log_table = $wpdb->prefix . DataRegistry::TABLE_SCAN_LOG;
     37                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     38                $wpdb->query("TRUNCATE TABLE {$log_table}");
    1939        }
    2040
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/Core/ScanStatusService.php

    r3523935 r3524967  
    1717         * Determine if a shortcode tag is active, disabled, or orphaned.
    1818         *
    19          * A tag is "active" if it's currently registered and running natively, OR if it has been manually adopted.
    20     * A tag is "disabled" if it is intercepted/turned off by the Shortcode Control plugin.
    21          * A tag is "orphaned" if it's found in content but no longer registered (the plugin was deleted) AND not adopted.
     19         * A tag is "active" if it's currently registered and running natively.
     20        * A tag is "disabled" if it is intercepted/turned off by the Shortcode Control plugin.
     21         * A tag is "orphaned" if it's found in content but no longer registered (the plugin was deleted).
    2222         *
    2323         * @param string $tag           The shortcode tag to evaluate
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/Core/ScannerDataProvider.php

    r3523935 r3524967  
    6969                                $row->live_status = $live_status;
    7070
    71                                 // Adoption is no longer a separate concept
    72                                 $row->is_adopted = false;
    73 
    7471                                // Get source and granular status
    7572                                $sc_data = $source_map[$row->tag] ?? [];
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Scanner/Core/ShortcodeExtractor.php

    r3523952 r3524967  
    2626        public static function extract_shortcodes(string $content): array
    2727        {
    28                 // Strip Gutenberg block comments before scanning.
     28                // Strip entire block contents for user-configured excluded block types FIRST,
     29                // before the general comment stripper removes the markers we need to match against.
     30                // Each excluded block removes everything from its opening comment to its closing comment,
     31                // including any shortcode-like syntax inside (e.g. JS in Custom HTML blocks).
     32                $excluded_blocks = get_option(\FoureyedShortcodeControl\DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, ['html']);
     33                if (!empty($excluded_blocks) && is_array($excluded_blocks)) {
     34                        foreach ($excluded_blocks as $block_name) {
     35                                $block_name = preg_quote(trim($block_name), '/');
     36                                // Matches <!-- wp:html ... --> ... content ... <!-- /wp:html -->
     37                                $content = preg_replace('/<!--\s*wp:' . $block_name . '(?:\s[^-]*)?\s*-->.*?<!--\s*\/wp:' . $block_name . '\s*-->/s', '', $content);
     38                        }
     39                }
     40
     41                // Strip remaining Gutenberg block comments.
    2942                // Block comments like <!-- wp:gallery {"ids":[52301,52302]} --> contain JSON
    3043                // with bracket-wrapped numbers that the shortcode regex falsely matches.
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Settings/AdminUi/SettingsPageController.php

    r3523935 r3524967  
    1515        public function render_page()
    1616        {
    17                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    18                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     17                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    1918                wp_enqueue_style(
    2019                        'foureyed-shortcode-control-settings-css',
    … …  
    4443                        </div>
    4544
     45                        <?php if (!\FoureyedShortcodeControl\Services\DismissedNotices::is_dismissed('settings')) : ?>
    4646                        <div class="scc-helper-card" data-dismiss-key="settings">
    4747                                <strong><?php esc_html_e('Beginner Tip:', 'foureyed-shortcode-control'); ?></strong>
    4848                                <?php esc_html_e('Change one setting at a time, click Save All Settings, then verify behavior in Manage Shortcodes or Scanner.', 'foureyed-shortcode-control'); ?>
    4949                        </div>
     50                        <?php endif; ?>
    5051
    5152                        <?php
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Settings/Core/PluginDefaults.php

    r3523935 r3524967  
    3636                add_option(DataRegistry::OPTION_HIDE_CORE, true);
    3737                add_option(DataRegistry::OPTION_SCAN_BATCH_SIZE, 10);
     38                add_option(DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, ['html']);
    3839
    3940                // Shortcode Manager runtime data
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/Settings/Core/SettingsRegistrar.php

    r3523935 r3524967  
    106106                );
    107107
     108                register_setting(
     109                        DataRegistry::SETTINGS_GROUP,
     110                        DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS,
     111                        [
     112                                'type' => 'array',
     113                                'sanitize_callback' => [self::class, 'sanitize_excluded_blocks'],
     114                                'default' => ['html'],
     115                        ]
     116                );
     117
    108118                add_settings_section(
    109119                        'foureyed_shortcode_control_scanner_section',
    … …  
    117127                        __('Posts Per Batch', 'foureyed-shortcode-control'),
    118128                        [self::class, 'render_scan_batch_size_select'],
     129                        'foureyed-shortcode-control-scanner-settings',
     130                        'foureyed_shortcode_control_scanner_section'
     131                );
     132
     133                add_settings_field(
     134                        'foureyed_shortcode_control_scan_excluded_blocks',
     135                        __('Exclude Blocks from Scan', 'foureyed-shortcode-control'),
     136                        [self::class, 'render_excluded_blocks_checkboxes'],
    119137                        'foureyed-shortcode-control-scanner-settings',
    120138                        'foureyed_shortcode_control_scanner_section'
    … …  
    201219                return in_array($value, $allowed_sizes, true) ? $value : 50;
    202220        }
     221
     222        public static function render_excluded_blocks_checkboxes()
     223        {
     224                $excluded = get_option(DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, ['html']);
     225                if (!is_array($excluded)) {
     226                        $excluded = ['html'];
     227                }
     228
     229                $blocks = [
     230                        'html'          => __('Custom HTML block <code>[wp:html]</code> — JS, CSS, raw HTML (recommended)', 'foureyed-shortcode-control'),
     231                        'code'          => __('Code block <code>[wp:code]</code> — code snippets and tutorials', 'foureyed-shortcode-control'),
     232                        'preformatted'  => __('Preformatted block <code>[wp:preformatted]</code> — raw text content', 'foureyed-shortcode-control'),
     233                        'verse'         => __('Verse block <code>[wp:verse]</code> — poetry or bracketed notation', 'foureyed-shortcode-control'),
     234                ];
     235                ?>
     236                <fieldset>
     237                        <?php foreach ($blocks as $name => $label) : ?>
     238                        <label style="display: block; margin-bottom: 6px;">
     239                                <input type="checkbox"
     240                                        name="<?php echo esc_attr(DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS); ?>[]"
     241                                        value="<?php echo esc_attr($name); ?>"
     242                                        <?php checked(in_array($name, $excluded, true)); ?> />
     243                                <?php echo wp_kses($label, ['code' => []]); ?>
     244                        </label>
     245                        <?php endforeach; ?>
     246                </fieldset>
     247                <p class="description" style="margin-top: 8px;">
     248                        <?php esc_html_e('The scanner will skip the full content of checked block types. This reduces false positives from blocks that use brackets for non-shortcode purposes. Re-run a full scan after changing this.', 'foureyed-shortcode-control'); ?>
     249                </p>
     250                <?php
     251        }
     252
     253        public static function sanitize_excluded_blocks($value): array
     254        {
     255                $allowed = ['html', 'code', 'preformatted', 'verse'];
     256                if (!is_array($value)) {
     257                        return [];
     258                }
     259                return array_values(array_intersect($value, $allowed));
     260        }
    203261}
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php

    r3523952 r3524967  
    150150
    151151                $deactivated_badge = '';
    152                 if (!empty($item['deactivated_at'])) {
     152                if (isset($item['source_type']) && $item['source_type'] === 'unknown') {
     153                        // For completely unknown orphans, replace the fallback tag name with 'Unknown Source'
     154                        $name_link = '<strong><span class="scc-muted-italic" style="opacity: 0.7;">' . esc_html__('Unknown Source', 'foureyed-shortcode-control') . '</span></strong>';
     155                        $deactivated_badge = '';
     156                } elseif (!empty($item['deactivated_at'])) {
    153157                        $time_diff = human_time_diff($item['deactivated_at'], current_time('timestamp'));
    154158                        // translators: %s is a human-readable time difference, e.g. "3 days" or "2 hours".
    155159                        $deactivated_text = sprintf(esc_html__('Deactivated %s ago', 'foureyed-shortcode-control'), $time_diff);
    156160                        $deactivated_badge = ' <span class="scc-muted-italic" style="font-size: 0.85em; opacity: 0.7;">(' . $deactivated_text . ')</span>';
    157                 } elseif (isset($item['source_type']) && $item['source_type'] === 'unknown') {
    158                         // For completely unknown orphans, replace the fallback tag name with 'Unknown Source'
    159                         $name_link = '<strong><span class="scc-muted-italic" style="opacity: 0.7;">' . esc_html__('Unknown Source', 'foureyed-shortcode-control') . '</span></strong>';
    160                         $deactivated_badge = '';
    161161                }
    162162
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php

    r3523935 r3524967  
    131131        public function single_row($item)
    132132        {
    133                 $status = isset($item['status']) ? esc_attr($item['status']) : 'active';
    134                 echo '<tr data-status="' . esc_attr( $status ) . '">';
     133                $status    = $item['status'] ?? 'registered';
     134                $is_active = !empty($item['is_active']);
     135
     136                if ($status === 'registered') {
     137                        $row_status = 'enabled';
     138                } elseif ($status === 'hidden') {
     139                        $row_status = 'hidden';
     140                } elseif ($status === 'unregistered' && $is_active) {
     141                        $row_status = 'disabled';
     142                } else {
     143                        $row_status = 'orphaned';
     144                }
     145
     146                echo '<tr data-status="' . esc_attr($row_status) . '">';
    135147                $this->single_row_columns($item);
    136148                echo '</tr>';
    … …  
    142154        public function render_page()
    143155        {
    144                 // Tab switcher (reuses the same JS as the Settings page)
    145                 wp_enqueue_script('foureyed-shortcode-control-settings-tabs', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/Settings/AdminUi/settings-tabs.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    146 
    147156                wp_enqueue_script('foureyed-shortcode-control-wporg-api', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/ShortcodeManager/AdminUi/wporg-api.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    148157                wp_enqueue_script('foureyed-shortcode-control-shortcode-toggle', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/ShortcodeManager/AdminUi/shortcode-toggle.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    … …  
    169178                ]);
    170179
    171                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    172                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     180                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    173181                wp_enqueue_style('foureyed-shortcode-control-shortcodes-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/ShortcodeManager/AdminUi/shortcodes.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    174182
    … …  
    178186                $grouped_data = DataGrouper::group_by_tab($all_data);
    179187
     188                // Compute counts for filter tab labels
     189                $counts = ['all' => count($all_data), 'enabled' => 0, 'disabled' => 0, 'hidden' => 0, 'orphaned' => 0];
     190                foreach ($all_data as $sc) {
     191                        $sc_status    = $sc['status'] ?? 'registered';
     192                        $sc_is_active = !empty($sc['is_active']);
     193                        if ($sc_status === 'registered')                             $counts['enabled']++;
     194                        elseif ($sc_status === 'hidden')                             $counts['hidden']++;
     195                        elseif ($sc_status === 'unregistered' && $sc_is_active)      $counts['disabled']++;
     196                        elseif ($sc_status === 'unregistered' && !$sc_is_active)     $counts['orphaned']++;
     197                }
     198
    180199                include_once FOUREYED_SHORTCODE_CONTROL_PATH . 'includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php';
    181200        }
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php

    r3523935 r3524967  
    55 * Variables available:
    66 * - $grouped_data (array): ['active' => [...], 'orphaned' => [...]]
     7 * - $counts       (array): ['all', 'enabled', 'disabled', 'hidden', 'orphaned']
    78 */
    89
    910if (!defined('ABSPATH')) {
    10         exit;
     11exit;
    1112}
    1213// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Template file included inside a class method; variables are local to that method's scope, not global
     14
     15$scc_registered = $grouped_data['active']   ?? [];
     16$scc_orphaned   = $grouped_data['orphaned'] ?? [];
     17
     18// phpcs:ignore WordPress.Security.NonceVerification.Recommended
     19$search_query = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
     20// phpcs:ignore WordPress.Security.NonceVerification.Recommended
     21$scc_page_val = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
    1322?>
    1423<div class="wrap scc-admin-page">
    15         <div class="scc-page-header">
    16                 <h1>
    17                         <?php esc_html_e('Manage Shortcodes', 'foureyed-shortcode-control'); ?>
    18                         <span class="scc-tooltip"
    19                                 data-tooltip="<?php esc_attr_e('Active Shortcodes are from running plugins and themes — you can Enable, Disable, or Hide them. Orphaned Shortcodes are from plugins that have been deactivated — you can Hide or Restore them.', 'foureyed-shortcode-control'); ?>">?</span>
    20                 </h1>
    21                 <p>
    22                         <?php esc_html_e('Control which shortcodes are active or suppressed across your WordPress installation.', 'foureyed-shortcode-control'); ?>
    23                 </p>
    24         </div>
     24<div class="scc-page-header">
     25<h1>
     26<?php esc_html_e('Manage Shortcodes', 'foureyed-shortcode-control'); ?>
     27<span class="scc-tooltip" data-tooltip="<?php esc_attr_e('Registered Shortcodes come from active plugins, themes, and WordPress core. Orphaned Shortcodes come from plugins that are no longer active.', 'foureyed-shortcode-control'); ?>">?</span>
     28</h1>
     29<p><?php esc_html_e('Control which shortcodes are active or suppressed across your WordPress installation.', 'foureyed-shortcode-control'); ?></p>
     30</div>
    2531
    26         <div class="scc-helper-card" data-dismiss-key="manager">
    27                 <h2><?php esc_html_e('How To Use This Page', 'foureyed-shortcode-control'); ?></h2>
    28                 <p><?php esc_html_e('Start in Active Shortcodes to review what is currently running. Use search to quickly find a tag or plugin source, then switch to Orphaned Shortcodes to clean up leftover shortcode tags safely.', 'foureyed-shortcode-control'); ?></p>
    29         </div>
     32<?php if (!\FoureyedShortcodeControl\Services\DismissedNotices::is_dismissed('manager')) : ?>
     33<div class="scc-helper-card" data-dismiss-key="manager">
     34<h2><?php esc_html_e('How To Use This Page', 'foureyed-shortcode-control'); ?></h2>
     35<p><?php esc_html_e('Registered shortcodes can be Enabled, Disabled, or Hidden. Orphaned shortcodes come from deactivated plugins — you can Silence them (output nothing) or Restore them.', 'foureyed-shortcode-control'); ?></p>
     36</div>
     37<?php endif; ?>
    3038
    31         <!-- Global Search Bar -->
    32         <div class="scc-manager-search-wrap">
    33                 <?php
    34                 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only parameter for search filter
    35                 $search_query = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
    36                 ?>
    37                 <input
    38                         type="search"
    39                         id="scc-manager-search"
    40                         placeholder="<?php esc_attr_e('Search by tag or source…', 'foureyed-shortcode-control'); ?>"
    41                         autocomplete="off"
    42                         value="<?php echo esc_attr($search_query); ?>"
    43                 />
    44                 <button type="button" id="scc-manager-search-clear" style="display:none;">
    45                         <?php esc_html_e('Clear', 'foureyed-shortcode-control'); ?>
    46                 </button>
    47         </div>
    48         <?php if ($search_query !== '') : ?>
    49                 <p class="scc-search-context">
    50                         <?php
    51                         echo esc_html(
    52                                 sprintf(
    53                                         /* translators: %s: shortcode search term */
    54                                         __('Showing filtered results for "%s". Clear search to view all shortcodes.', 'foureyed-shortcode-control'),
    55                                         $search_query
    56                                 )
    57                         );
    58                         ?>
    59                 </p>
    60         <?php endif; ?>
     39<!-- Toolbar: Filter tabs + Search -->
     40<input type="hidden" id="scc-manager-filter-status" value="all">
     41<div class="scc-toolbar">
     42<div class="scc-toolbar-main">
     43<div class="scc-filter-tabs">
     44<button type="button" class="scc-manager-filter-tab scc-filter-tab-active" data-filter="all">
     45<?php esc_html_e('All', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['all']); ?></span>)
     46</button>
     47<button type="button" class="scc-manager-filter-tab" data-filter="enabled">
     48<?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['enabled']); ?></span>)
     49</button>
     50<button type="button" class="scc-manager-filter-tab" data-filter="disabled">
     51<?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['disabled']); ?></span>)
     52</button>
     53<button type="button" class="scc-manager-filter-tab" data-filter="hidden">
     54<?php esc_html_e('Hidden', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['hidden']); ?></span>)
     55</button>
     56<button type="button" class="scc-manager-filter-tab" data-filter="orphaned">
     57<?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['orphaned']); ?></span>)
     58</button>
     59</div>
     60<div class="scc-search-wrap" style="display: flex; gap: 8px;">
     61<label class="screen-reader-text" for="scc-manager-search"><?php esc_html_e('Search shortcodes:', 'foureyed-shortcode-control'); ?></label>
     62<input type="search" id="scc-manager-search"
     63placeholder="<?php esc_attr_e('Search by tag or source...', 'foureyed-shortcode-control'); ?>"
     64autocomplete="off"
     65value="<?php echo esc_attr($search_query); ?>">
     66<button type="button" id="scc-manager-search-clear" class="button" style="display: none;"><?php esc_html_e('Clear Filter', 'foureyed-shortcode-control'); ?></button>
     67</div>
     68</div>
     69</div>
    6170
    62         <!-- Tab Navigation (same pattern as Settings page) -->
    63         <h2 class="nav-tab-wrapper">
    64                 <a href="#" class="nav-tab nav-tab-active" data-target="tab-active">
    65                         <?php esc_html_e('Active Shortcodes', 'foureyed-shortcode-control'); ?>
    66                         <?php if (!empty($grouped_data['active'])): ?>
    67                                 <span class="scc-tab-count"><?php echo count($grouped_data['active']); ?></span>
    68                         <?php endif; ?>
    69                 </a>
    70                 <a href="#" class="nav-tab" data-target="tab-orphaned">
    71                         <?php esc_html_e('Orphaned Shortcodes', 'foureyed-shortcode-control'); ?>
    72                         <?php if (!empty($grouped_data['orphaned'])): ?>
    73                                 <span class="scc-tab-count<?php echo count(array_filter($grouped_data['orphaned'], fn($i) => ($i['status'] ?? '') !== 'hidden')) > 0 ? ' scc-tab-count--alert' : ''; ?>">
    74                                         <?php echo count($grouped_data['orphaned']); ?>
    75                                 </span>
    76                         <?php endif; ?>
    77                 </a>
    78         </h2>
     71<!-- Table 1: Registered Shortcodes -->
     72<?php if (!empty($scc_registered)) : ?>
     73<div class="scc-manager-table-section">
     74<h2 class="scc-table-section-heading"><?php esc_html_e('Registered Shortcodes', 'foureyed-shortcode-control'); ?></h2>
     75<div class="scc-table-card">
     76<form method="get">
     77<input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
     78<?php
     79$scc_table_registered = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
     80$scc_table_registered->set_items($scc_registered);
     81$scc_table_registered->prepare_items();
     82$scc_table_registered->display();
     83?>
     84</form>
     85</div>
     86</div>
     87<?php endif; ?>
    7988
    80         <div>
     89<!-- Table 2: Orphaned Shortcodes -->
     90<?php if (!empty($scc_orphaned)) : ?>
     91<div class="scc-manager-table-section">
     92<h2 class="scc-table-section-heading"><?php esc_html_e('Orphaned Shortcodes', 'foureyed-shortcode-control'); ?></h2>
     93<p class="scc-orphaned-description"><?php esc_html_e('These shortcodes come from plugins that are no longer active. They will output raw text unless silenced. Use Hide to suppress them.', 'foureyed-shortcode-control'); ?></p>
     94<div class="scc-table-card">
     95<form method="get">
     96<input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
     97<?php
     98$scc_table_orphaned = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
     99$scc_table_orphaned->set_items($scc_orphaned);
     100$scc_table_orphaned->prepare_items();
     101$scc_table_orphaned->display();
     102?>
     103</form>
     104</div>
     105</div>
     106<?php endif; ?>
    81107
    82                 <!-- ACTIVE TAB -->
    83                 <div id="tab-active" class="scc-tab-content" style="display: block;">
    84                         <p class="scc-search-no-results" style="display:none;">
    85                                 <?php esc_html_e('No results in this tab for', 'foureyed-shortcode-control'); ?>
    86                                 “<span class="scc-search-no-results__query"></span>”
    87                         </p>
    88                         <?php if (empty($grouped_data['active'])): ?>
    89                                 <p class="scc-empty-tab"><?php esc_html_e('No active shortcodes found.', 'foureyed-shortcode-control'); ?></p>
    90                         <?php else: ?>
    91                                 <form method="get">
    92                                         <?php
    93                                         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    94                                         $scc_page_val = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
    95                                         ?>
    96                                         <input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
    97                                         <?php
    98                                         $scc_table_active = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
    99                                         $scc_table_active->set_items($grouped_data['active']);
    100                                         $scc_table_active->prepare_items();
    101                                         $scc_table_active->display();
    102                                         ?>
    103                                 </form>
    104                         <?php endif; ?>
    105                 </div>
     108<?php if (empty($scc_registered) && empty($scc_orphaned)) : ?>
     109<p class="scc-empty-tab"><?php esc_html_e('No shortcodes found.', 'foureyed-shortcode-control'); ?></p>
     110<?php endif; ?>
    106111
    107                 <!-- ORPHANED TAB -->
    108                 <div id="tab-orphaned" class="scc-tab-content" style="display: none;">
    109                         <p class="scc-search-no-results" style="display:none;">
    110                                 <?php esc_html_e('No results in this tab for', 'foureyed-shortcode-control'); ?>
    111                                 “<span class="scc-search-no-results__query"></span>”
    112                         </p>
    113                         <?php if (empty($grouped_data['orphaned'])): ?>
    114                                 <p class="scc-empty-tab"><?php esc_html_e('No orphaned shortcodes found. All plugins providing shortcodes on this site are currently active.', 'foureyed-shortcode-control'); ?></p>
    115                         <?php else: ?>
    116                                 <p class="scc-orphaned-description">
    117                                         <?php esc_html_e('These shortcodes come from plugins that are no longer active. If they appear in your content they will output raw text. You can silence them (output nothing) or restore them to their previous state.', 'foureyed-shortcode-control'); ?>
    118                                 </p>
    119                                 <form method="get">
    120                                         <?php
    121                                         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    122                                         $scc_page_val = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
    123                                         ?>
    124                                         <input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
    125                                         <?php
    126                                         $scc_table_orphaned = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
    127                                         $scc_table_orphaned->set_items($grouped_data['orphaned']);
    128                                         $scc_table_orphaned->prepare_items();
    129                                         $scc_table_orphaned->display();
    130                                         ?>
    131                                 </form>
    132                         <?php endif; ?>
    133                 </div>
    134 
    135         </div>
    136112</div>
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/AdminUi/manager-search.js

    r3523935 r3524967  
    11/**
    2  * Shortcode Manager — Global Search Filter
     2 * Shortcode Manager — Filter Tabs + Search
    33 *
    4  * Filters rows in both the Active and Orphaned tabs simultaneously.
    5  * Updates count badges and shows a "no results" message per tab.
     4 * Filters rows across both table sections simultaneously.
     5 * Hides entire sections when they have no visible rows after filtering.
     6 * Updates counts in filter tab labels to reflect search matches.
    67 */
    78document.addEventListener('DOMContentLoaded', function () {
    8         const searchInput = document.getElementById('scc-manager-search');
    9         if (!searchInput) return;
     9const searchInput   = document.getElementById('scc-manager-search');
     10const clearBtn      = document.getElementById('scc-manager-search-clear');
     11const filterInput   = document.getElementById('scc-manager-filter-status');
     12const filterTabs    = document.querySelectorAll('.scc-manager-filter-tab');
     13const tableSections = document.querySelectorAll('.scc-manager-table-section');
    1014
    11         const clearBtn   = document.getElementById('scc-manager-search-clear');
    12         const tabPanels  = document.querySelectorAll('.scc-tab-content');
     15if (!searchInput) return;
    1316
    14         // ── Core filter function ─────────────────────────────────────────────────
    15         function filterAll(scrollToTop = false) {
    16                 const query = searchInput.value.toLowerCase().trim();
     17// ── Core filter function ──────────────────────────────────────────────────
     18function applyFilters() {
     19const status = filterInput ? filterInput.value : 'all';
     20const query  = searchInput.value.toLowerCase().trim();
    1721
    18                 tabPanels.forEach(function (panel) {
    19                         const rows = panel.querySelectorAll(
    20                                 'table.wp-list-table tbody tr:not(.no-items)'
    21                         );
    22                         let visibleCount = 0;
     22if (clearBtn) {
     23clearBtn.style.display = query ? '' : 'none';
     24}
    2325
    24                         rows.forEach(function (row) {
    25                                 const tag    = (row.querySelector('.scc-tag-code')  || {}).textContent || '';
    26                                 const source = (row.querySelector('td.column-source') || {}).textContent || '';
    27                                 const match  = !query
    28                                         || tag.toLowerCase().includes(query)
    29                                         || source.toLowerCase().includes(query);
     26tableSections.forEach(function (section) {
     27const rows = section.querySelectorAll('table.wp-list-table tbody tr[data-status]');
     28let visibleCount = 0;
    3029
    31                                 row.style.display = match ? '' : 'none';
    32                                 if (match) visibleCount++;
    33                         });
     30rows.forEach(function (row) {
     31const rowStatus     = row.getAttribute('data-status');
     32const matchesFilter = (status === 'all' || rowStatus === status);
    3433
    35                         // ── Count badge ────────────────────────────────────────────────
    36                         const tabId   = panel.id; // 'tab-active' or 'tab-orphaned'
    37                         const tabLink = document.querySelector('[data-target="' + tabId + '"]');
    38                         if (tabLink) {
    39                                 const badge = tabLink.querySelector('.scc-tab-count');
    40                                 if (badge) {
    41                                         badge.textContent = visibleCount;
     34const tagEl    = row.querySelector('.scc-tag-code');
     35const sourceEl = row.querySelector('td.column-source');
     36const tagText  = tagEl    ? tagEl.textContent.toLowerCase()    : '';
     37const srcText  = sourceEl ? sourceEl.textContent.toLowerCase() : '';
     38const matchesSearch = !query || tagText.includes(query) || srcText.includes(query);
    4239
    43                                         // Re-check alert state for orphaned tab (only count non-silenced)
    44                                         if (tabId === 'tab-orphaned') {
    45                                                 let alertCount = 0;
    46                                                 rows.forEach(function (row) {
    47                                                         if (row.style.display !== 'none'
    48                                                                 && row.querySelector('.scc-status-orphaned')) {
    49                                                                 alertCount++;
    50                                                         }
    51                                                 });
    52                                                 badge.classList.toggle('scc-tab-count--alert', alertCount > 0);
    53                                         }
    54                                 }
    55                         }
     40const visible = matchesFilter && matchesSearch;
     41row.style.display = visible ? '' : 'none';
     42if (visible) visibleCount++;
     43});
    5644
    57                         // ── No-results message ─────────────────────────────────────────
    58                         const noResults = panel.querySelector('.scc-search-no-results');
    59                         if (noResults) {
    60                                 if (query && visibleCount === 0) {
    61                                         noResults.querySelector('.scc-search-no-results__query').textContent = query;
    62                                         noResults.style.display = '';
    63                                 } else {
    64                                         noResults.style.display = 'none';
    65                                 }
    66                         }
    67                 });
     45// Hide the entire section (heading + table) if nothing matches
     46section.style.display = visibleCount > 0 ? '' : 'none';
     47});
    6848
    69                 // ── Clear button visibility ────────────────────────────────────────
    70                 if (clearBtn) {
    71                         clearBtn.style.display = query ? '' : 'none';
    72                 }
     49updateTabCounts(query);
     50}
    7351
    74                 // ── Scroll to top if requested (on initial load with search param) ────
    75                 if (scrollToTop && query) {
    76                         window.scrollTo({ top: 0, behavior: 'smooth' });
    77                 }
    78         }
     52// ── Update counts in tab labels based on search query ────────────────────
     53function updateTabCounts(query) {
     54var counts = { all: 0, enabled: 0, disabled: 0, hidden: 0, orphaned: 0 };
    7955
    80         // ── Trigger filter on page load if search parameter exists ─────────────────
    81         // This handles the case when Scanner's "Manage" link passes ?s=shortcode_tag
    82         if (searchInput.value.trim()) {
    83                 filterAll(true);
     56tableSections.forEach(function (section) {
     57section.querySelectorAll('table.wp-list-table tbody tr[data-status]').forEach(function (row) {
     58const rowStatus = row.getAttribute('data-status');
     59const tagEl    = row.querySelector('.scc-tag-code');
     60const sourceEl = row.querySelector('td.column-source');
     61const tagText  = tagEl    ? tagEl.textContent.toLowerCase()    : '';
     62const srcText  = sourceEl ? sourceEl.textContent.toLowerCase() : '';
     63const matchesSearch = !query || tagText.includes(query) || srcText.includes(query);
    8464
    85                 // Auto-switch to Orphaned tab if the search has no Active matches but does match Orphaned
    86                 const activePanel   = document.getElementById('tab-active');
    87                 const orphanedPanel = document.getElementById('tab-orphaned');
    88                 if (activePanel && orphanedPanel) {
    89                         const countVisible = panel =>
    90                                 [...panel.querySelectorAll('table.wp-list-table tbody tr:not(.no-items)')]
    91                                         .filter(r => r.style.display !== 'none').length;
    92                         if (countVisible(activePanel) === 0 && countVisible(orphanedPanel) > 0) {
    93                                 const orphanedTabLink = document.querySelector('.nav-tab[data-target="tab-orphaned"]');
    94                                 if (orphanedTabLink) orphanedTabLink.click();
    95                         }
    96                 }
    97         }
     65if (matchesSearch) {
     66counts.all++;
     67if (counts[rowStatus] !== undefined) counts[rowStatus]++;
     68}
     69});
     70});
    9871
    99         // ── Event listeners ──────────────────────────────────────────────────────
    100         searchInput.addEventListener('input', filterAll);
     72filterTabs.forEach(function (tab) {
     73const f    = tab.getAttribute('data-filter');
     74const span = tab.querySelector('.scc-filter-count');
     75if (span && counts[f] !== undefined) {
     76span.textContent = counts[f];
     77}
     78});
     79}
    10180
    102         if (clearBtn) {
    103                 clearBtn.addEventListener('click', function () {
    104                         searchInput.value = '';
    105                         filterAll();
    106                         searchInput.focus();
    107                 });
    108         }
     81// ── Filter tab click handler ──────────────────────────────────────────────
     82filterTabs.forEach(function (tab) {
     83tab.addEventListener('click', function () {
     84filterTabs.forEach(function (t) { t.classList.remove('scc-filter-tab-active'); });
     85tab.classList.add('scc-filter-tab-active');
     86if (filterInput) filterInput.value = tab.getAttribute('data-filter');
     87applyFilters();
    10988});
     89});
     90
     91// ── Search input handler ──────────────────────────────────────────────────
     92searchInput.addEventListener('input', applyFilters);
     93
     94// ── Clear button ──────────────────────────────────────────────────────────
     95if (clearBtn) {
     96clearBtn.addEventListener('click', function () {
     97searchInput.value = '';
     98applyFilters();
     99searchInput.focus();
     100});
     101}
     102
     103// ── Run on load (handles ?s= from Scanner's Manage link) ─────────────────
     104applyFilters();
     105});
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/AdminUi/shortcodes.css

    r3523935 r3524967  
    11/* Shortcode Manager admin styles */
    22
    3 .scc-search-context {
    4     margin: 6px 0 12px;
    5     color: #50575e;
    6     font-style: italic;
     3/* ── Toolbar ─────────────────────────────────────────────────────────────── */
     4
     5.scc-toolbar {
     6    margin-bottom: 12px;
     7}
     8
     9.scc-toolbar-main {
     10    display: flex;
     11    align-items: center;
     12    justify-content: space-between;
     13    flex-wrap: wrap;
     14    gap: 8px;
     15}
     16
     17.scc-filter-tabs {
     18    display: inline-flex;
     19    border: 1px solid #c3c4c7;
     20    border-radius: 4px;
     21    overflow: hidden;
     22}
     23
     24.scc-manager-filter-tab {
     25    flex: 1;
     26    border: 0;
     27    border-right: 1px solid #c3c4c7;
     28    background: #f6f7f7;
     29    cursor: pointer;
     30    padding: 6px 16px;
     31    white-space: nowrap;
     32    transition: background 0.15s, color 0.15s;
     33}
     34
     35.scc-manager-filter-tab:last-child {
     36    border-right: 0;
     37}
     38
     39.scc-filter-tab-active {
     40    background: #2271b1;
     41    color: #fff;
     42    font-weight: 600;
     43}
     44
     45.scc-search-wrap input[type="search"] {
     46    width: 240px;
     47}
     48
     49/* ── Table sections ─────────────────────────────────────────────────────── */
     50
     51.scc-manager-table-section {
     52    margin-bottom: 24px;
     53}
     54
     55.scc-table-section-heading {
     56    font-size: 14px;
     57    font-weight: 600;
     58    margin: 0 0 8px;
     59    padding: 0;
     60    color: #1d2327;
     61}
     62
     63.scc-table-card {
     64    border: 1px solid #c3c4c7;
     65    border-radius: 6px;
     66    overflow: hidden;
     67    background: #fff;
     68}
     69
     70.scc-admin-page .wp-list-table {
     71    margin: 0;
     72    border: 0;
     73    box-shadow: none;
    774}
    875
    … …  
    34101
    35102.scc-status-orphaned {
    36     background: #fef3cd;
    37     color: #7a4f00;
    38 }
    39 
    40 .scc-tab-count {
    41     display: inline-block;
    42     background: #ddd;
    43     color: #444;
    44     font-size: 11px;
    45     font-weight: 600;
    46     border-radius: 10px;
    47     padding: 1px 7px;
    48     margin-left: 5px;
    49     vertical-align: middle;
    50 }
    51 
    52 .scc-tab-count--alert {
    53103    background: #fef3cd;
    54104    color: #7a4f00;
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/Api/ShortcodeManagerApi.php

    r3523935 r3524967  
    3838        }
    3939
     40        /**
     41         * Get shortcode status counts for stats display.
     42         * Single source of truth for all stat cards (Manager, Start Here, etc.).
     43         *
     44         * Four categories:
     45         *  - enabled  → status 'registered'                              (plugin active, shortcode on)
     46         *  - disabled → status 'unregistered' AND is_active true         (user disabled an active shortcode, returns raw text)
     47         *  - hidden   → status 'hidden'                                  (user silenced it, outputs nothing)
     48         *  - orphaned → status 'unregistered' AND is_active false        (plugin deactivated, user hasn't touched it)
     49         *
     50         * @return array{enabled: int, disabled: int, hidden: int, orphaned: int}
     51         */
     52        public static function get_stats(): array
     53        {
     54                $data = self::get_all_data();
     55
     56                // Respect the "hide core shortcodes" setting, same as the Manager page does.
     57                $hide_core = get_option(\FoureyedShortcodeControl\DataRegistry::OPTION_HIDE_CORE, true);
     58                if ($hide_core) {
     59                        $data = array_filter($data, fn($sc) => ($sc['source_type'] ?? '') !== 'core');
     60                }
     61
     62                $enabled  = 0;
     63                $disabled = 0;
     64                $hidden   = 0;
     65                $orphaned = 0;
     66
     67                foreach ($data as $sc) {
     68                        $status    = $sc['status'] ?? '';
     69                        $is_active = $sc['is_active'] ?? false;
     70                        if ($status === 'registered') {
     71                                $enabled++;
     72                        } elseif ($status === 'hidden') {
     73                                $hidden++;
     74                        } elseif ($status === 'unregistered' && $is_active) {
     75                                $disabled++;
     76                        } elseif ($status === 'unregistered' && !$is_active) {
     77                                $orphaned++;
     78                        }
     79                }
     80
     81                return compact('enabled', 'disabled', 'hidden', 'orphaned');
     82        }
     83
    4084}
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/ShortcodeManager/Core/ShortcodeRegistry.php

    r3523935 r3524967  
    224224                foreach ($master as $tag => $item) {
    225225                        $is_active = in_array($tag, $active_tags, true);
    226                         $is_discovered = in_array($tag, $discovered_tags, true);
     226                        // Cast $tag to string: PHP coerces numeric string array keys to integers,
     227                        // so a tag like '13' is stored as integer 13 in $master. $discovered_tags
     228                        // from get_col() are always strings, so strict in_array(13, ['13'], true)
     229                        // would return false and incorrectly prune numeric-tag orphans.
     230                        $is_discovered = in_array((string) $tag, $discovered_tags, true);
    227231                        $is_hidden = ($item['status'] ?? '') === 'hidden';
    228232
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/StartHere/AdminUi/StartHerePageController.php

    r3523935 r3524967  
    55use FoureyedShortcodeControl\Features\StartHere\Core\StartHereHelper;
    66use FoureyedShortcodeControl\Features\Scanner\Api\ScannerApi;
     7use FoureyedShortcodeControl\Features\ShortcodeManager\Api\ShortcodeManagerApi;
    78
    89if (!defined('ABSPATH')) {
    … …  
    2324        public function render_page()
    2425        {
    25                 // Enqueue shared + page-specific assets
    26                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    27                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     26                // Enqueue page-specific assets (shared assets loaded globally via Bootstrap)
    2827                wp_enqueue_style('foureyed-shortcode-control-start-here', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/StartHere/AdminUi/styles.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    2928
    30                 // Get scanner counts (all zeroes if no scan has been run yet)
    31                 $scan_data   = ScannerApi::get_prepared_data();
    32                 $scan_counts = $scan_data['counts'];
     29                // Get scanner counts — single source of truth via Scanner API
     30                $scan_stats = ScannerApi::get_stats();
    3331
    34                 // Get stats for the page
    35                 $total_shortcodes    = StartHereHelper::get_total_shortcodes();
    36                 $active_shortcodes   = StartHereHelper::get_active_shortcodes();
    37                 $disabled_shortcodes = StartHereHelper::get_disabled_shortcodes();
    38                 $hidden_shortcodes   = StartHereHelper::get_hidden_shortcodes();
     32                // Shortcode stats — single source of truth via Manager API
     33                $stats = ShortcodeManagerApi::get_stats();
     34
    3935                // A scan has been run if there are any results in the DB.
    40                 $has_been_scanned = $scan_counts['total'] > 0;
     36                $has_been_scanned = $scan_stats['total'] > 0;
    4137
    4238                // Prepare template data
    4339                $data = [
    44                         'total_shortcodes'    => $total_shortcodes,
    45                         'active_shortcodes'   => $active_shortcodes,
    46                         'disabled_shortcodes' => $disabled_shortcodes,
    47                         'hidden_shortcodes'   => $hidden_shortcodes,
     40                        'all_shortcodes'      => $stats['enabled'] + $stats['disabled'] + $stats['hidden'] + $stats['orphaned'],
     41                        'enabled_shortcodes'  => $stats['enabled'],
     42                        'disabled_shortcodes' => $stats['disabled'],
     43                        'hidden_shortcodes'   => $stats['hidden'],
     44                        'orphaned_shortcodes' => $stats['orphaned'],
    4845                        'has_been_scanned'    => $has_been_scanned,
    49                         'scan_total'          => $scan_counts['total'],
    50                         'scan_active'         => $scan_counts['active'],
    51                         'scan_disabled'       => $scan_counts['disabled'],
    52                         'scan_orphaned'       => $scan_counts['orphaned'],
     46                        'scan_total'          => $scan_stats['total'],
     47                        'scan_active'         => $scan_stats['active'],
     48                        'scan_disabled'       => $scan_stats['disabled'],
     49                        'scan_orphaned'       => $scan_stats['orphaned'],
    5350                ];
    5451
    … …  
    7269                        <h2 class="scc-start-section-title"><?php esc_html_e('Registered Shortcodes', 'foureyed-shortcode-control'); ?></h2>
    7370                        <div class="scc-start-stats-row">
    74                                 <div class="scc-start-stat-card">
    75                                         <div class="scc-stat-number"><?php echo intval($data['total_shortcodes']); ?></div>
    76                                         <div class="scc-stat-label"><?php esc_html_e('Total', 'foureyed-shortcode-control'); ?></div>
    77                                 </div>
     71                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control')); ?>" class="scc-start-stat-card">
     72                                        <div class="scc-stat-number"><?php echo intval($data['all_shortcodes']); ?></div>
     73                                        <div class="scc-stat-label"><?php esc_html_e('All', 'foureyed-shortcode-control'); ?></div>
     74                                </a>
    7875                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control')); ?>" class="scc-start-stat-card scc-start-stat-enabled">
    79                                         <div class="scc-stat-number"><?php echo intval($data['active_shortcodes']); ?></div>
     76                                        <div class="scc-stat-number"><?php echo intval($data['enabled_shortcodes']); ?></div>
    8077                                        <div class="scc-stat-label"><?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?></div>
    8178                                </a>
    … …  
    8885                                        <div class="scc-stat-label"><?php esc_html_e('Hidden', 'foureyed-shortcode-control'); ?></div>
    8986                                </div>
     87                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control#tab-orphaned')); ?>" class="scc-start-stat-card<?php echo $data['orphaned_shortcodes'] > 0 ? ' scc-start-stat-orphaned--alert' : ' scc-start-stat-orphaned'; ?>">
     88                                        <div class="scc-stat-number"><?php echo intval($data['orphaned_shortcodes']); ?></div>
     89                                        <div class="scc-stat-label"><?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?></div>
     90                                </a>
    9091                        </div>
    9192
    … …  
    105106                                <div class="scc-start-stat-card scc-start-stat-enabled">
    106107                                        <div class="scc-stat-number"><?php echo intval($data['scan_active']); ?></div>
    107                                         <div class="scc-stat-label"><?php esc_html_e('Enabled in Content', 'foureyed-shortcode-control'); ?></div>
     108                                        <div class="scc-stat-label"><?php esc_html_e('Active', 'foureyed-shortcode-control'); ?></div>
    108109                                </div>
    109110                                <div class="scc-start-stat-card scc-start-stat-disabled">
    110111                                        <div class="scc-stat-number"><?php echo intval($data['scan_disabled']); ?></div>
    111                                         <div class="scc-stat-label"><?php esc_html_e('Disabled in Content', 'foureyed-shortcode-control'); ?></div>
     112                                        <div class="scc-stat-label"><?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?></div>
    112113                                </div>
    113                                 <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control-scanner')); ?>"
    114                                    class="scc-start-stat-card<?php echo $data['scan_orphaned'] > 0 ? ' scc-start-stat-orphaned--alert' : ' scc-start-stat-orphaned'; ?>">
     114                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control-scanner')); ?>" class="scc-start-stat-card<?php echo $data['scan_orphaned'] > 0 ? ' scc-start-stat-orphaned--alert' : ' scc-start-stat-orphaned'; ?>">
    115115                                        <div class="scc-stat-number"><?php echo intval($data['scan_orphaned']); ?></div>
    116116                                        <div class="scc-stat-label"><?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?></div>
  • foureyed-shortcode-control/tags/1.0.4/includes/Features/StartHere/Core/StartHereHelper.php

    r3523935 r3524967  
    44
    55use FoureyedShortcodeControl\DataRegistry;
    6 use FoureyedShortcodeControl\Features\ShortcodeManager\Core\ShortcodesDataProvider;
    76
    87if (!defined('ABSPATH')) {
    … …  
    1110
    1211/**
    13  * Start Here Helper — Provides data for the welcome wizard page.
    14  *
    15  * Fetches statistics and information to display on the Start Here page.
    16  * Routes through ShortcodesDataProvider so hide_core and other settings
    17  * are respected, keeping counts consistent with the Shortcode Manager page.
     12 * Start Here Helper — Lightweight helpers for the Start Here page.
     13 *
     14 * Stat counts are owned by ShortcodeManagerApi::get_stats().
     15 * This class only provides helpers that have no other home.
    1816 */
    1917class StartHereHelper
    2018{
    21         /**
    22          * Get all shortcode data respecting current settings (e.g. hide_core).
    23          */
    24         private static function get_data(): array
    25         {
    26                 static $cache = null;
    27                 if ($cache !== null) {
    28                         return $cache;
    29                 }
    30                 $provider = new ShortcodesDataProvider();
    31                 $data     = $provider->get_data();
    32                 $cache    = $provider->maybe_hide_core($data);
    33                 return $cache;
    34         }
    35 
    36         /**
    37          * Get total number of shortcodes (after settings filters applied).
    38          */
    39         public static function get_total_shortcodes(): int
    40         {
    41                 return count(self::get_data());
    42         }
    43 
    44         /**
    45          * Get number of enabled shortcodes (status === 'registered').
    46          */
    47         public static function get_active_shortcodes(): int
    48         {
    49                 $count = 0;
    50                 foreach (self::get_data() as $sc) {
    51                         if (($sc['status'] ?? '') === 'registered') {
    52                                 $count++;
    53                         }
    54                 }
    55                 return $count;
    56         }
    57 
    58         /**
    59          * Get number of disabled or hidden shortcodes (anything not 'registered').
    60          */
    61         public static function get_disabled_shortcodes(): int
    62         {
    63                 $count = 0;
    64                 foreach (self::get_data() as $sc) {
    65                         if (($sc['status'] ?? '') === 'unregistered') {
    66                                 $count++;
    67                         }
    68                 }
    69                 return $count;
    70         }
    71 
    72         /**
    73          * Get number of hidden shortcodes (status === 'hidden').
    74          */
    75         public static function get_hidden_shortcodes(): int
    76         {
    77                 $count = 0;
    78                 foreach (self::get_data() as $sc) {
    79                         if (($sc['status'] ?? '') === 'hidden') {
    80                                 $count++;
    81                         }
    82                 }
    83                 return $count;
    84         }
    85 
    8619        /**
    8720         * Check if site has been scanned yet.
  • foureyed-shortcode-control/tags/1.0.4/includes/Services/tooltip.css

    r3523935 r3524967  
    2929    cursor: pointer;
    3030    display: inline-block;
    31     color: inherit;
     31    color: #2271b1;
    3232    font-weight: inherit;
    3333    font-size: inherit;
    3434    margin-left: 0;
     35}
     36
     37a.scc-tooltip:hover,
     38a.scc-tooltip:focus {
     39    color: #135e96;
    3540}
    3641
  • foureyed-shortcode-control/tags/1.0.4/includes/Services/tooltip.js

    r3523933 r3524967  
    3232            tooltip.style.display = 'block';
    3333
    34             // Position relative to trigger
     34            // Position relative to trigger.
     35            // tooltip-box is position:fixed so coordinates are viewport-relative;
     36            // do NOT add window.scrollX/Y (that's for position:absolute).
    3537            const rect = trigger.getBoundingClientRect();
    36             tooltip.style.left = (rect.left + window.scrollX) + 'px';
    37             tooltip.style.top = (rect.bottom + window.scrollY + 8) + 'px';
     38            tooltip.style.left = rect.left + 'px';
     39            tooltip.style.top = (rect.bottom + 8) + 'px';
    3840        }
    3941
    … …  
    4951        trigger.addEventListener('mouseleave', hideTooltip);
    5052
    51         // Click events (for touch devices)
     53        // Click events (for touch devices / non-link tooltips)
    5254        trigger.addEventListener('click', function (e) {
    53             e.preventDefault();
     55            // For links and buttons, don't block navigation — just toggle tooltip
     56            // alongside the native action. Only preventDefault for non-interactive
     57            // elements like <span class="scc-tooltip"> (the ? badges).
     58            const isInteractive = trigger.tagName === 'A' || trigger.tagName === 'BUTTON';
     59            if (!isInteractive) {
     60                e.preventDefault();
     61            }
    5462            if (tooltip && tooltip.style.display === 'block') {
    5563                hideTooltip();
  • foureyed-shortcode-control/tags/1.0.4/languages/foureyed-shortcode-control.pot

    r3523933 r3524967  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Foureyed Shortcode Control 1.0.0\n"
     5"Project-Id-Version: Foureyed Shortcode Control 1.0.4\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foureyed-shortcode-control\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
    … …  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2026-04-28T03:07:16+00:00\n"
     12"POT-Creation-Date: 2026-05-07T03:40:17+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.12.0\n"
    … …  
    1717#. Plugin Name of the plugin
    1818#: foureyed-shortcode-control.php
     19#: includes/Features/StartHere/AdminUi/StartHerePageController.php:64
    1920msgid "Foureyed Shortcode Control"
    2021msgstr ""
    … …  
    4041msgstr ""
    4142
    42 #: includes/Bootstrap.php:55
    43 #: includes/Bootstrap.php:56
     43#: includes/Bootstrap.php:66
     44#: includes/Bootstrap.php:67
    4445msgid "Shortcode Control"
    4546msgstr ""
    4647
    47 #: includes/Bootstrap.php:67
     48#: includes/Bootstrap.php:78
    4849msgid "Start Here — Shortcode Control"
    4950msgstr ""
    5051
    51 #: includes/Bootstrap.php:68
     52#: includes/Bootstrap.php:79
    5253msgid "Start Here"
    5354msgstr ""
    5455
    55 #: includes/Bootstrap.php:76
    56 #: includes/Bootstrap.php:77
     56#: includes/Bootstrap.php:87
     57#: includes/Bootstrap.php:88
     58#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:26
     59#: includes/Features/StartHere/AdminUi/StartHerePageController.php:124
    5760msgid "Manage Shortcodes"
    5861msgstr ""
    5962
    60 #: includes/Bootstrap.php:90
    61 #: includes/Bootstrap.php:91
    62 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:36
     63#: includes/Bootstrap.php:101
     64#: includes/Bootstrap.php:102
     65#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:41
    6366msgid "Find Orphaned Shortcodes"
    6467msgstr ""
    6568
    66 #: includes/Bootstrap.php:99
    67 #: includes/Bootstrap.php:100
    68 #: includes/Features/Settings/AdminUi/SettingsPageController.php:36
    69 msgid "Tools & Settings"
    70 msgstr ""
    71 
    72 #. translators: %s: shortcode tag name
    73 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:29
    74 #, php-format
    75 msgid "Successfully adopted shortcode &ldquo;%s&rdquo;. It is now <strong>disabled</strong> by default. You can manage it in the &ldquo;Manually Adopted&rdquo; section of your Shortcodes page."
    76 msgstr ""
    77 
    78 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:97
    79 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:29
     69#: includes/Bootstrap.php:110
     70#: includes/Bootstrap.php:111
     71#: includes/Features/Settings/AdminUi/SettingsPageController.php:37
     72msgid "Settings & Tools"
     73msgstr ""
     74
     75#: includes/Features/Scanner/AdminUi/ScannerPageController.php:76
     76#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:34
    8077msgid "Start Scan"
    8178msgstr ""
    8279
    83 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:98
    84 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:26
     80#: includes/Features/Scanner/AdminUi/ScannerPageController.php:77
     81#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:30
    8582msgid "Scan Changes"
    8683msgstr ""
    8784
    88 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:99
     85#: includes/Features/Scanner/AdminUi/ScannerPageController.php:78
    8986#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:23
    9087msgid "Continue Scan"
    9188msgstr ""
    9289
    93 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:100
     90#: includes/Features/Scanner/AdminUi/ScannerPageController.php:79
     91msgid "Scanning..."
     92msgstr ""
     93
     94#: includes/Features/Scanner/AdminUi/ScannerPageController.php:80
     95msgid "Scan complete!"
     96msgstr ""
     97
     98#. translators: 1: number of posts scanned, 2: total posts, 3: percentage
     99#: includes/Features/Scanner/AdminUi/ScannerPageController.php:82
     100#, php-format
     101msgid "Scanned %1$s of %2$s posts (%3$s%%)"
     102msgstr ""
     103
     104#: includes/Features/Scanner/AdminUi/ScannerPageController.php:83
     105#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:191
     106msgid "(No Title)"
     107msgstr ""
     108
     109#: includes/Features/Scanner/AdminUi/ScannerPageController.php:84
     110msgid "No shortcodes found. Run a scan to populate this table."
     111msgstr ""
     112
    94113#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:20
    95114msgid "Scanning\\u2026"
    96115msgstr ""
    97116
    98 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:101
    99 msgid "Scan complete!"
    100 msgstr ""
    101 
    102 #. translators: 1: number of posts scanned, 2: total posts, 3: percentage
    103 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:103
     117#. translators: %d is the number of modified posts waiting to be scanned.
     118#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:28
    104119#, php-format
    105 msgid "Scanned %1$s of %2$s posts (%3$s%%)"
    106 msgstr ""
    107 
    108 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:104
    109 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:183
    110 msgid "(No Title)"
    111 msgstr ""
    112 
    113 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:105
    114 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:148
    115 msgid "No shortcodes found. Run a scan to populate this table."
    116 msgstr ""
    117 
    118 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:37
     120msgid "Scan %d Changes"
     121msgstr ""
     122
     123#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:42
    119124msgid "Scans your posts and pages for shortcodes whose plugins have been deactivated or deleted. These broken shortcodes may display as raw text or cause layout issues on your site."
    120125msgstr ""
    121126
    122 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:40
    123 msgid "Scan your published content to find shortcodes that no longer have an active plugin behind them — so you can fix or remove them before they cause problems."
    124 msgstr ""
    125 
    126 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:55
    127 msgid "PHP time limit reached"
    128 msgstr ""
    129 
    130 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:56
    131 msgid "PHP memory limit reached"
    132 msgstr ""
    133 
    134 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:57
    135 msgid "server process was interrupted"
    136 msgstr ""
    137 
    138 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:58
    139 msgid "an unexpected error"
    140 msgstr ""
    141 
    142 #. translators: 1: processed count, 2: total count, 3: reason
     127#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:48
     128msgid "Quick Guide:"
     129msgstr ""
     130
     131#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:49
     132msgid "Run a scan, review orphaned findings first, then click Manage to jump directly into Shortcode Manager for that shortcode tag."
     133msgstr ""
     134
     135#. translators: %d is the number of posts that have been modified since the last scan.
    143136#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:62
    144137#, php-format
     138msgid "Scan required: %d modified posts pending."
     139msgstr ""
     140
     141#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:64
     142msgid "You can safely leave this page anytime once the scan begins. Scanning happens in background batches based on your Settings."
     143msgstr ""
     144
     145#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:77
     146msgid "PHP time limit reached"
     147msgstr ""
     148
     149#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:78
     150msgid "PHP memory limit reached"
     151msgstr ""
     152
     153#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:79
     154msgid "server process was interrupted"
     155msgstr ""
     156
     157#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:80
     158msgid "an unexpected error"
     159msgstr ""
     160
     161#. translators: 1: processed count, 2: total count, 3: reason
     162#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:84
     163#, php-format
    145164msgid "Scan stopped after processing %1$s of %2$s posts (%3$s). Click \\u201cContinue Scan\\u201d to resume from where it stopped."
    146165msgstr ""
    147166
    148 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:87
    149 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:29
    150 msgid "Total"
    151 msgstr ""
    152 
    153 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:91
    154 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:121
    155 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:162
    156 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:176
    157 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:25
    158 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:159
    159 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:33
    160 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:64
    161 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:84
    162 #: includes/Services/StatusHelper.php:38
    163 #: includes/Services/StatusHelper.php:73
    164 msgid "Active"
    165 msgstr ""
    166 
    167 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:95
    168 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:125
    169 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:161
    170 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:166
    171 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:175
    172 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:25
    173 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:160
    174 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:37
    175 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:68
    176 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:88
     167#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:96
     168msgid "Scans all published posts and pages for shortcode tags, then cross-checks them against currently active plugins."
     169msgstr ""
     170
     171#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:113
     172#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:45
     173#: includes/Features/StartHere/AdminUi/StartHerePageController.php:73
     174msgid "All"
     175msgstr ""
     176
     177#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:116
     178#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:40
     179#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:48
     180#: includes/Features/StartHere/AdminUi/StartHerePageController.php:77
     181#: includes/Services/DataGrouper.php:60
     182msgid "Enabled"
     183msgstr ""
     184
     185#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:119
     186#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:43
     187#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:51
     188#: includes/Features/StartHere/AdminUi/StartHerePageController.php:81
     189#: includes/Features/StartHere/AdminUi/StartHerePageController.php:112
     190#: includes/Services/DataGrouper.php:58
    177191#: includes/Services/StatusHelper.php:37
    178192#: includes/Services/StatusHelper.php:75
    … …  
    180194msgstr ""
    181195
    182 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:99
    183 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:129
    184 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:164
    185 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:115
     196#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:122
     197#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:176
     198#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:36
     199#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:57
     200#: includes/Features/StartHere/AdminUi/StartHerePageController.php:89
     201#: includes/Features/StartHere/AdminUi/StartHerePageController.php:116
    186202#: includes/Services/StatusHelper.php:77
    187203msgid "Orphaned"
    188204msgstr ""
    189205
    190 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:107
     206#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:127
    191207msgid "Search findings:"
    192208msgstr ""
    193209
    194 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:109
    195 msgid "Search post title or tag..."
    196 msgstr ""
    197 
    198 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:117
    199 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:60
    200 msgid "All"
     210#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:129
     211msgid "Search by post title or shortcode tag..."
     212msgstr ""
     213
     214#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:130
     215#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:66
     216msgid "Clear Filter"
    201217msgstr ""
    202218
    203219#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:139
    204 msgid "Post Title"
     220msgid "Location"
    205221msgstr ""
    206222
    207223#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:140
    208 msgid "Post Type"
     224msgid "Shortcode"
    209225msgstr ""
    210226
    211227#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:141
    212 msgid "Shortcode Tag"
     228#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:58
     229msgid "Status"
    213230msgstr ""
    214231
    215232#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:142
    216 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:56
    217 msgid "Status"
    218 msgstr ""
    219 
    220 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:143
    221 msgid "Last Scanned"
    222 msgstr ""
    223 
    224 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:159
    225 #: includes/Services/DataGrouper.php:37
    226 #: includes/Services/ShortcodeFormatter.php:33
    227 msgid "Manually Adopted"
    228 msgstr ""
    229 
    230 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:169
    231 #: includes/Services/ShortcodeFormatter.php:27
    232 msgid "Plugin Shortcode"
    233 msgstr ""
    234 
    235 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:170
    236 #: includes/Services/ShortcodeFormatter.php:29
    237 msgid "Theme Shortcode"
    238 msgstr ""
    239 
    240 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:171
    241 #: includes/Services/ShortcodeFormatter.php:31
    242 msgid "WordPress Shortcode"
    243 msgstr ""
    244 
    245 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:172
    246 #: includes/Services/ShortcodeFormatter.php:36
    247 msgid "Registered"
    248 msgstr ""
    249 
    250 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:190
    251 msgid "Edit Post"
    252 msgstr ""
    253 
    254 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:197
    255 msgid "Filter this tag"
     233#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:60
     234msgid "Source"
     235msgstr ""
     236
     237#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:147
     238#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:109
     239msgid "No shortcodes found."
     240msgstr ""
     241
     242#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:147
     243msgid "Run a scan to populate this table."
     244msgstr ""
     245
     246#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:174
     247#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:33
     248msgid "Silenced"
     249msgstr ""
     250
     251#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:178
     252#: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:200
     253#: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:227
     254#: includes/Services/StatusHelper.php:79
     255msgid "Unknown"
    256256msgstr ""
    257257
    258258#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:198
    259 msgid "Manage Shortcode"
    260 msgstr ""
    261 
    262 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:200
    263 msgid "Adopt"
    264 msgstr ""
    265 
    266 #: includes/Features/Scanner/Rest/ScannerRestController.php:83
     259msgid "Open this post in the WordPress editor"
     260msgstr ""
     261
     262#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:198
     263msgid "Edit"
     264msgstr ""
     265
     266#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:205
     267msgid "View this post on the front-end"
     268msgstr ""
     269
     270#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:205
     271msgid "View"
     272msgstr ""
     273
     274#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:217
     275msgid "WordPress Core"
     276msgstr ""
     277
     278#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:217
     279msgid "Enable &ldquo;Show WordPress Core shortcodes&rdquo; in Settings to manage this shortcode"
     280msgstr ""
     281
     282#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:217
     283msgid "enable in Settings"
     284msgstr ""
     285
     286#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:219
     287msgid "Go to Shortcode Manager and filter to this tag"
     288msgstr ""
     289
     290#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:219
     291msgid "Manage"
     292msgstr ""
     293
     294#: includes/Features/Scanner/Rest/ScannerRestController.php:84
    267295msgid "A scan is already in progress."
    268296msgstr ""
    … …  
    288316msgstr ""
    289317
    290 #: includes/Features/Settings/AdminUi/SettingsPageController.php:37
     318#: includes/Features/Settings/AdminUi/SettingsPageController.php:38
    291319msgid "Configure global plugin settings, control scanner behavior, manage performance, and perform maintenance tasks like clearing caches or resetting data."
    292320msgstr ""
    293321
    294 #: includes/Features/Settings/AdminUi/SettingsPageController.php:53
    295 msgid "General"
    296 msgstr ""
    297 
    298 #: includes/Features/Settings/AdminUi/SettingsPageController.php:56
    299 #: includes/Services/DataGrouper.php:106
    300 msgid "Shortcodes"
    301 msgstr ""
    302 
    303 #: includes/Features/Settings/AdminUi/SettingsPageController.php:59
    304 msgid "Scanner"
    305 msgstr ""
    306 
    307 #: includes/Features/Settings/AdminUi/SettingsPageController.php:62
    308 #: includes/Features/Settings/AdminUi/SettingsPageController.php:89
    309 msgid "Advanced Tools"
    310 msgstr ""
    311 
    312 #: includes/Features/Settings/AdminUi/SettingsPageController.php:90
     322#: includes/Features/Settings/AdminUi/SettingsPageController.php:41
     323msgid "Adjust how the plugin behaves across modules. If you are unsure, keep the defaults — they are safe for most sites."
     324msgstr ""
     325
     326#: includes/Features/Settings/AdminUi/SettingsPageController.php:47
     327msgid "Beginner Tip:"
     328msgstr ""
     329
     330#: includes/Features/Settings/AdminUi/SettingsPageController.php:48
     331msgid "Change one setting at a time, click Save All Settings, then verify behavior in Manage Shortcodes or Scanner."
     332msgstr ""
     333
     334#: includes/Features/Settings/AdminUi/SettingsPageController.php:64
     335#: includes/Features/StartHere/AdminUi/StartHerePageController.php:138
     336msgid "Settings"
     337msgstr ""
     338
     339#: includes/Features/Settings/AdminUi/SettingsPageController.php:67
     340#: includes/Features/Settings/AdminUi/SettingsPageController.php:86
     341msgid "Tools"
     342msgstr ""
     343
     344#: includes/Features/Settings/AdminUi/SettingsPageController.php:87
    313345msgid "Server-level maintenance tools. Proceed with caution."
    314346msgstr ""
    315347
    316 #: includes/Features/Settings/AdminUi/SettingsPageController.php:94
     348#: includes/Features/Settings/AdminUi/SettingsPageController.php:91
    317349msgid "Reset Shortcode Manager Data"
    318350msgstr ""
    319351
     352#: includes/Features/Settings/AdminUi/SettingsPageController.php:93
     353msgid "Clears all shortcode manager data including disabled toggles, adopted orphans, performance metrics, and registry caches. All your manually managed shortcodes will be reset."
     354msgstr ""
     355
     356#: includes/Features/Settings/AdminUi/SettingsPageController.php:95
     357msgid "Are you sure? This will clear all disabled toggles and adopted orphans."
     358msgstr ""
     359
    320360#: includes/Features/Settings/AdminUi/SettingsPageController.php:96
    321 msgid "Clears all shortcode manager data including disabled toggles, adopted orphans, performance metrics, and registry caches. All your manually managed shortcodes will be reset."
    322 msgstr ""
    323 
    324 #: includes/Features/Settings/AdminUi/SettingsPageController.php:98
    325 msgid "Are you sure? This will clear all disabled toggles and adopted orphans."
    326 msgstr ""
    327 
    328 #: includes/Features/Settings/AdminUi/SettingsPageController.php:99
    329361msgid "Reset Shortcode Data"
    330362msgstr ""
    331363
    332 #: includes/Features/Settings/AdminUi/SettingsPageController.php:105
    333 #: includes/Features/Settings/AdminUi/SettingsPageController.php:110
     364#: includes/Features/Settings/AdminUi/SettingsPageController.php:102
     365#: includes/Features/Settings/AdminUi/SettingsPageController.php:107
    334366msgid "Reset Scanner Data"
    335367msgstr ""
    336368
    337 #: includes/Features/Settings/AdminUi/SettingsPageController.php:107
     369#: includes/Features/Settings/AdminUi/SettingsPageController.php:104
    338370msgid "Clears all scanner results and progress markers. This allows the scanner to re-scan all posts as if running for the first time. All previous scan results will be deleted."
    339371msgstr ""
    340372
    341 #: includes/Features/Settings/AdminUi/SettingsPageController.php:109
     373#: includes/Features/Settings/AdminUi/SettingsPageController.php:106
    342374msgid "Are you sure you want to delete all scanner data? The next scan will re-scan every post."
    343375msgstr ""
    344376
    345 #: includes/Features/Settings/AdminUi/SettingsPageController.php:116
     377#: includes/Features/Settings/AdminUi/SettingsPageController.php:113
    346378msgid "Factory Reset (Nuclear Option)"
    347379msgstr ""
    348380
     381#: includes/Features/Settings/AdminUi/SettingsPageController.php:115
     382msgid "Wipes EVERYTHING. Deletes all scanner results, clears all shortcode manager data, resets all settings, and un-toggles every shortcode. Reverts the plugin to Day 1."
     383msgstr ""
     384
     385#: includes/Features/Settings/AdminUi/SettingsPageController.php:117
     386msgid "WARNING: This will delete EVERYTHING and re-enable every shortcode. Are you absolutely certain?"
     387msgstr ""
     388
    349389#: includes/Features/Settings/AdminUi/SettingsPageController.php:118
    350 msgid "Wipes EVERYTHING. Deletes all scanner results, clears all shortcode manager data, resets all settings, and un-toggles every shortcode. Reverts the plugin to Day 1."
    351 msgstr ""
    352 
    353 #: includes/Features/Settings/AdminUi/SettingsPageController.php:120
    354 msgid "WARNING: This will delete EVERYTHING and re-enable every shortcode. Are you absolutely certain?"
    355 msgstr ""
    356 
    357 #: includes/Features/Settings/AdminUi/SettingsPageController.php:121
    358390msgid "Factory Reset"
    359391msgstr ""
    360392
    361 #: includes/Features/Settings/AdminUi/SettingsPageController.php:131
     393#: includes/Features/Settings/AdminUi/SettingsPageController.php:128
    362394msgid "Save All Settings"
    363395msgstr ""
    364396
    365 #: includes/Features/Settings/AdminUi/SettingsPageController.php:132
     397#: includes/Features/Settings/AdminUi/SettingsPageController.php:129
    366398msgid "You can save adjustments from multiple tabs simultaneously."
    367399msgstr ""
    … …  
    375407msgstr ""
    376408
    377 #: includes/Features/Settings/Core/SettingsRegistrar.php:76
     409#: includes/Features/Settings/Core/SettingsRegistrar.php:81
    378410msgid "Shortcode Display Settings"
    379411msgstr ""
    380412
    381 #: includes/Features/Settings/Core/SettingsRegistrar.php:83
    382 msgid "Hide Core Shortcodes"
    383 msgstr ""
    384 
    385 #: includes/Features/Settings/Core/SettingsRegistrar.php:91
    386 msgid "Fallback Behavior"
    387 msgstr ""
    388 
    389 #: includes/Features/Settings/Core/SettingsRegistrar.php:112
     413#: includes/Features/Settings/Core/SettingsRegistrar.php:88
     414msgid "WordPress Core Shortcodes"
     415msgstr ""
     416
     417#: includes/Features/Settings/Core/SettingsRegistrar.php:120
    390418msgid "Scanner Configuration"
    391419msgstr ""
    392420
    393 #: includes/Features/Settings/Core/SettingsRegistrar.php:119
     421#: includes/Features/Settings/Core/SettingsRegistrar.php:127
    394422msgid "Posts Per Batch"
    395423msgstr ""
    396424
    397 #: includes/Features/Settings/Core/SettingsRegistrar.php:129
     425#: includes/Features/Settings/Core/SettingsRegistrar.php:135
     426msgid "Exclude Blocks from Scan"
     427msgstr ""
     428
     429#: includes/Features/Settings/Core/SettingsRegistrar.php:145
    398430msgid "Global plugin behaviors and data management."
    399431msgstr ""
    400432
    401 #: includes/Features/Settings/Core/SettingsRegistrar.php:138
     433#: includes/Features/Settings/Core/SettingsRegistrar.php:155
    402434msgid "Completely delete all toggles, scanner history, and data if you uninstall the plugin."
    403435msgstr ""
    404436
    405 #: includes/Features/Settings/Core/SettingsRegistrar.php:140
     437#: includes/Features/Settings/Core/SettingsRegistrar.php:158
    406438msgid "If unchecked (default), your configurations will be remembered if you ever deactivate/delete and then reinstall Shortcode Control later."
    407439msgstr ""
    408440
    409 #: includes/Features/Settings/Core/SettingsRegistrar.php:147
     441#: includes/Features/Settings/Core/SettingsRegistrar.php:166
    410442msgid "Configure how shortcodes are displayed and behave on your site."
    411443msgstr ""
    412444
    413 #: includes/Features/Settings/Core/SettingsRegistrar.php:156
    414 msgid "Hide WordPress Core shortcodes completely from the dashboard to reduce clutter"
    415 msgstr ""
    416 
    417 #: includes/Features/Settings/Core/SettingsRegistrar.php:167
    418 msgid "Show Raw Text (Default)"
    419 msgstr ""
    420 
    421 #: includes/Features/Settings/Core/SettingsRegistrar.php:169
    422 msgid "Hide Completely (Invisible)"
    423 msgstr ""
    424 
    425 #: includes/Features/Settings/Core/SettingsRegistrar.php:173
    426 msgid "Currently Active: Show Raw Text."
    427 msgstr ""
    428 
    429 #: includes/Features/Settings/Core/SettingsRegistrar.php:175
    430 msgid "Currently Active: Hide Completely."
    431 msgstr ""
    432 
    433445#: includes/Features/Settings/Core/SettingsRegistrar.php:178
    434 msgid "Choose what website visitors see when a shortcode is turned off:"
    435 msgstr ""
    436 
    437 #: includes/Features/Settings/Core/SettingsRegistrar.php:180
    438 msgid "Show Raw Text"
    439 msgstr ""
    440 
    441 #: includes/Features/Settings/Core/SettingsRegistrar.php:181
    442 msgid "The shortcode is neutralized for maximum security. Visitors will just see the bracketed text itself (e.g., [my_shortcode])."
    443 msgstr ""
    444 
    445 #: includes/Features/Settings/Core/SettingsRegistrar.php:183
    446 msgid "Hide Completely"
    447 msgstr ""
    448 
    449 #: includes/Features/Settings/Core/SettingsRegistrar.php:184
    450 msgid "The shortcode is replaced with a blank space invisibly. This keeps your web pages looking clean when disabling broken shortcodes."
    451 msgstr ""
    452 
    453 #: includes/Features/Settings/Core/SettingsRegistrar.php:192
     446msgid "Show WordPress Core shortcodes in the dashboard"
     447msgstr ""
     448
     449#: includes/Features/Settings/Core/SettingsRegistrar.php:182
     450msgid "If you show core shortcodes, be careful — WordPress relies on them (e.g. [gallery], [embed], [caption]) for built-in functionality. Accidentally disabling a core shortcode can break your site."
     451msgstr ""
     452
     453#: includes/Features/Settings/Core/SettingsRegistrar.php:191
    454454msgid "Configure how many posts are processed per scan request."
    455455msgstr ""
    456456
    457 #: includes/Features/Settings/Core/SettingsRegistrar.php:210
     457#: includes/Features/Settings/Core/SettingsRegistrar.php:209
    458458msgid "Higher values scan faster but can increase server load and timeout risk."
    459459msgstr ""
    460460
    461 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:37
    462 msgid "Remove from adopted state and revert to orphaned"
    463 msgstr ""
    464 
    465 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:38
    466 msgid "Unadopt"
    467 msgstr ""
    468 
    469 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:92
    470 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:155
     461#: includes/Features/Settings/Core/SettingsRegistrar.php:230
     462msgid "Custom HTML block <code>[wp:html]</code> — JS, CSS, raw HTML (recommended)"
     463msgstr ""
     464
     465#: includes/Features/Settings/Core/SettingsRegistrar.php:231
     466msgid "Code block <code>[wp:code]</code> — code snippets and tutorials"
     467msgstr ""
     468
     469#: includes/Features/Settings/Core/SettingsRegistrar.php:232
     470msgid "Preformatted block <code>[wp:preformatted]</code> — raw text content"
     471msgstr ""
     472
     473#: includes/Features/Settings/Core/SettingsRegistrar.php:233
     474msgid "Verse block <code>[wp:verse]</code> — poetry or bracketed notation"
     475msgstr ""
     476
     477#: includes/Features/Settings/Core/SettingsRegistrar.php:248
     478msgid "The scanner will skip the full content of checked block types. This reduces false positives from blocks that use brackets for non-shortcode purposes. Re-run a full scan after changing this."
     479msgstr ""
     480
     481#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:46
     482#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:54
     483#: includes/Features/StartHere/AdminUi/StartHerePageController.php:85
     484#: includes/Services/DataGrouper.php:59
     485msgid "Hidden"
     486msgstr ""
     487
     488#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:60
     489#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:69
     490msgid "Restore"
     491msgstr ""
     492
     493#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:63
     494#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:77
     495msgid "Hide"
     496msgstr ""
     497
     498#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:73
     499msgid "Disable"
     500msgstr ""
     501
     502#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:108
     503msgid "Run a scan to see usage counts"
     504msgstr ""
     505
     506#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:110
     507msgid "Run scan"
     508msgstr ""
     509
     510#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:114
     511msgid "Not used in any post"
     512msgstr ""
     513
     514#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:154
     515#: includes/Services/DataGrouper.php:46
     516msgid "Unknown Source"
     517msgstr ""
     518
     519#. translators: %s is a human-readable time difference, e.g. "3 days" or "2 hours".
     520#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:159
     521#, php-format
     522msgid "Deactivated %s ago"
     523msgstr ""
     524
     525#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:166
     526#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:167
    471527msgid "By "
    472528msgstr ""
    473529
    474 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:97
     530#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:171
    475531msgid "Fetching WordPress.org data..."
    476532msgstr ""
    477533
    478 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:99
    479 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:153
     534#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:173
     535#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:165
    480536msgid "Installs: "
    481537msgstr ""
    482538
    483 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:99
    484 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:154
     539#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:173
     540#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:166
    485541msgid "Updated: "
    486542msgstr ""
    487543
    488 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:101
    489 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:156
     544#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:175
     545#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:168
    490546msgid "Plugin not in WP.org repository (Premium or Custom)"
    491547msgstr ""
    492548
    493 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:114
     549#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:188
    494550msgid "Plugin has low installs or outdated. Consider using a more actively maintained plugin with 500+ installs, as security vulnerabilities are more likely to be reported and fixed in popular plugins with active bug bounty programs."
    495551msgstr ""
    496552
    497 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:116
     553#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:190
    498554msgid "Plugin is actively maintained with adequate installs."
    499555msgstr ""
    … …  
    503559msgstr ""
    504560
    505 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:58
    506 msgid "Source"
    507 msgstr ""
    508 
    509 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:157
     561#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:59
     562msgid "Used In"
     563msgstr ""
     564
     565#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:169
    510566msgid "Failed to connect to WP.org API"
    511567msgstr ""
    512568
    513 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:158
     569#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:170
    514570msgid "Saving..."
    515571msgstr ""
    516572
    517 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:161
     573#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:171
    518574msgid "Error"
    519575msgstr ""
    520576
    521 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:162
     577#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:172
    522578msgid "Network Error"
    523579msgstr ""
    524580
    525 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:163
     581#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:173
    526582msgid "Re-test"
    527583msgstr ""
    528584
    529 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:164
     585#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:174
    530586msgid "Testing..."
    531587msgstr ""
    532588
    533 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:165
     589#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:175
    534590msgid "ms"
    535591msgstr ""
    536592
    537 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:166
     593#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:176
    538594msgid "avg"
    539595msgstr ""
    540596
    541 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:18
    542 msgid "Manage Registered Shortcodes"
    543 msgstr ""
    544 
    545 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:19
    546 msgid "View all shortcodes from active plugins, themes, and WordPress core. Toggle individual shortcodes on/off, adopt orphaned ones, or manually manage their behavior."
    547 msgstr ""
    548 
    549 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:22
    550 msgid "Control which shortcodes are active or disabled across your entire WordPress installation."
    551 msgstr ""
    552 
    553 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:41
    554 msgid "Conflicts"
    555 msgstr ""
    556 
    557 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:51
    558 msgid "Search Shortcodes:"
    559 msgstr ""
    560 
    561 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:53
     597#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:27
     598msgid "Registered Shortcodes come from active plugins, themes, and WordPress core. Orphaned Shortcodes come from plugins that are no longer active."
     599msgstr ""
     600
     601#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:29
     602msgid "Control which shortcodes are active or suppressed across your WordPress installation."
     603msgstr ""
     604
     605#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:34
     606msgid "How To Use This Page"
     607msgstr ""
     608
     609#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:35
     610msgid "Registered shortcodes can be Enabled, Disabled, or Hidden. Orphaned shortcodes come from deactivated plugins — you can Silence them (output nothing) or Restore them."
     611msgstr ""
     612
     613#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:61
     614msgid "Search shortcodes:"
     615msgstr ""
     616
     617#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:63
    562618msgid "Search by tag or source..."
    563619msgstr ""
    564620
    565 #. translators: %d: number of shortcodes with multiple registrations
    566 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:84
    567 #, php-format
    568 msgid "Conflict Found: %d shortcode has multiple registrations"
    569 msgid_plural "Conflicts Found: %d shortcodes have multiple registrations"
    570 msgstr[0] ""
    571 msgstr[1] ""
    572 
    573 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:88
    574 msgid "Multiple plugins or themes have registered the same shortcode tag. Only the last-registered version is active."
    575 msgstr ""
    576 
    577 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:131
    578 msgid "Caution Before Disabling Core Shortcodes"
    579 msgstr ""
    580 
    581 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:134
    582 msgid "WordPress heavily relies on native shortcodes like [gallery], [embed], and [caption] to process rich-text editor data. Additionally, other plugins may depend on these core shortcodes for their functionality. Disabling them may break website functionality. Only proceed if you fully understand the consequences."
     621#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:74
     622#: includes/Features/StartHere/AdminUi/StartHerePageController.php:69
     623msgid "Registered Shortcodes"
     624msgstr ""
     625
     626#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:92
     627msgid "Orphaned Shortcodes"
     628msgstr ""
     629
     630#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:93
     631msgid "These shortcodes come from plugins that are no longer active. They will output raw text unless silenced. Use Hide to suppress them."
    583632msgstr ""
    584633
    … …  
    590639msgstr ""
    591640
    592 #: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:200
    593 #: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:227
    594 #: includes/Services/StatusHelper.php:79
    595 msgid "Unknown"
    596 msgstr ""
    597 
    598641#. translators: %s: formatted number of downloads
    599642#: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:222
    … …  
    602645msgstr ""
    603646
    604 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:121
     647#: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:97
    605648msgid "Invalid parameters"
    606649msgstr ""
    607650
    608 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:130
    609 msgid "Toggle failed"
    610 msgstr ""
    611 
    612 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:143
    613 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:170
    614 msgid "Tag cannot be empty"
    615 msgstr ""
    616 
    617 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:155
    618 msgid "Orphan adopted successfully"
    619 msgstr ""
    620 
    621 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:158
    622 msgid "Failed to adopt orphan"
    623 msgstr ""
    624 
    625 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:181
    626 msgid "Orphan unadopted successfully"
    627 msgstr ""
    628 
    629 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:184
    630 msgid "Failed to unadopt orphan"
    631 msgstr ""
    632 
    633 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:66
    634 msgid "Welcome to Foureyed Shortcode Control"
    635 msgstr ""
    636 
    637 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:68
    638 msgid "Take control of your site's shortcodes. Discover, manage, and protect what runs on your site."
    639 msgstr ""
    640 
    641 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:76
    642 msgid "Registered Shortcodes"
    643 msgstr ""
    644 
    645 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:80
    646 msgid "Total Shortcodes"
    647 msgstr ""
    648 
    649 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:92
     651#: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:106
     652msgid "Status update failed"
     653msgstr ""
     654
     655#: includes/Features/StartHere/AdminUi/StartHerePageController.php:65
     656msgid "Overview of your site's shortcodes and scan results. Use the menu links to manage or scan."
     657msgstr ""
     658
     659#: includes/Features/StartHere/AdminUi/StartHerePageController.php:94
    650660msgid "Content Scan Results"
    651661msgstr ""
    652662
    653 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:95
    654 msgid "No scan has been run yet. Run a scan to detect orphaned shortcodes hiding in your content."
    655 msgstr ""
    656 
    657 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:96
    658 msgid "Start your first scan →"
    659 msgstr ""
    660 
    661 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:102
     663#: includes/Features/StartHere/AdminUi/StartHerePageController.php:97
     664msgid "No scan has been run yet."
     665msgstr ""
     666
     667#: includes/Features/StartHere/AdminUi/StartHerePageController.php:98
     668msgid "Run your first scan →"
     669msgstr ""
     670
     671#: includes/Features/StartHere/AdminUi/StartHerePageController.php:104
    662672msgid "Total Findings"
    663673msgstr ""
    664674
    665 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:106
    666 msgid "Active in Content"
    667 msgstr ""
    668 
    669 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:110
    670 msgid "Disabled in Content"
    671 msgstr ""
    672 
    673 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:117
    674 msgid "View →"
     675#: includes/Features/StartHere/AdminUi/StartHerePageController.php:108
     676#: includes/Services/StatusHelper.php:38
     677#: includes/Services/StatusHelper.php:73
     678msgid "Active"
     679msgstr ""
     680
     681#: includes/Features/StartHere/AdminUi/StartHerePageController.php:121
     682msgid "Pages"
     683msgstr ""
     684
     685#: includes/Features/StartHere/AdminUi/StartHerePageController.php:125
     686msgid "Enable, disable, or hide any shortcode on your site with one click."
    675687msgstr ""
    676688
    677689#: includes/Features/StartHere/AdminUi/StartHerePageController.php:127
    678 msgid "Here's What You Can Do"
     690#: includes/Features/StartHere/AdminUi/StartHerePageController.php:134
     691#: includes/Features/StartHere/AdminUi/StartHerePageController.php:141
     692msgid "Open →"
     693msgstr ""
     694
     695#: includes/Features/StartHere/AdminUi/StartHerePageController.php:131
     696msgid "Scanner"
    679697msgstr ""
    680698
    681699#: includes/Features/StartHere/AdminUi/StartHerePageController.php:132
    682 msgid "1. Manage Shortcodes"
    683 msgstr ""
    684 
    685 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:136
    686 msgid "See all registered shortcodes on your site and control which ones are active."
    687 msgstr ""
    688 
    689 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:138
    690 msgid "View every shortcode with details: name, source, plugin, version"
     700msgid "Scan your posts and pages to find orphaned shortcodes left by removed plugins."
    691701msgstr ""
    692702
    693703#: includes/Features/StartHere/AdminUi/StartHerePageController.php:139
    694 msgid "Turn any shortcode on or off with one click"
    695 msgstr ""
    696 
    697 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:140
    698 msgid "Disable unused shortcodes safely"
    699 msgstr ""
    700 
    701 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:141
    702 msgid "Disable broken shortcodes safely (broken shortcode need to be adopted first)"
    703 msgstr ""
    704 
    705 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:142
    706 msgid "See status badges: Active, Disabled, Conflicts"
    707 msgstr ""
    708 
    709 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:146
    710 msgid "View All Shortcodes →"
    711 msgstr ""
    712 
    713 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:151
    714 msgid "Pro Tip:"
    715 msgstr ""
    716 
    717 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:152
    718 msgid "Disabling a shortcode doesn't delete it—you can re-enable it anytime. It just won't run on the front-end. You could choose to return literal text or hide it completely from settings"
    719 msgstr ""
    720 
    721 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:159
    722 msgid "2. Find Orphaned Shortcodes"
    723 msgstr ""
    724 
    725 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:163
    726 msgid "Scan your entire site to find orphaned shortcodes that don't have a plugin anymore."
    727 msgstr ""
    728 
    729 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:165
    730 msgid "Scan all posts and pages for orphaned shortcodes"
    731 msgstr ""
    732 
    733 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:166
    734 msgid "See exactly which posts have broken shortcodes"
    735 msgstr ""
    736 
    737 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:167
    738 msgid "View the actual shortcode code found in your content"
    739 msgstr ""
    740 
    741 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:168
    742 msgid "Click edit link to open editor and manually remove shortcode if you want"
    743 msgstr ""
    744 
    745 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:169
    746 msgid "Non-destructive: Scanning never deletes or modifies content"
    747 msgstr ""
    748 
    749 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:173
    750 msgid "Scan Your Site →"
    751 msgstr ""
    752 
    753 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:178
    754 msgid "Safe to Run:"
    755 msgstr ""
    756 
    757 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:179
    758 msgid "The scanner is completely safe and won't slow down your site. It runs in the background."
    759 msgstr ""
    760 
    761 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:186
    762 msgid "3. Tools & Settings"
    763 msgstr ""
    764 
    765 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:190
    766 msgid "Configure how Shortcode Control works and access maintenance tools."
    767 msgstr ""
    768 
    769 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:192
    770 msgid "Hide core WordPress shortcodes from the list"
    771 msgstr ""
    772 
    773 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:193
    774 msgid "Access maintenance and troubleshooting tools"
    775 msgstr ""
    776 
    777 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:194
    778 msgid "Configure plugin preferences"
    779 msgstr ""
    780 
    781 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:198
    782 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:266
    783 msgid "Go to Settings →"
    784 msgstr ""
    785 
    786 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:203
    787 msgid "Info:"
    788 msgstr ""
    789 
    790 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:204
    791 msgid "Settings are optional—defaults are safe for most sites."
    792 msgstr ""
    793 
    794 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:211
    795 msgid "Key Things to Know"
    796 msgstr ""
    797 
    798 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:215
    799 msgid "🔒 Safe & Reversible"
    800 msgstr ""
    801 
    802 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:216
    803 msgid "Everything Shortcode Control does can be undone (unless you manually delete shortcode from editor). Disabling shortcodes is safe and doesn't delete data."
    804 msgstr ""
    805 
    806 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:220
    807 msgid "⚡ Zero Frontend Impact"
    808 msgstr ""
    809 
    810 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:221
    811 msgid "The heavy lifting only runs in each module pages. Your site's front-end performance is almost never affected. (we do need to run on front end to disable shortcode, but it only add less than a millisecond to page load)"
    812 msgstr ""
    813 
    814 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:225
    815 msgid "👤 Admin Only"
    816 msgstr ""
    817 
    818 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:226
    819 msgid "Only administrators with \"manage_options\" capability can access Shortcode Control. Your team content creators can't see this page, or any other page from this plugin"
    820 msgstr ""
    821 
    822 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:235
    823 msgid "Ready to Get Started?"
    824 msgstr ""
    825 
    826 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:241
    827 msgid "Explore Your Shortcodes"
    828 msgstr ""
    829 
    830 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:242
    831 msgid "Go to \"Manage Shortcodes\" to see what's installed on your site."
    832 msgstr ""
    833 
    834 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:244
    835 msgid "Open Manage Shortcodes →"
    836 msgstr ""
    837 
    838 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:252
    839 msgid "Scan for Broken Shortcodes"
    840 msgstr ""
    841 
    842 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:253
    843 msgid "Run a scan to find any orphaned or broken shortcodes in your content."
    844 msgstr ""
    845 
    846 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:255
    847 msgid "Start Scanner →"
    848 msgstr ""
    849 
    850 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:263
    851 msgid "Customize Settings"
    852 msgstr ""
    853 
    854 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:264
    855 msgid "Visit Settings to configure plugin behavior to match your needs."
    856 msgstr ""
    857 
    858 #: includes/Services/DataGrouper.php:35
     704msgid "Configure plugin behaviour. Defaults are safe — only change if needed."
     705msgstr ""
     706
     707#: includes/Services/DataGrouper.php:43
    859708msgid "From plugins"
    860709msgstr ""
    861710
    862 #: includes/Services/DataGrouper.php:36
     711#: includes/Services/DataGrouper.php:44
    863712msgid "From themes"
    864713msgstr ""
    865714
    866 #: includes/Services/DataGrouper.php:38
     715#: includes/Services/DataGrouper.php:45
     716msgid "Discovered Orphans"
     717msgstr ""
     718
     719#: includes/Services/DataGrouper.php:47
    867720msgid "From WordPress core"
    868721msgstr ""
     722
     723#: includes/Services/DataGrouper.php:57
     724msgid "⚠ Needs Attention — Deactivated & In Use"
     725msgstr ""
     726
     727#: includes/Services/DataGrouper.php:178
     728msgid "Shortcodes"
     729msgstr ""
     730
     731#: includes/Services/ShortcodeFormatter.php:27
     732msgid "Plugin Shortcode"
     733msgstr ""
     734
     735#: includes/Services/ShortcodeFormatter.php:29
     736msgid "Theme Shortcode"
     737msgstr ""
     738
     739#: includes/Services/ShortcodeFormatter.php:31
     740msgid "WordPress Shortcode"
     741msgstr ""
     742
     743#: includes/Services/ShortcodeFormatter.php:33
     744msgid "Discovered Orphan"
     745msgstr ""
     746
     747#: includes/Services/ShortcodeFormatter.php:36
     748msgid "Registered"
     749msgstr ""
  • foureyed-shortcode-control/tags/1.0.4/readme.txt

    r3523952 r3524967  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.3
     7Stable tag: 1.0.4
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    6262== Changelog ==
    6363
     64= 1.0.4 =
     65* Feature: Scan exception — exclude Gutenberg block types (Custom HTML, Code, Preformatted, Verse) from scanner to reduce false positives
     66* Improve: Manager redesign — two-table layout (Registered / Orphaned) with unified filter tabs and search
     67* Improve: Manager filter tabs now on left, search field on right (consistent with Scanner)
     68* Improve: Start Here stats card shows all 5 status counts (All, Enabled, Disabled, Hidden, Orphaned)
     69* Improve: Start Here stats respect the "hide core shortcodes" setting, matching Manager counts
     70* Fix: Manager source column shows "Unknown Source" for numeric/unknown orphan tags instead of wrong plugin name
     71* Fix: Scanner silenced orphan shows "Silenced" badge instead of "Orphaned"
     72
    6473= 1.0.3 =
    6574* Fix: Strip Gutenberg block comments before scanning to prevent false positive numeric shortcode matches
  • foureyed-shortcode-control/trunk/foureyed-shortcode-control.php

    r3523952 r3524967  
    44 * Plugin URI:        https://wordpress.org/plugins/foureyed-shortcode-control/
    55 * Description:       A WordPress admin plugin that discovers, lists, toggles, scans, and creates shortcodes.
    6  * Version:           1.0.3
     6 * Version:           1.0.4
    77 * Author:            Muhammad Yudha - DJ
    88 * Author URI:        https://profiles.wordpress.org/mryudha/
    … …  
    1818}
    1919
    20 define('FOUREYED_SHORTCODE_CONTROL_VERSION', '1.0.3');
     20define('FOUREYED_SHORTCODE_CONTROL_VERSION', '1.0.4');
    2121define('FOUREYED_SHORTCODE_CONTROL_PATH', plugin_dir_path(__FILE__));
    2222define('FOUREYED_SHORTCODE_CONTROL_URL', plugin_dir_url(__FILE__));
  • foureyed-shortcode-control/trunk/includes/Bootstrap.php

    r3523935 r3524967  
    1212use FoureyedShortcodeControl\Features\Scanner\Rest\ScannerRestController;
    1313use FoureyedShortcodeControl\Features\ShortcodeManager\Rest\ShortcodesRestController;
     14use FoureyedShortcodeControl\Services\DismissedNotices;
    1415
    1516if (!defined('ABSPATH')) {
    … …  
    4445                (new ScannerRestController())->register_routes();
    4546                (new ShortcodesRestController())->register_routes();
     47
     48                // Shared: dismiss notice
     49                register_rest_route('shortcode-control/v1', '/dismiss-notice', [
     50                        'methods'             => \WP_REST_Server::CREATABLE,
     51                        'callback'            => [DismissedNotices::class, 'handle_rest'],
     52                        'permission_callback' => [DismissedNotices::class, 'permissions_check'],
     53                        'args'                => [
     54                                'key' => ['type' => 'string', 'required' => true],
     55                        ],
     56                ]);
    4657        }
    4758
    … …  
    116127                }
    117128
     129                // Enqueue shared assets (applies to all SCC pages)
     130                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
     131                wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     132                wp_localize_script('foureyed-shortcode-control-shared-ui', 'sccSharedData', [
     133                        'restUrl' => esc_url_raw(rest_url('shortcode-control/v1')),
     134                        'nonce'   => wp_create_nonce('wp_rest'),
     135                ]);
     136
    118137                // Enqueue global tooltip system
    119                         wp_enqueue_style('foureyed-shortcode-control-tooltip-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    120                         wp_enqueue_script('foureyed-shortcode-control-tooltip', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     138                wp_enqueue_style('foureyed-shortcode-control-tooltip-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
     139                wp_enqueue_script('foureyed-shortcode-control-tooltip', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/tooltip.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    121140        }
    122141}
  • foureyed-shortcode-control/trunk/includes/DataRegistry.php

    r3523935 r3524967  
    2626        // ─── Options: Settings ────────────────────────────────────────────────────
    2727
    28         public const OPTION_DELETE_ON_UNINSTALL = 'foureyed_shortcode_control_delete_data_on_uninstall'; // bool
    29         public const OPTION_HIDE_CORE           = 'foureyed_shortcode_control_hide_core';                // bool
    30         public const OPTION_SCAN_BATCH_SIZE     = 'foureyed_shortcode_control_scan_batch_size';          // 10|50|100|500
     28        public const OPTION_DELETE_ON_UNINSTALL    = 'foureyed_shortcode_control_delete_data_on_uninstall'; // bool
     29        public const OPTION_HIDE_CORE              = 'foureyed_shortcode_control_hide_core';                // bool
     30        public const OPTION_SCAN_BATCH_SIZE        = 'foureyed_shortcode_control_scan_batch_size';          // 10|50|100|500
     31        public const OPTION_SCAN_EXCLUDED_BLOCKS   = 'foureyed_shortcode_control_scan_excluded_blocks';     // string[] of wp block names e.g. ['html','code']
    3132
    3233        /** For batch delete/reset. */
    … …  
    3536                self::OPTION_HIDE_CORE,
    3637                self::OPTION_SCAN_BATCH_SIZE,
     38                self::OPTION_SCAN_EXCLUDED_BLOCKS,
    3739        ];
    3840
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/AdminUi/ScannerPageController.php

    r3523935 r3524967  
    1919        public function render_page()
    2020        {
    21                 // Show adoption success notice when redirected back after a successful adoption.
    22                 if (!empty($_GET['adopted'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    23                         $adopted_tag = sanitize_key(wp_unslash($_GET['adopted'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    24                         printf(
    25                                 '<div class="notice notice-success is-dismissible"><p>%s</p></div>',
    26                                 wp_kses_post(
    27                                         sprintf(
    28                                                 /* translators: %s: shortcode tag name */
    29                                                 __('Successfully adopted shortcode &ldquo;%s&rdquo;. It is now <strong>disabled</strong> by default. You can manage it in the &ldquo;Manually Adopted&rdquo; section of your Shortcodes page.', 'foureyed-shortcode-control'),
    30                                                 esc_html($adopted_tag)
    31                                         )
    32                                 )
    33                         );
    34                 }
    35 
    3621                // Get enriched data with counts
    3722                $data = ScannerDataProvider::get_prepared_data();
    … …  
    7560                );
    7661
    77                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    78                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     62                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    7963                wp_enqueue_style('foureyed-shortcode-control-scanner-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/Scanner/AdminUi/scanner.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    8064
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/AdminUi/ScannerTemplate.php

    r3523935 r3524967  
    4444        </div>
    4545
     46        <?php if (!\FoureyedShortcodeControl\Services\DismissedNotices::is_dismissed('scanner')) : ?>
    4647        <div class="scc-helper-card" data-dismiss-key="scanner">
    4748                <strong><?php esc_html_e('Quick Guide:', 'foureyed-shortcode-control'); ?></strong>
    4849                <?php esc_html_e('Run a scan, review orphaned findings first, then click Manage to jump directly into Shortcode Manager for that shortcode tag.', 'foureyed-shortcode-control'); ?>
    4950        </div>
     51        <?php endif; ?>
    5052
    5153        <?php /* Status banner — shown by JS on interruption, hidden by default */ ?>
    … …  
    103105        </div>
    104106
    105         <div class="scc-stats">
    106                 <div class="scc-stat-card">
    107                         <div class="scc-stat-label"><?php esc_html_e('Total', 'foureyed-shortcode-control'); ?></div>
    108                         <div class="scc-stat-number" id="scc-stat-total"><?php echo esc_html($total_findings); ?></div>
    109                 </div>
    110                 <div class="scc-stat-card">
    111                         <div class="scc-stat-label"><?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?></div>
    112                         <div class="scc-stat-number" id="scc-stat-active"><?php echo esc_html($active_findings); ?></div>
    113                 </div>
    114                 <div class="scc-stat-card">
    115                         <div class="scc-stat-label"><?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?></div>
    116                         <div class="scc-stat-number" id="scc-stat-disabled"><?php echo esc_html($disabled_findings); ?></div>
    117                 </div>
    118                 <div class="scc-stat-card">
    119                         <div class="scc-stat-label"><?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?></div>
    120                         <div class="scc-stat-number" id="scc-stat-orphaned"><?php echo esc_html($orphaned_findings); ?></div>
    121                 </div>
    122         </div>
    123 
    124107        <div class="scc-toolbar">
    125108                <div class="scc-toolbar-main">
     109                        <input type="hidden" id="scc-filter-status" value="all">
     110
     111                        <div class="scc-filter-tabs">
     112                                <button type="button" class="scc-scan-filter-tab scc-filter-tab-active" data-filter="all">
     113                                        <?php esc_html_e('All', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-total"><?php echo esc_html($total_findings); ?></span>)
     114                                </button>
     115                                <button type="button" class="scc-scan-filter-tab" data-filter="active">
     116                                        <?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-active"><?php echo esc_html($active_findings); ?></span>)
     117                                </button>
     118                                <button type="button" class="scc-scan-filter-tab" data-filter="disabled">
     119                                        <?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-disabled"><?php echo esc_html($disabled_findings); ?></span>)
     120                                </button>
     121                                <button type="button" class="scc-scan-filter-tab" data-filter="orphaned">
     122                                        <?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?> (<span id="scc-stat-orphaned"><?php echo esc_html($orphaned_findings); ?></span>)
     123                                </button>
     124                        </div>
     125
    126126                        <div class="scc-search-wrap" style="display: flex; gap: 8px;">
    127127                                <label class="screen-reader-text" for="scc-search-posts"><?php esc_html_e('Search findings:', 'foureyed-shortcode-control'); ?></label>
    … …  
    129129                                        placeholder="<?php esc_attr_e('Search by post title or shortcode tag...', 'foureyed-shortcode-control'); ?>">
    130130                                <button type="button" id="scc-clear-search" class="button" style="display: none;"><?php esc_html_e('Clear Filter', 'foureyed-shortcode-control'); ?></button>
    131                         </div>
    132 
    133                         <input type="hidden" id="scc-filter-status" value="all">
    134 
    135                         <div class="scc-filter-tabs">
    136                                 <button type="button" class="scc-scan-filter-tab scc-filter-tab-active" data-filter="all"
    137                                 >
    138                                         <?php esc_html_e('All', 'foureyed-shortcode-control'); ?>
    139                                 </button>
    140                                 <button type="button" class="scc-scan-filter-tab" data-filter="active"
    141                                 >
    142                                         <?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?>
    143                                 </button>
    144                                 <button type="button" class="scc-scan-filter-tab" data-filter="disabled"
    145                                 >
    146                                         <?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?>
    147                                 </button>
    148                                 <button type="button" class="scc-scan-filter-tab" data-filter="orphaned"
    149                                 >
    150                                         <?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?>
    151                                 </button>
    152131                        </div>
    153132                </div>
    … …  
    171150                                        <?php
    172151                                        $live_status = isset($row->live_status) ? $row->live_status : 'orphaned';
    173                                         $is_adopted  = isset($row->is_adopted) ? $row->is_adopted : false;
    174152                                        $source_type = isset($row->source_type) ? $row->source_type : 'unknown';
    175153
    … …  
    191169                                        $item['wporg_status'] = $item['wporg_status'] ?? 'not_applicable';
    192170
    193                                         // Special case for unmanaged orphans which only exist in the Scanner until adopted
    194                                         if ($live_status === 'orphaned' && !$is_adopted) {
    195                                                 $status_badges = '<span class="scc-status-badge scc-status-orphaned">' . esc_html__('Orphaned', 'foureyed-shortcode-control') . '</span>';
    196                                                 $source_html   = '<span class="scc-muted-italic" style="color:#a7aaad;">' . esc_html__('Unknown', 'foureyed-shortcode-control') . '</span>';
     171                                        // Orphaned tags have no source data, so we render a static badge instead
     172                                        if ($live_status === 'orphaned') {
     173                                                if (($row->granular_status ?? '') === 'hidden') {
     174                                                        $status_badges = '<span class="scc-status-badge scc-status-hidden">' . esc_html__('Silenced', 'foureyed-shortcode-control') . '</span>';
     175                                                } else {
     176                                                        $status_badges = '<span class="scc-status-badge scc-status-orphaned">' . esc_html__('Orphaned', 'foureyed-shortcode-control') . '</span>';
     177                                                }
     178                                                $source_html = '<span class="scc-muted-italic" style="color:#a7aaad;">' . esc_html__('Unknown', 'foureyed-shortcode-control') . '</span>';
    197179                                        } else {
    198180                                                $status_badges = $renderer->render_status($item);
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/AdminUi/scanner.css

    r3523935 r3524967  
    11/* Scanner admin styles */
    2 
    3 .scc-stats {
    4     display: flex;
    5     background: #fff;
    6     border: 1px solid #c3c4c7;
    7     border-radius: 6px;
    8     margin-bottom: 16px;
    9     overflow: hidden;
    10 }
    11 
    12 .scc-stat-card {
    13     flex: 1;
    14     padding: 16px 20px;
    15     border: none;
    16     border-right: 1px solid #c3c4c7;
    17     border-radius: 0;
    18     background: transparent;
    19 }
    20 
    21 .scc-stat-card:last-child {
    22     border-right: none;
    23 }
    24 
    25 .scc-stat-label {
    26     color: #646970;
    27     margin-bottom: 4px;
    28 }
    29 
    30 .scc-stat-number {
    31     font-size: 18px;
    32     line-height: 1.2;
    33     font-weight: 600;
    34     color: #1d2327;
    35 }
    362
    373.scc-toolbar {
    … …  
    4612    display: flex;
    4713    align-items: center;
     14    justify-content: space-between;
    4815    gap: 8px;
    4916    width: 100%;
    … …  
    5118
    5219.scc-search-wrap {
    53     flex: 0 0 220px;
    54     /* fixed narrow width on the right */
    55     order: 2;
    56     /* always rendered after the tabs */
     20    flex: 0 0 240px;
    5721    min-width: 0;
    5822}
    … …  
    6428.scc-filter-tabs {
    6529    display: inline-flex;
    66     /* shrinks to content width — no stretching */
    67     order: 1;
    6830    border: 1px solid #c3c4c7;
    6931    border-radius: 4px;
    … …  
    13294}
    13395
    134 .scc-status-adopted {
    135     background: #d9edf7;
    136     color: #31708f;
     96.scc-status-hidden {
     97    background: #e5e5e5;
     98    color: #555555;
    13799}
    138100
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/Api/ScannerApi.php

    r3523935 r3524967  
    2626                return ScannerDataProvider::get_prepared_data();
    2727        }
     28
     29        /**
     30         * Get scanner result counts.
     31         * Single source of truth for scan stat cards (Start Here, etc.).
     32         *
     33         * Counts use live status (recalculated against current registry), not stored DB values.
     34         *
     35         * @return array{total: int, active: int, disabled: int, orphaned: int}
     36         */
     37        public static function get_stats(): array
     38        {
     39                return ScannerDataProvider::get_prepared_data()['counts'];
     40        }
    2841}
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/Core/ScanDataProvider.php

    r3523935 r3524967  
    3434                          AND (l.post_id IS NULL OR l.last_scanned_at < p.post_modified)
    3535                ");
    36         }
    37 
    38         /**
    39          * Fetch a batch of published posts that have been modified since their last scan.
    40          * Legacy method — retained for use by the save_post lifecycle hook.
    41          *
    42          * @param int $limit  Number of posts to fetch
    43          * @param int $offset Starting position
    44          * @return array Array of post objects
    45          */
    46         public static function get_posts_batch(int $limit, int $offset): array
    47         {
    48                 global $wpdb;
    49                 $log_table = $wpdb->prefix . DataRegistry::TABLE_SCAN_LOG;
    50                 return $wpdb->get_results($wpdb->prepare("
    51                         SELECT p.ID, p.post_type, p.post_content, p.post_modified
    52                         FROM {$wpdb->posts} p
    53                         LEFT JOIN {$log_table} l ON p.ID = l.post_id
    54                         WHERE p.post_status = 'publish'
    55                           AND p.post_type IN ('post', 'page')
    56                           AND (l.post_id IS NULL OR l.last_scanned_at < p.post_modified)
    57                         ORDER BY p.ID ASC
    58                         LIMIT %d OFFSET %d
    59                 ", $limit, $offset));
    6036        }
    6137
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/Core/ScanLifecycleHooks.php

    r3523935 r3524967  
    1717        {
    1818                add_action('deleted_post', [__CLASS__, 'on_deleted_post'], 10, 1);
     19
     20                // When the excluded-blocks setting changes, wipe the scan log so all posts
     21                // are treated as unscanned on the next run. Old results stay until overwritten.
     22                add_action('update_option_' . DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, [__CLASS__, 'on_excluded_blocks_changed'], 10, 2);
     23        }
     24
     25        /**
     26         * Fires when the excluded blocks setting is updated.
     27         * Only clears the log when the value actually changed.
     28         */
     29        public static function on_excluded_blocks_changed($old_value, $new_value)
     30        {
     31                if ($old_value === $new_value) {
     32                        return;
     33                }
     34
     35                global $wpdb;
     36                $log_table = $wpdb->prefix . DataRegistry::TABLE_SCAN_LOG;
     37                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
     38                $wpdb->query("TRUNCATE TABLE {$log_table}");
    1939        }
    2040
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/Core/ScanStatusService.php

    r3523935 r3524967  
    1717         * Determine if a shortcode tag is active, disabled, or orphaned.
    1818         *
    19          * A tag is "active" if it's currently registered and running natively, OR if it has been manually adopted.
    20     * A tag is "disabled" if it is intercepted/turned off by the Shortcode Control plugin.
    21          * A tag is "orphaned" if it's found in content but no longer registered (the plugin was deleted) AND not adopted.
     19         * A tag is "active" if it's currently registered and running natively.
     20        * A tag is "disabled" if it is intercepted/turned off by the Shortcode Control plugin.
     21         * A tag is "orphaned" if it's found in content but no longer registered (the plugin was deleted).
    2222         *
    2323         * @param string $tag           The shortcode tag to evaluate
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/Core/ScannerDataProvider.php

    r3523935 r3524967  
    6969                                $row->live_status = $live_status;
    7070
    71                                 // Adoption is no longer a separate concept
    72                                 $row->is_adopted = false;
    73 
    7471                                // Get source and granular status
    7572                                $sc_data = $source_map[$row->tag] ?? [];
  • foureyed-shortcode-control/trunk/includes/Features/Scanner/Core/ShortcodeExtractor.php

    r3523952 r3524967  
    2626        public static function extract_shortcodes(string $content): array
    2727        {
    28                 // Strip Gutenberg block comments before scanning.
     28                // Strip entire block contents for user-configured excluded block types FIRST,
     29                // before the general comment stripper removes the markers we need to match against.
     30                // Each excluded block removes everything from its opening comment to its closing comment,
     31                // including any shortcode-like syntax inside (e.g. JS in Custom HTML blocks).
     32                $excluded_blocks = get_option(\FoureyedShortcodeControl\DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, ['html']);
     33                if (!empty($excluded_blocks) && is_array($excluded_blocks)) {
     34                        foreach ($excluded_blocks as $block_name) {
     35                                $block_name = preg_quote(trim($block_name), '/');
     36                                // Matches <!-- wp:html ... --> ... content ... <!-- /wp:html -->
     37                                $content = preg_replace('/<!--\s*wp:' . $block_name . '(?:\s[^-]*)?\s*-->.*?<!--\s*\/wp:' . $block_name . '\s*-->/s', '', $content);
     38                        }
     39                }
     40
     41                // Strip remaining Gutenberg block comments.
    2942                // Block comments like <!-- wp:gallery {"ids":[52301,52302]} --> contain JSON
    3043                // with bracket-wrapped numbers that the shortcode regex falsely matches.
  • foureyed-shortcode-control/trunk/includes/Features/Settings/AdminUi/SettingsPageController.php

    r3523935 r3524967  
    1515        public function render_page()
    1616        {
    17                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    18                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     17                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    1918                wp_enqueue_style(
    2019                        'foureyed-shortcode-control-settings-css',
    … …  
    4443                        </div>
    4544
     45                        <?php if (!\FoureyedShortcodeControl\Services\DismissedNotices::is_dismissed('settings')) : ?>
    4646                        <div class="scc-helper-card" data-dismiss-key="settings">
    4747                                <strong><?php esc_html_e('Beginner Tip:', 'foureyed-shortcode-control'); ?></strong>
    4848                                <?php esc_html_e('Change one setting at a time, click Save All Settings, then verify behavior in Manage Shortcodes or Scanner.', 'foureyed-shortcode-control'); ?>
    4949                        </div>
     50                        <?php endif; ?>
    5051
    5152                        <?php
  • foureyed-shortcode-control/trunk/includes/Features/Settings/Core/PluginDefaults.php

    r3523935 r3524967  
    3636                add_option(DataRegistry::OPTION_HIDE_CORE, true);
    3737                add_option(DataRegistry::OPTION_SCAN_BATCH_SIZE, 10);
     38                add_option(DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, ['html']);
    3839
    3940                // Shortcode Manager runtime data
  • foureyed-shortcode-control/trunk/includes/Features/Settings/Core/SettingsRegistrar.php

    r3523935 r3524967  
    106106                );
    107107
     108                register_setting(
     109                        DataRegistry::SETTINGS_GROUP,
     110                        DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS,
     111                        [
     112                                'type' => 'array',
     113                                'sanitize_callback' => [self::class, 'sanitize_excluded_blocks'],
     114                                'default' => ['html'],
     115                        ]
     116                );
     117
    108118                add_settings_section(
    109119                        'foureyed_shortcode_control_scanner_section',
    … …  
    117127                        __('Posts Per Batch', 'foureyed-shortcode-control'),
    118128                        [self::class, 'render_scan_batch_size_select'],
     129                        'foureyed-shortcode-control-scanner-settings',
     130                        'foureyed_shortcode_control_scanner_section'
     131                );
     132
     133                add_settings_field(
     134                        'foureyed_shortcode_control_scan_excluded_blocks',
     135                        __('Exclude Blocks from Scan', 'foureyed-shortcode-control'),
     136                        [self::class, 'render_excluded_blocks_checkboxes'],
    119137                        'foureyed-shortcode-control-scanner-settings',
    120138                        'foureyed_shortcode_control_scanner_section'
    … …  
    201219                return in_array($value, $allowed_sizes, true) ? $value : 50;
    202220        }
     221
     222        public static function render_excluded_blocks_checkboxes()
     223        {
     224                $excluded = get_option(DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS, ['html']);
     225                if (!is_array($excluded)) {
     226                        $excluded = ['html'];
     227                }
     228
     229                $blocks = [
     230                        'html'          => __('Custom HTML block <code>[wp:html]</code> — JS, CSS, raw HTML (recommended)', 'foureyed-shortcode-control'),
     231                        'code'          => __('Code block <code>[wp:code]</code> — code snippets and tutorials', 'foureyed-shortcode-control'),
     232                        'preformatted'  => __('Preformatted block <code>[wp:preformatted]</code> — raw text content', 'foureyed-shortcode-control'),
     233                        'verse'         => __('Verse block <code>[wp:verse]</code> — poetry or bracketed notation', 'foureyed-shortcode-control'),
     234                ];
     235                ?>
     236                <fieldset>
     237                        <?php foreach ($blocks as $name => $label) : ?>
     238                        <label style="display: block; margin-bottom: 6px;">
     239                                <input type="checkbox"
     240                                        name="<?php echo esc_attr(DataRegistry::OPTION_SCAN_EXCLUDED_BLOCKS); ?>[]"
     241                                        value="<?php echo esc_attr($name); ?>"
     242                                        <?php checked(in_array($name, $excluded, true)); ?> />
     243                                <?php echo wp_kses($label, ['code' => []]); ?>
     244                        </label>
     245                        <?php endforeach; ?>
     246                </fieldset>
     247                <p class="description" style="margin-top: 8px;">
     248                        <?php esc_html_e('The scanner will skip the full content of checked block types. This reduces false positives from blocks that use brackets for non-shortcode purposes. Re-run a full scan after changing this.', 'foureyed-shortcode-control'); ?>
     249                </p>
     250                <?php
     251        }
     252
     253        public static function sanitize_excluded_blocks($value): array
     254        {
     255                $allowed = ['html', 'code', 'preformatted', 'verse'];
     256                if (!is_array($value)) {
     257                        return [];
     258                }
     259                return array_values(array_intersect($value, $allowed));
     260        }
    203261}
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php

    r3523952 r3524967  
    150150
    151151                $deactivated_badge = '';
    152                 if (!empty($item['deactivated_at'])) {
     152                if (isset($item['source_type']) && $item['source_type'] === 'unknown') {
     153                        // For completely unknown orphans, replace the fallback tag name with 'Unknown Source'
     154                        $name_link = '<strong><span class="scc-muted-italic" style="opacity: 0.7;">' . esc_html__('Unknown Source', 'foureyed-shortcode-control') . '</span></strong>';
     155                        $deactivated_badge = '';
     156                } elseif (!empty($item['deactivated_at'])) {
    153157                        $time_diff = human_time_diff($item['deactivated_at'], current_time('timestamp'));
    154158                        // translators: %s is a human-readable time difference, e.g. "3 days" or "2 hours".
    155159                        $deactivated_text = sprintf(esc_html__('Deactivated %s ago', 'foureyed-shortcode-control'), $time_diff);
    156160                        $deactivated_badge = ' <span class="scc-muted-italic" style="font-size: 0.85em; opacity: 0.7;">(' . $deactivated_text . ')</span>';
    157                 } elseif (isset($item['source_type']) && $item['source_type'] === 'unknown') {
    158                         // For completely unknown orphans, replace the fallback tag name with 'Unknown Source'
    159                         $name_link = '<strong><span class="scc-muted-italic" style="opacity: 0.7;">' . esc_html__('Unknown Source', 'foureyed-shortcode-control') . '</span></strong>';
    160                         $deactivated_badge = '';
    161161                }
    162162
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php

    r3523935 r3524967  
    131131        public function single_row($item)
    132132        {
    133                 $status = isset($item['status']) ? esc_attr($item['status']) : 'active';
    134                 echo '<tr data-status="' . esc_attr( $status ) . '">';
     133                $status    = $item['status'] ?? 'registered';
     134                $is_active = !empty($item['is_active']);
     135
     136                if ($status === 'registered') {
     137                        $row_status = 'enabled';
     138                } elseif ($status === 'hidden') {
     139                        $row_status = 'hidden';
     140                } elseif ($status === 'unregistered' && $is_active) {
     141                        $row_status = 'disabled';
     142                } else {
     143                        $row_status = 'orphaned';
     144                }
     145
     146                echo '<tr data-status="' . esc_attr($row_status) . '">';
    135147                $this->single_row_columns($item);
    136148                echo '</tr>';
    … …  
    142154        public function render_page()
    143155        {
    144                 // Tab switcher (reuses the same JS as the Settings page)
    145                 wp_enqueue_script('foureyed-shortcode-control-settings-tabs', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/Settings/AdminUi/settings-tabs.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    146 
    147156                wp_enqueue_script('foureyed-shortcode-control-wporg-api', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/ShortcodeManager/AdminUi/wporg-api.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    148157                wp_enqueue_script('foureyed-shortcode-control-shortcode-toggle', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/ShortcodeManager/AdminUi/shortcode-toggle.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
    … …  
    169178                ]);
    170179
    171                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    172                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     180                wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Services/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    173181                wp_enqueue_style('foureyed-shortcode-control-shortcodes-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/ShortcodeManager/AdminUi/shortcodes.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    174182
    … …  
    178186                $grouped_data = DataGrouper::group_by_tab($all_data);
    179187
     188                // Compute counts for filter tab labels
     189                $counts = ['all' => count($all_data), 'enabled' => 0, 'disabled' => 0, 'hidden' => 0, 'orphaned' => 0];
     190                foreach ($all_data as $sc) {
     191                        $sc_status    = $sc['status'] ?? 'registered';
     192                        $sc_is_active = !empty($sc['is_active']);
     193                        if ($sc_status === 'registered')                             $counts['enabled']++;
     194                        elseif ($sc_status === 'hidden')                             $counts['hidden']++;
     195                        elseif ($sc_status === 'unregistered' && $sc_is_active)      $counts['disabled']++;
     196                        elseif ($sc_status === 'unregistered' && !$sc_is_active)     $counts['orphaned']++;
     197                }
     198
    180199                include_once FOUREYED_SHORTCODE_CONTROL_PATH . 'includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php';
    181200        }
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php

    r3523935 r3524967  
    55 * Variables available:
    66 * - $grouped_data (array): ['active' => [...], 'orphaned' => [...]]
     7 * - $counts       (array): ['all', 'enabled', 'disabled', 'hidden', 'orphaned']
    78 */
    89
    910if (!defined('ABSPATH')) {
    10         exit;
     11exit;
    1112}
    1213// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Template file included inside a class method; variables are local to that method's scope, not global
     14
     15$scc_registered = $grouped_data['active']   ?? [];
     16$scc_orphaned   = $grouped_data['orphaned'] ?? [];
     17
     18// phpcs:ignore WordPress.Security.NonceVerification.Recommended
     19$search_query = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
     20// phpcs:ignore WordPress.Security.NonceVerification.Recommended
     21$scc_page_val = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
    1322?>
    1423<div class="wrap scc-admin-page">
    15         <div class="scc-page-header">
    16                 <h1>
    17                         <?php esc_html_e('Manage Shortcodes', 'foureyed-shortcode-control'); ?>
    18                         <span class="scc-tooltip"
    19                                 data-tooltip="<?php esc_attr_e('Active Shortcodes are from running plugins and themes — you can Enable, Disable, or Hide them. Orphaned Shortcodes are from plugins that have been deactivated — you can Hide or Restore them.', 'foureyed-shortcode-control'); ?>">?</span>
    20                 </h1>
    21                 <p>
    22                         <?php esc_html_e('Control which shortcodes are active or suppressed across your WordPress installation.', 'foureyed-shortcode-control'); ?>
    23                 </p>
    24         </div>
     24<div class="scc-page-header">
     25<h1>
     26<?php esc_html_e('Manage Shortcodes', 'foureyed-shortcode-control'); ?>
     27<span class="scc-tooltip" data-tooltip="<?php esc_attr_e('Registered Shortcodes come from active plugins, themes, and WordPress core. Orphaned Shortcodes come from plugins that are no longer active.', 'foureyed-shortcode-control'); ?>">?</span>
     28</h1>
     29<p><?php esc_html_e('Control which shortcodes are active or suppressed across your WordPress installation.', 'foureyed-shortcode-control'); ?></p>
     30</div>
    2531
    26         <div class="scc-helper-card" data-dismiss-key="manager">
    27                 <h2><?php esc_html_e('How To Use This Page', 'foureyed-shortcode-control'); ?></h2>
    28                 <p><?php esc_html_e('Start in Active Shortcodes to review what is currently running. Use search to quickly find a tag or plugin source, then switch to Orphaned Shortcodes to clean up leftover shortcode tags safely.', 'foureyed-shortcode-control'); ?></p>
    29         </div>
     32<?php if (!\FoureyedShortcodeControl\Services\DismissedNotices::is_dismissed('manager')) : ?>
     33<div class="scc-helper-card" data-dismiss-key="manager">
     34<h2><?php esc_html_e('How To Use This Page', 'foureyed-shortcode-control'); ?></h2>
     35<p><?php esc_html_e('Registered shortcodes can be Enabled, Disabled, or Hidden. Orphaned shortcodes come from deactivated plugins — you can Silence them (output nothing) or Restore them.', 'foureyed-shortcode-control'); ?></p>
     36</div>
     37<?php endif; ?>
    3038
    31         <!-- Global Search Bar -->
    32         <div class="scc-manager-search-wrap">
    33                 <?php
    34                 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only parameter for search filter
    35                 $search_query = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
    36                 ?>
    37                 <input
    38                         type="search"
    39                         id="scc-manager-search"
    40                         placeholder="<?php esc_attr_e('Search by tag or source…', 'foureyed-shortcode-control'); ?>"
    41                         autocomplete="off"
    42                         value="<?php echo esc_attr($search_query); ?>"
    43                 />
    44                 <button type="button" id="scc-manager-search-clear" style="display:none;">
    45                         <?php esc_html_e('Clear', 'foureyed-shortcode-control'); ?>
    46                 </button>
    47         </div>
    48         <?php if ($search_query !== '') : ?>
    49                 <p class="scc-search-context">
    50                         <?php
    51                         echo esc_html(
    52                                 sprintf(
    53                                         /* translators: %s: shortcode search term */
    54                                         __('Showing filtered results for "%s". Clear search to view all shortcodes.', 'foureyed-shortcode-control'),
    55                                         $search_query
    56                                 )
    57                         );
    58                         ?>
    59                 </p>
    60         <?php endif; ?>
     39<!-- Toolbar: Filter tabs + Search -->
     40<input type="hidden" id="scc-manager-filter-status" value="all">
     41<div class="scc-toolbar">
     42<div class="scc-toolbar-main">
     43<div class="scc-filter-tabs">
     44<button type="button" class="scc-manager-filter-tab scc-filter-tab-active" data-filter="all">
     45<?php esc_html_e('All', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['all']); ?></span>)
     46</button>
     47<button type="button" class="scc-manager-filter-tab" data-filter="enabled">
     48<?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['enabled']); ?></span>)
     49</button>
     50<button type="button" class="scc-manager-filter-tab" data-filter="disabled">
     51<?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['disabled']); ?></span>)
     52</button>
     53<button type="button" class="scc-manager-filter-tab" data-filter="hidden">
     54<?php esc_html_e('Hidden', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['hidden']); ?></span>)
     55</button>
     56<button type="button" class="scc-manager-filter-tab" data-filter="orphaned">
     57<?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?> (<span class="scc-filter-count"><?php echo intval($counts['orphaned']); ?></span>)
     58</button>
     59</div>
     60<div class="scc-search-wrap" style="display: flex; gap: 8px;">
     61<label class="screen-reader-text" for="scc-manager-search"><?php esc_html_e('Search shortcodes:', 'foureyed-shortcode-control'); ?></label>
     62<input type="search" id="scc-manager-search"
     63placeholder="<?php esc_attr_e('Search by tag or source...', 'foureyed-shortcode-control'); ?>"
     64autocomplete="off"
     65value="<?php echo esc_attr($search_query); ?>">
     66<button type="button" id="scc-manager-search-clear" class="button" style="display: none;"><?php esc_html_e('Clear Filter', 'foureyed-shortcode-control'); ?></button>
     67</div>
     68</div>
     69</div>
    6170
    62         <!-- Tab Navigation (same pattern as Settings page) -->
    63         <h2 class="nav-tab-wrapper">
    64                 <a href="#" class="nav-tab nav-tab-active" data-target="tab-active">
    65                         <?php esc_html_e('Active Shortcodes', 'foureyed-shortcode-control'); ?>
    66                         <?php if (!empty($grouped_data['active'])): ?>
    67                                 <span class="scc-tab-count"><?php echo count($grouped_data['active']); ?></span>
    68                         <?php endif; ?>
    69                 </a>
    70                 <a href="#" class="nav-tab" data-target="tab-orphaned">
    71                         <?php esc_html_e('Orphaned Shortcodes', 'foureyed-shortcode-control'); ?>
    72                         <?php if (!empty($grouped_data['orphaned'])): ?>
    73                                 <span class="scc-tab-count<?php echo count(array_filter($grouped_data['orphaned'], fn($i) => ($i['status'] ?? '') !== 'hidden')) > 0 ? ' scc-tab-count--alert' : ''; ?>">
    74                                         <?php echo count($grouped_data['orphaned']); ?>
    75                                 </span>
    76                         <?php endif; ?>
    77                 </a>
    78         </h2>
     71<!-- Table 1: Registered Shortcodes -->
     72<?php if (!empty($scc_registered)) : ?>
     73<div class="scc-manager-table-section">
     74<h2 class="scc-table-section-heading"><?php esc_html_e('Registered Shortcodes', 'foureyed-shortcode-control'); ?></h2>
     75<div class="scc-table-card">
     76<form method="get">
     77<input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
     78<?php
     79$scc_table_registered = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
     80$scc_table_registered->set_items($scc_registered);
     81$scc_table_registered->prepare_items();
     82$scc_table_registered->display();
     83?>
     84</form>
     85</div>
     86</div>
     87<?php endif; ?>
    7988
    80         <div>
     89<!-- Table 2: Orphaned Shortcodes -->
     90<?php if (!empty($scc_orphaned)) : ?>
     91<div class="scc-manager-table-section">
     92<h2 class="scc-table-section-heading"><?php esc_html_e('Orphaned Shortcodes', 'foureyed-shortcode-control'); ?></h2>
     93<p class="scc-orphaned-description"><?php esc_html_e('These shortcodes come from plugins that are no longer active. They will output raw text unless silenced. Use Hide to suppress them.', 'foureyed-shortcode-control'); ?></p>
     94<div class="scc-table-card">
     95<form method="get">
     96<input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
     97<?php
     98$scc_table_orphaned = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
     99$scc_table_orphaned->set_items($scc_orphaned);
     100$scc_table_orphaned->prepare_items();
     101$scc_table_orphaned->display();
     102?>
     103</form>
     104</div>
     105</div>
     106<?php endif; ?>
    81107
    82                 <!-- ACTIVE TAB -->
    83                 <div id="tab-active" class="scc-tab-content" style="display: block;">
    84                         <p class="scc-search-no-results" style="display:none;">
    85                                 <?php esc_html_e('No results in this tab for', 'foureyed-shortcode-control'); ?>
    86                                 “<span class="scc-search-no-results__query"></span>”
    87                         </p>
    88                         <?php if (empty($grouped_data['active'])): ?>
    89                                 <p class="scc-empty-tab"><?php esc_html_e('No active shortcodes found.', 'foureyed-shortcode-control'); ?></p>
    90                         <?php else: ?>
    91                                 <form method="get">
    92                                         <?php
    93                                         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    94                                         $scc_page_val = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
    95                                         ?>
    96                                         <input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
    97                                         <?php
    98                                         $scc_table_active = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
    99                                         $scc_table_active->set_items($grouped_data['active']);
    100                                         $scc_table_active->prepare_items();
    101                                         $scc_table_active->display();
    102                                         ?>
    103                                 </form>
    104                         <?php endif; ?>
    105                 </div>
     108<?php if (empty($scc_registered) && empty($scc_orphaned)) : ?>
     109<p class="scc-empty-tab"><?php esc_html_e('No shortcodes found.', 'foureyed-shortcode-control'); ?></p>
     110<?php endif; ?>
    106111
    107                 <!-- ORPHANED TAB -->
    108                 <div id="tab-orphaned" class="scc-tab-content" style="display: none;">
    109                         <p class="scc-search-no-results" style="display:none;">
    110                                 <?php esc_html_e('No results in this tab for', 'foureyed-shortcode-control'); ?>
    111                                 “<span class="scc-search-no-results__query"></span>”
    112                         </p>
    113                         <?php if (empty($grouped_data['orphaned'])): ?>
    114                                 <p class="scc-empty-tab"><?php esc_html_e('No orphaned shortcodes found. All plugins providing shortcodes on this site are currently active.', 'foureyed-shortcode-control'); ?></p>
    115                         <?php else: ?>
    116                                 <p class="scc-orphaned-description">
    117                                         <?php esc_html_e('These shortcodes come from plugins that are no longer active. If they appear in your content they will output raw text. You can silence them (output nothing) or restore them to their previous state.', 'foureyed-shortcode-control'); ?>
    118                                 </p>
    119                                 <form method="get">
    120                                         <?php
    121                                         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    122                                         $scc_page_val = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
    123                                         ?>
    124                                         <input type="hidden" name="page" value="<?php echo esc_attr($scc_page_val); ?>" />
    125                                         <?php
    126                                         $scc_table_orphaned = new \FoureyedShortcodeControl\Features\ShortcodeManager\AdminUi\ShortcodesPageController();
    127                                         $scc_table_orphaned->set_items($grouped_data['orphaned']);
    128                                         $scc_table_orphaned->prepare_items();
    129                                         $scc_table_orphaned->display();
    130                                         ?>
    131                                 </form>
    132                         <?php endif; ?>
    133                 </div>
    134 
    135         </div>
    136112</div>
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/AdminUi/manager-search.js

    r3523935 r3524967  
    11/**
    2  * Shortcode Manager — Global Search Filter
     2 * Shortcode Manager — Filter Tabs + Search
    33 *
    4  * Filters rows in both the Active and Orphaned tabs simultaneously.
    5  * Updates count badges and shows a "no results" message per tab.
     4 * Filters rows across both table sections simultaneously.
     5 * Hides entire sections when they have no visible rows after filtering.
     6 * Updates counts in filter tab labels to reflect search matches.
    67 */
    78document.addEventListener('DOMContentLoaded', function () {
    8         const searchInput = document.getElementById('scc-manager-search');
    9         if (!searchInput) return;
     9const searchInput   = document.getElementById('scc-manager-search');
     10const clearBtn      = document.getElementById('scc-manager-search-clear');
     11const filterInput   = document.getElementById('scc-manager-filter-status');
     12const filterTabs    = document.querySelectorAll('.scc-manager-filter-tab');
     13const tableSections = document.querySelectorAll('.scc-manager-table-section');
    1014
    11         const clearBtn   = document.getElementById('scc-manager-search-clear');
    12         const tabPanels  = document.querySelectorAll('.scc-tab-content');
     15if (!searchInput) return;
    1316
    14         // ── Core filter function ─────────────────────────────────────────────────
    15         function filterAll(scrollToTop = false) {
    16                 const query = searchInput.value.toLowerCase().trim();
     17// ── Core filter function ──────────────────────────────────────────────────
     18function applyFilters() {
     19const status = filterInput ? filterInput.value : 'all';
     20const query  = searchInput.value.toLowerCase().trim();
    1721
    18                 tabPanels.forEach(function (panel) {
    19                         const rows = panel.querySelectorAll(
    20                                 'table.wp-list-table tbody tr:not(.no-items)'
    21                         );
    22                         let visibleCount = 0;
     22if (clearBtn) {
     23clearBtn.style.display = query ? '' : 'none';
     24}
    2325
    24                         rows.forEach(function (row) {
    25                                 const tag    = (row.querySelector('.scc-tag-code')  || {}).textContent || '';
    26                                 const source = (row.querySelector('td.column-source') || {}).textContent || '';
    27                                 const match  = !query
    28                                         || tag.toLowerCase().includes(query)
    29                                         || source.toLowerCase().includes(query);
     26tableSections.forEach(function (section) {
     27const rows = section.querySelectorAll('table.wp-list-table tbody tr[data-status]');
     28let visibleCount = 0;
    3029
    31                                 row.style.display = match ? '' : 'none';
    32                                 if (match) visibleCount++;
    33                         });
     30rows.forEach(function (row) {
     31const rowStatus     = row.getAttribute('data-status');
     32const matchesFilter = (status === 'all' || rowStatus === status);
    3433
    35                         // ── Count badge ────────────────────────────────────────────────
    36                         const tabId   = panel.id; // 'tab-active' or 'tab-orphaned'
    37                         const tabLink = document.querySelector('[data-target="' + tabId + '"]');
    38                         if (tabLink) {
    39                                 const badge = tabLink.querySelector('.scc-tab-count');
    40                                 if (badge) {
    41                                         badge.textContent = visibleCount;
     34const tagEl    = row.querySelector('.scc-tag-code');
     35const sourceEl = row.querySelector('td.column-source');
     36const tagText  = tagEl    ? tagEl.textContent.toLowerCase()    : '';
     37const srcText  = sourceEl ? sourceEl.textContent.toLowerCase() : '';
     38const matchesSearch = !query || tagText.includes(query) || srcText.includes(query);
    4239
    43                                         // Re-check alert state for orphaned tab (only count non-silenced)
    44                                         if (tabId === 'tab-orphaned') {
    45                                                 let alertCount = 0;
    46                                                 rows.forEach(function (row) {
    47                                                         if (row.style.display !== 'none'
    48                                                                 && row.querySelector('.scc-status-orphaned')) {
    49                                                                 alertCount++;
    50                                                         }
    51                                                 });
    52                                                 badge.classList.toggle('scc-tab-count--alert', alertCount > 0);
    53                                         }
    54                                 }
    55                         }
     40const visible = matchesFilter && matchesSearch;
     41row.style.display = visible ? '' : 'none';
     42if (visible) visibleCount++;
     43});
    5644
    57                         // ── No-results message ─────────────────────────────────────────
    58                         const noResults = panel.querySelector('.scc-search-no-results');
    59                         if (noResults) {
    60                                 if (query && visibleCount === 0) {
    61                                         noResults.querySelector('.scc-search-no-results__query').textContent = query;
    62                                         noResults.style.display = '';
    63                                 } else {
    64                                         noResults.style.display = 'none';
    65                                 }
    66                         }
    67                 });
     45// Hide the entire section (heading + table) if nothing matches
     46section.style.display = visibleCount > 0 ? '' : 'none';
     47});
    6848
    69                 // ── Clear button visibility ────────────────────────────────────────
    70                 if (clearBtn) {
    71                         clearBtn.style.display = query ? '' : 'none';
    72                 }
     49updateTabCounts(query);
     50}
    7351
    74                 // ── Scroll to top if requested (on initial load with search param) ────
    75                 if (scrollToTop && query) {
    76                         window.scrollTo({ top: 0, behavior: 'smooth' });
    77                 }
    78         }
     52// ── Update counts in tab labels based on search query ────────────────────
     53function updateTabCounts(query) {
     54var counts = { all: 0, enabled: 0, disabled: 0, hidden: 0, orphaned: 0 };
    7955
    80         // ── Trigger filter on page load if search parameter exists ─────────────────
    81         // This handles the case when Scanner's "Manage" link passes ?s=shortcode_tag
    82         if (searchInput.value.trim()) {
    83                 filterAll(true);
     56tableSections.forEach(function (section) {
     57section.querySelectorAll('table.wp-list-table tbody tr[data-status]').forEach(function (row) {
     58const rowStatus = row.getAttribute('data-status');
     59const tagEl    = row.querySelector('.scc-tag-code');
     60const sourceEl = row.querySelector('td.column-source');
     61const tagText  = tagEl    ? tagEl.textContent.toLowerCase()    : '';
     62const srcText  = sourceEl ? sourceEl.textContent.toLowerCase() : '';
     63const matchesSearch = !query || tagText.includes(query) || srcText.includes(query);
    8464
    85                 // Auto-switch to Orphaned tab if the search has no Active matches but does match Orphaned
    86                 const activePanel   = document.getElementById('tab-active');
    87                 const orphanedPanel = document.getElementById('tab-orphaned');
    88                 if (activePanel && orphanedPanel) {
    89                         const countVisible = panel =>
    90                                 [...panel.querySelectorAll('table.wp-list-table tbody tr:not(.no-items)')]
    91                                         .filter(r => r.style.display !== 'none').length;
    92                         if (countVisible(activePanel) === 0 && countVisible(orphanedPanel) > 0) {
    93                                 const orphanedTabLink = document.querySelector('.nav-tab[data-target="tab-orphaned"]');
    94                                 if (orphanedTabLink) orphanedTabLink.click();
    95                         }
    96                 }
    97         }
     65if (matchesSearch) {
     66counts.all++;
     67if (counts[rowStatus] !== undefined) counts[rowStatus]++;
     68}
     69});
     70});
    9871
    99         // ── Event listeners ──────────────────────────────────────────────────────
    100         searchInput.addEventListener('input', filterAll);
     72filterTabs.forEach(function (tab) {
     73const f    = tab.getAttribute('data-filter');
     74const span = tab.querySelector('.scc-filter-count');
     75if (span && counts[f] !== undefined) {
     76span.textContent = counts[f];
     77}
     78});
     79}
    10180
    102         if (clearBtn) {
    103                 clearBtn.addEventListener('click', function () {
    104                         searchInput.value = '';
    105                         filterAll();
    106                         searchInput.focus();
    107                 });
    108         }
     81// ── Filter tab click handler ──────────────────────────────────────────────
     82filterTabs.forEach(function (tab) {
     83tab.addEventListener('click', function () {
     84filterTabs.forEach(function (t) { t.classList.remove('scc-filter-tab-active'); });
     85tab.classList.add('scc-filter-tab-active');
     86if (filterInput) filterInput.value = tab.getAttribute('data-filter');
     87applyFilters();
    10988});
     89});
     90
     91// ── Search input handler ──────────────────────────────────────────────────
     92searchInput.addEventListener('input', applyFilters);
     93
     94// ── Clear button ──────────────────────────────────────────────────────────
     95if (clearBtn) {
     96clearBtn.addEventListener('click', function () {
     97searchInput.value = '';
     98applyFilters();
     99searchInput.focus();
     100});
     101}
     102
     103// ── Run on load (handles ?s= from Scanner's Manage link) ─────────────────
     104applyFilters();
     105});
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/AdminUi/shortcodes.css

    r3523935 r3524967  
    11/* Shortcode Manager admin styles */
    22
    3 .scc-search-context {
    4     margin: 6px 0 12px;
    5     color: #50575e;
    6     font-style: italic;
     3/* ── Toolbar ─────────────────────────────────────────────────────────────── */
     4
     5.scc-toolbar {
     6    margin-bottom: 12px;
     7}
     8
     9.scc-toolbar-main {
     10    display: flex;
     11    align-items: center;
     12    justify-content: space-between;
     13    flex-wrap: wrap;
     14    gap: 8px;
     15}
     16
     17.scc-filter-tabs {
     18    display: inline-flex;
     19    border: 1px solid #c3c4c7;
     20    border-radius: 4px;
     21    overflow: hidden;
     22}
     23
     24.scc-manager-filter-tab {
     25    flex: 1;
     26    border: 0;
     27    border-right: 1px solid #c3c4c7;
     28    background: #f6f7f7;
     29    cursor: pointer;
     30    padding: 6px 16px;
     31    white-space: nowrap;
     32    transition: background 0.15s, color 0.15s;
     33}
     34
     35.scc-manager-filter-tab:last-child {
     36    border-right: 0;
     37}
     38
     39.scc-filter-tab-active {
     40    background: #2271b1;
     41    color: #fff;
     42    font-weight: 600;
     43}
     44
     45.scc-search-wrap input[type="search"] {
     46    width: 240px;
     47}
     48
     49/* ── Table sections ─────────────────────────────────────────────────────── */
     50
     51.scc-manager-table-section {
     52    margin-bottom: 24px;
     53}
     54
     55.scc-table-section-heading {
     56    font-size: 14px;
     57    font-weight: 600;
     58    margin: 0 0 8px;
     59    padding: 0;
     60    color: #1d2327;
     61}
     62
     63.scc-table-card {
     64    border: 1px solid #c3c4c7;
     65    border-radius: 6px;
     66    overflow: hidden;
     67    background: #fff;
     68}
     69
     70.scc-admin-page .wp-list-table {
     71    margin: 0;
     72    border: 0;
     73    box-shadow: none;
    774}
    875
    … …  
    34101
    35102.scc-status-orphaned {
    36     background: #fef3cd;
    37     color: #7a4f00;
    38 }
    39 
    40 .scc-tab-count {
    41     display: inline-block;
    42     background: #ddd;
    43     color: #444;
    44     font-size: 11px;
    45     font-weight: 600;
    46     border-radius: 10px;
    47     padding: 1px 7px;
    48     margin-left: 5px;
    49     vertical-align: middle;
    50 }
    51 
    52 .scc-tab-count--alert {
    53103    background: #fef3cd;
    54104    color: #7a4f00;
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/Api/ShortcodeManagerApi.php

    r3523935 r3524967  
    3838        }
    3939
     40        /**
     41         * Get shortcode status counts for stats display.
     42         * Single source of truth for all stat cards (Manager, Start Here, etc.).
     43         *
     44         * Four categories:
     45         *  - enabled  → status 'registered'                              (plugin active, shortcode on)
     46         *  - disabled → status 'unregistered' AND is_active true         (user disabled an active shortcode, returns raw text)
     47         *  - hidden   → status 'hidden'                                  (user silenced it, outputs nothing)
     48         *  - orphaned → status 'unregistered' AND is_active false        (plugin deactivated, user hasn't touched it)
     49         *
     50         * @return array{enabled: int, disabled: int, hidden: int, orphaned: int}
     51         */
     52        public static function get_stats(): array
     53        {
     54                $data = self::get_all_data();
     55
     56                // Respect the "hide core shortcodes" setting, same as the Manager page does.
     57                $hide_core = get_option(\FoureyedShortcodeControl\DataRegistry::OPTION_HIDE_CORE, true);
     58                if ($hide_core) {
     59                        $data = array_filter($data, fn($sc) => ($sc['source_type'] ?? '') !== 'core');
     60                }
     61
     62                $enabled  = 0;
     63                $disabled = 0;
     64                $hidden   = 0;
     65                $orphaned = 0;
     66
     67                foreach ($data as $sc) {
     68                        $status    = $sc['status'] ?? '';
     69                        $is_active = $sc['is_active'] ?? false;
     70                        if ($status === 'registered') {
     71                                $enabled++;
     72                        } elseif ($status === 'hidden') {
     73                                $hidden++;
     74                        } elseif ($status === 'unregistered' && $is_active) {
     75                                $disabled++;
     76                        } elseif ($status === 'unregistered' && !$is_active) {
     77                                $orphaned++;
     78                        }
     79                }
     80
     81                return compact('enabled', 'disabled', 'hidden', 'orphaned');
     82        }
     83
    4084}
  • foureyed-shortcode-control/trunk/includes/Features/ShortcodeManager/Core/ShortcodeRegistry.php

    r3523935 r3524967  
    224224                foreach ($master as $tag => $item) {
    225225                        $is_active = in_array($tag, $active_tags, true);
    226                         $is_discovered = in_array($tag, $discovered_tags, true);
     226                        // Cast $tag to string: PHP coerces numeric string array keys to integers,
     227                        // so a tag like '13' is stored as integer 13 in $master. $discovered_tags
     228                        // from get_col() are always strings, so strict in_array(13, ['13'], true)
     229                        // would return false and incorrectly prune numeric-tag orphans.
     230                        $is_discovered = in_array((string) $tag, $discovered_tags, true);
    227231                        $is_hidden = ($item['status'] ?? '') === 'hidden';
    228232
  • foureyed-shortcode-control/trunk/includes/Features/StartHere/AdminUi/StartHerePageController.php

    r3523935 r3524967  
    55use FoureyedShortcodeControl\Features\StartHere\Core\StartHereHelper;
    66use FoureyedShortcodeControl\Features\Scanner\Api\ScannerApi;
     7use FoureyedShortcodeControl\Features\ShortcodeManager\Api\ShortcodeManagerApi;
    78
    89if (!defined('ABSPATH')) {
    … …  
    2324        public function render_page()
    2425        {
    25                 // Enqueue shared + page-specific assets
    26                 wp_enqueue_style('foureyed-shortcode-control-shared-css', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    27                 wp_enqueue_script('foureyed-shortcode-control-shared-ui', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/AdminUi/shared-ui.js', [], FOUREYED_SHORTCODE_CONTROL_VERSION, true);
     26                // Enqueue page-specific assets (shared assets loaded globally via Bootstrap)
    2827                wp_enqueue_style('foureyed-shortcode-control-start-here', FOUREYED_SHORTCODE_CONTROL_URL . 'includes/Features/StartHere/AdminUi/styles.css', [], FOUREYED_SHORTCODE_CONTROL_VERSION);
    2928
    30                 // Get scanner counts (all zeroes if no scan has been run yet)
    31                 $scan_data   = ScannerApi::get_prepared_data();
    32                 $scan_counts = $scan_data['counts'];
     29                // Get scanner counts — single source of truth via Scanner API
     30                $scan_stats = ScannerApi::get_stats();
    3331
    34                 // Get stats for the page
    35                 $total_shortcodes    = StartHereHelper::get_total_shortcodes();
    36                 $active_shortcodes   = StartHereHelper::get_active_shortcodes();
    37                 $disabled_shortcodes = StartHereHelper::get_disabled_shortcodes();
    38                 $hidden_shortcodes   = StartHereHelper::get_hidden_shortcodes();
     32                // Shortcode stats — single source of truth via Manager API
     33                $stats = ShortcodeManagerApi::get_stats();
     34
    3935                // A scan has been run if there are any results in the DB.
    40                 $has_been_scanned = $scan_counts['total'] > 0;
     36                $has_been_scanned = $scan_stats['total'] > 0;
    4137
    4238                // Prepare template data
    4339                $data = [
    44                         'total_shortcodes'    => $total_shortcodes,
    45                         'active_shortcodes'   => $active_shortcodes,
    46                         'disabled_shortcodes' => $disabled_shortcodes,
    47                         'hidden_shortcodes'   => $hidden_shortcodes,
     40                        'all_shortcodes'      => $stats['enabled'] + $stats['disabled'] + $stats['hidden'] + $stats['orphaned'],
     41                        'enabled_shortcodes'  => $stats['enabled'],
     42                        'disabled_shortcodes' => $stats['disabled'],
     43                        'hidden_shortcodes'   => $stats['hidden'],
     44                        'orphaned_shortcodes' => $stats['orphaned'],
    4845                        'has_been_scanned'    => $has_been_scanned,
    49                         'scan_total'          => $scan_counts['total'],
    50                         'scan_active'         => $scan_counts['active'],
    51                         'scan_disabled'       => $scan_counts['disabled'],
    52                         'scan_orphaned'       => $scan_counts['orphaned'],
     46                        'scan_total'          => $scan_stats['total'],
     47                        'scan_active'         => $scan_stats['active'],
     48                        'scan_disabled'       => $scan_stats['disabled'],
     49                        'scan_orphaned'       => $scan_stats['orphaned'],
    5350                ];
    5451
    … …  
    7269                        <h2 class="scc-start-section-title"><?php esc_html_e('Registered Shortcodes', 'foureyed-shortcode-control'); ?></h2>
    7370                        <div class="scc-start-stats-row">
    74                                 <div class="scc-start-stat-card">
    75                                         <div class="scc-stat-number"><?php echo intval($data['total_shortcodes']); ?></div>
    76                                         <div class="scc-stat-label"><?php esc_html_e('Total', 'foureyed-shortcode-control'); ?></div>
    77                                 </div>
     71                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control')); ?>" class="scc-start-stat-card">
     72                                        <div class="scc-stat-number"><?php echo intval($data['all_shortcodes']); ?></div>
     73                                        <div class="scc-stat-label"><?php esc_html_e('All', 'foureyed-shortcode-control'); ?></div>
     74                                </a>
    7875                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control')); ?>" class="scc-start-stat-card scc-start-stat-enabled">
    79                                         <div class="scc-stat-number"><?php echo intval($data['active_shortcodes']); ?></div>
     76                                        <div class="scc-stat-number"><?php echo intval($data['enabled_shortcodes']); ?></div>
    8077                                        <div class="scc-stat-label"><?php esc_html_e('Enabled', 'foureyed-shortcode-control'); ?></div>
    8178                                </a>
    … …  
    8885                                        <div class="scc-stat-label"><?php esc_html_e('Hidden', 'foureyed-shortcode-control'); ?></div>
    8986                                </div>
     87                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control#tab-orphaned')); ?>" class="scc-start-stat-card<?php echo $data['orphaned_shortcodes'] > 0 ? ' scc-start-stat-orphaned--alert' : ' scc-start-stat-orphaned'; ?>">
     88                                        <div class="scc-stat-number"><?php echo intval($data['orphaned_shortcodes']); ?></div>
     89                                        <div class="scc-stat-label"><?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?></div>
     90                                </a>
    9091                        </div>
    9192
    … …  
    105106                                <div class="scc-start-stat-card scc-start-stat-enabled">
    106107                                        <div class="scc-stat-number"><?php echo intval($data['scan_active']); ?></div>
    107                                         <div class="scc-stat-label"><?php esc_html_e('Enabled in Content', 'foureyed-shortcode-control'); ?></div>
     108                                        <div class="scc-stat-label"><?php esc_html_e('Active', 'foureyed-shortcode-control'); ?></div>
    108109                                </div>
    109110                                <div class="scc-start-stat-card scc-start-stat-disabled">
    110111                                        <div class="scc-stat-number"><?php echo intval($data['scan_disabled']); ?></div>
    111                                         <div class="scc-stat-label"><?php esc_html_e('Disabled in Content', 'foureyed-shortcode-control'); ?></div>
     112                                        <div class="scc-stat-label"><?php esc_html_e('Disabled', 'foureyed-shortcode-control'); ?></div>
    112113                                </div>
    113                                 <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control-scanner')); ?>"
    114                                    class="scc-start-stat-card<?php echo $data['scan_orphaned'] > 0 ? ' scc-start-stat-orphaned--alert' : ' scc-start-stat-orphaned'; ?>">
     114                                <a href="<?php echo esc_url(admin_url('admin.php?page=foureyed-shortcode-control-scanner')); ?>" class="scc-start-stat-card<?php echo $data['scan_orphaned'] > 0 ? ' scc-start-stat-orphaned--alert' : ' scc-start-stat-orphaned'; ?>">
    115115                                        <div class="scc-stat-number"><?php echo intval($data['scan_orphaned']); ?></div>
    116116                                        <div class="scc-stat-label"><?php esc_html_e('Orphaned', 'foureyed-shortcode-control'); ?></div>
  • foureyed-shortcode-control/trunk/includes/Features/StartHere/Core/StartHereHelper.php

    r3523935 r3524967  
    44
    55use FoureyedShortcodeControl\DataRegistry;
    6 use FoureyedShortcodeControl\Features\ShortcodeManager\Core\ShortcodesDataProvider;
    76
    87if (!defined('ABSPATH')) {
    … …  
    1110
    1211/**
    13  * Start Here Helper — Provides data for the welcome wizard page.
    14  *
    15  * Fetches statistics and information to display on the Start Here page.
    16  * Routes through ShortcodesDataProvider so hide_core and other settings
    17  * are respected, keeping counts consistent with the Shortcode Manager page.
     12 * Start Here Helper — Lightweight helpers for the Start Here page.
     13 *
     14 * Stat counts are owned by ShortcodeManagerApi::get_stats().
     15 * This class only provides helpers that have no other home.
    1816 */
    1917class StartHereHelper
    2018{
    21         /**
    22          * Get all shortcode data respecting current settings (e.g. hide_core).
    23          */
    24         private static function get_data(): array
    25         {
    26                 static $cache = null;
    27                 if ($cache !== null) {
    28                         return $cache;
    29                 }
    30                 $provider = new ShortcodesDataProvider();
    31                 $data     = $provider->get_data();
    32                 $cache    = $provider->maybe_hide_core($data);
    33                 return $cache;
    34         }
    35 
    36         /**
    37          * Get total number of shortcodes (after settings filters applied).
    38          */
    39         public static function get_total_shortcodes(): int
    40         {
    41                 return count(self::get_data());
    42         }
    43 
    44         /**
    45          * Get number of enabled shortcodes (status === 'registered').
    46          */
    47         public static function get_active_shortcodes(): int
    48         {
    49                 $count = 0;
    50                 foreach (self::get_data() as $sc) {
    51                         if (($sc['status'] ?? '') === 'registered') {
    52                                 $count++;
    53                         }
    54                 }
    55                 return $count;
    56         }
    57 
    58         /**
    59          * Get number of disabled or hidden shortcodes (anything not 'registered').
    60          */
    61         public static function get_disabled_shortcodes(): int
    62         {
    63                 $count = 0;
    64                 foreach (self::get_data() as $sc) {
    65                         if (($sc['status'] ?? '') === 'unregistered') {
    66                                 $count++;
    67                         }
    68                 }
    69                 return $count;
    70         }
    71 
    72         /**
    73          * Get number of hidden shortcodes (status === 'hidden').
    74          */
    75         public static function get_hidden_shortcodes(): int
    76         {
    77                 $count = 0;
    78                 foreach (self::get_data() as $sc) {
    79                         if (($sc['status'] ?? '') === 'hidden') {
    80                                 $count++;
    81                         }
    82                 }
    83                 return $count;
    84         }
    85 
    8619        /**
    8720         * Check if site has been scanned yet.
  • foureyed-shortcode-control/trunk/includes/Services/tooltip.css

    r3523935 r3524967  
    2929    cursor: pointer;
    3030    display: inline-block;
    31     color: inherit;
     31    color: #2271b1;
    3232    font-weight: inherit;
    3333    font-size: inherit;
    3434    margin-left: 0;
     35}
     36
     37a.scc-tooltip:hover,
     38a.scc-tooltip:focus {
     39    color: #135e96;
    3540}
    3641
  • foureyed-shortcode-control/trunk/includes/Services/tooltip.js

    r3523933 r3524967  
    3232            tooltip.style.display = 'block';
    3333
    34             // Position relative to trigger
     34            // Position relative to trigger.
     35            // tooltip-box is position:fixed so coordinates are viewport-relative;
     36            // do NOT add window.scrollX/Y (that's for position:absolute).
    3537            const rect = trigger.getBoundingClientRect();
    36             tooltip.style.left = (rect.left + window.scrollX) + 'px';
    37             tooltip.style.top = (rect.bottom + window.scrollY + 8) + 'px';
     38            tooltip.style.left = rect.left + 'px';
     39            tooltip.style.top = (rect.bottom + 8) + 'px';
    3840        }
    3941
    … …  
    4951        trigger.addEventListener('mouseleave', hideTooltip);
    5052
    51         // Click events (for touch devices)
     53        // Click events (for touch devices / non-link tooltips)
    5254        trigger.addEventListener('click', function (e) {
    53             e.preventDefault();
     55            // For links and buttons, don't block navigation — just toggle tooltip
     56            // alongside the native action. Only preventDefault for non-interactive
     57            // elements like <span class="scc-tooltip"> (the ? badges).
     58            const isInteractive = trigger.tagName === 'A' || trigger.tagName === 'BUTTON';
     59            if (!isInteractive) {
     60                e.preventDefault();
     61            }
    5462            if (tooltip && tooltip.style.display === 'block') {
    5563                hideTooltip();
  • foureyed-shortcode-control/trunk/languages/foureyed-shortcode-control.pot

    r3523933 r3524967  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Foureyed Shortcode Control 1.0.0\n"
     5"Project-Id-Version: Foureyed Shortcode Control 1.0.4\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foureyed-shortcode-control\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
    … …  
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2026-04-28T03:07:16+00:00\n"
     12"POT-Creation-Date: 2026-05-07T03:40:17+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.12.0\n"
    … …  
    1717#. Plugin Name of the plugin
    1818#: foureyed-shortcode-control.php
     19#: includes/Features/StartHere/AdminUi/StartHerePageController.php:64
    1920msgid "Foureyed Shortcode Control"
    2021msgstr ""
    … …  
    4041msgstr ""
    4142
    42 #: includes/Bootstrap.php:55
    43 #: includes/Bootstrap.php:56
     43#: includes/Bootstrap.php:66
     44#: includes/Bootstrap.php:67
    4445msgid "Shortcode Control"
    4546msgstr ""
    4647
    47 #: includes/Bootstrap.php:67
     48#: includes/Bootstrap.php:78
    4849msgid "Start Here — Shortcode Control"
    4950msgstr ""
    5051
    51 #: includes/Bootstrap.php:68
     52#: includes/Bootstrap.php:79
    5253msgid "Start Here"
    5354msgstr ""
    5455
    55 #: includes/Bootstrap.php:76
    56 #: includes/Bootstrap.php:77
     56#: includes/Bootstrap.php:87
     57#: includes/Bootstrap.php:88
     58#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:26
     59#: includes/Features/StartHere/AdminUi/StartHerePageController.php:124
    5760msgid "Manage Shortcodes"
    5861msgstr ""
    5962
    60 #: includes/Bootstrap.php:90
    61 #: includes/Bootstrap.php:91
    62 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:36
     63#: includes/Bootstrap.php:101
     64#: includes/Bootstrap.php:102
     65#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:41
    6366msgid "Find Orphaned Shortcodes"
    6467msgstr ""
    6568
    66 #: includes/Bootstrap.php:99
    67 #: includes/Bootstrap.php:100
    68 #: includes/Features/Settings/AdminUi/SettingsPageController.php:36
    69 msgid "Tools & Settings"
    70 msgstr ""
    71 
    72 #. translators: %s: shortcode tag name
    73 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:29
    74 #, php-format
    75 msgid "Successfully adopted shortcode &ldquo;%s&rdquo;. It is now <strong>disabled</strong> by default. You can manage it in the &ldquo;Manually Adopted&rdquo; section of your Shortcodes page."
    76 msgstr ""
    77 
    78 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:97
    79 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:29
     69#: includes/Bootstrap.php:110
     70#: includes/Bootstrap.php:111
     71#: includes/Features/Settings/AdminUi/SettingsPageController.php:37
     72msgid "Settings & Tools"
     73msgstr ""
     74
     75#: includes/Features/Scanner/AdminUi/ScannerPageController.php:76
     76#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:34
    8077msgid "Start Scan"
    8178msgstr ""
    8279
    83 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:98
    84 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:26
     80#: includes/Features/Scanner/AdminUi/ScannerPageController.php:77
     81#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:30
    8582msgid "Scan Changes"
    8683msgstr ""
    8784
    88 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:99
     85#: includes/Features/Scanner/AdminUi/ScannerPageController.php:78
    8986#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:23
    9087msgid "Continue Scan"
    9188msgstr ""
    9289
    93 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:100
     90#: includes/Features/Scanner/AdminUi/ScannerPageController.php:79
     91msgid "Scanning..."
     92msgstr ""
     93
     94#: includes/Features/Scanner/AdminUi/ScannerPageController.php:80
     95msgid "Scan complete!"
     96msgstr ""
     97
     98#. translators: 1: number of posts scanned, 2: total posts, 3: percentage
     99#: includes/Features/Scanner/AdminUi/ScannerPageController.php:82
     100#, php-format
     101msgid "Scanned %1$s of %2$s posts (%3$s%%)"
     102msgstr ""
     103
     104#: includes/Features/Scanner/AdminUi/ScannerPageController.php:83
     105#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:191
     106msgid "(No Title)"
     107msgstr ""
     108
     109#: includes/Features/Scanner/AdminUi/ScannerPageController.php:84
     110msgid "No shortcodes found. Run a scan to populate this table."
     111msgstr ""
     112
    94113#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:20
    95114msgid "Scanning\\u2026"
    96115msgstr ""
    97116
    98 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:101
    99 msgid "Scan complete!"
    100 msgstr ""
    101 
    102 #. translators: 1: number of posts scanned, 2: total posts, 3: percentage
    103 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:103
     117#. translators: %d is the number of modified posts waiting to be scanned.
     118#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:28
    104119#, php-format
    105 msgid "Scanned %1$s of %2$s posts (%3$s%%)"
    106 msgstr ""
    107 
    108 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:104
    109 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:183
    110 msgid "(No Title)"
    111 msgstr ""
    112 
    113 #: includes/Features/Scanner/AdminUi/ScannerPageController.php:105
    114 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:148
    115 msgid "No shortcodes found. Run a scan to populate this table."
    116 msgstr ""
    117 
    118 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:37
     120msgid "Scan %d Changes"
     121msgstr ""
     122
     123#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:42
    119124msgid "Scans your posts and pages for shortcodes whose plugins have been deactivated or deleted. These broken shortcodes may display as raw text or cause layout issues on your site."
    120125msgstr ""
    121126
    122 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:40
    123 msgid "Scan your published content to find shortcodes that no longer have an active plugin behind them — so you can fix or remove them before they cause problems."
    124 msgstr ""
    125 
    126 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:55
    127 msgid "PHP time limit reached"
    128 msgstr ""
    129 
    130 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:56
    131 msgid "PHP memory limit reached"
    132 msgstr ""
    133 
    134 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:57
    135 msgid "server process was interrupted"
    136 msgstr ""
    137 
    138 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:58
    139 msgid "an unexpected error"
    140 msgstr ""
    141 
    142 #. translators: 1: processed count, 2: total count, 3: reason
     127#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:48
     128msgid "Quick Guide:"
     129msgstr ""
     130
     131#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:49
     132msgid "Run a scan, review orphaned findings first, then click Manage to jump directly into Shortcode Manager for that shortcode tag."
     133msgstr ""
     134
     135#. translators: %d is the number of posts that have been modified since the last scan.
    143136#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:62
    144137#, php-format
     138msgid "Scan required: %d modified posts pending."
     139msgstr ""
     140
     141#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:64
     142msgid "You can safely leave this page anytime once the scan begins. Scanning happens in background batches based on your Settings."
     143msgstr ""
     144
     145#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:77
     146msgid "PHP time limit reached"
     147msgstr ""
     148
     149#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:78
     150msgid "PHP memory limit reached"
     151msgstr ""
     152
     153#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:79
     154msgid "server process was interrupted"
     155msgstr ""
     156
     157#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:80
     158msgid "an unexpected error"
     159msgstr ""
     160
     161#. translators: 1: processed count, 2: total count, 3: reason
     162#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:84
     163#, php-format
    145164msgid "Scan stopped after processing %1$s of %2$s posts (%3$s). Click \\u201cContinue Scan\\u201d to resume from where it stopped."
    146165msgstr ""
    147166
    148 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:87
    149 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:29
    150 msgid "Total"
    151 msgstr ""
    152 
    153 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:91
    154 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:121
    155 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:162
    156 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:176
    157 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:25
    158 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:159
    159 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:33
    160 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:64
    161 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:84
    162 #: includes/Services/StatusHelper.php:38
    163 #: includes/Services/StatusHelper.php:73
    164 msgid "Active"
    165 msgstr ""
    166 
    167 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:95
    168 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:125
    169 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:161
    170 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:166
    171 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:175
    172 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:25
    173 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:160
    174 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:37
    175 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:68
    176 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:88
     167#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:96
     168msgid "Scans all published posts and pages for shortcode tags, then cross-checks them against currently active plugins."
     169msgstr ""
     170
     171#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:113
     172#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:45
     173#: includes/Features/StartHere/AdminUi/StartHerePageController.php:73
     174msgid "All"
     175msgstr ""
     176
     177#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:116
     178#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:40
     179#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:48
     180#: includes/Features/StartHere/AdminUi/StartHerePageController.php:77
     181#: includes/Services/DataGrouper.php:60
     182msgid "Enabled"
     183msgstr ""
     184
     185#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:119
     186#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:43
     187#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:51
     188#: includes/Features/StartHere/AdminUi/StartHerePageController.php:81
     189#: includes/Features/StartHere/AdminUi/StartHerePageController.php:112
     190#: includes/Services/DataGrouper.php:58
    177191#: includes/Services/StatusHelper.php:37
    178192#: includes/Services/StatusHelper.php:75
    … …  
    180194msgstr ""
    181195
    182 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:99
    183 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:129
    184 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:164
    185 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:115
     196#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:122
     197#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:176
     198#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:36
     199#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:57
     200#: includes/Features/StartHere/AdminUi/StartHerePageController.php:89
     201#: includes/Features/StartHere/AdminUi/StartHerePageController.php:116
    186202#: includes/Services/StatusHelper.php:77
    187203msgid "Orphaned"
    188204msgstr ""
    189205
    190 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:107
     206#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:127
    191207msgid "Search findings:"
    192208msgstr ""
    193209
    194 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:109
    195 msgid "Search post title or tag..."
    196 msgstr ""
    197 
    198 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:117
    199 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:60
    200 msgid "All"
     210#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:129
     211msgid "Search by post title or shortcode tag..."
     212msgstr ""
     213
     214#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:130
     215#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:66
     216msgid "Clear Filter"
    201217msgstr ""
    202218
    203219#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:139
    204 msgid "Post Title"
     220msgid "Location"
    205221msgstr ""
    206222
    207223#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:140
    208 msgid "Post Type"
     224msgid "Shortcode"
    209225msgstr ""
    210226
    211227#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:141
    212 msgid "Shortcode Tag"
     228#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:58
     229msgid "Status"
    213230msgstr ""
    214231
    215232#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:142
    216 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:56
    217 msgid "Status"
    218 msgstr ""
    219 
    220 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:143
    221 msgid "Last Scanned"
    222 msgstr ""
    223 
    224 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:159
    225 #: includes/Services/DataGrouper.php:37
    226 #: includes/Services/ShortcodeFormatter.php:33
    227 msgid "Manually Adopted"
    228 msgstr ""
    229 
    230 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:169
    231 #: includes/Services/ShortcodeFormatter.php:27
    232 msgid "Plugin Shortcode"
    233 msgstr ""
    234 
    235 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:170
    236 #: includes/Services/ShortcodeFormatter.php:29
    237 msgid "Theme Shortcode"
    238 msgstr ""
    239 
    240 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:171
    241 #: includes/Services/ShortcodeFormatter.php:31
    242 msgid "WordPress Shortcode"
    243 msgstr ""
    244 
    245 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:172
    246 #: includes/Services/ShortcodeFormatter.php:36
    247 msgid "Registered"
    248 msgstr ""
    249 
    250 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:190
    251 msgid "Edit Post"
    252 msgstr ""
    253 
    254 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:197
    255 msgid "Filter this tag"
     233#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:60
     234msgid "Source"
     235msgstr ""
     236
     237#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:147
     238#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:109
     239msgid "No shortcodes found."
     240msgstr ""
     241
     242#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:147
     243msgid "Run a scan to populate this table."
     244msgstr ""
     245
     246#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:174
     247#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:33
     248msgid "Silenced"
     249msgstr ""
     250
     251#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:178
     252#: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:200
     253#: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:227
     254#: includes/Services/StatusHelper.php:79
     255msgid "Unknown"
    256256msgstr ""
    257257
    258258#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:198
    259 msgid "Manage Shortcode"
    260 msgstr ""
    261 
    262 #: includes/Features/Scanner/AdminUi/ScannerTemplate.php:200
    263 msgid "Adopt"
    264 msgstr ""
    265 
    266 #: includes/Features/Scanner/Rest/ScannerRestController.php:83
     259msgid "Open this post in the WordPress editor"
     260msgstr ""
     261
     262#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:198
     263msgid "Edit"
     264msgstr ""
     265
     266#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:205
     267msgid "View this post on the front-end"
     268msgstr ""
     269
     270#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:205
     271msgid "View"
     272msgstr ""
     273
     274#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:217
     275msgid "WordPress Core"
     276msgstr ""
     277
     278#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:217
     279msgid "Enable &ldquo;Show WordPress Core shortcodes&rdquo; in Settings to manage this shortcode"
     280msgstr ""
     281
     282#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:217
     283msgid "enable in Settings"
     284msgstr ""
     285
     286#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:219
     287msgid "Go to Shortcode Manager and filter to this tag"
     288msgstr ""
     289
     290#: includes/Features/Scanner/AdminUi/ScannerTemplate.php:219
     291msgid "Manage"
     292msgstr ""
     293
     294#: includes/Features/Scanner/Rest/ScannerRestController.php:84
    267295msgid "A scan is already in progress."
    268296msgstr ""
    … …  
    288316msgstr ""
    289317
    290 #: includes/Features/Settings/AdminUi/SettingsPageController.php:37
     318#: includes/Features/Settings/AdminUi/SettingsPageController.php:38
    291319msgid "Configure global plugin settings, control scanner behavior, manage performance, and perform maintenance tasks like clearing caches or resetting data."
    292320msgstr ""
    293321
    294 #: includes/Features/Settings/AdminUi/SettingsPageController.php:53
    295 msgid "General"
    296 msgstr ""
    297 
    298 #: includes/Features/Settings/AdminUi/SettingsPageController.php:56
    299 #: includes/Services/DataGrouper.php:106
    300 msgid "Shortcodes"
    301 msgstr ""
    302 
    303 #: includes/Features/Settings/AdminUi/SettingsPageController.php:59
    304 msgid "Scanner"
    305 msgstr ""
    306 
    307 #: includes/Features/Settings/AdminUi/SettingsPageController.php:62
    308 #: includes/Features/Settings/AdminUi/SettingsPageController.php:89
    309 msgid "Advanced Tools"
    310 msgstr ""
    311 
    312 #: includes/Features/Settings/AdminUi/SettingsPageController.php:90
     322#: includes/Features/Settings/AdminUi/SettingsPageController.php:41
     323msgid "Adjust how the plugin behaves across modules. If you are unsure, keep the defaults — they are safe for most sites."
     324msgstr ""
     325
     326#: includes/Features/Settings/AdminUi/SettingsPageController.php:47
     327msgid "Beginner Tip:"
     328msgstr ""
     329
     330#: includes/Features/Settings/AdminUi/SettingsPageController.php:48
     331msgid "Change one setting at a time, click Save All Settings, then verify behavior in Manage Shortcodes or Scanner."
     332msgstr ""
     333
     334#: includes/Features/Settings/AdminUi/SettingsPageController.php:64
     335#: includes/Features/StartHere/AdminUi/StartHerePageController.php:138
     336msgid "Settings"
     337msgstr ""
     338
     339#: includes/Features/Settings/AdminUi/SettingsPageController.php:67
     340#: includes/Features/Settings/AdminUi/SettingsPageController.php:86
     341msgid "Tools"
     342msgstr ""
     343
     344#: includes/Features/Settings/AdminUi/SettingsPageController.php:87
    313345msgid "Server-level maintenance tools. Proceed with caution."
    314346msgstr ""
    315347
    316 #: includes/Features/Settings/AdminUi/SettingsPageController.php:94
     348#: includes/Features/Settings/AdminUi/SettingsPageController.php:91
    317349msgid "Reset Shortcode Manager Data"
    318350msgstr ""
    319351
     352#: includes/Features/Settings/AdminUi/SettingsPageController.php:93
     353msgid "Clears all shortcode manager data including disabled toggles, adopted orphans, performance metrics, and registry caches. All your manually managed shortcodes will be reset."
     354msgstr ""
     355
     356#: includes/Features/Settings/AdminUi/SettingsPageController.php:95
     357msgid "Are you sure? This will clear all disabled toggles and adopted orphans."
     358msgstr ""
     359
    320360#: includes/Features/Settings/AdminUi/SettingsPageController.php:96
    321 msgid "Clears all shortcode manager data including disabled toggles, adopted orphans, performance metrics, and registry caches. All your manually managed shortcodes will be reset."
    322 msgstr ""
    323 
    324 #: includes/Features/Settings/AdminUi/SettingsPageController.php:98
    325 msgid "Are you sure? This will clear all disabled toggles and adopted orphans."
    326 msgstr ""
    327 
    328 #: includes/Features/Settings/AdminUi/SettingsPageController.php:99
    329361msgid "Reset Shortcode Data"
    330362msgstr ""
    331363
    332 #: includes/Features/Settings/AdminUi/SettingsPageController.php:105
    333 #: includes/Features/Settings/AdminUi/SettingsPageController.php:110
     364#: includes/Features/Settings/AdminUi/SettingsPageController.php:102
     365#: includes/Features/Settings/AdminUi/SettingsPageController.php:107
    334366msgid "Reset Scanner Data"
    335367msgstr ""
    336368
    337 #: includes/Features/Settings/AdminUi/SettingsPageController.php:107
     369#: includes/Features/Settings/AdminUi/SettingsPageController.php:104
    338370msgid "Clears all scanner results and progress markers. This allows the scanner to re-scan all posts as if running for the first time. All previous scan results will be deleted."
    339371msgstr ""
    340372
    341 #: includes/Features/Settings/AdminUi/SettingsPageController.php:109
     373#: includes/Features/Settings/AdminUi/SettingsPageController.php:106
    342374msgid "Are you sure you want to delete all scanner data? The next scan will re-scan every post."
    343375msgstr ""
    344376
    345 #: includes/Features/Settings/AdminUi/SettingsPageController.php:116
     377#: includes/Features/Settings/AdminUi/SettingsPageController.php:113
    346378msgid "Factory Reset (Nuclear Option)"
    347379msgstr ""
    348380
     381#: includes/Features/Settings/AdminUi/SettingsPageController.php:115
     382msgid "Wipes EVERYTHING. Deletes all scanner results, clears all shortcode manager data, resets all settings, and un-toggles every shortcode. Reverts the plugin to Day 1."
     383msgstr ""
     384
     385#: includes/Features/Settings/AdminUi/SettingsPageController.php:117
     386msgid "WARNING: This will delete EVERYTHING and re-enable every shortcode. Are you absolutely certain?"
     387msgstr ""
     388
    349389#: includes/Features/Settings/AdminUi/SettingsPageController.php:118
    350 msgid "Wipes EVERYTHING. Deletes all scanner results, clears all shortcode manager data, resets all settings, and un-toggles every shortcode. Reverts the plugin to Day 1."
    351 msgstr ""
    352 
    353 #: includes/Features/Settings/AdminUi/SettingsPageController.php:120
    354 msgid "WARNING: This will delete EVERYTHING and re-enable every shortcode. Are you absolutely certain?"
    355 msgstr ""
    356 
    357 #: includes/Features/Settings/AdminUi/SettingsPageController.php:121
    358390msgid "Factory Reset"
    359391msgstr ""
    360392
    361 #: includes/Features/Settings/AdminUi/SettingsPageController.php:131
     393#: includes/Features/Settings/AdminUi/SettingsPageController.php:128
    362394msgid "Save All Settings"
    363395msgstr ""
    364396
    365 #: includes/Features/Settings/AdminUi/SettingsPageController.php:132
     397#: includes/Features/Settings/AdminUi/SettingsPageController.php:129
    366398msgid "You can save adjustments from multiple tabs simultaneously."
    367399msgstr ""
    … …  
    375407msgstr ""
    376408
    377 #: includes/Features/Settings/Core/SettingsRegistrar.php:76
     409#: includes/Features/Settings/Core/SettingsRegistrar.php:81
    378410msgid "Shortcode Display Settings"
    379411msgstr ""
    380412
    381 #: includes/Features/Settings/Core/SettingsRegistrar.php:83
    382 msgid "Hide Core Shortcodes"
    383 msgstr ""
    384 
    385 #: includes/Features/Settings/Core/SettingsRegistrar.php:91
    386 msgid "Fallback Behavior"
    387 msgstr ""
    388 
    389 #: includes/Features/Settings/Core/SettingsRegistrar.php:112
     413#: includes/Features/Settings/Core/SettingsRegistrar.php:88
     414msgid "WordPress Core Shortcodes"
     415msgstr ""
     416
     417#: includes/Features/Settings/Core/SettingsRegistrar.php:120
    390418msgid "Scanner Configuration"
    391419msgstr ""
    392420
    393 #: includes/Features/Settings/Core/SettingsRegistrar.php:119
     421#: includes/Features/Settings/Core/SettingsRegistrar.php:127
    394422msgid "Posts Per Batch"
    395423msgstr ""
    396424
    397 #: includes/Features/Settings/Core/SettingsRegistrar.php:129
     425#: includes/Features/Settings/Core/SettingsRegistrar.php:135
     426msgid "Exclude Blocks from Scan"
     427msgstr ""
     428
     429#: includes/Features/Settings/Core/SettingsRegistrar.php:145
    398430msgid "Global plugin behaviors and data management."
    399431msgstr ""
    400432
    401 #: includes/Features/Settings/Core/SettingsRegistrar.php:138
     433#: includes/Features/Settings/Core/SettingsRegistrar.php:155
    402434msgid "Completely delete all toggles, scanner history, and data if you uninstall the plugin."
    403435msgstr ""
    404436
    405 #: includes/Features/Settings/Core/SettingsRegistrar.php:140
     437#: includes/Features/Settings/Core/SettingsRegistrar.php:158
    406438msgid "If unchecked (default), your configurations will be remembered if you ever deactivate/delete and then reinstall Shortcode Control later."
    407439msgstr ""
    408440
    409 #: includes/Features/Settings/Core/SettingsRegistrar.php:147
     441#: includes/Features/Settings/Core/SettingsRegistrar.php:166
    410442msgid "Configure how shortcodes are displayed and behave on your site."
    411443msgstr ""
    412444
    413 #: includes/Features/Settings/Core/SettingsRegistrar.php:156
    414 msgid "Hide WordPress Core shortcodes completely from the dashboard to reduce clutter"
    415 msgstr ""
    416 
    417 #: includes/Features/Settings/Core/SettingsRegistrar.php:167
    418 msgid "Show Raw Text (Default)"
    419 msgstr ""
    420 
    421 #: includes/Features/Settings/Core/SettingsRegistrar.php:169
    422 msgid "Hide Completely (Invisible)"
    423 msgstr ""
    424 
    425 #: includes/Features/Settings/Core/SettingsRegistrar.php:173
    426 msgid "Currently Active: Show Raw Text."
    427 msgstr ""
    428 
    429 #: includes/Features/Settings/Core/SettingsRegistrar.php:175
    430 msgid "Currently Active: Hide Completely."
    431 msgstr ""
    432 
    433445#: includes/Features/Settings/Core/SettingsRegistrar.php:178
    434 msgid "Choose what website visitors see when a shortcode is turned off:"
    435 msgstr ""
    436 
    437 #: includes/Features/Settings/Core/SettingsRegistrar.php:180
    438 msgid "Show Raw Text"
    439 msgstr ""
    440 
    441 #: includes/Features/Settings/Core/SettingsRegistrar.php:181
    442 msgid "The shortcode is neutralized for maximum security. Visitors will just see the bracketed text itself (e.g., [my_shortcode])."
    443 msgstr ""
    444 
    445 #: includes/Features/Settings/Core/SettingsRegistrar.php:183
    446 msgid "Hide Completely"
    447 msgstr ""
    448 
    449 #: includes/Features/Settings/Core/SettingsRegistrar.php:184
    450 msgid "The shortcode is replaced with a blank space invisibly. This keeps your web pages looking clean when disabling broken shortcodes."
    451 msgstr ""
    452 
    453 #: includes/Features/Settings/Core/SettingsRegistrar.php:192
     446msgid "Show WordPress Core shortcodes in the dashboard"
     447msgstr ""
     448
     449#: includes/Features/Settings/Core/SettingsRegistrar.php:182
     450msgid "If you show core shortcodes, be careful — WordPress relies on them (e.g. [gallery], [embed], [caption]) for built-in functionality. Accidentally disabling a core shortcode can break your site."
     451msgstr ""
     452
     453#: includes/Features/Settings/Core/SettingsRegistrar.php:191
    454454msgid "Configure how many posts are processed per scan request."
    455455msgstr ""
    456456
    457 #: includes/Features/Settings/Core/SettingsRegistrar.php:210
     457#: includes/Features/Settings/Core/SettingsRegistrar.php:209
    458458msgid "Higher values scan faster but can increase server load and timeout risk."
    459459msgstr ""
    460460
    461 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:37
    462 msgid "Remove from adopted state and revert to orphaned"
    463 msgstr ""
    464 
    465 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:38
    466 msgid "Unadopt"
    467 msgstr ""
    468 
    469 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:92
    470 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:155
     461#: includes/Features/Settings/Core/SettingsRegistrar.php:230
     462msgid "Custom HTML block <code>[wp:html]</code> — JS, CSS, raw HTML (recommended)"
     463msgstr ""
     464
     465#: includes/Features/Settings/Core/SettingsRegistrar.php:231
     466msgid "Code block <code>[wp:code]</code> — code snippets and tutorials"
     467msgstr ""
     468
     469#: includes/Features/Settings/Core/SettingsRegistrar.php:232
     470msgid "Preformatted block <code>[wp:preformatted]</code> — raw text content"
     471msgstr ""
     472
     473#: includes/Features/Settings/Core/SettingsRegistrar.php:233
     474msgid "Verse block <code>[wp:verse]</code> — poetry or bracketed notation"
     475msgstr ""
     476
     477#: includes/Features/Settings/Core/SettingsRegistrar.php:248
     478msgid "The scanner will skip the full content of checked block types. This reduces false positives from blocks that use brackets for non-shortcode purposes. Re-run a full scan after changing this."
     479msgstr ""
     480
     481#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:46
     482#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:54
     483#: includes/Features/StartHere/AdminUi/StartHerePageController.php:85
     484#: includes/Services/DataGrouper.php:59
     485msgid "Hidden"
     486msgstr ""
     487
     488#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:60
     489#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:69
     490msgid "Restore"
     491msgstr ""
     492
     493#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:63
     494#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:77
     495msgid "Hide"
     496msgstr ""
     497
     498#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:73
     499msgid "Disable"
     500msgstr ""
     501
     502#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:108
     503msgid "Run a scan to see usage counts"
     504msgstr ""
     505
     506#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:110
     507msgid "Run scan"
     508msgstr ""
     509
     510#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:114
     511msgid "Not used in any post"
     512msgstr ""
     513
     514#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:154
     515#: includes/Services/DataGrouper.php:46
     516msgid "Unknown Source"
     517msgstr ""
     518
     519#. translators: %s is a human-readable time difference, e.g. "3 days" or "2 hours".
     520#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:159
     521#, php-format
     522msgid "Deactivated %s ago"
     523msgstr ""
     524
     525#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:166
     526#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:167
    471527msgid "By "
    472528msgstr ""
    473529
    474 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:97
     530#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:171
    475531msgid "Fetching WordPress.org data..."
    476532msgstr ""
    477533
    478 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:99
    479 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:153
     534#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:173
     535#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:165
    480536msgid "Installs: "
    481537msgstr ""
    482538
    483 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:99
    484 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:154
     539#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:173
     540#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:166
    485541msgid "Updated: "
    486542msgstr ""
    487543
    488 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:101
    489 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:156
     544#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:175
     545#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:168
    490546msgid "Plugin not in WP.org repository (Premium or Custom)"
    491547msgstr ""
    492548
    493 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:114
     549#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:188
    494550msgid "Plugin has low installs or outdated. Consider using a more actively maintained plugin with 500+ installs, as security vulnerabilities are more likely to be reported and fixed in popular plugins with active bug bounty programs."
    495551msgstr ""
    496552
    497 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:116
     553#: includes/Features/ShortcodeManager/AdminUi/ShortcodesColumnRenderer.php:190
    498554msgid "Plugin is actively maintained with adequate installs."
    499555msgstr ""
    … …  
    503559msgstr ""
    504560
    505 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:58
    506 msgid "Source"
    507 msgstr ""
    508 
    509 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:157
     561#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:59
     562msgid "Used In"
     563msgstr ""
     564
     565#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:169
    510566msgid "Failed to connect to WP.org API"
    511567msgstr ""
    512568
    513 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:158
     569#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:170
    514570msgid "Saving..."
    515571msgstr ""
    516572
    517 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:161
     573#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:171
    518574msgid "Error"
    519575msgstr ""
    520576
    521 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:162
     577#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:172
    522578msgid "Network Error"
    523579msgstr ""
    524580
    525 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:163
     581#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:173
    526582msgid "Re-test"
    527583msgstr ""
    528584
    529 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:164
     585#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:174
    530586msgid "Testing..."
    531587msgstr ""
    532588
    533 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:165
     589#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:175
    534590msgid "ms"
    535591msgstr ""
    536592
    537 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:166
     593#: includes/Features/ShortcodeManager/AdminUi/ShortcodesPageController.php:176
    538594msgid "avg"
    539595msgstr ""
    540596
    541 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:18
    542 msgid "Manage Registered Shortcodes"
    543 msgstr ""
    544 
    545 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:19
    546 msgid "View all shortcodes from active plugins, themes, and WordPress core. Toggle individual shortcodes on/off, adopt orphaned ones, or manually manage their behavior."
    547 msgstr ""
    548 
    549 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:22
    550 msgid "Control which shortcodes are active or disabled across your entire WordPress installation."
    551 msgstr ""
    552 
    553 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:41
    554 msgid "Conflicts"
    555 msgstr ""
    556 
    557 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:51
    558 msgid "Search Shortcodes:"
    559 msgstr ""
    560 
    561 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:53
     597#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:27
     598msgid "Registered Shortcodes come from active plugins, themes, and WordPress core. Orphaned Shortcodes come from plugins that are no longer active."
     599msgstr ""
     600
     601#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:29
     602msgid "Control which shortcodes are active or suppressed across your WordPress installation."
     603msgstr ""
     604
     605#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:34
     606msgid "How To Use This Page"
     607msgstr ""
     608
     609#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:35
     610msgid "Registered shortcodes can be Enabled, Disabled, or Hidden. Orphaned shortcodes come from deactivated plugins — you can Silence them (output nothing) or Restore them."
     611msgstr ""
     612
     613#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:61
     614msgid "Search shortcodes:"
     615msgstr ""
     616
     617#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:63
    562618msgid "Search by tag or source..."
    563619msgstr ""
    564620
    565 #. translators: %d: number of shortcodes with multiple registrations
    566 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:84
    567 #, php-format
    568 msgid "Conflict Found: %d shortcode has multiple registrations"
    569 msgid_plural "Conflicts Found: %d shortcodes have multiple registrations"
    570 msgstr[0] ""
    571 msgstr[1] ""
    572 
    573 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:88
    574 msgid "Multiple plugins or themes have registered the same shortcode tag. Only the last-registered version is active."
    575 msgstr ""
    576 
    577 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:131
    578 msgid "Caution Before Disabling Core Shortcodes"
    579 msgstr ""
    580 
    581 #: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:134
    582 msgid "WordPress heavily relies on native shortcodes like [gallery], [embed], and [caption] to process rich-text editor data. Additionally, other plugins may depend on these core shortcodes for their functionality. Disabling them may break website functionality. Only proceed if you fully understand the consequences."
     621#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:74
     622#: includes/Features/StartHere/AdminUi/StartHerePageController.php:69
     623msgid "Registered Shortcodes"
     624msgstr ""
     625
     626#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:92
     627msgid "Orphaned Shortcodes"
     628msgstr ""
     629
     630#: includes/Features/ShortcodeManager/AdminUi/ShortcodesTemplate.php:93
     631msgid "These shortcodes come from plugins that are no longer active. They will output raw text unless silenced. Use Hide to suppress them."
    583632msgstr ""
    584633
    … …  
    590639msgstr ""
    591640
    592 #: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:200
    593 #: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:227
    594 #: includes/Services/StatusHelper.php:79
    595 msgid "Unknown"
    596 msgstr ""
    597 
    598641#. translators: %s: formatted number of downloads
    599642#: includes/Features/ShortcodeManager/Core/WpOrgBatchFetcher.php:222
    … …  
    602645msgstr ""
    603646
    604 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:121
     647#: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:97
    605648msgid "Invalid parameters"
    606649msgstr ""
    607650
    608 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:130
    609 msgid "Toggle failed"
    610 msgstr ""
    611 
    612 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:143
    613 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:170
    614 msgid "Tag cannot be empty"
    615 msgstr ""
    616 
    617 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:155
    618 msgid "Orphan adopted successfully"
    619 msgstr ""
    620 
    621 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:158
    622 msgid "Failed to adopt orphan"
    623 msgstr ""
    624 
    625 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:181
    626 msgid "Orphan unadopted successfully"
    627 msgstr ""
    628 
    629 #: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:184
    630 msgid "Failed to unadopt orphan"
    631 msgstr ""
    632 
    633 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:66
    634 msgid "Welcome to Foureyed Shortcode Control"
    635 msgstr ""
    636 
    637 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:68
    638 msgid "Take control of your site's shortcodes. Discover, manage, and protect what runs on your site."
    639 msgstr ""
    640 
    641 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:76
    642 msgid "Registered Shortcodes"
    643 msgstr ""
    644 
    645 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:80
    646 msgid "Total Shortcodes"
    647 msgstr ""
    648 
    649 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:92
     651#: includes/Features/ShortcodeManager/Rest/ShortcodesRestController.php:106
     652msgid "Status update failed"
     653msgstr ""
     654
     655#: includes/Features/StartHere/AdminUi/StartHerePageController.php:65
     656msgid "Overview of your site's shortcodes and scan results. Use the menu links to manage or scan."
     657msgstr ""
     658
     659#: includes/Features/StartHere/AdminUi/StartHerePageController.php:94
    650660msgid "Content Scan Results"
    651661msgstr ""
    652662
    653 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:95
    654 msgid "No scan has been run yet. Run a scan to detect orphaned shortcodes hiding in your content."
    655 msgstr ""
    656 
    657 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:96
    658 msgid "Start your first scan →"
    659 msgstr ""
    660 
    661 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:102
     663#: includes/Features/StartHere/AdminUi/StartHerePageController.php:97
     664msgid "No scan has been run yet."
     665msgstr ""
     666
     667#: includes/Features/StartHere/AdminUi/StartHerePageController.php:98
     668msgid "Run your first scan →"
     669msgstr ""
     670
     671#: includes/Features/StartHere/AdminUi/StartHerePageController.php:104
    662672msgid "Total Findings"
    663673msgstr ""
    664674
    665 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:106
    666 msgid "Active in Content"
    667 msgstr ""
    668 
    669 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:110
    670 msgid "Disabled in Content"
    671 msgstr ""
    672 
    673 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:117
    674 msgid "View →"
     675#: includes/Features/StartHere/AdminUi/StartHerePageController.php:108
     676#: includes/Services/StatusHelper.php:38
     677#: includes/Services/StatusHelper.php:73
     678msgid "Active"
     679msgstr ""
     680
     681#: includes/Features/StartHere/AdminUi/StartHerePageController.php:121
     682msgid "Pages"
     683msgstr ""
     684
     685#: includes/Features/StartHere/AdminUi/StartHerePageController.php:125
     686msgid "Enable, disable, or hide any shortcode on your site with one click."
    675687msgstr ""
    676688
    677689#: includes/Features/StartHere/AdminUi/StartHerePageController.php:127
    678 msgid "Here's What You Can Do"
     690#: includes/Features/StartHere/AdminUi/StartHerePageController.php:134
     691#: includes/Features/StartHere/AdminUi/StartHerePageController.php:141
     692msgid "Open →"
     693msgstr ""
     694
     695#: includes/Features/StartHere/AdminUi/StartHerePageController.php:131
     696msgid "Scanner"
    679697msgstr ""
    680698
    681699#: includes/Features/StartHere/AdminUi/StartHerePageController.php:132
    682 msgid "1. Manage Shortcodes"
    683 msgstr ""
    684 
    685 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:136
    686 msgid "See all registered shortcodes on your site and control which ones are active."
    687 msgstr ""
    688 
    689 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:138
    690 msgid "View every shortcode with details: name, source, plugin, version"
     700msgid "Scan your posts and pages to find orphaned shortcodes left by removed plugins."
    691701msgstr ""
    692702
    693703#: includes/Features/StartHere/AdminUi/StartHerePageController.php:139
    694 msgid "Turn any shortcode on or off with one click"
    695 msgstr ""
    696 
    697 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:140
    698 msgid "Disable unused shortcodes safely"
    699 msgstr ""
    700 
    701 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:141
    702 msgid "Disable broken shortcodes safely (broken shortcode need to be adopted first)"
    703 msgstr ""
    704 
    705 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:142
    706 msgid "See status badges: Active, Disabled, Conflicts"
    707 msgstr ""
    708 
    709 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:146
    710 msgid "View All Shortcodes →"
    711 msgstr ""
    712 
    713 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:151
    714 msgid "Pro Tip:"
    715 msgstr ""
    716 
    717 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:152
    718 msgid "Disabling a shortcode doesn't delete it—you can re-enable it anytime. It just won't run on the front-end. You could choose to return literal text or hide it completely from settings"
    719 msgstr ""
    720 
    721 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:159
    722 msgid "2. Find Orphaned Shortcodes"
    723 msgstr ""
    724 
    725 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:163
    726 msgid "Scan your entire site to find orphaned shortcodes that don't have a plugin anymore."
    727 msgstr ""
    728 
    729 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:165
    730 msgid "Scan all posts and pages for orphaned shortcodes"
    731 msgstr ""
    732 
    733 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:166
    734 msgid "See exactly which posts have broken shortcodes"
    735 msgstr ""
    736 
    737 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:167
    738 msgid "View the actual shortcode code found in your content"
    739 msgstr ""
    740 
    741 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:168
    742 msgid "Click edit link to open editor and manually remove shortcode if you want"
    743 msgstr ""
    744 
    745 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:169
    746 msgid "Non-destructive: Scanning never deletes or modifies content"
    747 msgstr ""
    748 
    749 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:173
    750 msgid "Scan Your Site →"
    751 msgstr ""
    752 
    753 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:178
    754 msgid "Safe to Run:"
    755 msgstr ""
    756 
    757 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:179
    758 msgid "The scanner is completely safe and won't slow down your site. It runs in the background."
    759 msgstr ""
    760 
    761 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:186
    762 msgid "3. Tools & Settings"
    763 msgstr ""
    764 
    765 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:190
    766 msgid "Configure how Shortcode Control works and access maintenance tools."
    767 msgstr ""
    768 
    769 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:192
    770 msgid "Hide core WordPress shortcodes from the list"
    771 msgstr ""
    772 
    773 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:193
    774 msgid "Access maintenance and troubleshooting tools"
    775 msgstr ""
    776 
    777 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:194
    778 msgid "Configure plugin preferences"
    779 msgstr ""
    780 
    781 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:198
    782 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:266
    783 msgid "Go to Settings →"
    784 msgstr ""
    785 
    786 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:203
    787 msgid "Info:"
    788 msgstr ""
    789 
    790 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:204
    791 msgid "Settings are optional—defaults are safe for most sites."
    792 msgstr ""
    793 
    794 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:211
    795 msgid "Key Things to Know"
    796 msgstr ""
    797 
    798 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:215
    799 msgid "🔒 Safe & Reversible"
    800 msgstr ""
    801 
    802 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:216
    803 msgid "Everything Shortcode Control does can be undone (unless you manually delete shortcode from editor). Disabling shortcodes is safe and doesn't delete data."
    804 msgstr ""
    805 
    806 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:220
    807 msgid "⚡ Zero Frontend Impact"
    808 msgstr ""
    809 
    810 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:221
    811 msgid "The heavy lifting only runs in each module pages. Your site's front-end performance is almost never affected. (we do need to run on front end to disable shortcode, but it only add less than a millisecond to page load)"
    812 msgstr ""
    813 
    814 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:225
    815 msgid "👤 Admin Only"
    816 msgstr ""
    817 
    818 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:226
    819 msgid "Only administrators with \"manage_options\" capability can access Shortcode Control. Your team content creators can't see this page, or any other page from this plugin"
    820 msgstr ""
    821 
    822 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:235
    823 msgid "Ready to Get Started?"
    824 msgstr ""
    825 
    826 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:241
    827 msgid "Explore Your Shortcodes"
    828 msgstr ""
    829 
    830 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:242
    831 msgid "Go to \"Manage Shortcodes\" to see what's installed on your site."
    832 msgstr ""
    833 
    834 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:244
    835 msgid "Open Manage Shortcodes →"
    836 msgstr ""
    837 
    838 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:252
    839 msgid "Scan for Broken Shortcodes"
    840 msgstr ""
    841 
    842 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:253
    843 msgid "Run a scan to find any orphaned or broken shortcodes in your content."
    844 msgstr ""
    845 
    846 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:255
    847 msgid "Start Scanner →"
    848 msgstr ""
    849 
    850 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:263
    851 msgid "Customize Settings"
    852 msgstr ""
    853 
    854 #: includes/Features/StartHere/AdminUi/StartHerePageController.php:264
    855 msgid "Visit Settings to configure plugin behavior to match your needs."
    856 msgstr ""
    857 
    858 #: includes/Services/DataGrouper.php:35
     704msgid "Configure plugin behaviour. Defaults are safe — only change if needed."
     705msgstr ""
     706
     707#: includes/Services/DataGrouper.php:43
    859708msgid "From plugins"
    860709msgstr ""
    861710
    862 #: includes/Services/DataGrouper.php:36
     711#: includes/Services/DataGrouper.php:44
    863712msgid "From themes"
    864713msgstr ""
    865714
    866 #: includes/Services/DataGrouper.php:38
     715#: includes/Services/DataGrouper.php:45
     716msgid "Discovered Orphans"
     717msgstr ""
     718
     719#: includes/Services/DataGrouper.php:47
    867720msgid "From WordPress core"
    868721msgstr ""
     722
     723#: includes/Services/DataGrouper.php:57
     724msgid "⚠ Needs Attention — Deactivated & In Use"
     725msgstr ""
     726
     727#: includes/Services/DataGrouper.php:178
     728msgid "Shortcodes"
     729msgstr ""
     730
     731#: includes/Services/ShortcodeFormatter.php:27
     732msgid "Plugin Shortcode"
     733msgstr ""
     734
     735#: includes/Services/ShortcodeFormatter.php:29
     736msgid "Theme Shortcode"
     737msgstr ""
     738
     739#: includes/Services/ShortcodeFormatter.php:31
     740msgid "WordPress Shortcode"
     741msgstr ""
     742
     743#: includes/Services/ShortcodeFormatter.php:33
     744msgid "Discovered Orphan"
     745msgstr ""
     746
     747#: includes/Services/ShortcodeFormatter.php:36
     748msgid "Registered"
     749msgstr ""
  • foureyed-shortcode-control/trunk/readme.txt

    r3523952 r3524967  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.0.3
     7Stable tag: 1.0.4
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    6262== Changelog ==
    6363
     64= 1.0.4 =
     65* Feature: Scan exception — exclude Gutenberg block types (Custom HTML, Code, Preformatted, Verse) from scanner to reduce false positives
     66* Improve: Manager redesign — two-table layout (Registered / Orphaned) with unified filter tabs and search
     67* Improve: Manager filter tabs now on left, search field on right (consistent with Scanner)
     68* Improve: Start Here stats card shows all 5 status counts (All, Enabled, Disabled, Hidden, Orphaned)
     69* Improve: Start Here stats respect the "hide core shortcodes" setting, matching Manager counts
     70* Fix: Manager source column shows "Unknown Source" for numeric/unknown orphan tags instead of wrong plugin name
     71* Fix: Scanner silenced orphan shows "Silenced" badge instead of "Orphaned"
     72
    6473= 1.0.3 =
    6574* Fix: Strip Gutenberg block comments before scanning to prevent false positive numeric shortcode matches
Note: See TracChangeset for help on using the changeset viewer.