# Developer Documentation

## Architecture Overview

AppsFruit Elementor Embed follows a modular, object-oriented architecture with clear separation of concerns.

### File Structure

```
appsfruit-elementor-embed/
├── appsfruit-elementor-embed.php    # Main plugin file
├── uninstall.php                     # Uninstall cleanup
├── includes/                         # Core functionality
│   ├── class-aefe-post-type.php     # Custom post type registration
│   ├── class-aefe-shortcode.php     # Shortcode handler
│   ├── class-aefe-admin.php         # Admin UI enhancements
│   ├── class-aefe-gutenberg.php     # Gutenberg block
│   └── class-aefe-hooks.php         # Developer hooks documentation
├── assets/                           # Frontend/admin assets
│   ├── css/
│   │   ├── admin.css                # Admin styles
│   │   └── block-editor.css         # Block editor styles
│   └── js/
│       ├── admin.js                 # Admin JavaScript
│       └── block.js                 # Gutenberg block JavaScript
├── templates/                        # Template files
│   └── single-aefe-template.php     # Single template display
├── languages/                        # Translation files (empty by default)
├── README.md                         # User documentation
├── SETUP.md                          # Setup instructions
├── CHANGELOG.md                      # Version history
└── DEVELOPER.md                      # This file
```

## Core Classes

### AppsFruit_Elementor_Embed (Main Class)

**File:** `appsfruit-elementor-embed.php`

**Responsibilities:**
- Plugin initialization
- Dependency checking (Elementor)
- Loading core components
- Activation/deactivation hooks

**Key Methods:**
```php
instance()              // Singleton pattern
init()                  // Initialize components
load_textdomain()       // Load translations
activate()              // Activation hook
deactivate()            // Deactivation hook
```

### AEFE_Post_Type

**File:** `includes/class-aefe-post-type.php`

**Responsibilities:**
- Register `aefe_template` custom post type
- Register taxonomies (categories and tags)
- Handle single template display

**Key Methods:**
```php
register_post_type()    // Register CPT
register_taxonomies()   // Register taxonomies
template_include()      // Custom template loader
```

**Constants:**
```php
AEFE_Post_Type::POST_TYPE           // 'aefe_template'
AEFE_Post_Type::CATEGORY_TAXONOMY   // 'aefe_category'
AEFE_Post_Type::TAG_TAXONOMY        // 'aefe_tag'
```

### AEFE_Shortcode

**File:** `includes/class-aefe-shortcode.php`

**Responsibilities:**
- Register and handle `[aefe_embed]` shortcode
- Process conditional display logic
- Render templates using Elementor

**Key Methods:**
```php
render_shortcode()              // Main shortcode handler
should_display()                // Check display conditions
check_device_condition()        // Device-based logic
check_role_condition()          // Role-based logic
check_post_type_condition()     // Post type logic
render_template()               // Render with Elementor
render_error()                  // Error display
```

### AEFE_Admin

**File:** `includes/class-aefe-admin.php`

**Responsibilities:**
- Admin UI enhancements
- Shortcode column in list view
- Quick copy functionality
- Meta boxes
- Help page

**Key Methods:**
```php
add_shortcode_column()          // Add column to list
render_shortcode_column()       // Render column content
add_elementor_edit_link()       // Add edit link
enqueue_admin_assets()          // Load CSS/JS
add_shortcode_meta_box()        // Register meta box
render_shortcode_meta_box()     // Render meta box
render_help_page()              // Help page content
```

### AEFE_Gutenberg

**File:** `includes/class-aefe-gutenberg.php`

**Responsibilities:**
- Register Gutenberg block
- Provide template selector
- Server-side rendering

**Key Methods:**
```php
register_block()                // Register block type
enqueue_block_editor_assets()   // Load block assets
get_templates_for_block()       // Get template list
render_block()                  // Server-side render
render_placeholder()            // Empty state
```

### AEFE_Hooks

**File:** `includes/class-aefe-hooks.php`

**Responsibilities:**
- Documentation for available hooks
- Example usage code

## Hooks Reference

### Actions

#### aefe_init
Fires after plugin initialization.

```php
add_action( 'aefe_init', function() {
    // Plugin is fully loaded
} );
```

#### aefe_activated
Fires when plugin is activated.

```php
add_action( 'aefe_activated', function() {
    // Run activation tasks
} );
```

#### aefe_deactivated
Fires when plugin is deactivated.

```php
add_action( 'aefe_deactivated', function() {
    // Run deactivation tasks
} );
```

#### aefe_before_render_template
Fires before template rendering.

```php
add_action( 'aefe_before_render_template', function( $post_id, $atts ) {
    // Enqueue specific scripts/styles
    // Track analytics
}, 10, 2 );
```

#### aefe_after_render_template
Fires after template rendering.

```php
add_action( 'aefe_after_render_template', function( $post_id, $atts ) {
    // Clean up
    // Log usage
}, 10, 2 );
```

