WP Manifestindependent plugin directory
manifest / ecommerce / optical-shop_wordpress_plugin

Anura Lens Selector

Adds a "Select Lens" workflow on WooCommerce single product pages for eyewear products, with admin management for lens types and packages.

by Anura Dev · github.com/thelllmike/optical-shop_wordpress_plugin · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/thelllmike/optical-shop_wordpress_plugin/archive/refs/heads/main.zip

A WooCommerce plugin that adds a "Select Lens" workflow on single product pages for eyewear products — similar to Lenskart's lens selection experience.

Version: 1.0.0 Requires: WordPress 5.8+, WooCommerce 6.0+, PHP 7.4+ License: GPL v2 or later


Features

  • Full-screen, mobile-first modal for lens selection (Lenskart-style UI)
  • Two-step workflow: Select Lens Type → Choose Lens Package → Add to Cart
  • 5 default lens types: Single Vision, Bifocal/Progressive, Zero Power, Frame Only, With Power
  • Admin panel under WooCommerce → Lens Selector with full CRUD for types and packages
  • Custom database tables for scalability
  • Dynamic pricing: Frame + Lens total pricing with automatic addon calculation
  • Lens selections saved to cart item meta and order item meta
  • Media library integration for package images
  • Category-based product filtering (enable for all or specific categories)
  • Accessible markup (ARIA labels, ESC to close)
  • HPOS (High-Performance Order Storage) compatible
  • No external CDN dependencies

Installation

Option 1: Upload via WordPress Admin

  1. Download or zip the anura-lens-selector folder
  2. Go to Plugins → Add New → Upload Plugin
  3. Select the .zip file and click Install Now
  4. Click Activate Plugin

Option 2: Manual Upload

  1. Copy the anura-lens-selector/ folder to wp-content/plugins/
  2. Go to Plugins in WordPress admin
  3. Find "Anura Lens Selector" and click Activate

On activation, the plugin will:

  • Create two database tables (wp_als_lens_types, wp_als_lens_packages)
  • Seed 5 default lens types and sample packages with placeholder SVG images

Configuration

Navigate to WooCommerce → Lens Selector in the admin sidebar.

Settings Tab

Setting Description
Help Phone Number Displayed in the modal footer as "Not sure what to select? Call XXXXXXX"
Enable for Choose "All products" or "Selected categories only"
Product Categories Multi-select categories (only shown when "Selected categories only" is chosen)

Lens Types Tab

Edit the 5 built-in lens types:

Field Description
Title Display name shown in the modal
Description Subtitle text below the title
Sort Order Controls display order (ascending)
Active Toggle visibility on the frontend

Note: Lens type slugs cannot be changed as they are used internally.

Lens Packages Tab

Full CRUD for lens packages. Each package belongs to a lens type.

Field Description
Lens Type Which lens type this package belongs to
Slug Unique identifier (auto-generated from title)
Title Package name displayed on the card
Description One feature per line (rendered as bullet list)
Image Upload via WordPress media library
Total Price The "Frame + Lens" total price shown to the customer
Sort Order Controls display order within the type
Active Toggle visibility

How It Works

Customer Flow

  1. Customer visits a WooCommerce product page (for an enabled category)
  2. A "Select Lens" button appears next to Add to Cart
  3. Clicking opens a full-screen modal with Step 1: Select Lens Type
    • Frame Only → immediately adds the frame to cart and redirects to cart page
    • Any other type → proceeds to Step 2
  4. Step 2: Choose Lens Package shows selectable cards with image, title, features, and price
  5. Selecting a package reveals the "Confirm & Add to Cart" button
  6. On confirm → product is added to cart with lens meta → redirects to cart

Pricing Logic

The plugin uses Total Price mode:

addon_price = max(0, package_total_price - product_price)
cart_item_price = product_price + addon_price
  • If the package total is higher than the frame price → customer pays the package total
  • If the package total is lower than the frame price → customer pays only the frame price (addon = 0)

Cart & Order Meta

The following meta is saved to cart line items and order items:

Meta Key Value
Lens Type e.g., "Single Vision"
Lens Package e.g., "BLU+ Thin"
Frame + Lens Total e.g., "Rs 3,200"

These are visible in:

  • Cart page (below product name)
  • Checkout page
  • Order confirmation email
  • Admin order details

Folder Structure

anura-lens-selector/
├── anura-lens-selector.php          # Main plugin file
├── uninstall.php                     # Cleanup on plugin deletion
├── README.md                         # This file
├── includes/
│   ├── class-als-db.php             # DB schema, CRUD, seed data
│   ├── class-als-helpers.php        # Settings, pricing, utilities
│   ├── class-als-admin.php          # Admin menu page, AJAX handlers
│   ├── class-als-frontend.php       # Frontend button, modal, AJAX
│   └── class-als-cart.php           # Cart pricing, line item meta, order meta
├── templates/
│   └── admin-page.php               # Admin settings/types/packages UI
└── assets/
    ├── css/
    │   ├── als-admin.css            # Admin panel styles
    │   └── als-frontend.css         # Lenskart-style modal CSS
    ├── js/
    │   ├── als-admin.js             # Admin tab/form/AJAX logic
    │   └── als-frontend.js          # Modal workflow JS
    └── images/
        ├── frame.svg                # Lens type icon: Frame Only
        ├── non_prescription.svg     # Lens type icon: Zero Power
        ├── progressive.svg          # Lens type icon: Bifocal/Progressive
        ├── single_vision.svg        # Lens type icon: Single Vision
        ├── with_power.svg           # Lens type icon: With Power
        ├── single_vision/           # Package images for Single Vision
        ├── bifocal_progressive/     # Package images for Bifocal/Progressive
        ├── zero_power/              # Package images for Zero Power
        └── with_power/              # Package images for With Power

Replacing Placeholder Images

The plugin ships with SVG placeholder images. To use your own:

Lens Type Icons (Step 1)

  • Supported formats: .apng, .webp, .png, .svg
  • Go to WooCommerce → Lens Selector → Lens Types
  • Edit each type and update the icon URL (or upload via media library in the Packages tab)

Package Images (Step 2)

  • Supported formats: .webp, .png, .jpg, .svg
  • Go to WooCommerce → Lens Selector → Lens Packages
  • Click Edit on any package → Select Image → upload from media library
  • Recommended size: 200x200px

File-Based Replacement

You can also drop your images directly into the folder structure:

assets/images/
├── frame.apng                    # Replace frame.svg
├── single_vision.apng            # Replace single_vision.svg
├── progressive.apng              # Replace progressive.svg
├── non_prescription.apng         # Replace non_prescription.svg
├── single_vision/
│   ├── Anti-Glare_Premium.webp   # Replace .svg with .webp
│   └── ...
├── bifocal_progressive/
│   └── ...
├── zero_power/
│   └── ...
└── with_power/
    └── ...

Then update the image URLs in the admin panel to point to the new files.


Database Tables

wp_als_lens_types

Column Type Description
id BIGINT Primary key
slug VARCHAR(100) Unique identifier
title VARCHAR(255) Display name
description VARCHAR(500) Subtitle text
icon VARCHAR(500) Icon image URL
sort_order INT Display order
is_active TINYINT(1) Active toggle
requires_package TINYINT(1) Whether a package selection is required
created_at DATETIME Creation timestamp

wp_als_lens_packages

Column Type Description
id BIGINT Primary key
lens_type_id BIGINT Foreign key to lens types
slug VARCHAR(100) Unique identifier
title VARCHAR(255) Display name
description TEXT Newline-separated feature bullets
image_url VARCHAR(500) Package image URL
total_price DECIMAL(10,2) Frame + Lens total price
is_active TINYINT(1) Active toggle
sort_order INT Display order within type
created_at DATETIME Creation timestamp

Uninstall Behavior

When the plugin is deleted (not just deactivated):

  • By default, all custom tables and options are removed
  • To keep data after deletion, add this to wp-config.php before deleting:
define( 'ALS_DELETE_DATA_ON_UNINSTALL', false );

Deactivating the plugin does not delete any data.


Security

  • All AJAX requests are protected with WordPress nonces
  • Admin endpoints require manage_woocommerce capability
  • All user inputs are sanitized (sanitize_text_field, sanitize_textarea_field, esc_url_raw)
  • All outputs are escaped (esc_html, esc_attr, esc_url, wp_kses_post)
  • SQL queries use $wpdb->prepare() for parameterized queries

Hooks & Filters

The plugin uses standard WooCommerce hooks:

Hook Purpose
woocommerce_after_add_to_cart_button Renders the "Select Lens" button
woocommerce_before_calculate_totals Adjusts cart item prices with lens addon
woocommerce_get_item_data Displays lens meta in cart
woocommerce_checkout_create_order_line_item Saves lens meta to order items
woocommerce_cart_item_key Generates unique keys for different lens configs

Troubleshooting

Plugin not showing on product pages

  • Verify WooCommerce is active
  • Check WooCommerce → Lens Selector → Settings — ensure "Enable for all" is selected or the product belongs to an enabled category
  • Clear any page cache

Images not loading

  • Verify image URLs in the admin panel point to valid files
  • If using file-based replacement, ensure file extensions match the URLs in the database

"Frame Only" not redirecting to cart

  • Ensure WooCommerce cart page is set up correctly under WooCommerce → Settings → Advanced

Changelog

1.0.0

  • Initial release
  • 5 lens types with full admin CRUD
  • Lens package management with media library integration
  • Full-screen mobile-first modal
  • Cart and order meta integration
  • Custom database tables
  • Placeholder SVG images for all types and packages

Credits

Developed by Anura Dev


License

This plugin is licensed under the GPL v2 or later.