=== Comic Collector ===
Contributors: dustinlincoln
Tags: comics, collection, woocommerce, comic books, inventory
Requires at least: 6.2
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 2.6.8
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Manage your comic book collection. Track, organize, price, and sell your comics with WooCommerce integration.

== Description ==

Comic Collector turns your WordPress site into a full-featured comic book collection manager. Whether you have 50 comics or 50,000, Comic Collector helps you catalog, value, and showcase your collection.

**Core Features**

* Add comics with title, issue number, publisher, grade, variant type, purchase price, and more
* Automatic pricing powered by eBay sold listing data
* Public-facing collection shortcode with search, filters, A-Z navigation, and pagination
* WooCommerce integration for listing comics for sale directly from your collection
* CSV, XML, and PDF export for insurance, inventory, or sharing
* Bulk operations for managing large collections efficiently
* REST API for building custom integrations or mobile apps
* Gutenberg blocks and Elementor widgets for flexible page building
* Multi-currency support with automatic exchange rate conversion
* Progressive Web App (PWA) support for mobile-friendly access
* CSS variable theming system for matching your site design
* Custom fields for tracking any additional data you need
* Community annotations for shared knowledge on individual issues

**Public Collection Display**

Use the `[comic_collection]` shortcode to display your collection on any page. Visitors can search by title, filter by publisher, browse A-Z, and paginate through large collections. Comics listed for sale link directly to your WooCommerce product pages.

**Pricing Engine**

Comic Collector fetches recent eBay sold listing data to estimate current market values. Pricing runs on a configurable schedule or on demand. Supports eBay, GoCollect, and PriceCharting as data sources.

**Extension Ecosystem**

Comic Collector supports premium extensions that add specialized functionality:

* Analytics and value tracking over time
* Grading submission preparation and tracking
* Barcode scanning for quick lookups
* Lot sales and bundling
* Print run and rarity estimation
* Reading lists and progress tracking
* Wishlist monitoring with deal alerts
* Make-an-offer system for buyers
* Convention mode for shows and events
* And more

== Installation ==

1. Upload the `comic-collector` folder to the `/wp-content/plugins/` directory, or install directly through the WordPress plugin screen.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Navigate to Comic Collector in the admin menu to start adding comics.
4. (Optional) Install and activate WooCommerce to enable selling features.
5. (Optional) Add the `[comic_collection]` shortcode to any page to display your collection publicly.

== Frequently Asked Questions ==

= Do I need WooCommerce? =

No. WooCommerce is optional and only needed if you want to sell comics directly from your site. All collection management features work without it.

= How does pricing work? =

Comic Collector uses the eBay Browse API to look up recent sold listings for each comic in your collection. You need a free eBay developer API key, which you can configure in Settings > API Keys.

= Can visitors see my collection? =

Only if you add the `[comic_collection]` shortcode to a page. You control what is visible through the plugin settings.

= Does this work with page builders? =

Yes. Comic Collector includes Gutenberg blocks and Elementor widgets. The shortcode also works in any page builder that supports WordPress shortcodes.

= What data is sent to external services? =

Comic Collector connects to eBay, Comic Vine, GoCollect, and PriceCharting APIs to fetch pricing and metadata. These connections are user-initiated (via settings or manual actions) and only send the comic title/issue information needed for the lookup. No personal data is transmitted. Each service requires its own API key configured in Settings > API Keys.

== External Services ==

This plugin connects to the following third-party services. All connections are initiated by the site administrator via settings or manual actions — no data is sent automatically without configuration. No personal visitor data is transmitted.

**eBay Browse API**
Used to fetch recent sold listing prices for comics to estimate current market values. Sends the comic title and issue number as a search query. Requires a free eBay developer API key.
- Service URL: https://api.ebay.com/
- eBay Developer Terms: https://developer.ebay.com/join/api-license-agreement
- eBay Privacy Policy: https://www.ebay.com/help/policies/member-behaviour-policies/user-privacy-notice-privacy-policy

