Cloud HostingLaunch UnoPim on fully-managed cloud hosting — fast, secure and cost-effective plans.
Skip to content

Extending DAM

DAM exposes several extension points so you can add behaviour without forking the package or editing its files. This page is for developers building on top of DAM.


View Render Events

DAM's main asset screen is peppered with view_render_event hooks. Listen to one and your Blade output is injected at that exact point — no view overrides, no publishing.

EventWhere it renders
unopim.dam.admin.main.beforeBefore the entire DAM page
unopim.dam.admin.main.afterAfter the entire DAM page
dam.admin.main.form.beforeBefore the main form wrapper
dam.admin.main.form.afterAfter the main form wrapper
dam.admin.main.form.directory.beforeBefore the directory tree panel
dam.admin.main.form.directory.afterAfter the directory tree panel
dam.admin.main.form.grid.beforeBefore the asset grid
dam.admin.main.form.grid.afterAfter the asset grid
unopim.admin.dam.assets.list.beforeBefore the asset list
unopim.admin.dam.assets.list.afterAfter the asset list

Register a listener in your own package's service provider:

php
use Illuminate\Support\Facades\Event;

Event::listen('dam.admin.main.form.grid.before', function ($viewRenderEventManager) {
    $viewRenderEventManager->addTemplate('my-package::dam.grid-banner');
});

TIP

dam.admin.main.form.grid.before is the usual place for a custom toolbar or a banner above the gallery. dam.admin.main.form.directory.after suits anything that belongs alongside the folder tree.


DAM Events

DAM dispatches events around the actions that change data, so you can sync to an external system, write an audit trail, or invalidate a cache.

EventFired whenPayload
dam.asset.update.beforeImmediately before an asset is updatedAsset ID
dam.asset.update.afterImmediately after an asset is updatedAsset ID
dam.asset.delete.beforeBefore an asset is deletedAsset ID
dam.asset.delete.afterAfter an asset is deletedAsset ID
dam.asset.property.delete.beforeBefore a property is deletedProperty ID
dam.asset.property.delete.afterAfter a property is deletedProperty ID
core.model.proxy.sync.tagWhenever an asset's tags changeold_values, new_values, model
php
Event::listen('dam.asset.update.after', function ($assetId) {
    // push the change to a downstream system
});

The tag event carries the before and after tag names, which is what DAM's own history tracking uses — handy if you need to diff rather than just react.

Triggering events without changing data

There is a mass update endpoint that changes nothing at all:

POST /admin/dam/assets/mass-update

For each asset ID you pass in indices, it fires dam.asset.update.before and dam.asset.update.after and returns. That is its entire job.

It exists so an integration can force a re-sync of selected assets — re-push them to a CDN, rebuild a search index — without editing every asset to make something happen.


Blade Helper Functions

Five global helpers wrap the directory permission service. Use these in your own views and controllers rather than querying the permission tables yourself — they respect the same caching and bypass rules as DAM.

HelperReturnsUse it to
dam_can_view_dir(int $id)boolCheck read access to one directory
dam_can_access_dir(int $id)boolCheck act-on access to one directory
dam_viewable_directory_ids()arrayGet every directory ID the user can see
dam_accessible_dir_ids()arrayGet the directly granted directory IDs
dam_acl_bypass()boolDetect an unrestricted role (all directories)
blade
@if (dam_can_access_dir($directory->id))
    <button>Upload here</button>
@endif

IMPORTANT

view and access are not the same thing. A role can be allowed to see a folder in the tree without being allowed to act on it. Use dam_can_view_dir() to decide whether to render something, and dam_can_access_dir() to decide whether to let the user change something.

Always check dam_acl_bypass() first if you are building a query — for an unrestricted role, dam_accessible_dir_ids() is not meant to be used as a whitelist.


Catalog Sync Listeners

DAM keeps linked resources current automatically. When a product or category is saved, a listener reconciles that record's asset mappings — adding new links, removing ones that were cleared.

This means you do not need to maintain dam_asset_resource_mappings yourself. Save the product through the normal repository and the links follow.

The asset attribute type is also validated on save. An asset ID that does not exist, or that the user cannot reach, is rejected before the product is written.


Loose File Endpoints

Separate from the asset library, DAM exposes three endpoints for the plain file fields on product and category forms. These store files in private storage without creating a DAM asset record.

EndpointPermission required
POST /admin/dam/file/createdam.asset.upload
POST /admin/dam/file/updatedam.asset.re_upload
DELETE /admin/dam/file/deletedam.asset.destroy

WARNING

The permission names do not read the way you would expect. file/update is gated by dam.asset.re_upload, not dam.asset.update, and file/delete by dam.asset.destroy. Granting a role dam.asset.update alone will not let it replace a loose file.

Paths are validated against directory traversal — any path containing .. is rejected outright.


Localisation

DAM ships 33 UI locales:

ar_AE, ca_ES, da_DK, de_DE, en_AU, en_GB, en_NZ, en_US, es_ES, es_VE, fi_FI, fr_FR, hi_IN, hr_HR, id_ID, it_IT, ja_JP, ko_KR, mn_MN, nl_NL, no_NO, pl_PL, pt_BR, pt_PT, ro_RO, ru_RU, sv_SE, tl_PH, tr_TR, uk_UA, vi_VN, zh_CN, zh_TW

The interface follows the admin user's locale. To add or override strings, publish the language files and edit the locale you need:

bash
php artisan vendor:publish --provider="Webkul\DAM\Providers\DAMServiceProvider" --tag=lang

Released under the MIT License.