### Filters

#### aefe_post_type_args
Modify post type registration arguments.

```php
add_filter( 'aefe_post_type_args', function( $args ) {
    $args['menu_position'] = 25;
    $args['menu_icon'] = 'dashicons-admin-page';
    return $args;
} );
```

#### aefe_category_taxonomy_args
Modify category taxonomy arguments.

```php
add_filter( 'aefe_category_taxonomy_args', function( $args ) {
    $args['hierarchical'] = false;
    return $args;
} );
```

#### aefe_tag_taxonomy_args
Modify tag taxonomy arguments.

```php
add_filter( 'aefe_tag_taxonomy_args', function( $args ) {
    $args['show_admin_column'] = false;
    return $args;
} );
```

#### aefe_shortcode_atts
Modify shortcode attributes before processing.

```php
add_filter( 'aefe_shortcode_atts', function( $atts ) {
    // Add custom attribute
    if ( ! isset( $atts['custom'] ) ) {
        $atts['custom'] = '';
    }
    return $atts;
} );
```

#### aefe_should_display
Add custom display conditions.

```php
add_filter( 'aefe_should_display', function( $should_display, $atts ) {
    // Add custom logic
    if ( isset( $atts['custom'] ) && $atts['custom'] === 'value' ) {
        return your_custom_check();
    }
    return $should_display;
}, 10, 2 );
```

#### aefe_should_render_template
Prevent template rendering conditionally.

```php
add_filter( 'aefe_should_render_template', function( $should_render, $post_id, $atts ) {
    // Prevent rendering based on custom logic
    if ( your_condition() ) {
        return false;
    }
    return $should_render;
}, 10, 3 );
```

#### aefe_template_content
Modify template output.

```php
add_filter( 'aefe_template_content', function( $content, $post_id, $atts ) {
    // Wrap or modify content
    return '<div class="custom-wrapper">' . $content . '</div>';
}, 10, 3 );
```

#### aefe_wrapper_classes
Modify wrapper CSS classes.

```php
add_filter( 'aefe_wrapper_classes', function( $classes, $post_id, $atts ) {
    $classes[] = 'my-custom-class';
    
    // Add class based on template category
    $categories = get_the_terms( $post_id, 'aefe_category' );
    if ( $categories ) {
        foreach ( $categories as $cat ) {
            $classes[] = 'aefe-cat-' . $cat->slug;
        }
    }
    
    return $classes;
}, 10, 3 );
```

#### aefe_error_message
Modify error messages.

```php
add_filter( 'aefe_error_message', function( $message ) {
    // Customize error messages
    return 'Custom error: ' . $message;
} );
```

## Common Development Tasks

### 1. Adding a Custom Condition

```php
// Step 1: Add attribute support
add_filter( 'aefe_shortcode_atts', function( $atts ) {
    if ( ! isset( $atts['time_range'] ) ) {
        $atts['time_range'] = '';
    }
    return $atts;
} );

// Step 2: Implement condition logic
add_filter( 'aefe_should_display', function( $should_display, $atts ) {
    if ( ! empty( $atts['time_range'] ) ) {
        $current_hour = (int) date( 'H' );
        
        switch ( $atts['time_range'] ) {
            case 'morning':
                return $current_hour >= 6 && $current_hour < 12;
            case 'afternoon':
                return $current_hour >= 12 && $current_hour < 18;
            case 'evening':
                return $current_hour >= 18 && $current_hour < 24;
            case 'night':
                return $current_hour >= 0 && $current_hour < 6;
        }
    }
    return $should_display;
}, 10, 2 );

// Usage: [aefe_embed id="123" time_range="morning"]
```

### 2. Tracking Template Views

```php
// Track views
add_action( 'aefe_after_render_template', function( $post_id, $atts ) {
    $views = get_post_meta( $post_id, '_aefe_views', true );
    $views = $views ? (int) $views : 0;
    update_post_meta( $post_id, '_aefe_views', $views + 1 );
}, 10, 2 );

// Display views in admin column
add_filter( 'manage_aefe_template_posts_columns', function( $columns ) {
    $columns['views'] = __( 'Views', 'your-textdomain' );
    return $columns;
} );

add_action( 'manage_aefe_template_posts_custom_column', function( $column, $post_id ) {
    if ( 'views' === $column ) {
        $views = get_post_meta( $post_id, '_aefe_views', true );
        echo $views ? $views : '0';
    }
}, 10, 2 );
```

### 3. Adding Custom Meta Fields

```php
// Add meta box
add_action( 'add_meta_boxes', function() {
    add_meta_box(
        'aefe_custom_meta',
        __( 'Custom Settings', 'your-textdomain' ),
        'render_custom_meta_box',
        'aefe_template',
        'side'
    );
} );

function render_custom_meta_box( $post ) {
    $custom_value = get_post_meta( $post->ID, '_aefe_custom', true );
    wp_nonce_field( 'aefe_custom_meta', 'aefe_custom_nonce' );
    ?>
    <label>
        <input type="checkbox" name="aefe_custom" value="1" <?php checked( $custom_value, '1' ); ?>>
        <?php _e( 'Enable custom feature', 'your-textdomain' ); ?>
    </label>
    <?php
}

// Save meta
add_action( 'save_post_aefe_template', function( $post_id ) {
    if ( ! isset( $_POST['aefe_custom_nonce'] ) || 
         ! wp_verify_nonce( $_POST['aefe_custom_nonce'], 'aefe_custom_meta' ) ) {
        return;
    }
    
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }
    
    $value = isset( $_POST['aefe_custom'] ) ? '1' : '0';
    update_post_meta( $post_id, '_aefe_custom', $value );
} );
```

### 4. Modifying Template Output

```php
// Add schema markup
add_filter( 'aefe_template_content', function( $content, $post_id, $atts ) {
    $schema = '<script type="application/ld+json">' . json_encode( array(
        '@context' => 'https://schema.org',
        '@type' => 'WebPageElement',
        'name' => get_the_title( $post_id ),
    ) ) . '</script>';
    
    return $schema . $content;
}, 10, 3 );
```

### 5. Creating a Template Library

```php
// Add custom taxonomy for template library
add_action( 'init', function() {
    register_taxonomy( 'aefe_library', 'aefe_template', array(
        'label' => __( 'Template Library', 'your-textdomain' ),
        'hierarchical' => true,
        'show_ui' => true,
        'show_admin_column' => true,
    ) );
} );

// Filter templates by library
add_filter( 'aefe_should_render_template', function( $should_render, $post_id, $atts ) {
    if ( isset( $atts['library'] ) ) {
        $terms = get_the_terms( $post_id, 'aefe_library' );
        if ( $terms ) {
            $slugs = wp_list_pluck( $terms, 'slug' );
            return in_array( $atts['library'], $slugs );
        }
        return false;
    }
    return $should_render;
}, 10, 3 );

// Usage: [aefe_embed id="123" library="premium"]
```

## JavaScript API

### Admin JavaScript

The admin JavaScript provides clipboard functionality:

```javascript
// Available in admin.js
jQuery(document).on('click', '.aefe-copy-shortcode', function(e) {
    // Copy shortcode to clipboard
});
```

### Gutenberg Block

The block is registered in `assets/js/block.js`:

```javascript
wp.blocks.registerBlockType('aefe/embed-template', {
    // Block configuration
});
```

**Block Attributes:**
- `templateId` (number) - Template ID
- `device` (string) - Device condition
- `role` (string) - Role condition
- `postType` (string) - Post type condition

## Database Schema

### Post Type: aefe_template

Standard WordPress post table with:
- `post_type` = 'aefe_template'
- Supports: title, editor, thumbnail, revisions, author
- Elementor data stored in post meta

### Taxonomies

**aefe_category:**
- Hierarchical
- Used for organizing templates

**aefe_tag:**
- Non-hierarchical
- Used for labeling templates

### Post Meta

No custom post meta by default. Elementor stores its data in:
- `_elementor_data` - Elementor content
- `_elementor_edit_mode` - Edit mode
- `_elementor_template_type` - Template type
- `_elementor_version` - Elementor version

## Testing

### Manual Testing Checklist

- [ ] Create new template
- [ ] Edit with Elementor
- [ ] Copy shortcode
- [ ] Embed in post/page
- [ ] Test device conditions
- [ ] Test role conditions
- [ ] Test post type conditions
- [ ] Test Gutenberg block
- [ ] Test categories/tags
- [ ] Test template deletion
- [ ] Test plugin activation/deactivation
- [ ] Test without Elementor (should show notice)

### Unit Testing (Future)

Consider adding PHPUnit tests for:
- Shortcode parsing
- Condition checking
- Template rendering
- Hook execution

## Performance Considerations

1. **Caching**: Elementor handles its own caching
2. **Asset Loading**: Admin assets only load on AFE pages
3. **Database Queries**: Optimized with proper indexes
4. **Lazy Loading**: Templates render on-demand

## Security Best Practices

1. **Input Sanitization**: All user inputs are sanitized
2. **Output Escaping**: All outputs are escaped
3. **Capability Checks**: Admin functions check capabilities
4. **Nonce Verification**: Forms use nonces
5. **Direct Access Prevention**: All files check `ABSPATH`

## Coding Standards

This plugin follows:
- WordPress Coding Standards
- PHP 7.4+ compatibility
- PSR-4 autoloading structure
- Semantic versioning

## Contributing

When contributing:
1. Follow WordPress coding standards
2. Add inline documentation
3. Test thoroughly
4. Update CHANGELOG.md
5. Maintain backward compatibility

## Support

For developer support:
- GitHub: [Repository URL]
- Email: developers@appsfruit.com
- Documentation: README.md, SETUP.md
