Knowledge Base

Working With Custom Hooks: OnDeleteAsset

Having rules around how and when a content item is deleted is important to the successful management of any CMS. In this article, we explore how this custom hook can be used to set paramaters around the deletion of assets.


In the context of the Ingeniux CMS platform, assets refer to content items like images, PDF documents, and even sometimes code that are stored in the CMS and published out to a publishing target. Assets differ from page types and components – which are created, edited, and managed directly in the CMS Site Tree – in that they are uploaded, or brought into the CMS, from outside of the platform. Once uploaded, they are stored in the Asset Management System (and usually placed into an Asset Schema) where they can be managed, edited in certain ways, and have metadata assigned to them. 

In this article, we’ll look at how the OnDeleteAsset custom hook can be used to set paramaters around the action fo deleting an asset from the Asset Management System.  

When a user deletes a content item from the Asset Tree, that content item gets moved to the Recycle Folder. When sent to the Recycle Folder, content items are unmarked for publish from all publishing targets and unassigned.  

How To Trigger the Hook  

This hook may be triggered when a user takes the following action(s): 

  • Right-clicking on an Asset and selecting Delete from the context menu.  
  • Right-clicking on an Asset, selecting Cut, right-clicking on the Recycle Folder and selecting Paste 
  • Clicking and dragging an Asset into the Recycle Folder 

When to Use This Custom Hook  

Administrators may be interested in using this hook to place guardrails around the action of deleting a content item. As with all hooks, throwing any error inside the hook cancels the action that was attempted, which can be used to prevent important content items from being deleted.  

Other ways to use this hook might include:  

  • Update the pages and components that reference the asset as linked content and remove the references 
  • Push the deletion to a third-party system (such as a DAM), or simply add the deletion information to a log for auditing.  

Considerations 

When a content item is deleted, its children (descendant content items) are also deleted. So, the hook will be called for the content item and its children. In the Asset Tree, this means if you delete any item that has content items inside it, it also deletes all descendants. Only folders can have descendants in the Asset Tree. The script for delete is only fired one time for the batch though, so in your code you will have to test to see if there are descendants.  

Performance of the code in any scripts should be tested for efficiency. A user can multi-select items in the tree and delete them all, causing the script to be called multiple times at once. If it is too slow the CMS performance could be impacted dramatically.  

Deletion, in particular, has a higher need for the transactional nature of the before and after hooks. The item is moving to a new location, no longer in the tree, so the properties of the item change as it progresses. Be wary of ever getting an item that is moving directly from the Site object (assets are under the Site object in the API) as that is not the transactional copy and is unaware of any state changes being done by the action.  

Example One

Add to the CSAPI logs information about the deleted item  

Since an item that is moved to the Recycle Folder is no longer marked for publish, you may want to record the information about how it was marked for publish before it was deleted in case you want to restore the content item in the future.   

You will need to gather all of the publishing targets and see which versions of the content item were marked for those publishing targets. You can use the CSAPI log by calling the Info, Warn, or Error methods to add messages into the log at your desired level. This example uses Warn.  

int outVar;  

            string infoMessage = "" 

            var pubTargets = session.PublishingManager.Targets(out outVar);  

            infoMessage += "Deleted item " + contentItem.Id + " marked pub targets and versions: " 

            if (!contentItem.MarkedForPublish())  

            {  

                infoMessage += "No marked targets." 

            }  

            foreach(var pubTarget in pubTargets)  

            {  

                if(contentItem.MarkedForPublishOnTarget(pubTarget))  

                {   

                    infoMessage += pubTarget.Name + " at version # " + contentItem.MarkedVersionNumber(pubTarget) + ". " 

                }  

            }  

            session.Warn(infoMessage);  

Ways to Extend the Functionality Further  

Since the content item is also unassigned when it is deleted, you may enhance this further by adding information about the user or group who had possession of the item before it was deleted.  

Example Two

Email a list of items that reference the asset to the deleting user 

When an asset is deleted, content items that reference that item are left with broken references. These references won’t break the CMS, as it is built to ignore them, but it is still a good idea to do maintenance and remove or replace the references. The following example code will send an email to the deleting (current) user containing a list of all the places where a specific asset is being referenced before it is deleted. 

To accomplish this, the code first retrieves all the fields where the asset ID is referenced using the Ingeniux CMS site object and the KeywordSearch method. It then iterates through the list of PageFieldIndexableEntry objects and appends each content ID to a string variable called 'list', separated by commas. 

Next, the code defines the email server settings and creates a SmtpClient object to send the email. It sets the host, port, SSL, and credentials if necessary. 

Then, it creates a new MailMessage object and sets the from address, to address, subject, and body of the email. It uses the 'list' variable to populate the body with the list of places where the asset is referenced. 

Finally, the code sends the email using the SmtpClient object and catches any exceptions that may occur during the process. If an error occurs, it logs an error message using the session.Info method. 

int c; 

var usageFields = (session.Site as Ingeniux.CMS.Site).KeywordSearch<PageFieldIndexableEntry, ISite, ContentElementSearchIndex>(-1, -1, out c, "FieldValue", contentItem.Id); 

  

string list = string.Empty; 

  

foreach (var field in usageFields) 

{ 

string contentID = field.ContentId; 

  

if (!string.IsNullOrWhiteSpace(list)) 

{ 

                    list += ", "; 

} 

list += contentID; 

  

} 

  

//contentItem.Comment 

try 

{ 

var formsSmtpServer = "mx.ingeniuxondemand.com"; 

var formsSmtpServerPort = 25; 

var formsSmtpEnableSSL = false; 

var formsSmtpUsername = ""; 

var formsSmtpPassword = ""; 

var fromEmail = "noreply@ingeniux.com"; 

var toEmail = session.Site.CurrentUser.EmailAddress; 

  

SmtpClient smtpServer = new SmtpClient(formsSmtpServer); 

if (formsSmtpEnableSSL) 

{ 

smtpServer.Credentials = new System.Net.NetworkCredential( 

formsSmtpUsername, 

formsSmtpPassword); 

smtpServer.EnableSsl = true; 

} 

  

smtpServer.Port = formsSmtpServerPort; 

MailMessage mail = new MailMessage(); 

mail.From = new MailAddress(fromEmail); 

mail.To.Add(toEmail); 

mail.Subject = "Deleted Asset Usage Report"; 

mail.Body = "Below is a list of all the places your asset is being referenced" + list; 

mail.BodyEncoding = System.Text.Encoding.UTF8; 

mail.IsBodyHtml = true; 

smtpServer.Send(mail); 

} 

catch (Exception e) 

{ 

session.Info("Error sending email" + e); 

} 

} 

Ways to Extend the Functionality Further  

There are several ways that this code could be extended to add more functionality or customize its behavior for different scenarios. Here are a few possibilities: 

  1. Since the content item is also unassigned when it is deleted, you may enhance this further by adding information about the user or group who had possession of the item before it was deleted.  
  2. Customizing the email message: The email message body could be customized further to include additional information or formatting. For example, the code could be modified to include a link to each page or asset where the deleted asset is referenced, or to format the list of references as a table for easier reading. 
  3. Handling different types of assets: Currently, the code is designed to handle the deletion of a single asset item. However, it could be extended to handle the deletion of multiple assets at once, or to handle different types of assets (such as pages or images) by modifying the search query to retrieve different types of fields. 
  4. Adding more error handling: While the code currently catches any exceptions that occur during the email sending process, it could be extended to include more detailed error handling and logging. For example, it could log the specific type of error that occurred (such as a network error or authentication failure) and provide more detailed information about what went wrong. 
  5. Adding additional recipients: The code currently sends the usage report email to the current user only. However, it could be extended to include additional recipients, such as other users or groups, by modifying the 'toEmail' variable to include multiple email addresses. 
  6. Customizing the email subject: The email subject line could be customized further to include additional information or to be more descriptive. For example, the subject could include the name of the deleted asset, the date and time of the deletion, or the site or project name. 
  • PRODUCT: CMS
  • VERSION: CMS 10
  • RELEASE: 10.x
  • Published: June 26, 2023
  • LAST UPDATED: September 18, 2023
  • Comments: 0

Please login to comment

Comments


There are no comments yet.