Loki_UploadFieldComponents
File upload field component for Loki Checkout and Loki Field Components.
Overview
This module provides a reusable file upload field component that integrates with the Loki Field Components architecture. It allows developers to easily add file upload functionality to forms, checkouts, or any other frontend context where Loki Components are used.
Features
- Configurable Upload Location: Files are stored in
pub/media/order_attachment/by default (configurable) - Configurable File Types: Images (jpg, jpeg, png, gif, webp) by default (configurable)
- Configurable File Size: Uses Magento default limits (configurable)
- Single File Upload: Optimized for single file uploads
- Alpine.js Integration: Automatic upload on file selection
- Extensible Architecture: Easy to extend with custom repositories and configurations
Installation
composer require loki/magento2-upload-field-components
bin/magento module:enable Loki_UploadFieldComponents
bin/magento setup:upgrade
bin/magento cache:clean config
Basic Usage
Add an upload field to any layout XML:
<block name="my.upload.field" template="Loki_FieldComponents::form/field.phtml"> <arguments> <argument name="field_type" xsi:type="string">upload</argument> <argument name="field_name" xsi:type="string">my_file</argument> <argument name="field_label" xsi:type="string" translate="true">Upload File</argument> <argument name="required" xsi:type="boolean">false</argument> <argument name="component_name" xsi:type="string">loki-field-components.upload</argument> </arguments> </block>
Advanced Configuration
Custom Upload Path
To change the upload directory, create a virtual type in your module's di.xml:
<!-- Custom upload path: pub/media/custom_uploads/ --> <virtualType name="YourModule\Model\CustomUploadConfig" type="Loki\UploadFieldComponents\Model\Config\UploadConfig"> <arguments> <argument name="uploadPath" xsi:type="string">custom_uploads</argument> </arguments> </virtualType> <virtualType name="YourModule\Model\CustomFileUploader" type="Loki\UploadFieldComponents\Model\FileUploader"> <arguments> <argument name="config" xsi:type="object">YourModule\Model\CustomUploadConfig</argument> </arguments> </virtualType> <type name="YourModule\Component\CustomUpload\CustomUploadRepository"> <arguments> <argument name="fileUploader" xsi:type="object">YourModule\Model\CustomFileUploader</argument> </arguments> </type>
Custom File Types (PDF Only)
<virtualType name="YourModule\Model\PdfUploadConfig" type="Loki\UploadFieldComponents\Model\Config\UploadConfig"> <arguments> <argument name="uploadPath" xsi:type="string">pdf_documents</argument> <argument name="allowedExtensions" xsi:type="array"> <item name="pdf" xsi:type="string">pdf</item> </argument> <argument name="maxFileSizeMb" xsi:type="number">10</argument> </arguments> </virtualType>
Custom File Size Limit
<type name="Loki\UploadFieldComponents\Model\Config\UploadConfig"> <arguments> <argument name="maxFileSizeMb" xsi:type="number">5</argument> </arguments> </type>
Extending the Repository
To add custom logic after file upload (e.g., save file reference to quote or database):
<?php declare(strict_types=1); namespace YourModule\Component\CustomUpload; use Loki\UploadFieldComponents\Component\UploadField\UploadFieldRepository; use Magento\Quote\Model\Quote; class CustomUploadRepository extends UploadFieldRepository { public function __construct( private Quote $quote, ...$parentArgs ) { parent::__construct(...$parentArgs); } protected function afterFileUpload(array $uploadResult): void { // Save the file path to the quote $this->quote->setData('attachment_path', $uploadResult['path']); $this->quote->setData('attachment_name', $uploadResult['name']); $this->quote->save(); } public function getValue(): mixed { // Return the saved file path return $this->quote->getData('attachment_path') ?: false; } }
Register your custom repository in etc/loki_components.xml:
<component name="your-module.custom-upload" viewModel="Loki\UploadFieldComponents\Component\UploadField\UploadFieldViewModel" repository="YourModule\Component\CustomUpload\CustomUploadRepository" />
Use it in layout XML:
<block name="my.custom.upload" template="Loki_FieldComponents::form/field.phtml"> <arguments> <argument name="field_type" xsi:type="string">upload</argument> <argument name="field_name" xsi:type="string">custom_upload</argument> <argument name="component_name" xsi:type="string">your-module.custom-upload</argument> </arguments> </block>
Architecture
Component Structure
- UploadConfig: Configuration class for upload settings (path, extensions, size limit)
- FileUploader: Utility class that handles the actual file upload using Magento's
UploaderFactory - UploadFieldRepository: Repository that coordinates file upload and provides extension hooks
- UploadFieldViewModel: View model for rendering the upload field
Upload Flow
- User selects a file in the browser
- Alpine.js
@changeevent triggerssubmitValue - File is sent to
loki_components/index/htmlcontroller - Repository's
saveValue()method is called FileUploadervalidates and uploads the fileafterFileUpload()hook is called for custom logic- Success/error message is displayed to the user
File Storage
By default, files are stored in:
pub/media/order_attachment/
The uploaded file name may be renamed if a file with the same name already exists (e.g., file.jpg becomes file_1.jpg).
Dependencies
Loki_Components- Base component architectureLoki_FieldComponents- Field component base classesMagento_MediaStorage- File upload handling
Configuration Options
UploadConfig Constructor Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| uploadPath | string | order_attachment | Directory path relative to pub/media/ |
| allowedExtensions | array | ['jpg', 'jpeg', 'png', 'gif', 'webp'] | Allowed file extensions |
| maxFileSizeMb | int|null | null | Max file size in MB (null = Magento default) |
Extension Points
afterFileUpload(array $uploadResult): void
Called after successful file upload. Override this method in your custom repository to add post-upload logic.
Upload Result Array:
[
'file' => 'filename.jpg', // Uploaded file name
'path' => 'order_attachment/filename.jpg', // Relative path
'absolute_path' => '/path/to/pub/media/order_attachment/filename.jpg',
'name' => 'original_name.jpg', // Original file name
'type' => 'image/jpeg', // MIME type
'size' => 12345 // File size in bytes
]
Limitations
- Single file upload only (multiple file upload not supported)
- No built-in file preview functionality
- No built-in database storage (must be implemented by extending modules)
- Files are not automatically deleted when orders are cancelled
Future Enhancements
- Multiple file upload support
- File preview after selection
- Database table for file metadata
- Integration with quote/order lifecycle
- File cleanup cron job for orphaned files
- Admin configuration interface
Troubleshooting
Files not uploading
-
Check PHP settings:
upload_max_filesize(default: 2M)post_max_size(default: 8M)max_execution_time(default: 30s)
-
Check directory permissions:
chmod 775 pub/media/order_attachment/ -
Check error messages in browser console and Magento logs:
tail -f var/log/system.log
File type not accepted
Make sure the file extension is in the allowedExtensions array in your UploadConfig.
File size limit exceeded
Either reduce the file size or increase the maxFileSizeMb setting in your UploadConfig. Note that PHP's upload_max_filesize setting must also be increased.
License
OSL-3.0
Author
Loki Extensions
Support
For issues and questions, please visit:
- GitHub: https://github.com/loki-extensions
- Documentation: https://loki-extensions.com
@dev
to the composer command.
Support
For getting support, create an Issue under the following project URL:
https://gitlab.yireo.com/loki-checkout/Loki_UploadFieldComponents.git
Composer details
Loki_UploadFieldComponentsloki/magento2-upload-field-components
php: ^8.1|^8.2|^8.3
magento/framework: *
loki/magento2-components: *
loki/magento2-field-components: *