Skip to content

Instantly share code, notes, and snippets.

@nelsonlaquet
Created June 29, 2018 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nelsonlaquet/575c351488eedc58f78f638cab7ef898 to your computer and use it in GitHub Desktop.
Save nelsonlaquet/575c351488eedc58f78f638cab7ef898 to your computer and use it in GitHub Desktop.
<MvCOMMENT> ========== ========== ========== ========== ========== ==========
JSON.mv conversion function
Syntax and Usage:
Json_Stringify(data_object)
Returns a Json string
data_object = structured miva data object
Usage:
<MvEVAL EXPR="{ Json_Stringify(l.all_settings:basket) }">
========== ========== ========== ========== ========== ========== </MvCOMMENT>
<MvFUNCTION NAME="Json_Stringify" PARAMETERS="data VAR" STANDARDOUTPUTLEVEL="">
<MvCOMMENT>
Added an escaping arrays for stringifying, Timothy Bolton, 4/12/2012
renamed JSON() to Json_Stringify() 3/21/2010
(Original work by KAM, 3/2011)
Create JSON text from Miva Data: variable, array, structure, etc.
</MvCOMMENT>
<MvASSIGN NAME = "l.search_array" INDEX = "1" VALUE = "{ asciichar(92) $ 'b' }">
<MvASSIGN NAME = "l.search_array" INDEX = "2" VALUE = "{ asciichar(92) $ 't' }">
<MvASSIGN NAME = "l.search_array" INDEX = "3" VALUE = "{ asciichar(92) $ 'n' }">
<MvASSIGN NAME = "l.search_array" INDEX = "4" VALUE = "{ asciichar(92) $ 'f' }">
<MvASSIGN NAME = "l.search_array" INDEX = "5" VALUE = "{ asciichar(92) $ 'r' }">
<MvASSIGN NAME = "l.search_array" INDEX = "6" VALUE = "{ asciichar(34) }">
<MvASSIGN NAME = "l.search_array" INDEX = "7" VALUE = "{ asciichar(92) $ asciichar(92) }">
<MvASSIGN NAME = "l.replace_array" INDEX = "1" VALUE = "{ asciichar(92) $ asciichar(92) $ 'b' }">
<MvASSIGN NAME = "l.replace_array" INDEX = "2" VALUE = "{ asciichar(92) $ asciichar(92) $ 't' }">
<MvASSIGN NAME = "l.replace_array" INDEX = "3" VALUE = "{ asciichar(92) $ asciichar(92) $ 'n' }">
<MvASSIGN NAME = "l.replace_array" INDEX = "4" VALUE = "{ asciichar(92) $ asciichar(92) $ 'f' }">
<MvASSIGN NAME = "l.replace_array" INDEX = "5" VALUE = "{ asciichar(92) $ asciichar(92) $ 'r' }">
<MvASSIGN NAME = "l.replace_array" INDEX = "6" VALUE = "{ asciichar(92) $ asciichar(34) }">
<MvASSIGN NAME = "l.replace_array" INDEX = "7" VALUE = "{ asciichar(92) $ asciichar(92) $ asciichar(92) $ asciichar(92) }">
<MvASSIGN NAME="l.serial" VALUE="{ miva_array_serialize(l.data) }">
<MvASSIGN NAME="l.first" VALUE="{ substring(l.serial, 1, 1) }">
<MvIF EXPR="{ l.first EQ '=' }">
<MvIF EXPR="{ (len(l.data)) AND (l.data EQ (l.data + 0)) }"> <MvCOMMENT> --- valid number </MvCOMMENT>
<MvCOMMENT> 7/15/2014 Special case for number with leading zeros </MvCOMMENT>
<MvIF EXPR="{ len(l.data) GT 1 }">
<MvIF EXPR="{ substring(l.data,1,1) EQ '0' }">
<MvASSIGN NAME="l.data" VALUE="{ '\"' $ l.data $ '\"' }">
</MvIF>
</MvIF>
<MvFUNCRETURN VALUE="{ l.data }">
<MvELSE>
<MvFUNCRETURN VALUE="{ '\"' $ glosub_array(l.data, l.search_array, l.replace_array) $ '\"' }">
</MvIF>
</MvIF>
<MvASSIGN NAME="l.type" VALUE="{ l.first }">
<MvCOMMENT>
--- will be "[" or ":" to indicate array or structure
--- Loop thru all elements of the array or structure. Collect a list of the top-level children's "member IDs."
--- A member ID is either a number enclosed in brackets (array), or a colon followed by the member name (structure).
</MvCOMMENT>
<MvWHILE EXPR="{ gettoken(l.serial, ',', l.n + 1) }">
<MvASSIGN NAME="l.n" VALUE="{ l.n + 1 }">
<MvASSIGN NAME="l.member" VALUE="{ gettoken(l.serial, ',', l.n) }">
<MvASSIGN NAME="l.address" VALUE="{ gettoken(l.member, '=', 1) }">
<MvIF EXPR="{ l.type EQ '[' }">
<MvASSIGN NAME="l.mid" VALUE="{ substring(l.address, 1, (']' IN l.address)) }">
<MvELSE>
<MvASSIGN NAME="l.mid" VALUE="{ ':' $ gettoken( gettoken(l.address, ':', 2), '[', 1) }">
</MvIF>
<MvASSIGN NAME="l.mids" VALUE="{ AppendUnique(l.mids, l.mid) }">
</MvWHILE>
<MvCOMMENT> --- Call ourself recursively on each of the children. </MvCOMMENT>
<MvWHILE EXPR="{ gettoken(l.mids, ',', l.m + 1) }">
<MvASSIGN NAME="l.m" VALUE="{ l.m + 1 }">
<MvASSIGN NAME="l.mid" VALUE="{ gettoken(l.mids, ',', l.m) }">
<MvASSIGN NAME="l.childname" VALUE="{ 'l.data' $ l.mid }">
<MvREFERENCE NAME="l.child" VARIABLE="{ l.childname }">
<MvIF EXPR="{ l.m GT 1 }">
<MvASSIGN NAME="l.json" VALUE="{ l.json $ ', ' }">
</MvIF>
<MvIF EXPR="{ l.type EQ ':' }">
<MvASSIGN NAME="l.json" VALUE="{ l.json $ '\"' $ tolower(substring(l.mid, 2, 9999)) $ '\": ' }">
</MvIF>
<MvASSIGN NAME="l.json" VALUE="{ l.json $ Json_Stringify(l.child) }">
</MvWHILE>
<MvIF EXPR="{ NOT len(l.json) }">
<MvASSIGN NAME="l.json" VALUE="{ '\"\"' }">
<MvELSEIF EXPR="{ l.type EQ '[' }">
<MvASSIGN NAME="l.json" VALUE="{ ' [' $ l.json $ ']' }">
<MvELSE>
<MvASSIGN NAME="l.json" VALUE="{ ' {' $ l.json $ '}' }">
</MvIF>
<MvFUNCRETURN VALUE="{ l.json }">
</MvFUNCTION>
<MvFUNCTION NAME="AppendUnique" PARAMETERS="list, item" STANDARDOUTPUTLEVEL="">
<MvIF EXPR="{ IsIn(l.item, l.list) }">
<MvFUNCRETURN VALUE="{ l.list }">
<MvELSE>
<MvIF EXPR="{ (len(l.list) EQ 0) }">
<MvFUNCRETURN VALUE="{ l.item }">
</MvIF>
<MvFUNCRETURN VALUE="{ l.list $ ',' $ l.item }">
</MvIF>
</MvFUNCTION>
<MvFUNCTION NAME="Member" PARAMETERS="source VAR, member" STANDARDOUTPUTLEVEL="">
<MvFUNCRETURN VALUE="{ miva_variable_value('l.source:' $ l.member) }">
</MvFUNCTION>
<MvFUNCTION NAME="Structure" PARAMETERS="data, delim" STANDARDOUTPUTLEVEL="">
<MvASSIGN NAME="l.v" VALUE="{ miva_array_serialize(l.data) }">
<MvIF EXPR="{ substring(l.v, 1, 1) EQ '=' }">
<MvFUNCRETURN VALUE="{ l.data }">
</MvIF>
<MvWHILE EXPR="{ gettoken(l.v, ',', l.n + 1) }">
<MvASSIGN NAME="l.n" VALUE="{ l.n + 1 }">
<MvASSIGN NAME="l.fld" VALUE="{ gettoken(l.v, ',', l.n) }">
<MvASSIGN NAME="l.fnam" VALUE="{ gettoken(l.fld, '=', 1) }">
<MvASSIGN NAME="l.fval" VALUE="{ decodeattribute(gettoken(l.fld, '=', 2)) }">
<MvASSIGN NAME="l.ret" VALUE="{ l.ret $ l.fnam $ '=' $ l.fval }">
<MvIF EXPR="{ gettoken(l.v, ',', l.n + 1) }">
<MvASSIGN NAME="l.ret" VALUE="{ l.ret $ l.delim }">
</MvIF>
</MvWHILE>
<MvFUNCRETURN VALUE="{ l.ret }">
</MvFUNCTION>
<MvFUNCTION NAME="QSP" PARAMETERS="label, data VAR" STANDARDOUTPUTLEVEL="">
<MvFUNCRETURN VALUE="{ '<p>' $ l.label $ ': ' $ Structure(l.data, '; ') $ '</p>' }">
</MvFUNCTION>
<MvFUNCTION NAME="ValidNumber" PARAMETERS="n" STANDARDOUTPUTLEVEL="">
<MvFUNCRETURN VALUE="{ (len(l.n)) AND (l.n EQ (l.n + 0)) }">
</MvFUNCTION>
<MvFUNCTION NAME="ValidPositive" PARAMETERS="n" STANDARDOUTPUTLEVEL="">
<MvFUNCRETURN VALUE="{ (ValidNumber(l.n)) AND (l.n GT 0) }">
</MvFUNCTION>
<MvFUNCTION NAME="ValidNonNegative" PARAMETERS="n" STANDARDOUTPUTLEVEL="">
<MvFUNCRETURN VALUE="{ (ValidNumber(l.n)) AND (l.n GE 0) }">
</MvFUNCTION>
<MvFUNCTION NAME="IsIn" PARAMETERS="item, list" STANDARDOUTPUTLEVEL="">
<MvFUNCRETURN VALUE="{ (',' $ l.item $ ',') CIN (',' $ l.list $ ',') }">
</MvFUNCTION>
<MvComment>
GETs data from an OAuth 1 endpoint
</MvComment>
<MvFunction name="OAuth_Get" parameters="config var, endpoint, result var">
<MvCall
method="GET"
action="{l.endpoint}"
content-type="application/json"
headers="{OAuth_GetAuthHeader(l.config, 'GET', l.endpoint) $ asciichar(13) $ asciichar(10)}">
<MvAssign name="l._" value="{miva_json_decode(s.callvalue, l.result)}" />
</MvCall>
</MvFunction>
<MvComment>
POSTs data to an OAuth 1 endpoint
</MvComment>
<MvFunction name="OAuth_Post" parameters="config var, endpoint, payload var, result var">
<MvAssign name="l.payloadJson" value="{Json_Stringify(l.payload)}" />
<MvCall
method="RAW"
action="{l.endpoint}"
content-type="application/json"
fields="l.payloadJson"
headers="{OAuth_GetAuthHeader(l.config, 'POST', l.endpoint) $ asciichar(13) $ asciichar(10)}">
<MvAssign name="l._" value="{miva_json_decode(s.callvalue, l.result)}" />
</MvCall>
</MvFunction>
<MvComment>
Generates an OAuth Authorization header given the OAuth config and endpoint
</MvComment>
<MvFunction name="OAuth_GetAuthHeader" parameters="config var, method, endpoint">
<MvAssign name="l.urlPartCount" value="{miva_splitstring(l.endpoint, '?', l.urlParts, '')}" />
<MvIf expr="{l.urlPartCount}">
<MvAssign name="l._" value="{miva_splitstring(l.urlParts[2], '&', l.queryParts, '')}" />
<MvForeach array="l.queryParts" iterator="l.queryPart">
<MvAssign name="l._" value="{miva_splitstring(l.queryPart, '=', l.query, '')}" />
<MvAssignArray name="l.params" value="{l.query[2]}">
<MvMember name="{l.query[1]}" />
</MvAssignArray>
</MvForeach>
</MvIf>
<MvAssign name="l.params:oauth_consumer_key" value="{l.config:ConsumerKey}" />
<MvAssign name="l.params:oauth_nonce" value="{s.dyn_time_t}" />
<MvAssign name="l.params:oauth_signature_method" value="HMAC-SHA1" />
<MvAssign name="l.params:oauth_timestamp" value="{s.dyn_time_t}" />
<MvAssign name="l.params:oauth_token" value="{l.config:TokenId}" />
<MvAssign name="l.params:oauth_version" value="1.0" />
<MvAssign name="l.baseString" value="{l.method $ '&' $ encodeattribute(l.urlParts[1]) $ '&' $ encodeattribute(OAUTH_EncodeParams(l.params))}" />
<MvAssign name="l.key" value="{encodeattribute(l.config:ConsumerSecret) $ '&' $ encodeattribute(l.config:TokenSecret)}" />
<MvAssign name="l._" value="{crypto_hmac_sha1(l.baseString, l.key, 'binary', l.hashOutput)}" />
<MvAssign name="l.signature" value="{encodeattribute(crypto_base64_encode(l.hashOutput))}" />
<MvFunctionReturn value="{'Authorization: OAuth '
$ 'oauth_signature="' $ l.signature $ '",'
$ 'oauth_version="1.0",'
$ 'oauth_nonce="' $ l.params:oauth_nonce $ '",'
$ 'oauth_signature_method="HMAC-SHA1",'
$ 'oauth_consumer_key="' $ l.params:oauth_consumer_key $ '",'
$ 'oauth_token="' $ l.params:oauth_token $ '",'
$ 'oauth_timestamp="' $ l.params:oauth_timestamp $ '",'
$ 'realm="' $ l.config:CompanyId $ '"'}" />
</MvFunction>
<MvComment>
Sorts and encodes a structure of URL parameters into a single string suitable for hashing into a signature
</MvComment>
<MvFunction name="OAuth_EncodeParams" parameters="params">
<MvAssign name="l._" value="{miva_struct_members(l.params, l.paramKeys)}" />
<MvAssign name="l._" value="{miva_array_sort(l.paramKeys, 'OAuth_EncodeParams_Sort', l._)}" />
<MvAssign name="l.ret" value="" />
<MvForeach array="l.paramKeys" iterator="l.paramKey" index="l.pos1">
<MvIf expr="{l.pos1 GT 1}">
<MvAssign name="l.ret" value="{l.ret $ '&'}" />
</MvIf>
<MvReferenceArray name="l.paramValue" variable="l.params">
<MvMember name="{l.paramKey}" />
</MvReferenceArray>
<MvAssign name="l.ret" value="{l.ret $ encodeattribute(l.paramKey) $ '=' $ encodeattribute(l.paramValue)}" />
</MvForeach>
<MvFunctionReturn value="{l.ret}" />
</MvFunction>
<MvFunction name="OAuth_EncodeParams_Sort" parameters="left var, right var, data var">
<MvFunctionReturn value="{l.left LT l.right}" />
</MvFunction>
<MvComment>
GETs data to a netsuite RESTLet
</MvComment>
<MvFunction name="RESTLet_GET" parameters="scriptId, deployId, params, result var">
<MvIf expr="{NOT g.SpoNetsuite:Config}">
<MvAssign name="l._" value="{Config_Load(g.SpoNetsuite:Config)}" />
</MvIf>
<MvAssign name="l.endpoint" value="{g.SpoNetsuite:Config:RESTLetEndpoint $ '?Script=' $ l.scriptId $ '&deploy=' $ l.deployId}" />
<MvAssign name="l._" value="{miva_struct_members(l.params, l.paramKeys)}" />
<MvForeach array="l.paramKeys" iterator="l.paramKey">
<MvReferenceArray name="l.paramValue" variable="l.params">
<MvMember name="{l.paramKey}" />
</MvReferenceArray>
<MvAssign name="l.endpoint" value="{l.endpoint $ '&' $ encodeattribute(l.paramKey) $ '=' $ encodeattribute(l.paramValue)}" />
</MvForeach>
<MvAssign name="l._" value="{OAuth_Get(
g.SpoNetsuite:Config,
l.endpoint,
l.result)}" />
</MvFunction>
<MvComment>
POSTs data to a netsuite RESTLet
</MvComment>
<MvFunction name="RESTLet_POST" parameters="scriptId, deployId, payload var, result var">
<MvIf expr="{NOT g.SpoNetsuite:Config}">
<MvAssign name="l._" value="{Config_Load(g.SpoNetsuite:Config)}" />
</MvIf>
<MvAssign name="l._" value="{OAuth_Post(
g.SpoNetsuite:Config,
g.SpoNetsuite:Config:RESTLetEndpoint $ '?script=' $ l.scriptId $ '&deploy=' $ l.deployId,
l.payload,
l.result)}" />
</MvFunction>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment