Cloud CMS provides several ways to run validation ahead of deletion. There are many use cases where this employed - such as:
- Preventing an Image from being deleted when it is being referenced by a live Web Page
- Preventing a required sub-object from being deleted
- Preventing something from deleted when one or more other things are referencing it or depend on it in some way
Here are a few approaches which are commonly used:
## Content Model Dependencies
We implement link validation via the graph. Suppose you have two nodes - Product A and Image B - and a custom association type "Has Image". You might have Product A link to Product B via a "Has Image" association. The "Has Image" association may be an `owned` relationship. As such, there is an implicit understanding that Product A is dependent on Image B. If you try to delete Image B independently, the system will raise an error since it knows that A has a dependency on B.
Using this kind of approach, you build out your association types to inherently model these dependencies. And this prevents the editorial team from accidentally deleting things. The relationships about what depends on what is stored in the graph.
## Inline Links
We also provide a few places where we help with the aforementioned structure. One example is the `f:inline-links` feature. If you add this feature to Product A, then any text fields on Product A will automatically be parsed and have their links stored as associations in the graph.
Suppose that Product A has a text field that contains a link to Image B. This link can be created using, say, the CKEditor field with the Cloud CMS image plugin (provided by default). This results in Product A having an <img> tag that points to an attachment on Image B.
Upon saving, Cloud CMS makes sure that the graph contains "a:links-to" association that represents this DOM entry. The association essentially does what is described in "Content Model Dependencies" above in that it stores the fact that Product A is dependent on Image B. It also stores the fact of which field (and DOM element inside that field) contains the markup that implies the relationship.
As such, if you then try to delete Image B independently, the system will raise an error since it knows that A has a dependency on B.
## Link Checking
Another feature we offer is "link checking". This is a bit ancillary to the question but it is worth mentioning. If you use the Inline Links feature from above, you may have times where you reference an HTTP address that exists outside of Cloud CMS. For example, you might have text on Product A that looks like this:
When you save Product A, Cloud CMS will create a placeholder node for `https://www.bbc.co.uk` and then build the `a:links-to` association to it.
At any point, you can click on "Check Links" within the user interface to automatically run link checking against all of the links in your branch that point to these external HTTP resources. This gives you a way to be sure that any external dependencies are online and available ahead of publishing.
Thus, Cloud CMS gets pretty serious about link validation. Even to external locations. However, our means of achieving this is entirely by storing dependency information within associations in the graph.
A final option is that of policies. A policy is a "event type" or trigger type that you can hook into to have your own custom logic run when things happen within Cloud CMS.
If none of the above seems like a good fit or if you really need some custom control, then I would advise binding a behavior to a policy. For example, you could call out to a Web Hook vial to the `p:beforeDeleteAttachment` policy:
This policy triggers before an attachment is deleted. You can have this call out to a Web Hook, run a custom server-side script or even execute your own Java-based beans (since you're on-premise, you're free to build your own and register them within the API should you choose to). All of these approaches describe ways that you can hook into your own custom code.
Once you're in your custom code, you can run any custom validation logic that you wish. And if you find a reason to prevent the delete operation from proceeding, you simply throw an Exception. This will prevent the deletion from completing and will raise errors appropriately back the user.