Files
Facilitor/APPL/API2/model_custom_fields.inc
Jos Groot Lipman 6e2953faef FSN#38299 Flexkenmerken via de API kunnen bewerken
svn path=/Website/trunk/; revision=33796
2017-05-11 08:27:39 +00:00

268 lines
11 KiB
PHP

<% /*
$Revision$
$Id$
File: model_custom_fields.inc
Description: Flexkenmerken model
Context: Er is géén eigen api_custom_fields
We kunnen alleen via een include van een parent die dan ook
vooral alle autorisatiecontrole voor ons kan verzorgen
Notes: Voor de GET gebruiken we getSqlFlex uit resultset_flex
Lekker gemakkelijk hoewel hij niet 100% de volgnummer beperkingen volgt
Voor de PUT/POST/DELETE gebruiken we de functies van PACKAGE flx
*/
%>
<!-- #include file="../Shared/kenmerk_common.inc" -->
<!-- #include file="../Shared/resultset_flex.inc"-->
<%
function model_custom_fields(formodel, flexModule, flexParams)
{
var flexModel = null; // alleen nog niet bij issues
if (typeof flexModule != "string")
{
flexModel = flexModule;
flexModule = flexModel.module;
}
flexParams = flexParams || {};
this.module = flexModule;
this.records_name = "custom_fields";
this.record_name = "custom_field";
this.table = "flex";
this.primary = "kenmerk_key";
this.records_title = L("custom_field_m");
this.record_title = L("custom_field");
this.keyfield = "propertyid"; // api2/process_includes werkt nu iets anders
// getSqlFlex heeft bij multi-language 'user' al nodig voor de lcl's
// daarom hieronder een indirecte/ delayed fntablesql
this.fntablesql = function _fntablesql()
{
var theSqlFlex = getSqlFlex(flexModule, formodel.primary, flexParams);
var custom_fields = getQParamIntArray("custom_fields", []);
if (custom_fields.length)
theSqlFlex = "SELECT * FROM ({0}) WHERE kenmerk_key IN ({1})".format(theSqlFlex, custom_fields.join(", "))
return "(" + theSqlFlex + ") flex";
}
this.fields = {
// De echte unieke waarde "id" is bez_kenmerkwaarde_key.
// We doen echter alles op basis van de samengestelde kenmerk_key + parent_key
// De naam van dat veld weten we hier even niet echter
// en hebben we ook niet nodig
"propertyid": {
"dbs": "kenmerk_key",
"label": L("lcl_key"),
"typ": "key"
},
"value": {
"dbs": "waarde",
"label": L("lcl_fac_value"),
"typ": "varchar"
},
"type": {
"dbs": "kenmerktype",
"label": L("mgt_srtkenmerk_kenmerktype"),
"typ": "varchar"
},
"sequence": {
"dbs": "volgnummer",
"label": L("mgt_kenmerk_volgnummer"),
"typ": "number" },
"label": {
"dbs": "omschrijving",
"label": L("mgt_srtkenmerk_label"),
"typ": "varchar"
},
"flexparentkey": {
"dbs": "flexparentkey",
"typ": "key"
},
// TODO: record.flexparentid wordt er uitgestript vanwege niet teruglinken naar de parent
// we hebben hem echter wel nodig. Dit moet beter....
"xflexparentkey": {
"dbs": "flexparentkey",
"typ": "key",
"sql": "flexparentkey"
}
};
// Deze functie wordt na de GET aangeroepen. De bijlagen zijn zo afwijkend
// dat ik dat niet fatsoenlijk in 'fields' verwerkt kreeg
this.post_get = function (params, record)
{
if (record.type == 'F' || record.type == 'M')
{
var flexparam = flexProps(flexModule, record.xflexparentkey, String(record.propertyid), flexParams.pNiveau,
{ getFiles: true, getFileEncoded: params.filter.fileencoding, api2name: formodel.records_name });
record.attachments = [];
for (var f in flexparam.files)
{
var file = flexparam.files[f];
var attachment = { name: file.name,
date: file.date,
size: file.size,
content_url: file.deepurl,
digest: file.digest };
switch (params.filter.fileencoding) // De enige twee encodings die we ondersteunen
{
case "base64":
attachment.content_base64 = file.data;
break;
case "hex":
attachment.content_hex = file.data;
break;
}
record.attachments.push(attachment);
};
}
delete record["xflexparentkey"]; // nu niet meer nodig
}
// Voor flexbijlagen kennen we een duale interface
// Enerzijds zitten ze gewoon als attachements-object in de JSON
// die een GET van custom_fields oplevert
// Anderzijds zijn ze met GET/PUT/POST/DELETE rechtstreeks te benaderen onder
// /api2/visitors/1234/attachments/1000/test.jpg
this.streamattachment = function(filter, flexfields)
{
for (var fid in flexfields)
{
if (flexfields[fid].propertyid == filter.subfolder && flexfields[fid].attachments)
{
for (var i = 0; i < flexfields[fid].attachments.length; i++)
{
var att = flexfields[fid].attachments[i];
if (att.name.toLowerCase() == filter.filename.toLowerCase()) // Gevonden!!!!
{
var params = flexProps(this.module, filter.id, filter.subfolder, flexParams.pNiveau);
// In de praktijk (b)lijkt IE de ETag niet te sturen voor downloads
// maar wij ondersteunen het in ieder geval wel.
var eTag = '"' + att.digest + '"';
Response.AddHeader("ETag", eTag);
if (Request.ServerVariables("HTTP_IF_NONE_MATCH") == eTag)
{ // We hebben een match!
Response.Clear();
Response.Status = "304 Not modified";
Response.End;
}
StreamFile(params.AttachPath, att.name, "application/octet-stream");
}
}
}
}
__Log(filter);
Response.Status = "404 Not Found";
}
if (flexModel) // nog even niet voor MLD
this.REST_PUT = function (params, jsondata, the_key, parent_key) /* update custom_field */
{ // Let op: parameter the_key is de kenmerk_key, niet een een kenmerkwaarde_key
// Merk op dat flexProps ook wel het type oplevert. Ik wil echter migreren naar modellen
var kenmerkdata = api2.GET(flexModel, jsondata.propertyid);
// TODO: if (!kenmerkdata) en rechtencontrole
var typ = kenmerkdata.attributetype.id;
if (typ == 'F' || typ == 'M')
{
var flexparams = flexProps(this.module, parent_key, the_key, flexParams.pNiveau);
// TODO: bij type F zorgen dat er één file overblijft
for (var i = 0; i < jsondata.attachments.length; i++)
{
var attachment = jsondata.attachments[i];
var safefilename = safe.filename(attachment.name);
if (flexparams.isAllowedName(safefilename))
{
CreateFullPath(flexparams.AttachPath);
if ("datastream" in attachment) // PUT op /api2/visitors/1234/attachments/1000/test.jpg
{
attachment.datastream.SaveToFile(flexparams.AttachPath + safefilename, 2); // adSaveCreateOverWrite
}
else if ("content_base64" in attachment || "content_hex" in attachment)
{
var fileencoding = "content_base64" in attachment?"bin.base64":"bin.hex";
encodedString2File(flexparams.AttachPath + safefilename,
attachment.content_base64 || attachment.content_hex,
fileencoding);
}
}
else
{
Response.Status = "422 Unprocessable Entity";
Response.End;
}
}
}
if (typ != "M")
{
var sql = "BEGIN flx.setflex({0}".format(safe.quoted_sql(this.module))
+ " , {0}".format(the_key) // == jsondata.propertyid
+ " , {0}".format(parent_key)
+ " , {0}".format(safe.quoted_sql(flexParams.pNiveau))
+ " , {0});".format(safe.quoted_sql(jsondata.value))
+ "END;"
Oracle.Execute(sql);
}
}
if (flexModel) // nog even niet voor MLD
this.REST_POST = function (params, jsondata, parent_key) /* add custom_field */
{ // Voor flexvelden is er geen verschil tusen 'toevoegen' en 'bijwerken'
this.REST_PUT(params, jsondata, jsondata.propertyid, parent_key);
}
this.REST_DELETE = function (params, the_key) /* remove custom_field */
{
// custom_fields zijn ietwat afwijkend
// 'verwijderen' doe je door de waarde op NULL te zetten (net zoals met vaste velden)
// Anders loop je risico dat bij een update velden die niet in de include=custom_fields
// zitten (omdat je er gewoon geen rechten op had) zo maar verwijderd worden
// TODO: flexfiles wel kunnen deleten
}
this.list = { columns: ["id", "label", "value"] }
// Merk op: géén eigen REST_GET
// We werken toch alleen via een include van een parent die dan ook
// vooral alle autorisatiecontrole voor ons kan verzorgen
}
function set_custom_field(jsondata, kenmerk_key, val, typ)
{
if (!("custom_fields" in jsondata))
jsondata.custom_fields = [];
for (var i=0; i< jsondata.custom_fields.length; i++)
{
if (jsondata.custom_fields[i].propertyid == kenmerk_key)
{
jsondata.custom_fields[i].value = val;
return; // direct klaar
}
}
// JGL: is het volgende wel nodig? Opdrachten gingen via saveFlexKenmerken maar dat is achterhaald?
if (!typ)
abort_with_warning("Cannot set_custom_field key '{0}' without type".format(kenmerk_key));
jsondata.custom_fields.push({ propertyid: kenmerk_key, value: val, type: typ });
}
function get_custom_field(jsondata, kenmerk_key)
{
if (!("custom_fields" in jsondata))
return null;
for (var i=0; i< jsondata.custom_fields.length; i++)
{
if (jsondata.custom_fields[i].propertyid == kenmerk_key)
{
return jsondata.custom_fields[i].value; // direct klaar
}
}
return null;
}
%>