# Special Access Link - Product Priority Ordering

## Overview

This document explains the implementation of priority ordering for special access link products. When users access the registration page via a special access link (e.g., `?access=SUNWAY-GUEST`), products from that special link now appear **first** in each section, before regular visible products.

## Problem Statement

Previously, products were ordered by:
1. Category ID
2. Product ID
3. Pricing tier date

This meant that special access products (like "Delegate Pass for Sunway Guests") could appear **after** regular products, making them less prominent and often not selected by default.

## Solution

### Database Query Changes

Modified the SQL query in `api.php` to add a special access priority flag:

```sql
-- Added to SELECT clause
CASE WHEN p.id IN (special_access_product_ids) THEN 0 ELSE 1 END as is_special_access

-- Modified ORDER BY clause
ORDER BY is_special_access ASC, p.category_id, p.id, pp.valid_from ASC
```

### New Ordering Logic

Products are now ordered by:
1. **Special Access Priority** (0 = special access, 1 = regular)
   - Special access products get priority value `0`
   - Regular products get priority value `1`
2. **Category ID** (ascending)
3. **Product ID** (ascending)
4. **Pricing Tier Date** (ascending)

This ensures special access products always appear first in their respective sections.

## Implementation Details

### Modified Files

**1. `api.php` - getFrontendDisplayConfig() function**

**Changes:**
- Added `is_special_access` flag to SELECT statement using CASE expression
- Modified ORDER BY to prioritize special access products (value 0) before regular products (value 1)
- Updated parameter binding to pass product IDs twice (once for CASE, once for WHERE)
- Added `is_special_access` boolean flag to product data structure

**Key Code Changes:**

```php
// Add special access priority flag
if ($specialAccessLink && !empty($specialAccessProductIds)) {
    $placeholders = implode(',', array_fill(0, count($specialAccessProductIds), '?'));
    $productQuery .= ",
           CASE WHEN p.id IN ($placeholders) THEN 0 ELSE 1 END as is_special_access";
} else {
    $productQuery .= ",
           1 as is_special_access";
}

// Order by special access first
$productQuery .= ") ORDER BY is_special_access ASC, p.category_id, p.id, pp.valid_from ASC";

// Bind parameters twice
$executeParams = array_merge($specialAccessProductIds, $specialAccessProductIds);
$stmt->execute($executeParams);

// Add flag to product data
'is_special_access' => ($row['is_special_access'] == 0), // true if from special access link
```

### Product Data Structure

Each product now includes:

```php
[
    'id' => ...,
    'product_code' => ...,
    'name' => ...,
    'description' => ...,
    'base_price' => ...,
    'is_special_access' => true/false, // NEW: indicates if product is from special link
    'pricing_tiers' => [...]
]
```

## Visual Result

### Before (Old Ordering)
```
Conference Registration
├── Standard Delegate Pass (regular, selected by default)
└── Delegate Pass for Sunway Guests (special, appears last)
```

### After (New Ordering)
```
Conference Registration
├── Delegate Pass for Sunway Guests (special, appears first & selected)
└── Standard Delegate Pass (regular, appears second)
```

## Testing

### Test Script

A test script has been created: `test_special_access_ordering.php`

**Usage:**
```
http://yourdomain.com/test_special_access_ordering.php?access=SUNWAY-GUEST
```

**What it shows:**
- Visual display of product order in each section
- Highlights special access products with blue background
- Shows "SPECIAL" badge for products from the access link
- Confirms ordering is correct (special products first)

### Manual Testing

1. **Without Access Code:**
   ```
   http://yourdomain.com/index.html
   ```
   - Should show only regular visible products
   - Standard ordering applies

2. **With Access Code:**
   ```
   http://yourdomain.com/index.html?access=SUNWAY-GUEST
   ```
   - Special access products appear first
   - Regular products appear after (if include_visible_products = true)
   - Special access banner displayed at top

## Benefits

### User Experience
- **More prominent:** Special access products are immediately visible
- **Better conversion:** First product is often selected by default
- **Clear priority:** VIP/partner products get top billing

### Admin Control
- Admins can create special links knowing their products will be featured first
- No need to worry about product IDs or creation order
- Consistent behavior across all special access links

### Technical
- Clean SQL-based solution (no post-processing required)
- Maintains backward compatibility
- No frontend JavaScript changes needed
- Performance efficient (single query)

## Configuration

### Special Access Link Settings

In the admin panel (`admin/special-access-links.php`):

