Skip to content

Instantly share code, notes, and snippets.

@homestar9
Last active March 27, 2019 00:27
Show Gist options
  • Save homestar9/57cd3f01b1de4767e7d3d26c8b1ab010 to your computer and use it in GitHub Desktop.
Save homestar9/57cd3f01b1de4767e7d3d26c8b1ab010 to your computer and use it in GitHub Desktop.
Component Utilities (UDF)
<cfscript>
/*
COMPONENT UTILITIES
This component houses frequently used functions for things like
exporting a DTO from a component.
hashing component properties, etc.
*/
/*
GET COMPONENT PROPERTY HASH
Returns the hash value of all of the entity's properties
*/
private string function getComponentPropertyHash() {
var local = {};
local.properties = getComponentProperties();
local.hashList = []; // a master hash array which will hold each property's hash
// loop through the variables collection
for ( a in local.properties ) {
// assign a temp
arrayAppend( local.hashList, hashify( variables[ a[ "name" ] ] ) );
}
// returned a hashed copy of the hash list
return hashify( local.hashList );
}
/*
GET COMPONENT PROPERTIES
Returns the properties of the passed component "this" scope
*/
private array function getComponentProperties() {
return getMetadata( this ).properties;
}
/*
GET DTO
Converts a component's properties into a data transformation object (DTO)
which is essentially just a basic structure of data. Useful when sending data
from layer to layer.
todo: we need recursion here to go deeper into the dto and convert queries as needed.
*/
public struct function getDto() {
var a = "";
var b = "";
var local = {};
// new method of creating a dto. Simply convert the target to JSON and back again
var dto = deserializeJSON( serializeJSON( this, "struct") );
// now there may be some object properties that don't exist in the dto so far.
// these could be getters that don't have a setter (e.g. getName() which just combines getFirstName() + getLastName();
// we can find these by looping through the properties and then identifying any missing keys
// make the properties easy to access
local.properties = getComponentProperties();
// loop through the properties of the object
for ( a in local.properties ) {
// if we find a matching key in the dto for the property name
if ( structKeyExists( dto, a[ "name" ] ) ) {
// deSerializeJSON can't convert data back into a query.
// but we can use a little deduction to see if we should convert it back into a query object
// the only requirement is that it needs to have a public getter method
// if it does not, continue the loop
if ( !structKeyExists( this, "get#a[ "name" ]#" ) ) {
continue;
}
// assert. If we got here, we know there's a public getter for a property.
// is this property supposed to be a query object? (easiest)
if (
structKeyExists( a, "type" ) &&
a[ "type" ] == 'query'
) {
// replace the key with the original query object.
dto[ a[ "name" ] ] = evaluate( "this.get#a[ "name" ]#()" );
continue;
}
// assign a temp variable for the value
local.tempValue = evaluate( "this.get#a[ "name" ]#()" );
// is this property value an object? and does it have a getDto method?
if (
isObject( local.tempValue ) &&
structKeyExists( local.tempValue, "getDto" )
) {
// replace the key with the original query object.
dto[ a[ "name" ] ] = local.tempValue.getDto();
continue;
}
// is this property value an array?
// it's possible that it could be an array of objects.
if (
isArray( local.tempValue )
) {
for ( b=1; b<= arrayLen( local.tempValue ); b++ ) {
// if the array index isn't defined (yes, it's possible to have gaps in the array, skip it
if ( !arrayIsDefined( local.tempValue, b ) ) {
continue;
}
if (
isObject( local.tempValue[b] ) &&
structKeyExists( local.tempValue[b], "getDto" )
) {
// replace the key with the original query object.
dto[ a[ "name" ] ][b] = local.tempValue[b].getDto();
continue;
}
}
}
}
}
return dto;
}
</cfscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment