To provide server-side enforcement as well (from a security perspective, in addition to what you have client-side to provide a nicer experience for well-behaved users), you should be able to use %CSP.SessionEvents with OnLogin overridden to check a global (or something) and return an error set %session.EndSession = 1 if logins are disabled. This class would need to be set up for the web application(s) through which your application is accessed - see "Event Class" here.

When working with files, it's much better to use %Stream classes rather than an instance of %Library.File. If you're looking to get the attributes of a file/directory, the Attributes method in %Library.File is probably your best option. According to the class reference (which has all the details), it returns a combination of bits, the meaning of which varies depending on the operating system. This is kind of ugly, but here's an example on Windows:

USER>set attributes = ##class(%Library.File).Attributes("C:\Users\tleavitt\AppData\")
 
USER>w attributes
8210

USER>for i=0:1:16 { w:$zboolean(attributes,2**i,1) 2**i,! }
2
16
8192

According to the class reference, this is a directory (16) that is hidden (2) and not indexed (8192).

%Library.File also has some OS-independent classmethods that may be easier to use for simpler things like seeing if a file is read-only.

In a bit of testing, I was able to see this by using the wrong protocol - i.e., navigating to the web socket directly in the browser, or using http or https in the client code when it should be ws or wss. The "client code" in the documentation you linked should go in a separate page (CSP or just plain old HTML/JS) from the class that extends %CSP.WebSocket, and navigating to /csp/user/MyApp.MyWebSocketServer.cls (as in that example) directly will not work.

If that isn't clear or doesn't solve the problem, could you share your code and your Caché version ($zv)? Your web server and browser version may also be relevant, since web sockets are fairly new.

To expand on Rubens' comment about a variable arity of arguments, I often use the following pattern:

Set tQuery = "select fields from some_table"
Set tWhereList = ""

If (pFilter1 '= "") {
    Set tWhereList = tWhereList_$ListBuild("field1 = ?")
    Set tArgs($i(tArgs)) = pFilter1
}
If (pFilter2 '= "") {
    Set tWhereList = tWhereList_$ListBuild("field2 = ?")
    Set tArgs($i(tArgs)) = pFilter2
}

// and so on...

If (tWhereList '= "") {
    Set tQuery = tQuery_" "_$ListToString(tWhereList," and ")
}

Set tResult = ##class(%SQL.Statement).%ExecDirect(,tQuery,tArgs...)

Perhaps also generating and appending an ORDER BY similarly.

Regarding other comments about multiple uses of the same parameter value, an approach I've seen used for that is to JOIN to a list of parameters - something like:

select t.fields from some_table t join (select ? as field1, ? as field2) params where t.field1 = params.field1 and t.field2 = params.field2 and Some_Stored_Procedure(t.field3,params.field1) > params.field2

This is perhaps a little more readable/maintainable than trying to keep track of what all the ?'s mean when the query expects the same value to be repeated multiple times. I can imagine a similar general pattern for building such queries dynamically (e.g., build an array of parameters by name, then construct the subquery for the join and add values to the tArgs array in the order they appear in that subquery).

The Caché installation directory is easy:

USER>w $System.Util.InstallDirectory()
c:\intersystems\healthshare_4\

The OS version is OS-dependent.

On Windows only:

USER>write $System.Util.GetOSVersionInfo()
6.1.7601

On Unix:

USER>set sc = ##class(%Net.Remote.Utility).RunCommandViaZF("uname -r",,.tOutput) write tOutput
2.6.32-220.el6.x86_64

USER>set sc = ##class(%Net.Remote.Utility).RunCommandViaZF("lsb_release -a",,.tOutput) write tOutput
LSB Version:    :core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 6.2 (Santiago)
Release:        6.2
Codename:       Santiago

At a low level, there are two options:

Pipes / command pipes - useful if you want to be able to read command output OR write to the command. Unfortunately, you have to pick one or the other. To answer Nikita's question - maybe there's some tricky way around this by building a command that redirects stdout to a file, which is read using a separate device?

$zf(-1) $zf(-2) - these are a little bit easier to use. $zf(-1) spawns a child process and waits for it to return; $zf(-2) doesn't wait.

Needless to say, if you're building these into an application, make sure that you're careful about building user input into the commands that you execute. wink

System-wide:

Set ^%oddENV("callererrorinfo")=1

Or for the current namespace:

Set ^%oddENV("callererrorinfo",$namespace)=1

For more information, see macro definitions in %occEnvironment.inc. 

You can also set this global to 2 instead of 1, which has the side effect of including a full stack trace when a %Status is converted to a human-readable string (e.g., via $System.Status.GetErrorText()). This is handy for debugging, but probably not something to use on a production system (since it could end up exposing more information about your code than you'd really want).

I can't think of a built-in stored procedure for this, but it would be relatively simple to create one to wrap $System.Encryption.SHAHash(bitlength, text).

For example, approximating HASHBYTES with the features built in to $System.Encryption:

Class DC.Demo.SQL
{

ClassMethod HashBytes(pAlgorithm As %String, pText As %String) As %Binary [ SqlProc ]
{
    // Note: will result in <ILLEGAL VALUE> if pAlgorithm is not supported
    Quit $Case($ZConvert(pAlgorithm,"L"),
        "md5":$System.Encryption.MD5Hash(pText),
        "sha":$System.Encryption.SHA1Hash(pText),
        "sha1":$System.Encryption.SHA1Hash(pText),
        "sha2_256":$System.Encryption.SHAHash(256,pText),
        "sha2_512":$System.Encryption.SHAHash(512,pText))
}

}

Use (in SAMPLES):

select top 5 Name,DC_Demo.SQL_HashBytes('sha2_512',DOB) from Sample.Person

For a more direct approach, see the class query %SYS.ProcessQuery:PPG - it's not [SqlProc] so you need to call it the old-fashioned way.

For example:

Terminal 1:

USER>w $j
10740
USER>s ^||demo(2)=5,^||demo=2
USER>zw ^||demo
^||demo=2
^||demo(2)=5

Terminal 2:

%SYS>set rs = ##class(%ResultSet).%New("%SYS.ProcessQuery:PPG")
%SYS>set sc = rs.Execute("demo",10740)
%SYS>while rs.%Next() { do rs.%Print() }
demo 2
demo(2) 5

Generally speaking, the parameters defined in %ZEN.DataModel.objectModelParameters can be used to customize the appearance/behavior/really anything about the controls in a dynaForm. One such parameter is:

/// Optional.
/// id of a group component that the control used for this property
/// should be added to. This provides a way to control layout.<br>
/// If not defined, the control is added directly to the <class>dynaForm</class>.
Parameter ZENGROUP As STRING;

For example, given the model class:

Class DC.Demo.ZenDynaForm.Model Extends %ZEN.DataModel.ObjectDataModel
{

Property FirstName As %String(ZENGROUP = "nameGroup");

Property MiddleInitial As %String(ZENGROUP = "nameGroup");

Property LastName As %String(ZENGROUP = "nameGroup");

Property HomePhone As %String(ZENGROUP = "phoneGroup");

Property CellPhone As %String(ZENGROUP = "phoneGroup");

}

The following <dynaForm> will display the three name fields in one horizontal row, and the two phone fields in another:

Class DC.Demo.ZenDynaForm Extends %ZEN.Component.page
{

/// This XML block defines the contents of this page.
/// Setting XMLNamespace turns on StudioAssist for this XML block.
XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ]
{
<page xmlns="http://www.intersystems.com/zen">
<dataController id="myController" modelClass="DC.Demo.ZenDynaForm.Model" />
<dynaForm controllerId="myController">
<hgroup id="nameGroup" />
<hgroup id="phoneGroup" />
</dynaForm>
</page>
}

}

Here's some relevant documentation, if I'm understanding your question correctly: http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GZAP_customization

There are two topics covered here: custom Zen components, which have their own HTML rendering, and composite components, which are simply reusable groupings of other Zen components.

These really wouldn't be "system-defined" - you'd have them in a separate XML namespace and they'd be distinct from the "system-defined" Zen component classes, but they can be used in the same page alongside standard Zen components.