Advertisement
TheRedDuke

getSerializableObjectCopy

Jul 7th, 2014
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!---%%%  GetSerializableObjectCopy %%% --->
  2. <cffunction name="GetSerializableObjectCopy" access="public" output="no" returntype="any">
  3.     <cfargument name="o"            type="any"      required="yes">
  4.     <cfargument name="oKey"         type="any"      required="no" default="">
  5.     <cfargument name="currentDepth"     type="numeric"      required="no" default="1">
  6.  
  7.     <cfscript>
  8.  
  9.         // //////////////////////////////// //
  10.         // /// Declare local variables /// //
  11.         var MaxDepth            = 8;
  12.        
  13.         var oCopy           = StructNew();
  14.         var oKeyArray           = ArrayNew(1);
  15.         var oKeyArrayLen        = 0;
  16.         var oTreatAsStruct      = StructNew();
  17.        
  18.         var oKeyOrIndex         = '';
  19.        
  20.         var oValue          = '';
  21.         var oValueMeta          = StructNew();
  22.         var oValueTypeName      = 'unknown';
  23.         var oValueTreatAsStruct     = StructNew();
  24.  
  25.         oTreatAsStruct['treatAsStruct'] = false;
  26.  
  27.  
  28.         // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
  29.         // /// Inspect the base object 'o' to see what it is and if it has children we need to inspect (determined by oKeyArrayLen) /// //
  30.         if ( IsStruct( ARGUMENTS['o'] ) ) {
  31.            
  32.             oKeyArray   = StructKeyArray( ARGUMENTS['o'] );
  33.             oKeyArrayLen    = ArrayLen( oKeyArray );
  34.  
  35.             oTreatAsStruct['treatAsStruct'] = true;
  36.        
  37.         } else if ( IsArray( ARGUMENTS['o'] ) ) {
  38.            
  39.             oCopy       = ArrayNew(1); // Set our copy of the objecy (at this depth) to a type of array sice that is what the object (at this depth) is! (otherwise it remains a struct as defined above)
  40.             oKeyArrayLen    = ArrayLen( ARGUMENTS['o'] );
  41.        
  42.         } else if ( IsSimpleValue( ARGUMENTS['o'] ) ) {
  43.            
  44.             oCopy       = Trim( ARGUMENTS['o'] );
  45.             oKeyArrayLen    = 0;
  46.        
  47.         } else {
  48.  
  49.             // Call treatObjectAsStruct() to see if this object can be treated as a struct enen though it is of a different type
  50.             oTreatAsStruct = treatObjectAsStruct( ARGUMENTS['o'] );
  51.  
  52.             if( oTreatAsStruct['treatAsStruct'] ) {
  53.                 oKeyArray   = oTreatAsStruct['oKeys'];
  54.                 oKeyArrayLen    = oTreatAsStruct['oKeyLen'];
  55.             } else {
  56.                 oKeyArrayLen    = 0;
  57.                 if( Trim(  ARGUMENTS['oKey'] ) NEQ '' ) {
  58.                     oCopy[ Trim( ARGUMENTS['oKey'] ) ]  = '<UNSERIALIZABLE: Object of type "' & GetMetaData( ARGUMENTS['o'] ).GetName() & '">';
  59.                 } else {
  60.                     oCopy[ '[EMPTY_STRING]' ]       = '<UNSERIALIZABLE: Object of type "' & GetMetaData( ARGUMENTS['o'] ).GetName() & '">';
  61.                 }
  62.             }
  63.            
  64.         }
  65.  
  66.  
  67.         // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
  68.         // /// Ensure that ARGUMENTS['o'] is either an array or is a struct, then...                                                                                       /// //
  69.         // /// if oKeyArrayLen > 0 this object has children to inspect; look at the type/value of each child and add it to our copy or call recursivly if it has children /// //
  70.         if( oTreatAsStruct['treatAsStruct'] OR IsArray( ARGUMENTS['o'] ) ) {
  71.  
  72.             for( var i = 1; i LTE oKeyArrayLen; i++ ) {
  73.  
  74.                 oKeyOrIndex = ( IsStruct( ARGUMENTS['o'] ) OR oTreatAsStruct['treatAsStruct'] ) ? oKeyArray[i] : i; // Get the key for each child, regardless if it's an array index or struct key
  75.                    
  76.                 // Ensure that the key for this position in our loop actually exists (prevents trouble with proper null values)
  77.                 if(
  78.                     ( oTreatAsStruct['treatAsStruct'] AND StructKeyExists( ARGUMENTS['o'], oKeyOrIndex ) ) OR
  79.                     ( IsArray( ARGUMENTS['o'] ) AND NOT IsNull( ARGUMENTS['o'][ oKeyOrIndex ] ) )
  80.                 ) {
  81.  
  82.                     oValue = ARGUMENTS['o'][ oKeyOrIndex ]; // Get the value at this key
  83.                    
  84.                     if( IsStruct( oValue ) ) {
  85.                         oValueTreatAsStruct = { 'treatAsStruct': true };
  86.                     } else if( IsArray( oValue ) OR IsSimpleValue( oValue ) OR IsQuery( oValue ) ) {
  87.                         oValueTreatAsStruct = { 'treatAsStruct': false };
  88.                     } else {
  89.                         oValueTreatAsStruct = treatObjectAsStruct( oValue ); // Find out if we can treat the value at this key as a struct
  90.                     }
  91.                    
  92.                     // This value can have children, prep for recursive call
  93.                     if( oValueTreatAsStruct['treatAsStruct'] OR IsArray( oValue ) ) {
  94.  
  95.                         // Before calling recursively, check if this value is a component and kick out of this loop iteration if it is; do not call recursivly
  96.                         oValueMeta = GetMetaData( oValue );
  97.                         if ( StructKeyExists( oValueMeta, 'type' ) AND oValueMeta['type'] EQ 'component' ) {
  98.                             oCopy[ oKeyOrIndex ] = '<UNSERIALIZABLE: Component "' & oValueMeta['fullName'] & '">';
  99.                             continue; // Skips any code following in the loop, jumps to the beginning of the next loop iteration (for loop; var i)
  100.                         }
  101.  
  102.                         // Call recursively or mark that we are at depth limit
  103.                         if( ARGUMENTS['currentDepth'] LT MaxDepth ) {
  104.                            
  105.                             // Check if the struct/array actually has a len before the recursive call
  106.                             if( ( oValueTreatAsStruct['treatAsStruct'] AND StructCount( oValue ) ) OR ( IsArray( oValue ) AND ArrayLen( oValue ) ) ) {
  107.                                 oCopy[ oKeyOrIndex ] = GetSerializableObjectCopy( oValue, oKeyOrIndex, Evaluate( ARGUMENTS['currentDepth'] + 1 ) );
  108.                             } else if( oValueTreatAsStruct['treatAsStruct'] ) {
  109.                                 oCopy[ oKeyOrIndex ] = StructNew();
  110.                             } else if( IsArray( oValue ) ) {
  111.                                 oCopy[ oKeyOrIndex ] = ArrayNew(1);
  112.                             }
  113.  
  114.                         } else {
  115.  
  116.                             oCopy[ oKeyOrIndex ] = '<UNSERIALIZABLE: Limited at depth ' & MaxDepth & '>';
  117.  
  118.                         }
  119.                    
  120.                     // Output either the simple value or an unserializable value message for this key/index
  121.                     } else {
  122.  
  123.                         // Simple value, just set it in our copy
  124.                         if( IsSimpleValue( oValue ) ) {
  125.                            
  126.                             oCopy[ oKeyOrIndex ] = Trim( oValue );
  127.                        
  128.                         // Query, mark it as unserializable
  129.                         } else if ( IsQuery( oValue ) ) {
  130.                            
  131.                             oCopy[ oKeyOrIndex ] = '<UNSERIALIZABLE: Object value of type "query">';
  132.                        
  133.                         // Unknown type, lets check it
  134.                         } else {
  135.                            
  136.                             // This value behaves like a struct, pass it recursively!
  137.                             if( oValueTreatAsStruct['treatAsStruct'] ) {
  138.  
  139.                                 // Call recursively or mark that we are at depth limit
  140.                                 if( ARGUMENTS['currentDepth'] LT MaxDepth ) {
  141.                                    
  142.                                     // Check if the struct actually has a len before the recursive call
  143.                                     oCopy[ oKeyOrIndex ] = ( StructCount( oValue ) ) ? GetSerializableObjectCopy( oValue, oKeyOrIndex, Evaluate( ARGUMENTS['currentDepth'] + 1 ) ) : StructNew();
  144.  
  145.                                 } else {
  146.  
  147.                                     oCopy[ oKeyOrIndex ] = '<UNSERIALIZABLE: Limited at depth ' & MaxDepth & '>';
  148.  
  149.                                 }
  150.  
  151.                             // Can't treat it like a struct, log it as unserializable
  152.                             } else {
  153.  
  154.                                 try {
  155.                                     oValueTypeName = GetMetaData( oValue ).GetName();
  156.                                 } catch ( any e ) {
  157.                                     oValueTypeName = ( IsCustomFunction( oValue ) ) ? 'function' : 'unknown';
  158.                                 }
  159.                                 oCopy[ oKeyOrIndex ] = '<UNSERIALIZABLE: Object value of type "' & oValueTypeName & '">';
  160.  
  161.                             }
  162.                            
  163.                         }
  164.  
  165.                     }
  166.  
  167.                 // Could not find the value at the specified key or position, mark it
  168.                 } else {
  169.  
  170.                     oCopy[ oKeyOrIndex ] = '<UNSERIALIZABLE: Value for key "' & oKeyOrIndex & '" could not be found or evaluated; may be null>';
  171.  
  172.                 }
  173.  
  174.             }
  175.  
  176.         }
  177.      
  178.         return oCopy;
  179.  
  180.     </cfscript>
  181.  
  182. </cffunction>
  183.  
  184.  
  185. <!---%%% TreatObjectAsStruct %%% --->
  186. <cffunction name="TreatObjectAsStruct" access="private" output="no" returntype="struct">
  187.     <cfargument name="o" type="any" required="yes">
  188.  
  189.     <cfscript>
  190.  
  191.         var oKeys               = ArrayNew(1);
  192.         var ReturnStruct            = StructNew();
  193.  
  194.         ReturnStruct['treatAsStruct']       = false;
  195.         ReturnStruct['oKeys']           = oKeys;
  196.         ReturnStruct['oKeyLen']         = 0;
  197.  
  198.         // Check first if this object is not a (custom) function
  199.         if( NOT IsCustomFunction( o ) ) {
  200.  
  201.             try {
  202.                 oKeys = StructKeyArray( ARGUMENTS['o'] );
  203.             } catch( any e ) {
  204.                 // oKeys defined above
  205.             }
  206.  
  207.             if( ArrayLen( oKeys ) ) {
  208.                 ReturnStruct['treatAsStruct']   = true;
  209.                 ReturnStruct['oKeys']       = oKeys;
  210.                 ReturnStruct['oKeyLen']     = ArrayLen( oKeys );
  211.             }
  212.  
  213.         }
  214.  
  215.         return ReturnStruct;
  216.  
  217.     </cfscript>
  218.  
  219. </cffunction>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement