Blog

Gavin Pickin

August 15, 2017

Spread the word


Share your thoughts

In my last post, I talked about How to hook into Hibernate ORM Events easily with CBORM and ColdBox. I talked through the what, why, how, but didn't get to the code. So this post, is going to go through the code and give you a real example you could use today to extend ContentBox's core Author module with your own function.

Create an Interceptor

First, we need to create an interceptor. Naming is one of the hardest things in software development, so I'm going to call this interceptor AuthorORMExtender.cfc. If you have a better name, please share in the comments. I am curious what naming conventions other people use, so please share. I put this Interceptor in the Interceptors folder.

A common setup for interceptors when I create them look like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
*  Listens for the appropriate ORM Interception points announced by CBORM from Hibernate.
*/
component {
         
    /**
    * Configure Function
    */
    void function configure(){
        if( !propertyExists( "enabled" ) ){
            setProperty( "enabled", true );
        }
    }
}  

Load the Interceptor

Once you have your interceptor created, you need to let ColdBox know you want to use the interceptor. Let's register the intercerptor in my ModuleConfig.cfc. You could do this in your ColdBox.cfc, with a similar syntax, but I prefer to work in Modules, so I just added the interceptor into my ClientCore module. In the configure() function in my ModuleConfig.cfc I add the following

1
2
3
4
// Custom Declared Interceptors
interceptors = [
    { class="clientcore.interceptors.AuthorORMExtender" }
];

Next Framework reinit, the interceptor will be registered, and be ready to listen to your events.

What events are we listening for

Next, we have to decide what Hibernate events are we wanting to hook into? We want every Author object to have our new function checkPermissionsPlus() so we need to listen to the postLoad and postNew Hibernate events. Thanks to CBORM, that translates to an interceptor that listens to ORMPostLoad and ORMPostNew.

Add the follow code boiler plate into your Interceptor to listen for these events

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* on ORMPostNew, this interceptor injects a new permission check method to wrap the
* normal check permission method in the Author entity.
*/
function ORMPostNew( event, interceptData, buffer, rc, prc ){
    // verify turned on
    if( !getProperty( "enabled" ) ){ return; }
}
/**
* on ORMPostLoad, this interceptor injects a new permission check method to wrap the
* normal check permission method in the Author entity.
*/
function ORMPostLoad( event, interceptData, buffer, rc, prc ){
    // verify turned on
    if( !getProperty( "enabled" ) ){ return; }
}  

This listens code listens on those events, and if the interceptor is disabled, it will return immediately, otherwise it is ready to process the request.

How to we process the events we are listening for

Both of these Interception Points pass entity the actual entity, and entityName which is the name of the entity passed. We only care about the Author object, which has the full entity name of cbAuthor with the cb prefix. Now our functions look like this ( only showing one to save space ).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* on ORMPostNew, this interceptor injects a new permission check method to wrap the
* normal check permission method in the Author entity.
*/
function ORMPostNew( event, interceptData, buffer, rc, prc ){
         
    // verify turned on
    if( !getProperty( "enabled" ) ){ return; }
         
    if( arguments.interceptData.entityName == "cbAuthor" ){
        // do something here
    }
         
}

Now we have the author, what are we injecting?

We want to inject a new function, called checkPermissionsPlus() which calls the original checkPermissions() function... but only after doing some of its own magic. We can include this function in the interceptor, so it is easy to reference in the next step.

1
2
3
4
5
6
7
8
9
10
11
12
/**
* New function to be injected into every new or loaded Author Object
* This fucntion checks for excluded permissions, before continuing to check permissions
* via the original ContentBox permission structure.
* @permission The permission to be checked
*/ 
function checkPermissionPlus( permission='' ){
        if( arguments.permission == "GLOBAL_SEARCH" ){
            return false;
        }
        return checkPermission( arguments.permission );
    }

In this example, I'm going to just use a simple hard coded if statement, but you could do a lot more here. Instead of a hard coded if statement, you could check a list of excluded Permissions, or check to see if that user is disabled, or something else.

Now we have the new function, lets inject it

Now, lets remove our do something here comment, and replace it with a simple assignment to the entity. entity.newfunctionName = this.newFunction;

This is how it looks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* on ORMPostNew, this interceptor injects a new permission check method to wrap the
* normal check permission method in the Author entity.
*/
function ORMPostNew( event, interceptData, buffer, rc, prc ){
         
    // verify turned on
    if( !getProperty( "enabled" ) ){ return; }
         
    if( arguments.interceptData.entityName == "cbAuthor" ){
        arguments.interceptData.entity.checkPermissionPlus = this.checkPermissionPlus;
    }
         
}

Put it all together and reinit the framework

Reinit the framework, and now, every Author created new, or loaded, will now have the new injected function. Accessible with a user friendly and familiar syntax, author.checkPermissionPlus( 'permission_slug' );

Here is the whole AuthorORMExtender.cfc file in a github gist: https://gist.github.com/gpickin/35f0ac66e05b7191c217c9937086f070

Read more about CBORM module here: https://github.com/coldbox-modules/cbox-cborm/wiki

Read More about the ORM to ColdBox Interception Points here: https://github.com/coldbox-modules/cbox-cborm/wiki/ORM-To-ColdBox-Interceptions

Add Your Comment

Recent Entries

Into the Box Sessions Round 2 and Team Packs!

Into the Box Sessions Round 2 and Team Packs!

The second round of Into the Box sessions is here, packed with incredible new topics, sessions and expert speakers industry leaders in modern CFML getting us modern content and practices you can use to make your coding experience and projects better, faster and easy and expert-led talks on modern web development, serverless applications, cryptography, UI design, and more.

Maria Jose Herrera
Maria Jose Herrera
February 25, 2025
Building Serverless Functions with BoxLang in AWS Lambda!

Building Serverless Functions with BoxLang in AWS Lambda!

The serverless computing model has revolutionized the way we deploy and manage applications, and with BoxLang, it’s easier than ever to leverage AWS Lambda for efficient, scalable execution of cloud functions. In a recent blog post, Ray Camden explored the process of building and deploying BoxLang functions in AWS Lambda. Let’s take a closer look at how it works!

Maria Jose Herrera
Maria Jose Herrera
February 24, 2025
ColdBox Training: From Hero to Superhero – Master ColdFusion and BoxLang Development

ColdBox Training: From Hero to Superhero – Master ColdFusion and BoxLang Development

Are you ready to take your ColdBox development skills for ColdFusion and BoxLang to the next level? Whether you're new to ColdBox or looking to sharpen your expertise, our ColdBox From Hero to Superhero training is the perfect opportunity to become a ColdFusion and BoxLang powerhouse.

Why Attend?

This hands-on training is designed to help ColdFusion and BoxLang developers level up their ...

Cristobal Escobar
Cristobal Escobar
February 19, 2025