**GoCollect**
Used as an optional pricing data source. Sends the comic title and issue number to look up market values. Requires a GoCollect API key.
- Service URL: https://gocollect.com/
- GoCollect Terms of Service: https://gocollect.com/terms-of-service
- GoCollect Privacy Policy: https://gocollect.com/privacy-policy/

**PriceCharting**
Used as an optional pricing data source. Sends the comic title and issue number to look up market prices. Requires a PriceCharting API key.
- Service URL: https://www.pricecharting.com/
- PriceCharting Terms of Service: https://www.pricecharting.com/page/terms-of-service
- PriceCharting Privacy Policy: https://www.pricecharting.com/page/privacy-policy

**CGC Comics (Certified Guaranty Company)**
Used to look up grading certification details and census population data by certificate number. Sends the cert number or comic title/issue as a search query to CGC's public API. No authentication is required — census data is publicly accessible.
- Service URL: https://api.aws.ccg-ops.com/api
- Website: https://www.cgccomics.com/
- CGC Privacy Policy: https://www.cgccomics.com/privacy-policy/

**CBCS Comics (Comic Book Certification Service)**
Used to look up grading certification details by certificate number. Sends the cert number entered by the user.
- Service URL: https://www.cbcscomics.com/
- CBCS Privacy Policy: https://cbcscomics.com/privacy-policy/

**PGX Comics**
Used to look up grading certification details by certificate number. Sends the cert number entered by the user.
- Service URL: https://www.pgxcomics.com/
- PGX Legal Information: https://pgxcomics.com/legal-information-2/

**Twilio**
Used to send SMS notifications for pull list release alerts. When configured, sends the recipient phone number and a short text message summarizing new releases. Requires a Twilio account SID, auth token, and phone number, configured in the Wishlist Alerts extension settings. No SMS is sent without explicit admin configuration.
- Service URL: https://api.twilio.com/
- Twilio Terms of Service: https://www.twilio.com/en-us/legal/tos
- Twilio Privacy Policy: https://www.twilio.com/en-us/legal/privacy

**Google S2 Favicons**
Used to display publisher logos in the admin dashboard's Publisher Breakdown widget. The admin browser loads a small favicon image for known publisher website domains (e.g. marvel.com); no collection or personal data is sent. Images load only on the plugin's admin dashboard.
- Service URL: https://www.google.com/s2/favicons
- Google Privacy Policy: https://policies.google.com/privacy

**Comic Vine (Fandom/GameSpot)**
Used to fetch comic book metadata, series information, and cover images. Sends the comic title and issue number as a search query. Requires a free Comic Vine API key.
- Service URL: https://comicvine.gamespot.com/api/
- Fandom Privacy Policy: https://www.fandom.com/privacy-policy

**Open Library (Internet Archive)**
Used to fetch book metadata and cover images via ISBN barcode lookup. Sends the ISBN/barcode number entered by the user.
- Service URL: https://openlibrary.org/
- Internet Archive Privacy Policy: https://archive.org/about/terms.php

**Metron Cloud**
Used as an optional comic database source for issue and series metadata. Sends the comic title and issue number. Requires a Metron account.
- Service URL: https://metron.cloud/
- Metron Privacy Policy: https://metron.cloud/privacy/

**Grand Comics Database (GCD)**
Used as an optional comic database source for issue and series metadata. Sends the comic title and issue number as a search query.
- Service URL: https://www.comics.org/
- GCD Privacy Policy: https://www.comics.org/privacy/

**ExchangeRate-API**
Used to fetch current currency exchange rates for multi-currency support. Sends no user data — only fetches the latest USD base rates.
- Service URL: https://www.exchangerate-api.com/
- ExchangeRate-API Privacy Policy: https://www.exchangerate-api.com/privacy

**DustinLincoln.com License Server**
Used to manage premium extension licenses. When the administrator activates, deactivates, or validates a license key, the plugin sends the license key, site URL, and product slug to the license server. When installing a premium extension, the plugin sends the extension slug and license key to download the extension package. No visitor data is transmitted — these requests only occur during admin-initiated license actions.
- Service URL: https://dustinlincoln.com/wp-json/cc-license/v1/
- Terms of Service: https://dustinlincoln.com/comic-collector/terms-of-service/
- Privacy Policy: https://dustinlincoln.com/comic-collector/privacy-policy/

**Google Fonts**
Used when the administrator selects a Google Font in the theme settings. Loads the chosen font from Google's servers. The visitor's IP address is transmitted to Google as part of the font request.
- Service URL: https://fonts.googleapis.com/
- Google Privacy Policy: https://policies.google.com/privacy

== Screenshots ==

1. Main collection dashboard with filters and bulk actions
2. Add/edit comic form with all metadata fields
3. Public collection shortcode with search and filters
4. Pricing engine with eBay sold listing data
5. WooCommerce integration for selling comics

== Changelog ==

= 2.6.8 =
* Fix: the PWA service worker (cc-sw.js) and web app manifest (cc-manifest.json) were unreachable on sites with trailing-slash permalinks — WordPress 301-redirected them to a trailing-slash URL, and browsers refuse to register a service worker served behind a redirect. Offline/PWA support now works on such sites

= 2.6.7 =
* New: eBay Marketplace setting (Settings → General) — choose your local eBay site (US, UK, Canada, Australia, Germany, France, Italy, Spain). All eBay buy/search/sell links across the plugin now open on your local site with the correct regional affiliate attribution
* Fix: price inputs now accept European number formats — "12,50" is read as 12.50 instead of 1250, and "1.234,56" as 1234.56. Applies everywhere prices are entered (purchase price, cover price, listing price, etc.)
* Fix: eBay affiliate tracking is now applied to all regional eBay domains (ebay.co.uk, ebay.de, …) — previously only ebay.com links were wrapped
* Note: estimated values continue to use US sold data (the reference market for comic pricing) converted to your display currency

= 2.6.6 =
* Pricing fix: cached PriceCharting product matches are now verified against the comic's title and issue on every lookup — a stale or wrong cached match can no longer price the wrong product (the cause of wildly wrong values like a $4 book showing $200+)
* Pricing fix: when a cached PriceCharting match fails or is rejected, the engine now falls back to a fresh search instead of silently losing its primary source
* Pricing fix: eBay comps for a standard-cover comic now exclude variant/incentive listings (1:25, virgin, foil, Cover B, etc.) — ratio variants listing at many multiples of the standard cover were poisoning values
* Pricing safeguard: weak data (active-listing asks with no PriceCharting/GoCollect/eBay-sold corroboration) can no longer move a comic's value by more than 50% — the existing value is kept and the comic is flagged for review with the proposed value stored in the audit trail
* Pricing fix: when two same-name series tie in match scoring (e.g. "Little Monsters" 2020 vs 2022), the product with actual market data now wins instead of whichever came first
* Currency: listing prices are now converted from USD to the WooCommerce store currency when the store isn't set to USD — previously a $25 comic on a £/€/¥ store was listed as £25/€25/¥25
* Currency: manually entered listing prices are treated as store-currency amounts (what the buyer should see) and converted to USD internally
* Currency: completed-order sale prices are converted from the store currency back to USD so sold-archive revenue and profit stay consistent with USD costs
* Pricing accuracy: graded comics are now valued at their ACTUAL slab grade. PriceCharting's per-grade price ladder (Ungraded through 10.0) is matched to the comic's grade with interpolation between grade anchors — previously every slab used the 8.0/8.5 price regardless of grade
* Pricing accuracy: GoCollect is now used for slabbed comics only — its graded fair-market values were previously applied to raw comics, ignoring the slab premium
* Pricing accuracy: eBay active-listing comps are now restricted to fixed-price US listings — in-progress auctions (current bid, not market price) no longer drag values down
* Pricing accuracy: sold-listing comps no longer discard repeated identical sale prices, and the lookback window now widens to 90 days instead of all-time when recent data is thin
* Pricing accuracy: a variant priced from its standard cover's data (no variant-specific match) is now flagged low-confidence instead of silently trusted
* Pricing: price confidence can now reach "high" when PriceCharting and an independent sold/FMV source agree within 25%
* Pricing reliability: eBay scraping now backs off for 12 hours after repeated HTTP failures instead of burning two requests per comic per refresh (manual refresh still retries)
* Pricing reliability: GoCollect calls are capped at 45/day to stay inside the free tier instead of failing mid-batch
* Pricing observability: per-source hit rates (7 days) now display on the dashboard Tools card, and cron price updates now store the same audit trail as manual refreshes
* New: price sample size (number of market data points behind each value) is stored per comic for liquidity-aware analytics
* Maintenance: price history table is now purged daily (raw source samples kept 30 days, value timeline kept 365 days)
* Manual price refresh no longer discards the cached PriceCharting product match — the divergence check evicts bad matches automatically

