# Online Category Controller Documentation

**File**: `/controllers/onlineCatController.php`  
**Purpose**: Manages online store product categories with hierarchical structure and AJAX support  
**Last Updated**: December 20, 2024  
**Total Functions**: 15+  
**Lines of Code**: ~463

---

## 📋 Overview

The Online Category Controller manages the hierarchical product categories for the online store integration system. It handles:
- Hierarchical category management (parent-child relationships)
- AJAX-enabled category searching and selection
- Multi-language support (Arabic/English names)
- Category deletion with dependency checking
- Category image management
- Integration with ERP product systems
- Bulk category operations
- Category tree path generation

### Primary Functions
- [x] Add new online categories with parent-child relationships
- [x] Edit existing categories
- [x] Delete categories with dependency validation
- [x] AJAX category search and autocomplete
- [x] Hierarchical category display
- [x] Multi-language category names
- [x] Category image handling
- [x] Bulk operations (delete/restore)
- [x] Category path generation
- [x] Integration with product management

### Related Controllers
- [productCatController.php](productCatController.md) - Local product categories
- [productController.php](productController.md) - Products using categories
- [onlinestoresetting.php](onlinestoresetting.md) - Online store configuration
- [onlinestoresync.php](onlinestoresync.md) - Data synchronization

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **onlinecat** | Online store categories | onlinecatid, name, name_en, parentid, conditions, sysdate, user_id |
| **product** | Products linked to categories | productid, onlinecatid, conditions |

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

---

## 🔑 Key Functions

### 1. **Default Action / Add Form Display**
**Location**: Line 96  
**Purpose**: Display category creation form with parent category selection

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

**Function Signature**:
```php
// Triggered when: empty $do
$allParents = getOnlineCatParents();
$smarty->assign("categories", $allParents);
$smarty->display("onlineCatview/add.html");
```

---

### 2. **add() - Create New Category**
**Location**: Line 266  
**Purpose**: Insert new online category into database

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

**Process Flow**:
1. Extract form data (name, name_en, parent)
2. Validate parent ID (set to 0 if empty/-1)
3. Create new onlinecat record
4. Set system fields (conditions=0, sysdate, user_id)
5. Store in database and return ID

**Key Features**:
- Multi-language support (Arabic/English names)
- Parent relationship validation
- User tracking and timestamp logging

---

### 3. **show() - Display All Categories**
**Location**: Line 293  
**Purpose**: List all categories with parent information

**SQL Query**:
```sql
SELECT child.*, parent.name as parentName
FROM onlinecat child
LEFT JOIN onlinecat parent ON child.parentid = parent.id
ORDER BY child.id DESC
```

**Features**:
- Hierarchical display with parent names
- Ordered by newest first
- Includes deleted categories (conditions=1)

---

### 4. **showByCatId() - Display Specific Category**
**Location**: Line 304  
**Purpose**: Display single category by ID

**Function Signature**:
```php
function showByCatId($catId)
```

---

### 5. **tempdelete() - Soft Delete with Validation**
**Location**: Line 358  
**Purpose**: Safely delete category after checking dependencies

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

**Process Flow**:
1. Check for products using this category
2. Check for child categories
3. If dependencies exist, return error message
4. If safe, update conditions=1 (soft delete)
5. Return success/error status

**Dependency Checks**:
```php
$productsData = $ProductEX->queryByOnlineCatIdExt($id);
$childCategories = R::getAll('SELECT * FROM onlinecat WHERE parentid = ' . $id);
if (count($productsData) > 0 || count($childCategories) > 0) {
    return "لا يمكن حذف هذا التصنيف لارتباطه ببيانات أخرى";
}
```

---

### 6. **executeOperation() - Bulk Operations**
**Location**: Line 315  
**Purpose**: Perform bulk operations on selected categories

**Operations Supported**:
- Operation 1: Bulk temp delete
- Operation 2: Bulk restore

**Process Flow**:
1. Get operation type and selected item IDs
2. Loop through each selected category
3. Perform operation and collect results
4. Display success/error messages for each item

