# Dental File Upload Component

A modular, reusable file upload component for WordPress dental applications with progress tracking, validation, and secure file handling.

## Overview

This component provides a complete file upload solution with:
- **Drag & Drop** file uploads
- **Progress tracking** with visual feedback
- **File validation** (type, size, security)
- **Secure file storage** via FTP
- **Database integration** with separate attachments table
- **Automatic cleanup** of temporary files
- **Modular design** for easy integration

## Database Structure

### New Separate Attachments Table

The system now uses a dedicated `dental_attachments` table for better performance and data integrity:

```sql
CREATE TABLE wp_dental_attachments (
    id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    file_id VARCHAR(255) UNIQUE NOT NULL,
    original_name VARCHAR(255) NOT NULL,
    stored_name VARCHAR(255) NOT NULL,
    file_size BIGINT UNSIGNED NOT NULL,
    file_type VARCHAR(100) NOT NULL,
    file_path VARCHAR(500) NOT NULL,
    file_url VARCHAR(1000) NOT NULL,
    uploaded_by BIGINT UNSIGNED NOT NULL,
    uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    is_temp TINYINT(1) NOT NULL DEFAULT 1,
    dental_id BIGINT UNSIGNED NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
    INDEX idx_dental_id (dental_id),
    FOREIGN KEY (dental_id) REFERENCES wp_dentals(id) ON DELETE SET NULL
);
```

### Main Dental Table Changes

The main dental table now uses comma-separated attachment IDs instead of JSON:

```sql
ALTER TABLE wp_dentals 
CHANGE COLUMN attachments attachment_ids TEXT NOT NULL DEFAULT '';
```

## Key Features

### 1. File Upload Process

1. **Initial Upload**: Files are uploaded with `is_temp = 1` and `dental_id = NULL`
2. **Order Submission**: When order is submitted, files are updated to `is_temp = 0` and assigned `dental_id`
3. **Automatic Cleanup**: Temporary files older than 24 hours are automatically deleted

### 2. Security Features

- **Nonce verification** for all AJAX requests
- **User authentication** checks
- **File type validation** with MIME type checking
- **File size limits** (200MB max)
- **Secure file naming** with unique identifiers
- **FTP storage** for secure file hosting

### 3. Supported File Types

- **Images**: PNG, JPEG, WebP, HEIC, HEIF
- **Videos**: MP4, WebM, MOV, AVI, MKV
- **Audio**: MP3, WAV, OGG, M4A, AAC, FLAC
- **Archives**: ZIP, RAR, 7Z, TAR, GZ
- **3D/CAD**: STL, FLY
- **Documents**: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, CSV, TXT, RTF

## Installation

### 1. Include Required Files

```php
// In your theme's functions.php
require_once get_template_directory() . '/inc/dental-database.php';
require_once get_template_directory() . '/inc/file-upload-handlers.php';

// Enqueue assets
wp_enqueue_script('dental-file-upload', get_template_directory_uri() . '/js/file-upload-component.js', array(), '1.0.0', true);
wp_enqueue_style('dental-file-upload', get_template_directory_uri() . '/css/file-upload-component.css', array(), '1.0.0');
```

### 2. Provide WordPress Data

```php
// Add to your page template
wp_localize_script('dental-file-upload', 'dentalUploadData', array(
    'userId' => get_current_user_id(),
    'nonces' => array(
        'upload' => wp_create_nonce('dental_file_upload'),
        'delete' => wp_create_nonce('dental_file_delete')
    ),
    'ajaxUrl' => admin_url('admin-ajax.php')
));
```

### 3. Add HTML Structure

```html
<div id="dental-file-upload">
    <div id="dental-upload-area" class="upload-area">
        <div class="upload-content">
            <i class="bi bi-cloud-upload"></i>
            <h3>فایل‌های خود را اینجا رها کنید</h3>
            <p>یا کلیک کنید تا فایل انتخاب کنید</p>
            <button type="button" id="dental-select-btn" class="btn btn-primary">انتخاب فایل</button>
        </div>
        <input type="file" id="dental-file-input" multiple style="display: none;">
    </div>
    
    <div id="dental-progress" class="progress-container" style="display: none;">
        <h4>در حال آپلود...</h4>
        <div id="dental-progress-list"></div>
        <button type="button" id="dental-cancel-btn" class="btn btn-secondary">لغو همه</button>
    </div>
    
    <div id="dental-file-list" class="file-list-container" style="display: none;">
        <div class="file-list-header">
            <h4>فایل‌های انتخاب شده</h4>
            <span id="dental-file-count">0 فایل</span>
            <button type="button" id="dental-clear-btn" class="btn btn-danger">پاک کردن همه</button>
        </div>
        <div id="dental-file-list-items"></div>
    </div>
</div>
```

## Usage

### Basic Implementation

```javascript
// Initialize the component
const uploadComponent = new DentalFileUpload({
    onFileAdded: function(file, uploadData) {
        console.log('File added:', file.name);
    },
    onUploadComplete: function(file, uploadData) {
        console.log('Upload complete:', file.name);
    },
    onUploadError: function(file, error) {
        console.error('Upload error:', error);
    }
});
```

### Advanced Configuration

```javascript
const uploadComponent = new DentalFileUpload({
    // Upload settings
    maxFiles: 10,
    maxFileSize: 100 * 1024 * 1024, // 100 MB
    
    // UI settings
    showProgress: true,
    showFileList: true,
    showFormatInfo: true,
    dragDropEnabled: true,
    
    // Callbacks
    onFileAdded: function(file, uploadData) {
        // Handle file added
    },
    onFileRemoved: function(file) {
        // Handle file removed
    },
    onUploadComplete: function(file, uploadData) {
        // Handle upload complete
    },
    onUploadError: function(file, error) {
        // Handle upload error
    },
    onValidationError: function(file, errors) {
        // Handle validation error
    }
});
```

### Form Integration

```javascript
// Get uploaded file IDs for form submission
const fileIds = uploadComponent.getUploadedFileIds();

// Submit form with file IDs
const formData = new FormData();
formData.append('attachments', JSON.stringify(fileIds));
formData.append('action', 'submit_dental_order');
formData.append('nonce', dentalUploadData.nonces.submit);

fetch(dentalUploadData.ajaxUrl, {
    method: 'POST',
    body: formData
})
.then(response => response.json())
.then(data => {
    if (data.success) {
        console.log('Order submitted successfully');
    }
});
```

## API Reference

### Component Methods

#### `getSelectedFiles()`
Returns array of selected file objects with upload data.

#### `getUploadedFileIds()`
Returns array of uploaded file IDs for form submission.

```javascript
const fileIds = uploadComponent.getUploadedFileIds();
// Returns: ['file_123456_1234567890', 'file_789012_1234567891']
```

#### `clearAllFiles()`
Removes all files and cancels ongoing uploads.

#### `destroy()`
Destroys the component and cleans up resources.

### Configuration Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `maxFiles` | number | 15 | Maximum number of files allowed |
| `maxFileSize` | number | 200MB | Maximum file size in bytes |
| `allowedTypes` | object | See code | Allowed MIME types |
| `showProgress` | boolean | true | Show upload progress |
| `showFileList` | boolean | true | Show file list |
| `showFormatInfo` | boolean | true | Show file format information |
| `dragDropEnabled` | boolean | true | Enable drag and drop |

## Database Functions

### PHP Functions

#### `add_dental_attachment($attachment_data)`
Add a new attachment to the database.

#### `get_dental_attachments($dental_id, $include_temp = false)`
Get attachments for a dental order.

#### `update_attachments_to_permanent($file_ids, $dental_id)`
Update temporary attachments to permanent status.

#### `cleanup_temp_attachments($hours_old = 24)`
Delete temporary attachments older than specified hours.

#### `get_dental_attachment_ids($dental_id)`
Get comma-separated attachment IDs for a dental order.

## Migration

### From Old System

If you're upgrading from the old WordPress options system:

1. **Run Database Migration**:
   ```php
   // Go to Tools > Dental Database in WordPress admin
   // Click "Migrate Attachments" button
   ```

2. **Update Your Code**:
   - Replace JSON attachment handling with comma-separated IDs
   - Use new database functions for attachment management

### Manual Migration

```php
// Run migration programmatically
$result = migrate_dental_attachments_from_options();
echo $result['message'];
```

## Maintenance

### Automatic Cleanup

The system automatically cleans up temporary files:
- **Schedule**: Hourly cleanup job
- **Age**: Files older than 24 hours
- **Action**: Delete from database and file system

### Manual Cleanup

```php
// Clean up temporary files manually
$deleted_count = cleanup_temp_attachments(24);
echo "Deleted {$deleted_count} temporary files";
```

## Security Considerations

1. **File Validation**: All files are validated for type and size
2. **User Authentication**: Only logged-in users can upload files
3. **Nonce Protection**: All AJAX requests use WordPress nonces
4. **Secure Storage**: Files are stored on separate FTP server
5. **Temporary Files**: Unused files are automatically cleaned up

## Troubleshooting

### Common Issues

1. **Upload Fails**: Check FTP credentials and server connectivity
2. **File Type Rejected**: Verify file is in allowed types list
3. **Database Errors**: Ensure dental_attachments table exists
4. **Cleanup Not Working**: Check WordPress cron is enabled

### Debug Mode

Enable debug logging in WordPress to see detailed error messages:

```php
// In wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
```

## Performance Optimization

1. **Database Indexing**: Proper indexes on frequently queried columns
2. **File Cleanup**: Regular cleanup prevents disk space issues
3. **Separate Table**: Attachments table reduces main table size
4. **Comma-separated IDs**: Faster queries than JSON parsing

## Support

For issues and questions:
1. Check the WordPress debug log
2. Verify database table structure
3. Test FTP connectivity
4. Review file permissions
