/* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is comprised of the ADF directory The Initial Developer of the Original Code is PaperThin, Inc. Copyright (c) 2009-2019. All Rights Reserved. By downloading, modifying, distributing, using and/or accessing any files in this directory, you agree to the terms and conditions of the applicable end user license agreement. */ /* *************************************************************** */ /* Author: PaperThin, Inc. Name: ceData_3_0.cfc Summary: Custom Element Data functions for the ADF Library Version 2.1 History: 2015-08-31 - GAC - Created 2016-12-05 - GAC - Converted to a cfscript style component 2017-07-27 - GAC - Added getCEDataByPageID() and getCEDataViewByPageID() functions 2017-11-29 - GAC - Added formatDataForGceArchivePostImport() and outputDataForGceArchivePostImport() functions 2018-11-16 - GAC - Added Added getFormIDQueryFromPageID() and getFormIDArrayFromPageID() functions */ component displayname="ceData_3_0" extends="ceData_2_0" hint="Custom Element Data functions for the ADF Library" { /* PROPERTIES */ property name="version" type="string" default="3_0_6"; property name="type" value="singleton"; property name="data" type="dependency" injectedBean="data_2_0"; property name="wikiTitle" value="CEData_3_0"; variables.SQLViewNameADFVersion = "2.0"; /* *************************************************************** */ /* Author: PaperThin, Inc. Name: $getCEDataByPageID Summary: Returns a CEData Array of Structs (only 1 record) Returns: Array Arguments: Numeric - csPageID Usage: application.ADF.ceData.getCEDataByPageID(ficDataValues) History: 2017-07-27 - GAC - Created */ public array function getCEDataByPageID(required string customElementName,required numeric csPageID) { var retArray = ArrayNew(1); var csFormID = application.ADF.cedata.getFormIDByCEName(CEName=arguments.customElementName); var ceData = application.ADF.ceData.getElementInfoByPageID(pageid=arguments.csPageID,formid=csFormID,separateValueStruct=true); if ( !StructIsEmpty(ceData) AND structKeyExists(ceData,"FormID") AND IsNumeric(ceData.FormID) AND ceData.FormID GT 0 ) retArray[1] = ceData; return retArray; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: $getCEDataViewByPageID Summary: Returns a CEData View Query Returns: Array Arguments: Numeric - csPageID Usage: application.ADF.ceData.getCEDataByPageID(ficDataValues) History: 2017-07-27 - GAC - Created */ public query function getCEDataViewByPageID(required string customElementName,required numeric csPageID,string overrideViewTableName="",boolean forceRebuild=0) { var viewTableName = ""; var ceViewQry = QueryNew("null"); var queryService = new Query(); // Set the override for the view table name if defined if ( LEN(arguments.overrideViewTableName) ) viewTableName = arguments.overrideViewTableName; else viewTableName = getCEViewName(ceName=arguments.customElementName,type="adfversion",version=getSQLViewNameADFVersion()); // Verify if the view table exists, create if doesn't exists viewTableExists = buildView(ceName=arguments.customElementName, viewName=viewTableName, forceRebuild=arguments.forceRebuild); if ( viewTableExists ) { try { queryService.setDatasource("#request.site.datasource#"); queryService.setAttributes(maxrows=1); queryService.setSql(" SELECT * FROM #viewTableName# WHERE PageID = :PageID "); queryService.addParam( name = "PageID", value = "#arguments.csPageID#", cfsqltype = "cf_sql_integer" ); // Execute the query and store the results. ceViewQry = queryService.execute().getResult(); } catch ( any ex ) { application.ADF.utils.doDump(var=ex,label="getCEDataViewByPageID Query Failed!",expand=0); } } return ceViewQry; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: $convertFICDataValuesToCEData Summary: Returns a CEData Array of Structs from a FIC_ field data struct Returns: Array Arguments: Struct - ficDataValues Usage: application.ADF.ceData.convertFICDataValuesToCEData(ficDataValues) History: 2016-10-19 - GAC - Created 2017-03-29 - GAC - Updated to handle the case where the FIC_{formid}_{Fieldid}_FIELDNAME keys are not in the FIC data */ public array function convertFICDataValuesToCEData(struct ficDataValues=StructNew()) { var retArray = ArrayNew(1); var ceData = StructNew(); var key = ""; var fldName = ""; var fldValue = ""; var ficFieldNameKey = ""; var ficFieldValueKey = ""; var ficFieldID = 0; ceData.values = StructNew(); ceData.formid = 0; ceData.pageID = 0; // Set the Element ID from the formID or the controlTypeID if ( StructKeyExists(arguments.ficDataValues, 'controlTypeID') ) ceData.formid = arguments.ficDataValues.controlTypeID; else if ( StructKeyExists(arguments.ficDataValues, 'FormID') ) ceData.formid = arguments.ficDataValues.FormID; // Set the Data Page ID from the dataPageID or the PageID if( StructKeyExists(arguments.ficDataValues, 'dataPageID') ) ceData.pageID = arguments.ficDataValues.dataPageID; else if( StructKeyExists(arguments.ficDataValues, 'savePageID') ) ceData.pageID = arguments.ficDataValues.savePageID; else if( StructKeyExists(arguments.ficDataValues, 'pageID') ) ceData.pageID = arguments.ficDataValues.pageID; for ( key IN arguments.ficDataValues) { ficFieldID = 0; if ( FindNoCase('FIC_', key, 1) AND !FindNoCase('_FIELDNAME', key, 1) ) { // Get the Field ID from the FIC string if ( ListLen(key,"_") GT 2 ) ficFieldID = Val(ListGetAt(key,3,"_")); ficFieldNameKey = key & '_FIELDNAME'; ficFieldValueKey = key; fldName = ""; fldValue = ""; if ( StructKeyExists(arguments.ficDataValues,ficFieldNameKey) ) fldName = arguments.ficDataValues[ficFieldNameKey]; else if ( IsNumeric(ficFieldID) AND ficFieldID GT 0 ) fldName = application.ADF.fields.getCEFieldName(ceNameOrID=ceData.formid,FieldID=ficFieldID,useFIC=false); if ( StructKeyExists(arguments.ficDataValues,ficFieldValueKey) ) fldValue = arguments.ficDataValues[ficFieldValueKey]; if ( LEN(TRIM(fldName)) AND !StructKeyExists(ceData.values,fldName) ) ceData.values[fldName] = fldValue; } } retArray[1] = ceData; return retArray; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: $queryToCEDataArrayOfStructures Summary: Converts a query to an array of structures nested in the values node like a ceData array of structures Based on data.queryToArrayOfStructures() Returns: Array Arguments: Query - queryData - "The query that will be converted into an array of structures" Boolean - keysToLowercase - "Use to convert struct key to lowercase" History: 2016-11-16 - GAC - Created */ public array function queryToCEDataArrayOfStructures(required query queryData, boolean keysToLowercase=false) { var theArray = arraynew(1); var cols = ListtoArray(arguments.queryData.columnlist); var row = 1; var thisRow = StructNew(); var col = 1; for ( row = 1; row LTE arguments.queryData.recordcount; row = row + 1 ){ thisRow.formid = 0; thisRow.pageid = 0; thisRow.values = structnew(); for(col = 1; col LTE arraylen(cols); col = col + 1) { if ( cols[col] EQ "formid" AND StructKeyExists(arguments.queryData,"formid") ) thisRow.formid = arguments.queryData.formid[row]; if ( cols[col] EQ "pageid" AND StructKeyExists(arguments.queryData,"pageid") ) thisRow.pageid = arguments.queryData.pageid[row]; if ( arguments.keysToLowercase ) thisRow.values[lcase(cols[col])] = arguments.queryData[cols[col]][row]; else thisRow.values[cols[col]] = arguments.queryData[cols[col]][row]; } arrayAppend(theArray,duplicate(thisRow)); } return theArray; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: formatDataForGceArchivePostImport Summary: Returns a string of formatted CFML script code with the Fields and Data from a given custom element Returns: String Arguments: String - ceName (required) - "the Global Custom Element Name that contains the data to export" Boolean - alwaysAddFlag - "Set to 'true' to add this data when importing even if element exists and has data" String - skipFields - "A list of field names to skip to force default values to generated on import." Usage: application.ADF.ceData.formatDataForGceArchivePostImport(ceName,alwaysAddFlag,skipFields); History: 2017-11-29 - GAC - Created 2019-05-16 - GAC - Added skipFields parameter */ public string function formatDataForGceArchivePostImport(required string ceName,boolean alwaysAddFlag=false,string skipFields=""){ var retStr = ""; var items = getCEdata(arguments.ceName); var item = StructNew(); var TAB = CHR(9); var LF = CHR(10); var i = 1; var key = ""; savecontent variable="retStr" { WriteOutput('<cfscript>');WriteOutput('#LF#'); WriteOutput('#TAB#');WriteOutput(encodeForHTML("dataCFC = createObject('component', 'commonspot.components.form.gce-data'); // NOTE: do not call init"));WriteOutput('#LF#');WriteOutput('#LF#'); WriteOutput('#TAB#');WriteOutput("gceName = '#arguments.ceName#';");WriteOutput('#LF#'); WriteOutput('#TAB#');WriteOutput("alwaysAdd = #arguments.alwaysAddFlag#; // 'false' will NOT populate if any data found in Data_fieldvalue table");WriteOutput('#LF#'); WriteOutput('#TAB#');WriteOutput("data = ArrayNew(1);");WriteOutput('#LF#');WriteOutput('#LF#'); for ( i=1; i lte ArrayLen(items); i=i+1 ) { item = items[i].values; WriteOutput('#TAB#');WriteOutput("info = {};");WriteOutput('#LF#'); for ( key IN item ) { if ( ListFindNoCase(arguments.skipFields,key,",") EQ 0 ) { WriteOutput('#TAB#');WriteOutput("info['#lcase(key)#'] = '#item[key]#';");WriteOutput('#LF#'); } } WriteOutput('#TAB#');WriteOutput("ArrayAppend(data, info);");WriteOutput('#LF#');WriteOutput('#LF#'); } WriteOutput('#TAB#');WriteOutput(encodeForHTML("dataCFC.populateRawData(gceName, data, alwaysAdd);"));WriteOutput('#LF#'); WriteOutput('</cfscript>'); } return retStr; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: outputDataForGceArchivePostImport Summary: Renders to the page formatted CFML script code with the Fields and Data from a given custom element Returns: Void Arguments: String - ceName (required) - "the Global Custom Element Name that contains the data to export" Boolean - alwaysAddFlag - "Set to 'true' to add this data when importing even if element exists and has data" String - skipFields - "A list of field names to skip to force default values to generated on import." Boolean - indentedOutput = "Set to 'true' to add
tags around generated output to render the indents" Usage: application.ADF.ceData.outputDataForGceArchivePostImport(ceName,alwaysAddFlag,skipFields,indentedOutput); History: 2017-11-29 - GAC - Created 2019-05-16 - GAC - Added skipFields and indentedOutput parameters */ public void function outputDataForGceArchivePostImport(required string ceName,boolean alwaysAddFlag=false,string skipFields="",boolean indentedOutput=false){ if ( arguments.indentedOutput ) WriteOutput(""); WriteOutput(formatDataForGceArchivePostImport(arguments.ceName,arguments.alwaysAddFlag,arguments.skipFields)); if ( arguments.indentedOutput ) WriteOutput(""); } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: createFileForGceArchivePostImport Summary: Renders to the page formatted CFML script code with the Fields and Data from a given custom element Returns: Struct Arguments: String - fileDir (required) - "the folder under the site root where the file will be created"; String - ceName (required) - "the Global Custom Element Name that contains the data to export" Boolean - alwaysAddFlag - "Set to 'true' to add this data when importing even if element exists and has data" String - skipFields - "A list of field names to skip to force default values to generated on import." Boolean - overwrite - "Set to 'true' to rebuild file each the method is called" Usage: application.ADF.ceData.createFileForGceArchivePostImport(fileDir,ceName,alwaysAddFlag,skipFields,formattedOutput,overwrite); History: 2019-05-06 - GAC - Created */ public struct function createFileForGceArchivePostImport(required string fileDir,required string ceName,boolean alwaysAddFlag=false,string skipFields="",boolean overwrite=false){ var retData = StructNew(); var writeStatus = "no-file"; var dirCreate = StructNew(); var dataString = application.ADF.ceData.formatDataForGceArchivePostImport(arguments.ceName,arguments.alwaysAddFlag,arguments.skipFields); var filePath = request.site.dir; var fileName = ''; var fileSuffix = "_postimport"; var fileExt = 'cfm'; var charSet = 'utf-8'; retData.status = ''; retData.filepath = ''; // unescape the code/text in the datastring dataString = canonicalize(dataString,false,false); if ( LEN(TRIM(dataString)) ) { // create the file name fileName = application.ADF.csData.makeCSSafe(stringToFix=arguments.ceName,makeLowerCase=true,addDashes=true); // create the full file path in the siteroot filePath = application.ADF.utils.buildFullURL(hostURL=filePath,relPath=arguments.fileDir); filePath = application.ADF.utils.fixFilePathSlashes(filePath); if( Right(filePath,1) NEQ "/" ) filePath = filePath & "/"; filePath = filePath & fileName & fileSuffix & "." & fileExt; // If file exists and overwrite is false do NOT delete the file and create a new one if ( FileExists(filePath) AND !arguments.overwrite ) writeStatus = "exists"; if ( writeStatus NEQ "exists" ) { // If needed, create directory (or directories) to store data file dirCreate = application.ADF.utils.createDataFileFolders(filePath); if ( StructKeyExists(dirCreate,"Status") AND dirCreate.Status NEQ "dir-create-failed" ) { try { // Write the dataString to a file lock timeout="30" name="writePostImportDataFileLock" throwontimeout="Yes" type="exclusive" { FileWrite(filePath, dataString, charset); } writeStatus = "success"; retData.filepath = filePath; } catch ( any ex ) { writeStatus = "file-write-failed"; //WriteDump(ex); } } else { writeStatus = "dir-create-failed"; } // directory check } else { retData.filepath = filePath; } // writeStatus - fileexits check } else { writeStatus = "no-data"; } // datastring check retData.status = writeStatus; return retData; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: $getFormIDQueryFromPageID Summary: Returns the PageID,FormID,ControlID query for the PageID and optional ControlID. Returns: Query Arguments: Numeric - PageID - Data Page ID Numeric - ControlID - Control ID Boolean - excludeMDs - Exclude Custom Metadata Forms (controlID > 0) History: 2018-08-17 - GAC - Created */ public query function getFormIDQueryFromPageID(required numeric pageid, numeric controlid="0",boolean excludeMDs=false){ var retQry = queryNew("PageID,FormID,ControlID"); var qryDFV = ''; var queryObj = ''; var sqlSyntax = "SELECT distinct PageID, FormID, Controlid FROM Data_FieldValue WHERE PageID=:pageid AND VersionState = 2"; if ( arguments.excludeMDs ) sqlSyntax = sqlSyntax & " AND ControlID > 0 "; if ( arguments.controlid GT 0 ) sqlSyntax = sqlSyntax & " AND ControlID = :controlid"; sqlSyntax = sqlSyntax & " ORDER BY PageID, FormID, Controlid"; queryObj = new Query( name="qryDFV", datasource=request.site.datasource, sql = sqlSyntax ); queryObj.addParam(name="pageid",value=arguments.pageid, cfsqltype="cf_sql_integer"); if ( arguments.controlid GT 0 ) queryObj.addParam(name="controlid",value=arguments.controlid, cfsqltype="cf_sql_integer"); retQry = queryObj.execute().getResult(); return retQry; } /* *************************************************************** */ /* Author: PaperThin, Inc. Name: $getFormIDArrayFromPageID Summary: Returns the PageID,FormID,ControlID array of struct for the PageID and optional ControlID. Returns: Query Arguments: Numeric - PageID - Data Page ID Numeric - ControlID - Control ID Boolean - excludeMDs - Exclude Custom Metadata Forms (controlID > 0) History: 2018-08-17 - GAC - Created */ public array function getFormIDArrayFromPageID(required numeric pageid, numeric controlid="0",boolean excludeMDs=false){ var retArr = ArrayNew(1); var qryDFV = getFormIDQueryFromPageID(pageid=arguments.pageid,controlid=arguments.controlid,excludeMDs=arguments.excludeMDs); // Check that we have a query values if ( qryDFV.RecordCount GT 0 ) retArr = variables.data.queryToArrayOfStructures(queryData=qryDFV,keysToLowercase=true); return retArr; } }