---

### 7. **edit() - Load Category for Editing**
**Location**: Line 395  
**Purpose**: Load category data for edit form

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

**Features**:
- Loads category data by ID
- Loads available parent categories (excluding self)
- Handles parent category display

---

### 8. **update() - Update Category**
**Location**: Line 402  
**Purpose**: Update existing category information

**Fields Updated**:
- name (Arabic name)
- name_en (English name)  
- parentid (parent category)
- conditions (status)
- sysdate (update timestamp)
- user_id (user making changes)

---

### 9. **deleteFinaly() - Permanent Deletion**
**Location**: Line 429  
**Purpose**: Permanently delete category and all children recursively

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

**Process Flow**:
1. Find all child categories
2. Recursively delete children first
3. Delete products in this category
4. Permanently delete category record

**⚠️ Warning**: This is permanent deletion - no recovery possible

---

### 10. **AJAX Functions**

#### **getallonlinecats** - Category Search
**Location**: Line 201  
**Purpose**: AJAX endpoint for category autocomplete

**Parameters**:
- `term` - Search term
- `page_limit` - Results limit
- `withoutId` - Exclude specific ID

**Response**: JSON array with category paths

#### **getallonlineSubCats** - Subcategory Search  
**Location**: Line 221  
**Purpose**: Search only child categories (parentid != 0)

---

### 11. **fetch_recursive() - Category Path Generation**
**Location**: Line 447  
**Purpose**: Build hierarchical category path string

**Function Signature**:
```php
function fetch_recursive($parentid, $categories)
```

**Example Output**: "Electronics/Phones/Smartphones/"

---

### 12. **getOnlineCatParents() - Load Parent Options**
**Location**: Line 256  
**Purpose**: Get available parent categories for selection

**Features**:
- Excludes categories that are products themselves
- Excludes the current category (when editing)
- Only returns active categories (conditions=0)

---

## 🔄 Workflows

### Workflow 1: Category Creation
```
┌─────────────────────────────────────────────────────────────┐
│                    START: Add Category                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Add Form                                        │
│     - Load available parent categories                      │
│     - Display add.html template                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. User Submits Form                                       │
│     - Category name (Arabic)                                │
│     - Category name (English)                               │
│     - Parent category selection                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Validate and Process                                    │
│     - Validate parent ID                                    │
│     - Set system fields                                     │
│     - Insert into database                                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Success/Error Response                                  │
│     - Redirect to success page                              │
│     - Or display error message                              │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Category Deletion with Validation
```
┌─────────────────────────────────────────────────────────────┐
│                 START: Delete Category                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Check Product Dependencies                              │
│     - Query products using this category                    │
│     - Count associated products                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Check Child Categories                                  │
│     - Find categories with this as parent                   │
│     - Count child categories                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Dependency Decision                                     │
│     ┌─────────────────┐         ┌─────────────────────────┐ │
│     │ Has Dependencies│   YES   │ Return Error Message     │ │
│     │ Products/Children│────────▶│ "Cannot delete..."       │ │
│     └─────────────────┘         └─────────────────────────┘ │
│             │                                               │
│             │ NO                                            │
│             ▼                                               │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ Proceed with Soft Delete                            │ │
│     │ - Set conditions = 1                                │ │
│     │ - Update timestamp                                  │ │
│     └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display add category form |
| `do=add` | `add()` | Create new category |
| `do=show` | `show()` | List all categories |
| `do=edit` | `edit()` | Edit category form |
| `do=update` | `update()` | Update category |
| `do=tempdelete` | `tempdelete()` | Soft delete category |
| `do=returndelete` | `returndelete()` | Restore deleted category |
| `do=deleteFinaly` | `deleteFinaly()` | Permanent deletion |
| `do=executeOperation` | `executeOperation()` | Bulk operations |
| `do=getallonlinecats` | AJAX search | Category autocomplete |
| `do=getallonlineSubCats` | AJAX search | Subcategory search |

