/*
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-2025.
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:
scriptsService_2_0.cfc
Summary:
Scripts Service functions for the ADF Library
Version:
2.0
History:
2016-03-11 - GAC - Created
2017-08-24 - GAC - Updated checkResourceURL() and checkRemoteResourceURL() methods
- Added the missing component metadata properties
2020-10-08 - GAC - Added parameters isCritical, Integrity and Crossorigin to getResourceStruct for CommonSpot 10.7
2020-10-20 - GAC - Switched checkResourceURL and checkRemoteResourceURL to public methods for use by scripts tools
2022-01-05 - GAC - Updated getResourceStruct() to add default values for canCombine, canMinify, isCritical, Integrity and Crossorigin arguments
*/
component displayname="scriptsService_2_0" extends="scriptsService_1_1" hint="Scripts functions for the ADF Library" output="no"
{
property name="version" value="2_0_8";
property name="type" value="singleton";
property name="wikiTitle" value="ScriptsService_2_0";
/*
resourceAPI.save(id, name, category, earlyLoadSourceArray, lateLoadSourceArray, description, installInstructions, aliasList, redistributable);
sourceArray: [{LoadTagType, SourceURL}]}
LoadTagType: 1=StyleSheet 2=JavaScript
History:
2017-03-27 - GAC - Updated to better handle argument validation from the CMD API since the wrapper function adds some additional arguments.
*/
public numeric function registerResource
(
required string name,
required string category,
required array earlyLoadSourceArray,
required array lateLoadSourceArray,
required string description,
required string installInstructions,
string aliasList="",
boolean redistributable=0,
boolean updateExisting=0,
boolean silent=0,
boolean preserveAliases=1
)
{
var resSpecs = "";
var action = "registered";
var resourceAPI = Server.CommonSpot.ObjectFactory.getObject("Resource");
var msg = "";
var a = 1;
var savedAliasArr = [];
var aliasSpecs = {};
var aliasArr = [];
var aliasItm = '';
var aliasMsg = '';
var tmpMsg = '';
arguments.id = 0;
// Check for Name conflicts
if (structKeyExists(Request.Site.CS_Resources.Resources_by_name, arguments.name))
{
resSpecs = Request.Site.CS_Resources.Resources_by_name[arguments.name];
// Save off the aliaslist for later use
savedAliasArr = ListToArray(resSpecs.aliasList);
if (resSpecs.name != arguments.name) // registered version is an alias, can't update it
{
msg = "Alias with this name already exists, skipped: #arguments.name#";
if ( !arguments.silent )
writeOutput(msg & "
");
return 0;
}
else if (arguments.updateExisting == 0)
{
msg = "Resource already exists, skipped: #arguments.name#";
if ( !arguments.silent )
writeOutput(msg & "
");
return 0;
}
else
{
arguments.id = resSpecs.id;
action = "updated";
}
}
// Check for Alias conflicts, create an array form the aliasList parameter
aliasArr = ListToArray(arguments.aliasList);
if ( arguments.preserveAliases ) {
// Union/Merge the current Alais list for this record with new AliasList
if ( ArrayLen(savedAliasArr) )
aliasArr = _unionArr(aliasArr,savedAliasArr);
}
// Loop backwards through the new (or combined) alaises to see if any are currently in use
// - if preserving, remove any from the list that are found in other resources
for ( a=ArrayLen(aliasArr); a >= 1; a-- ) {
aliasItm = aliasArr[a];
if ( structKeyExists(Request.Site.CS_Resources.Resources_by_name, aliasItm) ) {
// we have a potential conflict, lets get more info
aliasSpecs = Request.Site.CS_Resources.Resources_by_name[aliasItm];
// this Alias exists, but only care if it is NOT the current resource being registered
if ( aliasSpecs.name != arguments.name ) {
tmpMsg = "[Alias found - ";
if ( arguments.preserveAliases ) {
ArrayDeleteAt(aliasArr, a);
tmpMsg = tmpMsg & ' preserving: "#aliasItm#" in #aliasSpecs.name#]';
}
else
tmpMsg = tmpMsg & ' re-assigning: "#aliasItm#" from #aliasSpecs.name#]';
if ( LEN(TRIM(aliasMsg)) )
aliasMsg = aliasMsg & " " & tmpMsg;
else
aliasMsg = tmpMsg;
}
}
}
// Copy back the aliasList parameter
arguments.aliasList = ArrayToList(aliasArr);
arguments.earlyLoadSourceArray = getResourceArray(arguments.earlyLoadSourceArray);
arguments.lateLoadSourceArray = getResourceArray(arguments.lateLoadSourceArray);
msg = "Resource #action#: #arguments.name#";
if ( LEN(TRIM(aliasMsg)) )
msg = msg & " " & aliasMsg;
if ( !arguments.silent )
writeOutput(msg & "
");
// Check Resource URLs
arguments.earlyLoadSourceArray = checkResourceURL(resourceArray=arguments.earlyLoadSourceArray, silent=arguments.silent);
arguments.lateLoadSourceArray = checkResourceURL(resourceArray=arguments.lateLoadSourceArray, silent=arguments.silent);
// returns NUMERIC ID on NEW/UPDATE
// - Updated to better handle argument validation from the CMD API
if ( ArrayLen(arguments.earlyLoadSourceArray) OR ArrayLen(arguments.lateLoadSourceArray) )
{
return resourceAPI.save(id=arguments.id,
name=arguments.name,
category=arguments.category,
earlyLoadSourceArray=arguments.earlyLoadSourceArray,
lateLoadSourceArray=arguments.lateLoadSourceArray,
description=arguments.description,
installInstructions=arguments.installInstructions,
aliasList=arguments.aliasList,
redistributable=arguments.redistributable
);
}
else
return 0;
}
private array function getResourceArray(resourceSpecsArray)
{
var arr = Request.TypeFactory.newObjectInstance("ResourceLoadStruct_Array");
var count = arrayLen(arguments.resourceSpecsArray);
var i = 0;
for (i = 1; i <= count; i++)
arrayAppend(arr, getResourceStruct(argumentCollection=arguments.resourceSpecsArray[i]));
return arr;
}
private struct function getResourceStruct(required string loadTagType, required string sourceURL, boolean canCombine=0, boolean canMinify=0, boolean isCritical=0, string Integrity="", string Crossorigin="")
{
var res = Request.TypeFactory.newObjectInstance("ResourceLoadStruct");
var csVersion = server.ADF.csVersion;
var isCS107plus = application.ADF.utils.minimumVersionCheck(version=csVersion,minimumVersionsList="10.7");
if (!structKeyExists(arguments, "canCombine"))
arguments.canCombine = (left(arguments.sourceURL, 4) == "http") ? 0 : 1;
if (!structKeyExists(arguments, "canMinify"))
arguments.canMinify =
(
!arguments.canCombine
|| findNoCase(".min", arguments.sourceURL)
|| findNoCase("_min", arguments.sourceURL)
|| findNoCase("-pack", arguments.sourceURL)
|| findNoCase(".pack", arguments.sourceURL)
) ? 0 : 1;
res.loadTagType = arguments.loadTagType;
res.sourceURL = arguments.sourceURL;
res.canCombine = arguments.canCombine;
res.canMinify = arguments.canMinify;
// New for CommonSpot 10.7
if ( isCS107plus )
{
res.isCritical = ( StructKeyExists(arguments,"isCritical") ) ? arguments.isCritical : 0;
res.Integrity = ( StructKeyExists(arguments,"Integrity") ) ? arguments.Integrity : "";
res.Crossorigin = ( StructKeyExists(arguments,"Crossorigin") ) ? arguments.Crossorigin : "";
}
return res;
}
public array function checkResourceURL(required array resourceArray, boolean silent=0)
{
var retArray = ArrayNew(1);
var i = 1;
var msg = "";
var srcURL = ";
var srcPath = ";
//writedump(var=arguments.resourceArray,expand=false);
for ( i=1; i LTE ArrayLen(arguments.resourceArray); i=i+1 ) {
msg = "";
if ( StructKeyExists(arguments.resourceArray[i],"sourceURL") )
{
srcURL = arguments.resourceArray[i].sourceURL;
// Check Local
if ( left(srcURL,4) != "http" AND left(srcURL,2) != "//" )
{
srcPath = ExpandPath(ListFirst(srcURL,"?"));
// CEHCK the Local Resource Path
if ( !FileExists(srcPath) )
msg = "Error: #srcURL# does not exist!";
}
else
{
// CHECK the Remote Resource URL
if ( !checkRemoteResourceURL(srcURL) )
msg = "Error: The remote resource #srcURL# was not available. Please verify it is a valid URL!";
}
}
else
msg = "Error: Resource has no sourceURL!";
if ( !arguments.silent && LEN(TRIM(msg)) )
{
writeOutput(msg & "
");
writeOutput(" -- Skipping resource registration. Please verify resource exists!" & "
");
}
else
arrayAppend(retArray,arguments.resourceArray[i]);
} // resourceArray loop
return retArray;
}
public boolean function checkRemoteResourceURL(required string sourceURL)
{
var retVal = false;
var retResult = '';
var httpService = '';
var cfmlEngineType = server.coldfusion.productname;
var cfmlEngineMajorVer = ListFirst(SERVER.ColdFusion.ProductVersion,",");
if ( FindNoCase(cfmlEngineType,'ColdFusion Server') )
{
if ( cfmlEngineMajorVer GTE 11 )
{
cfhttp(method="GET", charset="utf-8", url="#arguments.sourceURL#", result="retResult");
}
else
{
httpService = new http(method = "GET", charset = "utf-8", url = "#arguments.sourceURL#");
retResult = httpService.send().getPrefix();
}
}
else
{
cfhttp(method="GET", charset="utf-8", url="#arguments.sourceURL#", result="retResult");
}
if ( StructKeyExists(retResult,"statuscode") AND Find("200",retResult.statuscode) )
retVal = true;
return retVal;
}
/***********************************************************/
/******************* Local Utilities ***********************/
/***********************************************************/
private array function _diffArr(required array a, required array b) {
return application.ADF.data.arrayDiff(argumentCollection=arguments);
}
private array function _unionArr(required array a, required array b) {
return application.ADF.data.arrayUnion(argumentCollection=arguments);
}
}