First create a new utils service from your project root:
npx strapi generate service utils
Now copy in the code contents to
/src/api/utils/services/utils.js
'use strict';
/**
* My Strapi utils service.
*/
module.exports = ({ strapi }) => ({
async deleteFilesFromEntity(ctx, entity, field) {
if (entity != null && entity[field] != null) {
var params;
for (var i = 0; i < entity[field].length; i++) {
params = {id: entity[field][i].id };
await strapi.plugins['upload'].controllers['content-api'].destroy({state: ctx.state, params: params});
}
}
},
async updateFileInfo(user, fileInfo) {
for (var i = 0; i < fileInfo.length; i++) {
if(fileInfo[i].id && fileInfo[i].id>0) {
await strapi.plugin('upload').service('upload').updateFileInfo(fileInfo[i].id, {alternativeText: fileInfo[i].alternativeText, caption: fileInfo[i].caption}, user);
}
}
},
});
Here is an example of a ‘restaurant’ content type with a media field called ‘images’. When a restaurant record is deleted, then the associated images will also be deleted. Please note that in this example I assume that the media files are not being shared amongst multiple records.
/src/api/restaurant/controllers/restaurant.js contents:
'use strict';
/**
* restaurant controller
*/
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::restaurant.restaurant' , ({ strapi }) => ({
async delete(ctx) {
const user = ctx.state.user;
if (!user) return ctx.badRequest(null, [{ messages: [{ id: 'No authorization header was found' }] }]);
const {id} = ctx.params;
const restaurant = await strapi.entityService.findOne('api::restaurant.restaurant', id, {
populate: ['images'],
});
if (restaurant) {
// delete related files
await strapi.service('api::utils.utils').deleteFilesFromEntity(ctx, restaurant, 'images');
}
const response = await super.delete(ctx);
return response;
}
}));