### Required Parameters by Action

**Add Category** (`do=add`):
- `name` - Arabic category name
- `name_en` - English category name  
- `parent` - Parent category ID (-1 for root)

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

**Delete Operations**:
- `id` - Category ID to delete

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

---

## 🧮 Category Hierarchy Logic

### Parent-Child Relationships
```php
// Root category (no parent)
$parentid = 0;

// Child category  
$parentid = [parent_category_id];

// Path generation
function fetch_recursive($parentid, $categories) {
    // Builds path like "Electronics/Phones/Smartphones"
    if ($parentid) {
        $catData = R::getRow('SELECT child.*, parent.name as parentName 
                             FROM onlinecat as child
                             LEFT JOIN onlinecat as parent ON child.parentid = parent.id
                             WHERE child.id = ' . $parentid);
        if (count($catData) > 0) {
            $categories .= $catData['name'] . '/';
            return fetch_recursive($catData['parentid'], $categories);
        }
    }
    return rtrim($categories, '/');
}
```

---

## 🔒 Security & Permissions

### Input Sanitization
- All POST data filtered through PHP input filters
- SQL injection prevention via RedBeanPHP ORM
- User ID validation from session

### User Tracking
```php
// Every operation tracks user
$onlineCat->user_id = $_SESSION['userid'];
$onlineCat->sysdate = date("Y-m-d");
```

### AJAX Security
- AJAX operations included in `$ajaxDoArr` whitelist
- CURL post verification for admin operations

---

## 📊 Performance Considerations

### Database Optimization
1. **Indexes Needed**:
   - `onlinecat(parentid)` for hierarchy queries
   - `onlinecat(conditions)` for active category filtering
   - `onlinecat(name)` for search operations

2. **Query Optimization**:
   - LEFT JOINs for parent name display
   - Efficient recursive path building
   - Pagination for large category lists

### Memory Management
- Recursive functions have depth limits
- AJAX responses limited by `page_limit` parameter

---

## 🐛 Common Issues & Troubleshooting

### 1. **Circular Parent References**
**Issue**: Category becomes its own ancestor  
**Prevention**: Validate parent selection excludes self and descendants

### 2. **Orphaned Categories**
**Issue**: Parent deleted but children remain  
**Solution**: Use `deleteFinaly()` for cascading deletion or update children

### 3. **AJAX Search Not Working**
**Debug**:
```php
// Check if AJAX action is whitelisted
$ajaxDoArr = array("getallonlinecats","getallonlineSubCats");
if (!in_array($do, $ajaxDoArr)) {
    // Will include header/footer, breaking AJAX
}
```

### 4. **Path Generation Issues**
**Issue**: Incorrect category paths  
**Cause**: Broken parent relationships or circular references

**Debug Query**:
```sql
-- Check for orphaned categories
SELECT * FROM onlinecat 
WHERE parentid > 0 
AND parentid NOT IN (SELECT id FROM onlinecat WHERE conditions = 0);

-- Check for circular references  
SELECT child.id, child.name, parent.name as parent_name
FROM onlinecat child
JOIN onlinecat parent ON child.parentid = parent.id
WHERE child.id = child.parentid;
```

---

## 🧪 Testing Scenarios

### Test Case 1: Category Creation
```
1. Create root category (parentid = 0)
2. Create child category under root
3. Verify hierarchy display
4. Test with Arabic/English names
5. Check path generation
```

### Test Case 2: Deletion Validation
```
1. Create category with products
2. Attempt deletion - should fail
3. Remove products
4. Create child category  
5. Attempt deletion - should fail
6. Remove child categories
7. Deletion should succeed
```

### Test Case 3: AJAX Search
```
1. Create categories with various names
2. Test search with partial names
3. Verify JSON response format
4. Test search limits
5. Check parent exclusion in edit mode
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [productCatController.md](productCatController.md) - Local product categories
- [onlinestoresetting.md](onlinestoresetting.md) - Online store configuration  
- [Database Schema Documentation](#) - Table relationships

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur