Variable.rst 18.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
.. ==================================================
.. ==================================================
.. ==================================================
.. Header hierarchy
.. ==
..  --
..   ^^
..    ""
..     ;;
..      ,,
..
.. --------------------------------------------used to the update the records specified ------
.. Best Practice T3 reST: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/CheatSheet.html
..             Reference: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/Index.html
.. Italic *italic*
.. Bold **bold**
.. Code ``text``
.. External Links: `Bootstrap <http://getbootstrap.com/>`_
.. Add Images:    .. image:: ../Images/a4.jpg
..
..
.. Admonitions
..           .. note::   .. important::     .. tip::     .. warning::
.. Color:   (blue)       (orange)           (green)      (red)
..
.. Definition:
.. some text becomes strong (only one line)
..      description has to indented

.. -*- coding: utf-8 -*- with BOM.

.. include:: Includes.txt


.. _variables:

Variable
========

Variables in QFQ are surrounded by double curly braces. Four different types of variable substitution functionality is
provided. Access to:

* :ref:`store-variables`
* :ref:`sql-variables`
* :ref:`row-column-variables`
* :ref:`link-column-variables`

Some examples, including nesting::

  # Store
  #---------------------------------------------
  {{r}}
  {{index:FS}}
  {{name:FS:alnumx:s:my default}}

  # SQL
  #---------------------------------------------
  {{SELECT name FROM Person WHERE id=1234}}

  # Row columns
  #---------------------------------------------
  {{10.pId}}
  {{10.20.pId}}

  # Nesting
  #---------------------------------------------
  {{SELECT name FROM Person WHERE id={{r}} }}
  {{SELECT name FROM Person WHERE id={{key1:C:alnumx}} }} # explained below
  {{SELECT name FROM Person WHERE id={{SELECT id FROM Persfunction LIMIT 1}} }} # it's more efficient to use only one query

  # Link Columns
  {{p:form=Person&r=1|t:Edit Person|E|s AS link}}

Leading and trailing spaces inside curly braces are removed.

* *{{ SELECT "Hello World"   }}* becomes *{{SELECT "Hello World"}}*
* *{{ varname   }}* becomes *{{varname}}*

Types
-----

.. _`store-variables`:

Store variables
^^^^^^^^^^^^^^^

.. note::

89
  {{ *variable name* : :ref:`store` : :ref:`sanitize-class` : :ref:`variable-escape` : :ref:`variable-default` : :ref:`variable-type-message-violate` }}
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

Example::

  {{pId}}
  {{pId:FSE}}
  {{pId:FSE:digit}}
  {{pId::digit}}
  {{name:FSE:alnumx:m}}
  {{name:::m}}
  {{name:FSE:alnumx:m:John Doe}}
  {{name::::John Doe}}
  {{name:FSE:alnumx:m:John Doe:forbidden characters}}
  {{name:::::forbidden characters}}

* Zero or more stores might be specified to be searched for the given VarName.
* If no store is specified, the default for the searched stores are: **FSRVD** (=FORM > SIP > RECORD > VARS > DEFAULT).
* If the VarName is not found in one store, the next store is searched,  up to the last specified store.
* If the VarName is not found and a default value is given, the default is returned.
Carsten  Rose's avatar
Carsten Rose committed
108
* If no value is found, nothing is replaced - the string ``{{<VarName>}}`` remains.
109
110
111
112
113
114
115
116
117
118
119
* If anywhere along the line an empty string is found, this **is** a value: therefore, the search will stop.

.. _`sanitize-class`:

Sanitize class
--------------

Values in STORE_CLIENT *C* (Client=Browser) and STORE_FORM *F* (Form, HTTP 'post') are checked against a
sanitize class. Values from other stores are *not* checked against any sanitize class, even if a sanitize class is specified.

* Variables get by default the sanitize class defined in the corresponding `FormElement`. If not defined,
Carsten  Rose's avatar
Carsten Rose committed
120
  the default class is ``digit``.
121
122
123
124
125
126
127
128
129
* A default sanitize class can be overwritten by individual definition: *{{a:C:alnumx}}*
* If a value violates the specific sanitize class, see :ref:`variable-type-message-violate` for default or customized message.
  By default the value becomes `!!<name of sanitize class>!!`. E.g. `!!digit!!`.

For QFQ variables and FormElements:

+------------------+------+-------+-----------------------------------------------------------------------------------------+
| Name             | Form | Query | Pattern                                                                                 |
+==================+======+=======+=========================================================================================+
130
| **alnumx**       | Form | Query | [A-Za-z][0-9]@-_.,;: /() ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüÿçß           |
131
132
133
134
135
+------------------+------+-------+-----------------------------------------------------------------------------------------+
| **digit**        | Form | Query | [0-9]                                                                                   |
+------------------+------+-------+-----------------------------------------------------------------------------------------+
| **numerical**    | Form | Query | [0-9.-+]                                                                                |
+------------------+------+-------+-----------------------------------------------------------------------------------------+
Carsten  Rose's avatar
Carsten Rose committed
136
| **allbut**       | Form | Query | All characters allowed, but not [ ]  { } % \ #. The used regexp: ``^[^\[\]{}%\\#]+$',`` |
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
+------------------+------+-------+-----------------------------------------------------------------------------------------+
| **all**          | Form | Query | no sanitizing                                                                           |
+------------------+------+-------+-----------------------------------------------------------------------------------------+


Only in FormElement:

+------------------+------+-------+-------------------------------------------------------------------------------------------+
| **auto**         | Form |       | Only supported for FormElements. Most suitable checktype is dynamically evaluated based   |
|                  |      |       | on native column definition, the FormElement type, and other info. See below for details. |
+------------------+------+-------+-------------------------------------------------------------------------------------------+
| **email**        | Form | Query | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\.[a-zA-Z]{2,}                                          |
+------------------+------+-------+-------------------------------------------------------------------------------------------+
| **pattern**      | Form |       | Compares the value against a regexp.                                                      |
+------------------+------+-------+-------------------------------------------------------------------------------------------+


Rules for CheckType Auto (by priority):

* TypeAheadSQL or TypeAheadLDAP defined: **alnumx**
* Table definition
  * integer type: **digit**
  * floating point number: **numerical**
* FE Type
Carsten  Rose's avatar
Carsten Rose committed
161
162
  * ``password``, ``note``: **all**
  * ``editor``, ``text`` and encode = ``specialchar``: **all**
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
* None of the above: **alnumx**


.. _`variable-escape`:

Escape/Action class
-------------------

The following `escape` & `action` types are available:


+-------+----------------------------------------------------------------------------------------------------------------------------------+
| Token | Description                                                                                                                      |
+=======+==================================================================================================================================+
| c     | Config - the escape type configured in :ref:`configuration`.                                                                     |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| C     | Colon ``:`` will be escaped by ``\:``                                                                                            |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| d     | Double ticks ``"`` will be escaped by ``\"``.                                                                                    |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| l     | LDAP search filter values: `ldap-escape() <http://php.net/manual/en/function.ldap-escape.php>`_ (LDAP_ESCAPE_FILTER).            |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| L     | LDAP DN values. `ldap-escape() <http://php.net/manual/en/function.ldap-escape.php>`_ (LDAP_ESCAPE_DN).                           |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| s     | Single ticks ``'`` will be escaped by ``\'``.                                                                                    |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| S     | Stop replace. If the replaced value contains nested variables, they won't be replaced.                                           |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| m     | `real_escape_string() <http://php.net/manual/en/mysqli.real-escape-string.php>`_ (m = mysql)                                     |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| p     | Password hashing: depends on the hashing type in the Typo3 installation, includes salting if configured.                         |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| w     | wipe out current key/value pair from SIP store :ref:`variable-escape-wipe-key<variable-escape-wipe-key>`                         |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| X     | Throw exception if variable is not found in the given store(s). Outputs :ref:`variable-type-message-violate`                     |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| ''    | Nothing defined - the escape/action class type configured in :ref:`configuration`.                                               |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| \-    | No escaping.                                                                                                                     |
+-------+----------------------------------------------------------------------------------------------------------------------------------+


* The ``escape/action`` class is defined by the fourth parameter of the variable. E.g.: ``{{name:FE:alnumx:m}}`` (m = mysql).
* It's possible to combine multiple ``escape/action`` classes, they will be processed in the order given. E.g. ``{{name:FE:alnumx:Ls}}`` (L, s).
* Escaping is typically necessary for all user supplied content, especially if they are processed via SQL or LDAP queries.
* Be careful when escaping nested variables. Best is to escape **only** the most outer variable.
* In :ref:`configuration` a global ``escapeTypeDefault`` can be defined. The configured ``escape/action`` class applies to all substituted
  variables, who *do not* contain a *specific* ``escape/action`` class.
* Additionally a ``defaultEscapeType`` can be defined per ``Form`` (separate field in the *Form editor*). This overwrites the
  global definition of ``configuration``. By default, every ``Form.defaultEscapeType`` = 'c' (=config), which means the setting
  in :ref:`configuration`.
* To suppress an escape type, define the ``escape type`` = '-' on the specific variable. E.g.: ``{{name:FE:alnumx:-}}``.

Escape
^^^^^^

Carsten  Rose's avatar
Carsten Rose committed
219
To *escape* a character typically means: a character, which have a special meaning/function, should not treated as a special
220
character.
Carsten  Rose's avatar
Carsten Rose committed
221
E.g. a string is surrounded by single ticks ``'``. If such a string should contain the same single tick inside,
222
223
224
225
226
227
228
229
230
231
the inside single tick has to be escaped - if not, the string end's at the second tick, not the third. This is typically
done by a backlash: \\

QFQ offers different ways of escaping. Which of them to use, depends on the situation.

Especially variables used in SQL statements might cause trouble when using: NUL (ASCII 0), \\n, \\r, \\, ', ", or Control-Z.

Action
^^^^^^

Carsten  Rose's avatar
Carsten Rose committed
232
* *password* - ``p``: transforms the value of the variable into a Typo3 salted password hash. The hash function is the one
233
234
  used by Typo3 to encrypt and salt a password. This is useful to manipulate FE user passwords via QFQ. See :ref:`setFeUserPassword`

Carsten  Rose's avatar
Carsten Rose committed
235
* *stop replace*  - ``S``: typically QFQ will replace nested variables as long as there are variables to replace. This options
236
237
  stops this

Carsten  Rose's avatar
Carsten Rose committed
238
* *exception* - ``X``: If a variable is not found in any given store, it's replace by a default value or an error message.
239
240
241
242
243
  In special situation it might be useful to do a full stop on all current actions (no further procession). A custom
  message can be defined via: :ref:`variable-type-message-violate`.

.. _`variable-escape-wipe-key`:

Carsten  Rose's avatar
Carsten Rose committed
244
245
246
* *wipe* - ``w``: In special cases it might be useful to get a value via SIP only one time and after retrieving the value
  it will be deleted in STORE SIP . Further access to the variable will return *variable undefined*. At time of writing
  only the STORE SIP supports the feature *wipe*. This is useful to suppress any repeating events by using the browser history.
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  The following example will send a mail only the first when it is called with a given SIP::

    10.sql = SELECT '...' AS _sendmail FROM Person AS p WHERE '{{action:S::w}}'='send' AND p.id={{pId:S}}



.. _`variable-default`:

Default
-------

* Any string can be given to define a default value.
* If a default value is given, it makes no sense to define more than one store: with a default value given, only the
  first store is considered.
Carsten  Rose's avatar
Carsten Rose committed
261
* If the default value contains a ``:``, that one needs to be escaped by ``\``
Carsten  Rose's avatar
Carsten Rose committed
262
* For dedicated variables this value has a special meaning. E.g. ``{{randomUniq:V}}`` uses this as ``expire`` argument.
263
264
265
266
267
268
269
270

.. _`variable-type-message-violate`:

Type message violate
--------------------

If a value violates the sanitize class, the following actions are possible:

Carsten  Rose's avatar
Carsten Rose committed
271
272
273
274
275
* ``c`` - The violated class will be set as content, surrounded by *!!*. E.g. *!!digit!!*. This is the default.
* ``e`` - Instead of the value an empty string will be set as content.
* ``0`` - Instead of the value the string *0* will be set as content.
* *custom text ...* - Instead of the value, the custom text will be set as content. If the text contains a ``:``, that one
  needs to be escaped by \\ . Check :ref:`variable-escape` qualifier ``C`` to let QFQ do the colon escaping.
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

.. _`sql-variables`:

SQL variables
^^^^^^^^^^^^^

* The detection of an SQL command is case *insensitive*.
* Leading  whitespace will be skipped.
* The following commands are interpreted as SQL commands:

  * SELECT
  * INSERT, UPDATE, DELETE, REPLACE, TRUNCATE
  * SHOW, DESCRIBE, EXPLAIN, SET

* An SQL Statement might contain variables, including additional SQL statements. Inner SQL queries will be executed first.
* All variables will be substituted one by one from inner to outer.
* The number of variables inside an input field or an SQL statement is not limited.

Result: string
""""""""""""""

A result of an SQL statement will be imploded over all: concat all columns of a row, concat all rows - there is no
glue string.

Result: row
"""""""""""

A few functions needs more than a returned string, instead separate columns are necessary. To indicate an array
Carsten  Rose's avatar
Carsten Rose committed
304
result, specify those with an ``!``::
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

   {{!SELECT ...}}

This manual will specify the individual QFQ elements, who needs an array instead of a string. It's an error to return
a string where an array is needed and vice versa.

Database index
""""""""""""""

To access different databases in a :ref:`multi-database`  setup, the database index can be specified after the opening curly
braces. ::

  {{[1]SELECT ... }}

For using the indexData and indexQfq (:ref:configuration), it's a good practice to specify the variable name
instead of the numeric index. ::

   {{[{{indexData:Y}}]SELECT ...}}

If no dbIndex is given, `{{indexData:Y}}` is used.


Example
"""""""

::

  {{SELECT id, name FROM Person}}
Carsten  Rose's avatar
Carsten Rose committed
333
  {{SELECT id, name, IF({{feUser:T0}}=0, 'Yes', 'No')  FROM Person WHERE id={{r:S}} }}
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  {{SELECT id, city FROM Address AS adr WHERE adr.accId={{SELECT id FROM Account AS acc WHERE acc.name={{feUser:T0}} }} }}
  {{!SELECT id, name FROM Person}}
  {{[2]SELECT id, name FROM Form}}
  {{[{{indexQfq:Y}}]SELECT id, name FROM Form}}

.. _`row-column-variables`:

Row column variables
""""""""""""""""""""

Syntax:  *{{<level>.<column>}}*

Only used in report to access outer columns. See :ref:`access-column-values` and :ref:`syntax-of-report`.

Carsten  Rose's avatar
Carsten Rose committed
348
349
There might be name conflicts between VarName / SQL keywords and <line identifier>. QFQ checks first for *<level>*,
than for *SQL keywords* and than for *VarNames* in stores.
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366

All types might be nested with each other. There is no limit of nesting variables.

Very specific: Also, it's possible that the content of a variable is again (including curly braces) a variable - this
is sometimes used in text templates, where the template is retrieved from a record and
specific locations in the text will be (automatically by QFQ) replaced by values from other sources.

General note: using this type of variables is only the second choice. First choice is `{{column:R}}` (see
:ref:`access-column-values`) - using the STORE_RECORD is more portable cause no renumbering is needed if the level keys change.


.. _`link-column-variables`:

Link column variables
^^^^^^^^^^^^^^^^^^^^^

These variables return a link, completely rendered in HTML. The syntax and all features of :ref:`column-link` are available.
Carsten  Rose's avatar
Carsten Rose committed
367
The following code will render a *new person* button::
368
369
370
371
372
373
374
375
376
377

  {{p:form&form=Person|s|N|t:new person AS link}}

For better reading, the format string might be wrapped in single or double quotes (this is optional): ::

  {{"p:form&form=Person|s|N|t:new person" AS link}}

These variables are especially helpful in:

* `report`, to create create links or buttons outside of an SQL statement. E.g. in `head`, `rbeg`, ...
378
* `form`, to create links and buttons in labels or notes.