get_site_options(); $ai_quota = (is_object($site_options) && isset($site_options->aiQuota)) ? $site_options->aiQuota : null; $is_preview = !$gated && $ai_quota !== null; $data = null; $err = null; if ($gated || $is_preview) { $resp = $client->get_plugin_images(array( 'page' => $page, 'perPage' => $perPage, 'filter' => $filter, )); if (is_wp_error($resp)) { $err = $resp->get_error_message(); } else { $data = $resp; } } AllAccessible_Debug::console('ImageManagerPage', array( 'gated' => $gated, 'filter' => $filter, 'page' => $page, 'per_page' => $perPage, 'is_error' => $err !== null, 'error' => $err, 'data_keys' => is_array($data) ? array_keys($data) : null, 'image_count' => is_array($data) && isset($data['images']) ? count($data['images']) : null, 'total' => is_array($data) && isset($data['total']) ? $data['total'] : null, )); ?>
__('Image alt text is available on paid plans', 'allaccessible'), 'description' => __('Upgrade to review, refine, and approve every alt text on your site. Includes inline editing, manual overrides, and full media library coverage.', 'allaccessible'), )); ?>


0 ? (int) round(($with_alt / $total) * 100) : 0; $covered = $pct >= 80; ?>
0) : ?>
__('All images', 'allaccessible'), 'missing' => __('Missing alt', 'allaccessible'), 'ai' => __('AI-suggested', 'allaccessible'), 'manual' => __('Manual', 'allaccessible'), ); $base_url = admin_url('admin.php?page=' . self::PAGE_SLUG); ?>

' . esc_html__('No alt text yet.', 'allaccessible') . ''; } elseif ($text !== '') { echo esc_html($text); } else { echo esc_html($ai_text); } ?>

' . esc_html__('Needs alt', 'allaccessible') . ''; } return '' . esc_html__('Set', 'allaccessible') . ''; } private static function filename_from_url($url, $id) { if (!$url) { return sprintf( /* translators: %d = image ID */ __('Image #%d', 'allaccessible'), (int) $id ); } $parts = wp_parse_url($url); $path = isset($parts['path']) ? $parts['path'] : ''; $name = basename($path); if ($name === '' || $name === '/') { return sprintf(__('Image #%d', 'allaccessible'), (int) $id); } return $name; } private static function shorten_url($url) { $parts = wp_parse_url($url); $path = isset($parts['path']) ? $parts['path'] : $url; return mb_strlen($path) > 40 ? mb_substr($path, 0, 37) . '…' : $path; } /* ─── Free-tier preview (Aikido-style blur teaser) ──────────────── */ /** * Top banner for free-tier preview mode. */ private static function render_preview_banner($ai_quota) { $used = (int) ($ai_quota->altTextUsed ?? 0); $max = (int) ($ai_quota->altTextMax ?? 10); ?>

altTextMax ?? 10); $idx = 0; ?>
= $max; if ($is_locked) { echo ''; } $idx++; endforeach; ?>
$max) : ?>

$filter); if ($search !== '') $q['q'] = $search; ?> for focus trap) ──────────────── */ private static function render_edit_modal() { ?>


__('Insufficient permissions', 'allaccessible')), 403); } check_ajax_referer(self::NONCE_NAME); $image_id = isset($_POST['image_id']) ? (int) $_POST['image_id'] : 0; $text = isset($_POST['text']) ? wp_unslash($_POST['text']) : ''; $text = is_string($text) ? sanitize_text_field($text) : ''; if ($image_id <= 0) { wp_send_json_error(array('message' => __('Invalid image ID', 'allaccessible')), 400); } if ($text === '' || mb_strlen($text) > 500) { wp_send_json_error(array('message' => __('Alt text must be 1–500 characters', 'allaccessible')), 400); } $client = AllAccessible_ApiClient::get_instance(); $result = $client->override_image_alt_text($image_id, $text); if (is_wp_error($result)) { $err_data = $result->get_error_data(); $upstream = is_array($err_data) && isset($err_data['status']) ? (int) $err_data['status'] : 0; $status = ($upstream >= 400 && $upstream < 600) ? $upstream : 502; wp_send_json_error( array( 'message' => $result->get_error_message(), 'code' => $result->get_error_code(), 'upstream' => $upstream ?: null, ), $status ); } wp_send_json_success($result); } } add_action('plugins_loaded', function() { AllAccessible_ImageManager_Page::register(); });