Overview
FacturaScripts provides a powerful extension system that allows plugins to modify the behavior of core classes without modifying their source code. This is achieved through:- ExtensionsTrait - Dynamic method injection system
- InitClass - Plugin initialization and extension registration
- Extension pattern - Organized extension structure
How Extensions Work
Extensions allow you to:- Add new methods to existing classes
- Override existing method behavior
- Hook into lifecycle events (save, delete, etc.)
- Modify data before/after operations
Extension Architecture
The extension system uses PHP’s magic methods and closures:- Extensions are registered via
addExtension() - Extension methods return closures
- Closures are bound to the target class context
- Extensions can be prioritized (0-1000)
Creating Extensions
Plugin Structure
Extensions are organized in your plugin’sExtension directory:
Basic Extension Example
Extend theCliente (Customer) model:
Plugins/MyPlugin/Extension/Model/Cliente.php:
Registering Extensions
Register your extensions in the plugin’sInit.php:
Plugins/MyPlugin/Init.php:
Using Extended Methods
Once registered, the extended methods can be called on model instances:Extension Hooks
Model Lifecycle Hooks
Intercept model operations:Validation Hooks
Extending Business Documents
Business documents (invoices, orders, etc.) can be extended at once:Extend All Business Documents
Extension/Model/Base/BusinessDocument.php:AlbaranCliente/AlbaranProveedorFacturaCliente/FacturaProveedorPedidoCliente/PedidoProveedorPresupuestoCliente/PresupuestoProveedor
Extend Sales Documents Only
Extension/Model/Base/SalesDocument.php:AlbaranCliente, FacturaCliente, PedidoCliente, PresupuestoCliente
Extend Purchase Documents Only
Extension/Model/Base/PurchaseDocument.php:AlbaranProveedor, FacturaProveedor, PedidoProveedor, PresupuestoProveedor
Extending Controllers
Extend All Edit Controllers
Extension/Controller/EditController.php:Extend All List Controllers
Extension/Controller/ListController.php:Extend Specific Controller
Extension/Controller/EditCliente.php:Extension Priority
When multiple extensions implement the same method, priority determines execution order:Pipe Methods
Thepipe() method allows multiple extensions to process data sequentially:
PipeFalse Method
Stop execution if any extension returnsfalse:
Auto-Loading Extensions
TheloadExtension() method automatically targets the correct classes:
Best Practices
Return null to continue
Return null to continue
Extensions should return
null to allow normal execution:Return false to stop
Return false to stop
Return
false to prevent the operation:Use meaningful method names
Use meaningful method names
Choose descriptive names for extension methods:
Document your extensions
Document your extensions
Add PHPDoc comments to extension methods:
Handle errors gracefully
Handle errors gracefully
Catch exceptions in extensions:
Common Extension Patterns
Adding Custom Fields
Logging Changes
Sending Notifications
Data Validation
Reference
ExtensionsTrait Methods
| Method | Description |
|---|---|
addExtension($ext, $priority) | Register extension with priority |
clearExtensions() | Remove all extensions |
getExtensions() | Get list of extension names |
hasExtension($name) | Check if extension exists |
pipe($name, ...$args) | Execute all extensions for method |
pipeFalse($name, ...$args) | Execute until one returns false |
removeExtension($name) | Remove specific extension |
Common Hook Methods
| Hook | When Called | Use Case |
|---|---|---|
clear() | After clearing model | Initialize fields |
test() | Before validation | Add validation |
save() | Before save | Pre-save logic |
saveInsert() | Before insert | Modify insert data |
saveUpdate() | Before update | Modify update data |
delete() | Before delete | Prevent deletion |
loadData() | When loading view | Add custom data |
execPreviousAction() | Before action | Log/validate action |

