4 min readAug 10, 2026by jakub
Changelog
Current version: 1.1.0
All notable changes to the Qoliber Product Attachments module are documented here. The format is based on Keep a Changelog.
[1.1.0] - 2026-07-27
Fixed
- The
Enabledsystem configuration switch now actually gates the module. It had no call sites, so attachments rendered and downloaded regardless of the setting. The shipped default moves from0to1so existing stores keep their current behaviour. - System configuration referenced the ACL resource
Qoliber_ProductAttachments::config, whichacl.xmlnever defined, leaving the section ungrantable to restricted admin roles. It now points atQoliber_ProductAttachments::product_attachments. - The adminhtml attachment preview controller declared no
ADMIN_RESOURCEand so fell back toMagento_Backend::admin, letting any backend user fetch any attachment by id. It now requiresMagento_Catalog::products, matching upload. - A sort order of
0was rejected as "not a positive integer" becausefilter_var()returns a falsyint(0). Zero is valid for an unsigned column. ContentUploadernever populated the parent uploader's validator, so every API-side upload fatally dereferenced null and the protected-extension check never ran. Executable extensions are now refused.- Base64 payloads are decoded in strict mode instead of silently writing corrupt bytes when the input is malformed.
- Attachment downloads verify the owning product is enabled and assigned to the current website. Previously a link kept working after the product was disabled.
Content-Dispositionfile names are escaped, so a stored name containing a quote or a line break can no longer truncate or split the response headers.- URL-type attachments validate the redirect target before sending the visitor.
- Attachments stream to the client in chunks. They were read wholly into memory first, making peak usage scale with the largest file on the store.
- A zero-byte attachment, or one whose contents are exactly
0, no longer reports itself as unreadable. - Cancelled orders no longer grant access to purchased-item attachments, and the listing is scoped to the current website.
- The purchased-items lookup selects ids in two queries instead of hydrating every order and order item the customer has ever placed.
store_idis quoted throughquoteInto()in the title join.- Implicit nullable parameters were made explicit for PHP 8.4 forward compatibility.
Added
- Unit test coverage for attachment validation and download header construction.
db_schema_whitelist.json, absent until now, which the declarative schema needs before it will apply column or constraint removals.created_atandupdated_atonqoliber_product_attachments.- A unique key on
(attachment_id, store_id)in the title table, plus a foreign key tostore. Title writes useinsertOnDuplicateso concurrent saves cannot violate it.
Changed
attachment_urlwidened from 255 to 1024 characters.qoliber_product_attachments_title.store_idis nowsmallint unsignedto matchstore.store_id, which the new foreign key requires.
Upgrade notes
-
The new unique key on
(attachment_id, store_id)will fail to apply if the table already holds duplicate rows for a pair. Remove them before upgrading:SQLDELETE t1 FROM qoliber_product_attachments_title t1 INNER JOIN qoliber_product_attachments_title t2 WHERE t1.title_id > t2.title_id AND t1.attachment_id = t2.attachment_id AND t1.store_id = t2.store_id; -
Hyvä support moved to the separate
qoliber/product-attachments-hyvapackage. Stores running a Hyvä theme must require it explicitly, otherwise the attachment tab and the account attachment list fall back to the Luma templates.
Removed
- Hyvä layout handles and templates, now shipped by
qoliber/product-attachments-hyva.
[1.0.1] - 2025-05-14
Fixed
- Code quality improvements with PHPStan and PHPCS fixes
- Styling improvements for both Hyva and Luma themes
- Frontend code optimizations
[1.0.0] - 2025-04-30
Added
- Initial release of Product Attachments module
- Complete product attachment management system integrated into product edit form
- File attachment functionality with dual modes:
- File upload: Direct file upload to server storage
- URL attachment: Link to external files or resources
- Multi-store title support for attachments:
- Store-specific attachment titles
- Title localization per store view
- Product edit form integration:
- Attachment panel in product form
- Drag-and-drop file upload
- Sort order management
- Attachment type selection (file/URL)
- Frontend attachment display:
- Product detail page attachment tab
- Downloadable file links with security
- SVG icon sprite for file type indicators
- Attachment title display
- Customer dashboard integration:
- "My Product Attachments" section in customer account
- List of purchased product attachments
- Attachment access based on purchase history
- Dedicated customer account page for attachment downloads
- Security features:
- Attachment ID obfuscation for secure downloads
- Purchase validation before download access
- Resource resolver for download authorization
- Hyva theme support:
- Alpine.js-enhanced attachment display
- Hyva-specific product view tab
- Hyva customer account templates
- Responsive attachment section styling
- Luma theme support:
- Standard product tab integration
- Luma customer account templates
- Compatible with default Magento styling
- Admin functionality:
- File uploader component with preview
- File upload controller with validation
- File preview functionality for admin users
- Database schema:
- Attachment table with product foreign key
- Attachment title table with store view support
- Cascade delete on product removal
- Sort order for attachment display sequence
- UI data providers:
- Product form modifier for attachment panel
- Composite modifier for attachment data processing
- Attachment data builder for form population
- Attachment type handlers:
- File type handler for uploaded files
- URL type handler for external links
- API interfaces:
- AttachmentRepositoryInterface for CRUD operations
- ConfigInterface for module configuration
- ContentUploaderInterface for file uploads
- PurchasedItemsAttachmentProviderInterface for customer access
- Validators:
- Content validation for file uploads
- Attachment type validation
- Observers:
- Type conversion prevention for attachment products
- Plugins:
- InitForSave plugin for attachment data processing
- Service classes:
- URL service for attachment link generation
- Translation support:
- English (en_US) translations
- Polish (pl_PL) translations
- Data patches:
- Product attribute creation for attachments title
- EAV attribute integration for product attachments
- Extension attributes for attachment data in product entity
- Fieldset configuration for data mapping
- ACL permissions for attachment management
- Admin routes for upload and preview
- Frontend routes for download functionality