= 2.6.4 =
* Dashboard: Publisher Breakdown now shows each publisher's logo (with a colored-initial fallback for unrecognized publishers)
* Dashboard: added shared cover-thumbnail styles used by Pro extension widgets (Pull List, Reading List, Offers, Print Run Estimator)

= 2.6.3 =
* Dashboard: new Recent Additions widget — a cover-art strip of the latest comics added to your collection (toggleable from Customize)
* Dashboard: Key Issues widget now shows cover thumbnails next to each issue
* Dashboard: added a Scan button to the header toolbar when the Inventory Scanner Pro extension is active

= 2.6.2 =
* Security: removed unused remote extension-installer code left over from the retired marketplace (PHP handler and all related admin JS)
* Security: added a capability check to the duplicate-comic AJAX lookup
* Security: hardened the PWA service worker endpoint with proper 404/500 handling
* Fixed the comcol_comic_sold action firing twice with inconsistent argument order on WooCommerce sales — listeners now always receive (comic_id, sale_price, order_id)
* Fixed duplicate sold-archive rows and double profit accounting when an order passed through both processing and completed statuses
* Fixed the database schema upgrade routine running on every admin page load
* Internationalization: wrapped all user-facing strings (admin notices, public collection page, offer and annotation forms, emails) for translation, and enabled JS translations via wp.i18n — the plugin is now fully translation-ready

= 2.6.1 =
* Removed forced "Powered by Comic Collector" from user-facing offer emails — only the site/store name is shown
* Added CSS-specific sanitization for theme settings (card shadow, border radius, font family) to prevent CSS injection
* Changed /extensions REST endpoint to require edit_posts capability instead of public access
* Fixed /search REST endpoint exposing estimated_value to unauthenticated users when public value display is disabled
* Added Twilio SMS service disclosure to External Services documentation
* Updated CGC entry to reference the actual API endpoint (api.aws.ccg-ops.com)

= 2.6.0 =
* Added automatic AI model fallback — if one provider returns a quota/rate-limit error (429), automatically retries with the next configured model
* Overhauled AI Insights system prompt to produce actionable, section-based insights instead of generic summaries
* AI Insights now surfaces sell opportunities, hidden gems, portfolio risk, grading candidates, and declining values
* Increased AI max tokens from 800 to 1200 to support richer structured output
* Hardened eBay affiliate tracking — centralized EPN campaign ID with obfuscation and integrity verification
* Removed plaintext affiliate IDs from all plugin source files
* All extensions now use centralized COMCOL_eBay methods for affiliate URL generation

= 2.5.9 =
* Updated AI model preferences to current free-tier-compatible models (gemini-2.0-flash, gpt-4o-mini)
* Added comcol_ai_model_preference filter hook for customizing AI model fallback order
* Centralized model preference into reusable get_model_preference() method

= 2.5.8 =
* Fixed all WordPress.org plugin check errors for escape output compliance
* Fixed unescaped output in Pull List admin tabs, AI settings, Pull List shortcode
* Fixed unescaped output in Elementor Comic Display, Stats, and Grid widgets
* Fixed SQL security scanner errors in Pull List query builder with phpcs annotations
* Restructured Elementor widget render methods for scanner compatibility

= 2.5.7 =
* Fixed WordPress.org plugin check security warnings in Activity Log query builder
* Updated "Tested up to" to WordPress 7.0

= 2.5.6 =
* Added filter hook for variant cover data so Pro can supplement from LOCG releases
* Changed "Pulled" status label to "Owned" across all admin and frontend displays
* Enlarged variant cover thumbnails from 32x48 to 40x60 with border styling
* Added dark mode border color for variant cover thumbnails
* Removed loading="lazy" from variant cover images inside expandable panels
* Removed duplicate description field from variant cover API requests

= 2.5.5 =
* Pull list variant covers display and label improvements

= 2.5.4 =
* Pull list enhancements and bug fixes

= 2.4.0 =
* Added Activity Log — tracks all collection changes (add, edit, delete, sell) with timestamps and details
* Added Activity Log admin page with filterable table, pagination, and clear old entries
* Added Activity Log retention setting in Settings > General
* Added WordPress admin dashboard widget showing collection stats, recent adds, and recent sales
* Added GoCollect CSV import — upload GoCollect exports with auto-detected column mapping
* Added Comic Vine JSON import — upload Comic Vine API response files with cover download support
* Expanded Import page with format auto-detection (XML/CSV/JSON) and per-format documentation
* Improved deduplication across all import formats (barcode, Comic Vine ID, title+issue+publisher)

= 2.3.0 =
* Added Dark Mode — enable separately for admin pages and public collection via Settings > General
* Added frontend dark mode for the public-facing collection shortcode
* Added duplicate detection warnings when adding comics that match existing entries
* Added eBay listing integration with "List on eBay" button for one-click pre-filled listings
* Added eBay affiliate tracking to support continued plugin development

= 2.2.0 =
* Added AI-powered comic identification from cover photos (requires WordPress 7.0+)
* Added AI smart search for natural-language wishlist queries
* Added AI collection insights and lot description generation
* Added AI settings section with usage tracking and rate limiting
* Fixed duplicate plugin folder creation on ZIP upload (upgrader_source_selection filter)
* Fixed "Type ERASE to confirm" input truncation in Danger Zone settings

= 2.1.2 =
* Major pricing accuracy overhaul
* Search queries now include volume and year for precise series disambiguation
* PriceCharting results validated against requested issue number to prevent cross-issue contamination
* Fixed cache key collisions that caused consecutive issues to share prices
* Lot/bundle listings filtered from eBay sold data for raw comics
* eBay searches narrowed to Comic Books category (259104) with negative keyword filtering
* Source weight rebalancing — PriceCharting and GoCollect weighted higher as trusted references
* Divergence filtering discards eBay outliers when they conflict with reference sources
* Recentered condition multiplier baseline from NM (9.4) to VF (8.0) to match eBay sold averages
* Raised scraping price floor from $1 to $3 to exclude junk listings

= 2.1.0 =
* Added multi-currency support with automatic exchange rate conversion
* Added Metron, GCD, and Open Library as additional data sources
* Added A-Z alphabet filter to public collection shortcode
* Added community annotations system
* Added custom fields support
* Improved API key management in settings
* Various bug fixes and performance improvements

= 2.0.0 =
* Major release with extension ecosystem support
* Added REST API (comcol/v1 namespace)
* Added Gutenberg blocks and Elementor widgets
* Added PWA support
* Added CSS variable theming
* Added onboarding wizard
* WooCommerce integration improvements

= 1.0.0 =
* Initial release

== Upgrade Notice ==

= 2.6.1 =
WordPress.org compliance fixes — email attribution, CSS sanitization, REST API permissions, and external service documentation.

= 2.6.0 =
AI model fallback — automatically retries with next provider on quota errors. AI Insights overhauled with actionable intelligence.

= 2.5.9 =
Fixes AI Insights 429 errors by switching to free-tier-compatible models. Adds comcol_ai_model_preference filter.

= 2.5.8 =
Fixes all remaining WordPress.org plugin check errors — escape output and SQL scanner compliance.

= 2.5.7 =
Security hardening for WordPress.org plugin check compliance. Tested up to WordPress 7.0.

= 2.1.0 =
Adds multi-currency support, new data sources (Metron, GCD, Open Library), and A-Z collection filters.
