# CLAUDE.md
This file provides guidance to Claude Code when working with code in this repository.
## Overview
This is a **XenForo 2.3.6** development environment for building custom addons. It runs in Docker containers (PHP-FPM + Nginx + MariaDB) with Xdebug support.
**Access Points**:
- Web UI: http://localhost
- Admin Panel: http://localhost/admin.php (credentials: `admin` / `admin`)
- Database: localhost:3306 (user: `xenforo`, password: `password`)
**Quick Start**: `docker compose up -d` to start, `docker compose stop` to stop. See [Docker Management](docs/docker-management.md) for details.
## Essential CLI Pattern
All XenForo commands run inside the Docker container:
```sh
docker exec -it xenforo php cmd.php <command>
```
**Common commands**: `xf-addon:create`, `xf-addon:export`, `xf:addon-install`, `xf-dev:import`, `xf-dev:export`, `xf-dev:rebuild-caches`
See [CLI Commands Reference](docs/cli-commands.md) for complete list and usage examples.
## Directory Structure
```
src/addons/Vendor/AddonName/
├── addon.json # Addon metadata
├── Setup.php # Install/upgrade logic (optional)
├── Entity/ # Database entities
├── Repository/ # Data access layer
├── Pub/Controller/ # Public controllers
├── Admin/Controller/ # Admin controllers
├── ThreadType/ # Custom thread types (optional)
├── XF/ # Core class extensions
└── _output/ # Development exports (Git-tracked)
├── templates/
├── phrases/
├── permissions/
└── ...
```
## Core XenForo Concepts
- **Entities**: Database models with relations (ORM pattern)
- **Repositories**: Data access layer for fetching/manipulating entities
- **Controllers**: HTTP request handlers (Pub = frontend, Admin = backend)
- **Templates**: XenForo template syntax (similar to Twig/Smarty)
- **Phrases**: Translatable text strings
- **Options**: Admin-configurable settings
- **Permissions**: User permission system
- **Class Extensions**: XenForo's approach to extending core classes (XFCP pattern)
- **Code Event Listeners**: Hook into core events without extending classes
## Development Workflow
1. **Create**: `xf-addon:create` or manually create addon structure
2. **Edit**: Add PHP classes, templates, phrases via code or Admin CP
3. **Export**: `xf-addon:export` to save Admin CP changes to `_output/`
4. **Import**: `xf-dev:import -a Vendor/AddonName` to import changes made to `_output/`
4. **Test**: Install/enable addon, test functionality
5. **Commit**: Both PHP classes and `_output/` directory
**Critical**: Always import after making changes in the `_output/` directory. This directory is your source of truth for version control.
## Addon Development Essentials
**Namespace Convention**: PSR-4 autoloading. `Vendor/AddonName` → `Vendor\AddonName\...`
**Class Extensions**: To extend `XF\Entity\Thread`, create `src/addons/Vendor/AddonName/XF/Entity/Thread.php`
**addon.json Structure**:
```json
{
"title": "My Addon",
"version_id": 1000010,
"version_string": "1.0.0 Alpha",
"dev": "Developer Name",
"require": [],
"icon": "fa-icon-name"
}
```
**Development Mode**: Enabled in `config.php`. PHP changes reflect immediately, `_output/` stores development files.
## XenForo Core Reference (READ-ONLY)
**CRITICAL**: The directory `src/addons/XF/_output/` contains XenForo's core database configuration exported as files. This is NOT a custom addon—it's the core framework reference.
**This directory is READ-ONLY**. Do not edit these files.
**Purpose**: Search and reference built-in templates, phrases, permissions, events, and understand XenForo's internal structure.
**Key subdirectories**:
- `templates/` - Core XenForo templates (find extension points)
- `phrases/` - Core translatable strings
- `permissions/` - Permission definitions
- `code_events/` - Available events to hook into
- `options/` - Admin options
- `routes/` - Route definitions
**Your custom addon's `_output/`** is at `src/addons/YourVendor/YourAddon/_output/` and IS editable via Admin CP and `xf-addon:export`.
## Best Practices
### Avoid PHP Reflection for Accessing Protected/Private Members
**IMPORTANT**: Avoid using PHP Reflection API (`ReflectionClass`, `ReflectionMethod`, `ReflectionProperty`) to access protected/private methods/properties unless absolutely no other solution exists.
**Preferred approaches**:
1. Make methods public in your addon class when extending
2. Create new public wrapper methods
3. Redesign to avoid needing protected members
4. Override parent's public method that calls the protected one
**Only use reflection when**:
- No public API exists in XenForo core
- Cannot override or extend the class appropriately
- Alternative implementation is impractical
**Why avoid reflection**:
- Breaks encapsulation, makes code fragile
- Breaks silently when signatures change
- Performance overhead
- Cannot be tracked by IDE/static analysis tools
- Makes debugging difficult
## Documentation
**Before working on specialized tasks, consult the relevant documentation**:
- [CLI Commands Reference](docs/cli-commands.md) - Complete XenForo command reference with examples
- [Docker Management](docs/docker-management.md) - Container operations, volume management, troubleshooting
- [Thread Types Implementation](docs/thread-types.md) - Custom thread type development (capabilities, templates, lifecycle)
- [Template Macros Guide](docs/template-macros.md) - Macro definition, calling, extension patterns
- [Development Setup](docs/development-setup.md) - IDE configuration, Xdebug, database access, debugging
- [JavaScript Implementation](docs/javascript-implementation.md) - JavaScript in XenForo addons
## Configuration
Main config: `/config.php` (root, not `src/config.php`). Mounted into container.
**Current settings**: Debug enabled, Development mode enabled, Email disabled (for local dev).
See [Development Setup](docs/development-setup.md) for detailed configuration options.