Commit 1800c286 authored by Marc Egger's avatar Marc Egger

Merge branch 'develop' into F11035QfqWithoutTypo3

# Conflicts:
#	Documentation/Report.rst
parents ce84c05b 67a02319
Pipeline #3841 failed with stages
in 1 minute and 50 seconds
......@@ -1410,25 +1410,35 @@ Run a php function defined in an external script.
* All column parameters are passed as an associative array to the function as the first argument.
* The second argument (here called $qfq) is an object which acts as an interface to QFQ functionality.
* The script has access to the following qfq functions using this interface:
* The script has access to the following qfq functions using this interface (see examples below):
* $qfq::apiCall($method, $url, $data = '', $header = [], $timeout = 5)
* string $method: can be PUT/POST/GET/DELETE
* string $url
* string $data: a json string which will be added as GET parameters or as POST fields respectively.
* array $header: is of the form ['Content-type: text/plain', 'Content-length: 100']
* int $timeout: is the number of seconds to wait until call is aborted.
* arguments:
* string $method: can be PUT/POST/GET/DELETE
* string $url
* string $data: a json string which will be added as GET parameters or as POST fields respectively.
* array $header: is of the form ['Content-type: text/plain', 'Content-length: 100']
* int $timeout: is the number of seconds to wait until call is aborted.
* return array:
* [0]: Http status code
* [1]: API answer as string.
* $qfq::getVar($key, $useStores = 'FSRVD', $sanitizeClass = '', &$foundInStore = '', $typeMessageViolate = 'c')
* string $key: is the name of qfq variable
* string $useStores: are the stores in which variable is searched (in order from left to right). see :ref:`store`.
* string $sanitizeClass: (see :ref:`sanitize-class`)
* string $foundInStore: is filled with the name of the store in which the variable was found.
* string $typeMessageViolate: defines what to return if the sanitize class was violated:
* 'c' : returns '!!<sanitize class>!!'
* '0' : returns '0'
* 'e' : returns ''
* arguments:
* string $key: is the name of qfq variable
* string $useStores: are the stores in which variable is searched (in order from left to right). see :ref:`store`.
* string $sanitizeClass: (see :ref:`sanitize-class`)
* string $foundInStore: is filled with the name of the store in which the variable was found.
* string $typeMessageViolate: defines what to return if the sanitize class was violated:
* 'c' : returns '!!<sanitize class>!!'
* '0' : returns '0'
* 'e' : returns ''
* return string|false:
* The value of the variable if found.
* A placeholder if the variable violates the sanitize class. (see argument `$typeMessageViolate`)
* `false` if the variable was not found.
* The current working directory is the current web instance (e.g. ``/var/www/html``) .
* All output (e.g. using echo) will be returned by the special column as is.
* If the function returns an associative array, then the key-value pairs will be accessible via the Client store.
* If the function returns an associative array, then the key-value pairs will be accessible via the VARS store `V`.
* If the function throws an exception then a standard QFQ error message is shown.
* Text sent to 'stderr' by the php function is not returned at all.
**Column Parameters**
......@@ -1445,12 +1455,12 @@ Run a php function defined in an external script.
**Example**
* PHP script (fileadmin/scripts/my_script.php) ::
* PHP script (`fileadmin/scripts/my_script.php`) ::
<?php
function my_function($param, $qfq) {
echo 'The first argument contains all attributes including "src" and "f":<br>';
echo 'The first argument contains all attributes including "F" and "c":<br>';
print_r($param);
echo '<br><br>get variable from record store:<br>';
......@@ -1460,15 +1470,15 @@ Run a php function defined in an external script.
list($http_code, $answer) = $qfq::apiCall('GET', 'google.com');
echo 'Http code: ' . $http_code;
// Returned array fills client store
return ["IAmInClientStore" => "FooBar"];
// Returned array fills VARS store
return ["IAmInVarStore" => "FooBar"];
}
* QFQ report ::
5.sql = SELECT "IAmInRecordStore" AS _savedInRecordStore
10.sql = SELECT "F:fileadmin/scripts/my_script.php|c:my_function|a1:Hello|a2:World" AS _script
20.sql = SELECT "<br><br>Returened value: {{IAmInClientStore:C:alnumx}}"
20.sql = SELECT "<br><br>Returened value: {{IAmInVarStore:V:alnumx}}"
* Output ::
......@@ -1697,7 +1707,9 @@ API Call QFQ Report (e.g. AJAX)
* General use API call to fire a specific QFQ tt-content record. Useful for e.g. AJAX calls. No Typo3 is involved. *No FE-Group access control*.
* This defines just a simple API endpoint. For defining a rest API see: :ref:`restApi`.
* Custom response headers can be defined by setting the variable `apiResponseHeader` in the record store.
* Multiple headers should be separated by '\n' or '\r\n'. e.g.: 'Content-Type: application/json\ncustom-header: fooBar'
* Multiple headers should be separated by `\n` or `\r\n`. e.g.: `Content-Type: application/json\ncustom-header: fooBar`
* If the api call succeeds the rendered content of the report is returned as is. (no additional formatting, no JSON encoding)
* You can use MYSQL to create Json. See: `MYSQL create Json <https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html>`_ and `MariaDB Json functions <https://mariadb.com/kb/en/json-functions/>`_
* If a QFQ error occurs then a http-status of 400 is returned together with a JSON encoded response of the form: `{"status":"error", "message":"..."}`
Example QFQ record JS (with tt_content.uid=12345)::
......@@ -1728,6 +1740,10 @@ Example QFQ record called by above AJAX::
10.sql = SELECT '{{arg1:S}} {{arg2:S}} {{arg3:C}} {{arg4:C}}', NOW()
, 'Content-Type: application/json\ncustom-header: fooBar' AS _apiResponseHeader
Example text returned by the above AJAX call::
Hello World 456 5672020-09-22 18:09:47
.. _rest_client:
REST Client
......@@ -1742,7 +1758,7 @@ be processed in subsequent calls.
Example::
# Retrieve information. Received data is delivered in JSON and decoded / copied on the fly to STORE_CLIENT
# Retrieve information. Received data is delivered in JSON and decoded / copied on the fly to CLIENT store (CLIENT store is emptied beforehand)
10.sql = SELECT 'n:https://www.dummy.ord/rest/person/id/123' AS _restClient
20.sql = SELECT 'Status: {{http-status:C}}<br>Name: {{name:C:alnumx}}<br>Surname: {{surname:C:alnumx}}'
......@@ -1781,6 +1797,7 @@ Example::
A value starting with '2..' shows success.
* In case of an error, ``{{error-message:C:allbut}}`` shows some details.
* In case the returned answer is a valid JSON string, it is flattened and automatically copied to STORE_CLIENT with corresponding key names.
* NOTE: The CLIENT store is emptied beforehand!
JSON answer example::
......
......@@ -11,8 +11,8 @@ use IMATHUZH\Qfq\Core\Store\Store;
* @package IMATHUZH\Qfq\Core\Report
*
* Executes a function of an external script. Column parameters:
* scr: path to script
* f: function name
* F: path to script
* c: function name
*
* All parameters are passed to the function as the first argument.
* The second argument passed is an instance of ScriptFunctions which acts as an interface to QFQ functionality.
......@@ -61,7 +61,10 @@ class ColumnScript {
}
// return buffer output and fill store
Store::setStore($return, STORE_CLIENT, true);
if (is_array($return)) {
$returnNoArrays = array_filter($return, function ($value) {return !is_array($value);});
Store::appendToStore($returnNoArrays, STORE_VAR);
}
return $output;
}
}
......@@ -71,11 +74,14 @@ class ColumnScript {
* @package IMATHUZH\Qfq\Core\Report
*
* An instance of this class is passed as the last argument to every external function call.
* WARNING: Be aware that this acts as a "public" interface to QFQ. All changes made in here might break existing applications.
*
* ** WARNING ** : Be aware that this class acts as a "public" interface to QFQ. All changes made in here might break existing applications.
*/
class ScriptFunctions {
public static function apiCall(string $method, string $url, string $data = '', array $header = [], int $timeout = 5) {
return RestClient::callApiCurl($method, $url, $data, $header, $timeout);
list($http_code, $answer) = RestClient::callApiCurl($method, $url, $data, $header, $timeout);
return [$http_code, $answer];
}
public static function getVar($key, $useStores = STORE_USE_DEFAULT, $sanitizeClass = '', &$foundInStore = '',
$typeMessageViolate = SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment