# Search Filters Controller Documentation

**File**: `/controllers/searchFiltersController.php`  
**Purpose**: Manages hierarchical search filters/categories for product organization and filtering  
**Last Updated**: December 20, 2024  
**Total Functions**: 12 main functions + 4 utility functions  
**Lines of Code**: ~460

---

## 📋 Overview

The Search Filters Controller is a comprehensive category management system that provides hierarchical product filtering and organization capabilities. This controller handles:

- Hierarchical category/filter structures with parent-child relationships
- Multi-language support (Arabic/English category names)
- Color-coded category identification
- AJAX endpoints for dynamic category selection
- Bulk operations (delete, restore)
- Recursive category tree management
- Integration with product management system

### Primary Functions
- [x] Create and manage hierarchical categories/filters
- [x] Multi-language category names (Arabic/English)
- [x] Parent-child category relationships
- [x] Color coding for visual category identification
- [x] AJAX search and autocomplete functionality
- [x] Bulk category operations
- [x] Soft delete with restore functionality
- [x] Recursive category tree operations
- [x] Category path generation and display

### Related Controllers
- [productController.php](productController.md) - Product management
- [productCatController.php](productCatController.md) - Product categories
- [onlineCatController.php](onlineCatController.md) - Online store categories

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **searchfilters** | Hierarchical search filters/categories | id, name, name_en, parentid, conditions, color_code, user_id, created_at, updated_at |

### Integration Tables (Referenced)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **product** | Products linked to filters | productId, searchfiltersid |

### Reference Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **youtubelink** | Tutorial video links | youtubelinkid, title, url |
| **programsettings** | System configuration | programsettingsid, settingkey, settingvalue |

### Key Relationships
```sql
-- Hierarchical structure
searchfilters.parentid -> searchfilters.id (self-referencing)

-- Product integration
product.searchfiltersid -> searchfilters.id

-- User tracking
searchfilters.user_id -> user.userid
```

---

## 🔑 Key Functions

### 1. **Default Action (empty $do)** - Add Form Display
**Location**: Lines 95-99  
**Purpose**: Display form for creating new search filters/categories

**Process Flow**:
1. Load parent categories via `getSearchFiltersParents()`
2. Assign categories to template
3. Display add form

**Template Variables**:
- `$categories` - Available parent categories for selection

---

### 2. **add ($do == "add")** - Create Search Filter
**Location**: Lines 100-108 (function at 264-288)  
**Purpose**: Create new search filter/category with hierarchical support

**Function Signature**:
```php
function add()
```

**Form Fields**:
- `name` - Arabic category name (required)
- `name_en` - English category name
- `parent` - Parent category ID (-1 for root level)
- `color_code` - Color code for visual identification (default: #000000)

**Process Flow**:
1. Extract form data from POST
2. Validate parent ID (-1 becomes 0 for root)
3. Create new searchfilters record using RedBeanPHP
4. Set metadata (timestamps, user, color)
5. Return inserted ID

**Database Operation**:
```php
$searchFilters = R::dispense('searchfilters');
$searchFilters->conditions = 0; // Active
$searchFilters->created_at = date("Y-m-d H:i:s");
$searchFilters->updated_at = date("Y-m-d H:i:s");
$searchFilters->name = $name;
$searchFilters->name_en = $name_en;
$searchFilters->parentid = $parent;
$searchFilters->user_id = $_SESSION['userid'];
$searchFilters->color_code = isset($_POST['color_code']) ? $_POST['color_code'] : '#000000';
$id = R::store($searchFilters);
```

---

### 3. **show ($do == "show")** - Display Categories List
**Location**: Lines 109-125 (function at 290-300)  
**Purpose**: Display all search filters with hierarchical information

**Parameters**:
- `catId` - Optional category ID to filter by

**Process Flow**:
1. Load YouTube tutorial links
2. Check if specific category ID provided
3. Call appropriate display function (`showByCatId()` or `show()`)
4. Enable custom validation and checks

**Template Variables**:
- `$allData` - All category data
- `$youtubes` - Tutorial video links
- `$searchFiltersData` - Formatted category data with parent names

---

### 4. **executeOperation ($do == "executeOperation")** - Bulk Operations
**Location**: Lines 125-135 (function at 313-354)  
**Purpose**: Handle bulk operations on multiple categories

**Parameters**:
- `operation` - Operation type (1 = temp delete, 2 = restore)
- `choosedItem[]` - Array of category IDs to operate on

**Process Flow**:
1. Get operation type from POST
2. Iterate through selected category IDs
3. For each category:
   - Load category name for feedback
   - Execute operation (delete/restore)
   - Collect success/error messages
4. Display operation results

**Operation Types**:
```php
if ($operationType == '1') { // Temp delete
    $note = tempdelete($id);
} elseif ($operationType == "2") { // Restore
    returndelete($id);
}
```

---

### 5. **tempdelete ($do == "tempdelete")** - Soft Delete
**Location**: Lines 142-157 (function at 356-381)  
**Purpose**: Mark category as deleted with dependency checking

**Parameters**:
- `id` - Category ID to delete

**Function Signature**:
```php
function tempdelete($id)
```

**Process Flow**:
1. Check for dependent products (commented out in current code)
2. Check for child categories
3. If dependencies exist, return error message
4. If safe to delete, mark as deleted (`conditions = 1`)
5. Return success/error status

**Dependency Checking**:
```php
// Check for child categories
$childCategories = R::getAll('SELECT * FROM searchfilters WHERE parentid = ' . $id);
if (count($childCategories) > 0) {
    $note = "لا يمكن حذف هذا التصنيف لارتباطه ببيانات أخرى";
} else {
    // Safe to delete
    R::exec('UPDATE searchfilters SET sysdate = "' . date("Y-m-d") . '", user_id = ' . $_SESSION['userid'] . ', conditions = 1 where id = ' . $id);
    $note = "success";
}
```

---

### 6. **returndelete ($do == "returndelete")** - Restore Deleted Category
**Location**: Lines 135-142 (function at 383-391)  
**Purpose**: Restore soft-deleted category

**Parameters**:
- `id` - Category ID to restore

**Function Signature**:
```php
function returndelete($id)
```

**Process Flow**:
1. Update conditions field to 0 (active)
2. Category becomes visible again in listings

---

### 7. **edit ($do == "edit")** - Edit Form Display
**Location**: Lines 167-182 (function at 393-398)  
**Purpose**: Display edit form for existing category

**Parameters**:
- `id` - Category ID to edit
- `parentid` - Optional parent category ID

**Process Flow**:
1. Load all parent categories (excluding current category)
2. Load current category data
3. If parent ID provided, load parent data for context
4. Display edit form with pre-filled data

---

### 8. **update ($do == "update")** - Update Category
**Location**: Lines 183-193 (function at 400-424)  
**Purpose**: Update existing search filter/category

**Function Signature**:
```php
function update()
```

**Form Fields**:
- `id` - Category ID to update
- `conditions` - Category status
- `name` - Arabic category name
- `name_en` - English category name
- `parent` - Parent category ID
- `color_code` - Color code

**Process Flow**:
1. Extract form data including category ID
2. Validate parent ID
3. Load existing category record
4. Update all fields with new values
5. Save updated record

---

### 9. **getallsearchfilters ($do == "getallsearchfilters")** - AJAX Category Search
**Location**: Lines 200-219  
**Purpose**: AJAX endpoint for category autocomplete/search

**Parameters**:
- `term` - Search term
- `page_limit` - Results limit
- `withoutId` - Category ID to exclude from results

**Process Flow**:
1. Query categories matching search term
2. For each result, generate category path
3. Format as JSON array for autocomplete
4. Return JSON response

**Response Format**:
```php
$row_array = array();
$row_array['id'] = $parentId;
$row_array['text'] = $pathArr; // Full category path
array_push($return_arr, $row_array);
echo json_encode($return_arr);
```

---

### 10. **getallSubFilters ($do == "getallSubFilters")** - AJAX Subcategory Search
**Location**: Lines 220-242  
**Purpose**: AJAX endpoint for leaf category search (categories without children)

**Parameters**:
- `term` - Search term
- `page_limit` - Results limit
- `withoutId` - Category ID to exclude

**Process Flow**:
1. Query categories that are not parents (leaf nodes)
2. Include parent name in results
3. Generate category paths
4. Return JSON formatted results

**SQL Query**:
```sql
SELECT child.*, parent.name as parentName
FROM searchfilters child
LEFT JOIN searchfilters parent ON child.parentid = parent.id 
WHERE child.conditions = 0 
  AND child.id NOT IN (SELECT DISTINCT(parentid) FROM searchfilters) 
  AND child.name LIKE "%{$term}%" 
LIMIT {$limit}
```

---

## 🔄 Workflows

### Workflow 1: Hierarchical Category Creation
```
┌─────────────────────────────────────────────────────────────┐
│             START: Create Search Filter Category           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Parent Categories                                  │
│     ├─→ Query existing categories for parent selection      │
│     ├─→ Exclude self-reference for edit operations         │
│     └─→ Build parent dropdown options                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Display Creation Form                                   │
│     ├─→ Category name fields (Arabic/English)              │
│     ├─→ Parent category selection                           │
│     ├─→ Color code picker                                   │
│     └─→ Form validation setup                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Form Submission                                 │
│     ├─→ Validate required fields                            │
│     ├─→ Handle parent ID (-1 becomes 0 for root)           │
│     ├─→ Set timestamps and user tracking                   │
│     └─→ Insert new category record                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Build Category Hierarchy                                │
│     ├─→ Establish parent-child relationship                 │
│     ├─→ Update category tree structure                      │
│     └─→ Enable category for product assignment             │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Category Management and Operations
```
┌─────────────────────────────────────────────────────────────┐
│                START: Manage Categories                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Category List                                   │
│     ├─→ Query categories with parent information            │
│     ├─→ Show hierarchical relationships                     │
│     ├─→ Display status and metadata                         │
│     └─→ Provide action buttons                              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Handle User Actions                                     │
│     │                                                       │
│     ├─→ EDIT: Load category and show edit form             │
│     │                                                       │
│     ├─→ DELETE: Check dependencies and soft delete         │
│     │                                                       │
│     ├─→ RESTORE: Reactivate deleted categories              │
│     │                                                       │
│     └─→ BULK OPERATIONS: Process multiple categories       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Dependency and Integrity Checks                        │
│     ├─→ Check for child categories                          │
│     ├─→ Check for associated products                       │
│     ├─→ Prevent orphaning of data                           │
│     └─→ Maintain referential integrity                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Update Database and Confirm                             │
│     ├─→ Apply changes with audit trail                      │
│     ├─→ Update timestamps and user tracking                 │
│     └─→ Provide operation feedback                          │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display category creation form |
| `do=add` | `add()` | Create new search filter category |
| `do=show` | `show()` / `showByCatId()` | Display categories list |
| `do=executeOperation` | `executeOperation()` | Handle bulk operations |
| `do=tempdelete` | `tempdelete()` | Soft delete category |
| `do=returndelete` | `returndelete()` | Restore deleted category |
| `do=edit` | `edit()` | Display edit form |
| `do=update` | `update()` | Update category |
| `do=deleteFinaly` | `deleteFinaly()` | Permanently delete category |
| `do=getallsearchfilters` | AJAX endpoint | Category autocomplete search |
| `do=getallSubFilters` | AJAX endpoint | Subcategory search |

### Required Parameters by Action

**Category Creation** (`do=add`):
- `name` - Arabic category name (required)
- `name_en` - English category name (optional)
- `parent` - Parent category ID (optional, -1 for root)
- `color_code` - Color code (optional, defaults to #000000)

**Category Display** (`do=show`):
- `catId` - Optional category ID to filter by

**Bulk Operations** (`do=executeOperation`):
- `operation` - Operation type (1=delete, 2=restore)
- `choosedItem[]` - Array of category IDs

**Edit Category** (`do=edit`):
- `id` - Category ID to edit
- `parentid` - Optional parent category context

**Update Category** (`do=update`):
- `id` - Category ID
- `name` - Arabic name
- `name_en` - English name
- `parent` - Parent category ID
- `conditions` - Category status
- `color_code` - Color code

**AJAX Endpoints**:
- `term` - Search term
- `page_limit` - Results limit
- `withoutId` - Category ID to exclude

---

## 🧮 Calculation Methods

### Hierarchical Path Generation
```php
function fetch_recursive($parentid, $categories) {
    if ($parentid) {
        $catData = R::getRow('SELECT child.*, parent.name as parentName
                    FROM searchfilters as child
                    LEFT JOIN searchfilters as parent ON child.parentid = parent.id
                    WHERE child.id = ' . $parentid);
        if (count($catData) > 0) {
            $categories .= $catData['name'] . '/';
            $newParentId = $catData['parentid'];
            return fetch_recursive($newParentId, $categories);
        }
    }
    $categories = substr($categories, 0, strlen($categories) - 1); // Remove trailing slash
    return $categories;
}
```

### Parent ID Validation
```php
// Convert -1 (no parent) to 0 (root level)
if (empty($parent) || $parent == -1) {
    $parent = 0;
}
```

### Status Management
```php
// Active category
$searchFilters->conditions = 0;

// Deleted category (soft delete)
UPDATE searchfilters SET conditions = 1 WHERE id = ?

// Restore category
UPDATE searchfilters SET conditions = 0 WHERE id = ?
```

---

## 🔒 Security & Permissions

### Session Management
```php
// Handle CURL requests with session initiation
if (isset($_POST['curlpost']) && $_POST['curlpost'] == 1) {
    array_push($ajaxDoArr, $do);
}

// Conditional header/footer for AJAX requests
if (!in_array($do, $ajaxDoArr)) {
    include("../public/impOpreation.php");
    $smarty->display("header.html");
}
```

### User Tracking
```php
// Track user who creates/modifies categories
$searchFilters->user_id = $_SESSION['userid'];

// Audit trail for deletions
UPDATE searchfilters SET user_id = {user_id}, sysdate = "{date}" WHERE id = ?
```

### Input Validation
- **Search term sanitization**: LIKE queries properly escaped
- **Parent ID validation**: Converted to integer, -1 handled as special case
- **Color code validation**: Default value provided if missing
- **AJAX response validation**: JSON encoding for safe data transmission

---

## 📊 Performance Considerations

### Database Optimization
1. **Indexes Recommended**:
   ```sql
   CREATE INDEX idx_searchfilters_parent ON searchfilters(parentid);
   CREATE INDEX idx_searchfilters_conditions ON searchfilters(conditions);
   CREATE INDEX idx_searchfilters_name ON searchfilters(name);
   CREATE INDEX idx_searchfilters_user ON searchfilters(user_id);
   ```

2. **Query Performance**:
   - Recursive category path generation may be slow for deep hierarchies
   - Consider materialized path or closure table for better performance
   - AJAX endpoints use LIMIT to control result size
   - JOIN queries for parent-child relationships

3. **Memory Considerations**:
   - Category hierarchy depth should be monitored
   - AJAX responses limited by page_limit parameter
   - Bulk operations process arrays in memory

### Potential Performance Issues
```php
// N+1 Problem in recursive path generation
// Current: Multiple queries for each level
// Better: Single query with Common Table Expression (CTE)

// Improved approach:
WITH RECURSIVE category_path AS (
    SELECT id, name, parentid, CAST(name AS VARCHAR(1000)) as path
    FROM searchfilters WHERE parentid = 0
    UNION ALL
    SELECT s.id, s.name, s.parentid, 
           CONCAT(cp.path, '/', s.name) as path
    FROM searchfilters s
    JOIN category_path cp ON s.parentid = cp.id
)
SELECT * FROM category_path WHERE id = ?;
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **Recursive Loop in Category Hierarchy**
**Issue**: Category assigned as its own parent or circular reference  
**Cause**: No validation preventing circular references

**Prevention**:
```php
function validateParentAssignment($categoryId, $newParentId) {
    // Check if new parent is descendant of current category
    $descendants = getDescendants($categoryId);
    if (in_array($newParentId, $descendants)) {
        throw new Exception("Cannot create circular reference");
    }
}
```

### 2. **Orphaned Categories After Deletion**
**Issue**: Child categories become orphaned when parent deleted  
**Cause**: Dependency checking not comprehensive

**Fix**:
```php
function tempdelete($id) {
    // Check for child categories
    $childCategories = R::getAll('SELECT * FROM searchfilters WHERE parentid = ' . $id);
    if (count($childCategories) > 0) {
        return "Cannot delete category with child categories";
    }
    
    // Check for associated products
    $products = R::getAll('SELECT * FROM product WHERE searchfiltersid = ' . $id);
    if (count($products) > 0) {
        return "Cannot delete category with associated products";
    }
    
    // Safe to delete
    // ... deletion code
}
```

### 3. **AJAX Endpoints Not Working**
**Issue**: Category search/autocomplete fails  
**Cause**: Session management issues or incorrect headers

**Debug**:
```php
// Check if AJAX request properly handled
if (!in_array($do, $ajaxDoArr)) {
    // This should NOT execute for AJAX requests
    include("../public/impOpreation.php");
}

// Verify JSON response format
header('Content-Type: application/json');
echo json_encode($return_arr);
```

### 4. **Path Generation Fails**
**Issue**: Category paths show incomplete or incorrect information  
**Cause**: Recursive function hits null or circular references

**Debug**:
```sql
-- Check for circular references
WITH RECURSIVE category_check AS (
    SELECT id, parentid, 1 as level
    FROM searchfilters WHERE id = [CATEGORY_ID]
    UNION ALL
    SELECT s.id, s.parentid, cc.level + 1
    FROM searchfilters s
    JOIN category_check cc ON s.id = cc.parentid
    WHERE cc.level < 10 -- Prevent infinite recursion
)
SELECT * FROM category_check;
```

---

## 🧪 Testing Scenarios

### Test Case 1: Hierarchical Category Creation
```
1. Create root level category (parent = -1)
2. Create child category under root
3. Create grandchild category
4. Verify hierarchy displays correctly
5. Test category path generation
6. Confirm parent-child relationships
```

### Test Case 2: Bulk Operations
```
1. Create multiple test categories
2. Select multiple categories for bulk delete
3. Verify dependency checking works
4. Execute bulk operation
5. Check operation feedback messages
6. Test bulk restore functionality
```

### Test Case 3: AJAX Functionality
```
1. Test category autocomplete search
2. Verify search results format
3. Test subcategory filtering
4. Check JSON response structure
5. Test search with special characters
6. Verify pagination with page_limit
```

### Test Case 4: Circular Reference Prevention
```
1. Create parent category A
2. Create child category B under A
3. Attempt to make A a child of B
4. Verify system prevents circular reference
5. Test with deeper hierarchies
6. Check error messaging
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [productController.md](productController.md) - Product management
- [productCatController.md](productCatController.md) - Product categories
- [Database Schema Documentation](#) - Table relationships
- [AJAX Implementation Guide](#) - Frontend integration

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When category management requirements change