1. **Create Special Link**
   - Set unique link code (e.g., "SUNWAY-GUEST")
   - Select products to show
   - Choose whether to include visible products

2. **Product Priority**
   - Products selected in the link automatically get priority
   - They will appear first in their respective sections
   - Order within special products: by product ID

3. **Include Visible Products**
   - ✅ **Checked:** Special products first, then regular products
   - ❌ **Unchecked:** Only special products shown

## Examples

### Example 1: VIP Conference Access

**Special Link:** `?access=VIP2025`

**Products Selected:**
- VIP Delegate Pass ($800)

**Include Visible Products:** ✅ Yes

**Result:**
```
Conference Registration
├── VIP Delegate Pass ($800) ← SPECIAL ACCESS PRODUCT (appears first)
├── Standard Delegate Pass ($580) ← regular product
└── Early Bird Pass ($500 - expired) ← regular product
```

### Example 2: Partner Exclusive

**Special Link:** `?access=PARTNER-EXCLUSIVE`

**Products Selected:**
- Partner Delegate Pass ($450)
- Partner Exhibition Space ($300)

**Include Visible Products:** ❌ No

**Result:**
```
Conference Registration
└── Partner Delegate Pass ($450) ← SPECIAL ACCESS PRODUCT (only one shown)

Exhibition Space
└── Partner Exhibition Space ($300) ← SPECIAL ACCESS PRODUCT (only one shown)
```

### Example 3: Sunway Guest Access

**Special Link:** `?access=SUNWAY-GUEST`

**Products Selected:**
- Delegate Pass for Sunway Guests ($290)

**Include Visible Products:** ✅ Yes

**Result:**
```
Conference Registration
├── Delegate Pass for Sunway Guests ($290) ← SPECIAL (50% discount, appears first)
├── Standard Delegate Pass ($580) ← regular
└── Early Bird Pass ($500 - expired) ← regular
```

## Database Impact

### Query Performance
- Added CASE expression in SELECT (minimal overhead)
- ORDER BY includes one additional column (is_special_access)
- Same number of rows returned
- No additional table joins required

### Backward Compatibility
- Existing special access links work unchanged
- Links without access code show products in standard order
- No database schema changes required
- Existing product configurations unaffected

## Troubleshooting

### Issue: Special products not appearing first

**Possible causes:**
1. Access code incorrect or expired
2. Products not selected in special link configuration
3. Browser cache showing old order

**Solution:**
```php
// Check access code validity
SELECT * FROM special_access_links 
WHERE link_code = 'YOUR_CODE' 
AND is_active = 1 
AND (expires_at IS NULL OR expires_at > NOW());

// Check products in link
SELECT product_ids FROM special_access_links 
WHERE link_code = 'YOUR_CODE';

// Clear browser cache and test again
```

### Issue: Products showing but not marked as special

**Possible causes:**
1. `is_special_access` flag not in product data
2. Frontend not updated

**Solution:**
- Verify api.php changes are deployed
- Check product data structure includes `is_special_access` field
- Test with test_special_access_ordering.php

### Issue: Regular products not showing with special link

**Possible causes:**
1. `include_visible_products` is set to false/0

**Solution:**
- Edit special access link in admin
- Check "Include visible products" option
- Save changes

## Future Enhancements

### Potential Improvements

1. **Custom Sort Order**
   - Allow admins to specify exact order of special products
   - Add `display_order` field to special_access_links

2. **Multiple Priority Levels**
   - Support tiered priority (VIP, Premium, Standard)
   - CASE expression with multiple levels

3. **Category-Specific Priority**
   - Different priorities for different sections
   - More granular control

4. **Visual Indicators in Frontend**
   - Add badge/ribbon for special access products
   - Different styling for special products

## Version History

- **v1.0** (October 2025): Initial implementation
  - Added special access priority ordering
  - Modified SQL query with CASE expression
  - Added is_special_access flag to products
  - Created test script

## Related Documentation

- `SPECIAL_ACCESS_LINKS_GUIDE.md` - Complete guide to special access links
- `SPECIAL_ACCESS_LINKS_QUICKSTART.md` - Quick start guide
- `NEW_PRODUCT_INTEGRATION_GUIDE.md` - Adding new products
- `README.md` - General system documentation

---

## Summary

The special access link priority ordering ensures that products configured in special access links always appear first in their respective sections, providing better visibility and conversion for targeted offerings. This is achieved through a clean SQL-based solution that adds a priority flag to products and sorts accordingly, maintaining performance and backward compatibility.

