Skip to content

Instantly share code, notes, and snippets.

@JamoCA
Last active November 3, 2024 00:33
Show Gist options
  • Save JamoCA/fbbd2599102216448ada8e9f85d40b9c to your computer and use it in GitHub Desktop.
Save JamoCA/fbbd2599102216448ada8e9f85d40b9c to your computer and use it in GitHub Desktop.
<cfscript>
/**
* generateZint UDF
* @displayname generateZint
* @Dependency Requires Zint executable from https://zint.org.uk/
* @Dependency_Documentation https://zint.org.uk/manual/chapter/4
* @author James Moberg http://sunstarmedia.com, @sunstarmedia
* @version 1
* @lastUpdate 10/30/2024 16:00 Pacific
* @gist https://gist.github.com/JamoCA/fbbd2599102216448ada8e9f85d40b9c
* @blog https://dev.to/gamesover/coldfusion-wrapper-for-zint-barcode-generator-15mc
* @twitter https://x.com/gamesover/status/1851768390760960101
* @LinkedIn https://www.linkedin.com/posts/jamesmoberg_coldfusion-activity-7257534479445962752-aeoL
* @param String filepath The path and file name to use when storing the generated file. (These params can also be defined in "options".)
* @param String barcodeType The barcode type. Normally a integer, but also accepts "QR". (https://zint.org.uk/manual/chapter/4#selecting-barcode-type)
* @param String data The data to encode.
* @param String exePath The filepath to the Zint executable.
* @param struct options All of the configuration data. Some very basic defaults are used if nothing is passed.
*/
struct function generateZint(string filepath="", string barcodeType=58, string data="", string exePath="", struct options={}) {
local.timestart = gettickcount();
local.response = [
"success": false
,"duration": 0
,"filePath": ""
,"cmd": ""
,"output": ""
,"errors": []
];
local.options = duplicate(arguments.options);
// reset some primary values if found in options & validate
if (local.options.keyexists("exePath")){
arguments.exePath = local.options.exePath;
structdelete(local.options, "exePath");
}
if (!fileexists(arguments.exePath)){
arrayappend(local.response.errors, "exePath is required.");
}
if (local.options.keyexists("o")){
arguments.filePath = local.options.o;
structdelete(local.options, "o");
}else if (local.options.keyexists("filePath")){
arguments.filePath = local.options.filePath;
structdelete(local.options, "filePath");
}
if (!len(arguments.filepath)){
arrayappend(local.response.errors, "filePath is required.");
}
if (local.options.keyexists("b")){
arguments.barcodeType = local.options.b;
structdelete(local.options, "b");
} else if (local.options.keyexists("barcodeType")){
arguments.barcodeType = local.options.barcodeType;
structdelete(local.options, "barcodeType");
}
arguments.barcodeType = (arguments.barcodeType eq "qr") ? 58 : arguments.barcodeType;
if (!val(arguments.barcodeType)){
arrayappend(local.response.errors, "barcodeType is required.");
}
if (local.options.keyexists("d")){
arguments.data = local.options.d;
structdelete(local.options, "d");
} else if (local.options.keyexists("data")){
arguments.data = local.options.data;
structdelete(local.options, "data");
}
if (!issimplevalue(arguments.data) || !len(arguments.data)){
arrayappend(local.response.errors, "data is required.");
}
// populate options with some default setting (if empty)
if (!structcount(local.options)){
// if QR code, set default options for barcode type 58
if (arguments.barcodeType eq 58){
local.options = [
"scale": javacast("int", 12)
,"fg": javacast("string", "000000")
,"bg": "ffffff"
,"nobackground": true
,"whitesp": javacast("int", 2)
,"vwhitesp": javacast("int", 2)
];
// default scale
} else {
local.options = [
"scale": javacast("int", 5)
];
}
}
local.cmd = [
"-o ""#arguments.filePath#"""
,"-b #javacast("int", val(arguments.barcodeType))#"
];
if (structcount(local.options)){
for (local.p in local.options){
local.v = trim(local.options[local.p]);
if (refindnocase("^([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$", local.v)){
local.v = javacast("string", local.v); // hex
} else if (isvalid("integer", local.v)) {
local.v = javacast("int", local.v); // integers
} else if (refind(local.v, "[:space:]")){
local.v = """#local.v#"""; // values with spaces
}
if (local.p eq "nobackground"){
if (isvalid("boolean", local.v) && local.v){
arrayappend(local.cmd, "--nobackground");
}
} else if (len(local.p) gt 1){
local.s = len(trim(local.v)) ? "--#local.p#=#local.v#" : "--#local.p#";
arrayappend(local.cmd, local.s);
} else if (len(local.p) eq 1){
local.s = len(trim(local.v)) ? "-#local.p# #local.v#" : "-#local.p#";
arrayappend(local.cmd, local.s);
}
}
}
arrayappend(local.cmd, "-d ""#replace(arguments.data, """", "\""", "all")#""");
local.response["cmd"] = arraytolist(local.cmd, " ");
if (!arraylen(local.response.errors)){
cfexecute(name="#arguments.exePath#", arguments="#local.response.cmd#", timeout="90", variable="local.response.output");
local.response.success = fileexists(arguments.filePath);
local.response.filePath = fileexists(arguments.filePath) ? arguments.filePath : "";
}
local.response.duration = javacast("int", gettickcount() - local.timestart);
return local.response;
}
/* Example
testImageName = "this-is-a-test.svg";
options = [
"filePath": "D:\www\#testImageName#"
,"data": "This is a test"
,"exePath": "C:\zint\zint.exe"
];
zintData = request.generateZint(options=options);
writeoutput('<img src="/#testImageName#" style="width:250px; height:auto;">');
writedump(var=zintData, label="zintData");
*/
</cfscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment