Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
typo3
qfq
Commits
abd9cdee
Commit
abd9cdee
authored
Mar 21, 2021
by
Carsten Rose
Browse files
Merge branch 'develop' into 'master'
Develop See merge request
!323
parents
8d76c6a1
fe9aca70
Pipeline
#5064
passed with stages
in 3 minutes and 55 seconds
Changes
18
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Documentation/Concept.rst
View file @
abd9cdee
...
...
@@ -320,8 +320,8 @@ In :ref:`config-qfq-php` mutliple database credentials can be prepared. Mandator
`DB_1_USER`, `DB_1_SERVER`, `DB_1_PASSWORD`, `DB_1_NAME`. The number '1' indicates the `dbIndex`. Increment the number
to specify further database credential setups.
Typically the credentials for `DB_1`
also have access to the T3 database.
By convention, it's necessary that `DB_1` is the one who
also have access to the T
ypo
3 database.
E.q. `QFQ Function`_ or
download links (based on QFQ functions) needs access to the T3 database to directly fetch tt-content records.
Different QFQ versions, shared database
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
...
Documentation/Report.rst
View file @
abd9cdee
This diff is collapsed.
Click to expand it.
Documentation/index.rst
View file @
abd9cdee
...
...
@@ -22,7 +22,7 @@ Quick Form Query Extension
en
:Copyright:
2017-202
0
2017-202
1
:Authors:
Carsten Rose, Benjamin Baer
...
...
extension/Classes/Core/AbstractBuildForm.php
View file @
abd9cdee
...
...
@@ -661,6 +661,9 @@ abstract class AbstractBuildForm {
}
/**
* @return mixed
*/
abstract
public
function
getProcessFilter
();
/**
...
...
@@ -1334,6 +1337,10 @@ abstract class AbstractBuildForm {
$class
=
'form-control'
;
$elementCharacterCount
=
''
;
if
(
isset
(
$formElement
[
FE_INPUT_CLEAR_ME
])
&&
$formElement
[
FE_INPUT_CLEAR_ME
]
!=
'0'
)
{
$class
.
=
' qfq-clear-me'
;
}
if
(
$formElement
[
FE_MAX_LENGTH
]
>
0
&&
$value
!==
''
)
{
// crop string only if it's not empty (substr returns false on empty strings)
$value
=
mb_substr
(
$value
,
0
,
$formElement
[
FE_MAX_LENGTH
]);
...
...
extension/Classes/Core/Constants.php
View file @
abd9cdee
...
...
@@ -233,7 +233,7 @@ const ERROR_PLAY_SQL_MULTIQUERY = 1087;
// Subrecord
const
ERROR_SUBRECORD_MISSING_COLUMN_ID
=
1100
;
const
ERROR_SUBRECORD_DETAIL_COLUMN_NOT_FOUND
=
'Column not found in primary record or current row'
;
const
ERROR_SUBRECORD_DETAIL_COLUMN_NOT_FOUND
=
'Column not found in primary record or current row
(or missed & to indicate a constant?)
'
;
// Store
const
ERROR_STORE_VALUE_ALREADY_CODPIED
=
1200
;
...
...
@@ -490,9 +490,6 @@ const SYSTEM_DB_INIT = 'init';
const
SYSTEM_DB_INDEX_DATA
=
"indexData"
;
const
SYSTEM_DB_INDEX_QFQ
=
"indexQfq"
;
//const SYSTEM_DB_INDEX_DATA_DEPRECATED = "DB_INDEX_DATA";
//const SYSTEM_DB_INDEX_QFQ_DEPRECATED = "DB_INDEX_QFQ";
// Automatically filled by QFQ
const
SYSTEM_DB_NAME_DATA
=
'dbNameData'
;
const
SYSTEM_DB_NAME_QFQ
=
'dbNameQfq'
;
...
...
@@ -639,6 +636,7 @@ const SYSTEM_FORM_LANGUAGE_D_LABEL = 'formLanguageDLabel';
const
SYSTEM_ENTER_AS_SUBMIT
=
'enterAsSubmit'
;
const
SYSTEM_SHOW_ID_IN_FORM_TITLE
=
'showIdInFormTitle'
;
const
SYSTEM_INPUT_CLEAR_ME
=
'clearMe'
;
const
SYSTEM_CMD_WKHTMLTOPDF
=
'cmdWkhtmltopdf'
;
const
SYSTEM_CMD_INKSCAPE
=
'cmdInkscape'
;
...
...
@@ -1010,6 +1008,7 @@ const F_PARAMETER = 'parameter'; // valid for F_ and FE_
// Form columns: via parameter field
const
F_DB_INDEX
=
'dbIndex'
;
const
DB_INDEX_DEFAULT
=
"1"
;
const
DB_INDEX_T3
=
DB_INDEX_DEFAULT
;
const
PARAM_DB_INDEX_DATA
=
'__dbIndexData'
;
// Submitted via SIP to make record locking DB aware.
const
F_FORM_SUBMIT_LOG_MODE
=
'formSubmitLogMode'
;
...
...
@@ -1070,6 +1069,7 @@ const F_ORDER_COLUMN = 'orderColumn';
const
F_ORDER_COLUMN_NAME
=
'ord'
;
const
F_SHOW_ID_IN_FORM_TITLE
=
SYSTEM_SHOW_ID_IN_FORM_TITLE
;
const
F_INPUT_CLEAR_ME
=
SYSTEM_INPUT_CLEAR_ME
;
const
F_MULTI_MSG_NO_RECORD
=
'multiMsgNoRecord'
;
const
F_MULTI_MSG_NO_RECORD_TEXT
=
'No data'
;
...
...
@@ -1284,6 +1284,7 @@ const FE_INPUT_EXTRA_BUTTON_INFO = 'extraButtonInfo';
const
FE_INPUT_EXTRA_BUTTON_INFO_CLASS
=
SYSTEM_EXTRA_BUTTON_INFO_CLASS
;
const
FE_INPUT_EXTRA_BUTTON_INFO_MIN_WIDTH
=
'extraButtonMinWidth'
;
const
FE_INPUT_EXTRA_BUTTON_INFO_MIN_WIDTH_DEFAULT
=
'250'
;
const
FE_INPUT_CLEAR_ME
=
F_INPUT_CLEAR_ME
;
const
FE_INPUT_AUTOCOMPLETE
=
'autocomplete'
;
const
FE_TMP_EXTRA_BUTTON_HTML
=
'_extraButtonHtml'
;
// will be filled on the fly during building extrabutton
const
FE_CHECKBOX_CHECKED
=
'checked'
;
...
...
@@ -1529,6 +1530,7 @@ const SENDMAIL_TOKEN_ATTACHMENT_PAGE = 'p';
// Report, BodyText
const
TOKEN_SQL
=
'sql'
;
const
TOKEN_FUNCTION
=
'function'
;
const
TOKEN_TWIG
=
'twig'
;
const
TOKEN_HEAD
=
'head'
;
const
TOKEN_ALT_HEAD
=
'althead'
;
...
...
@@ -1553,7 +1555,7 @@ const TOKEN_DB_INDEX = F_DB_INDEX;
const
TOKEN_CONTENT
=
'content'
;
const
TOKEN_REPORT_FILE
=
'file'
;
const
TOKEN_VALID_LIST
=
'sql|twig|head|althead|altsql|tail|shead|stail|rbeg|rend|renr|rsep|fbeg|fend|fsep|fskipwrap|rbgd|debug|form|r|debugShowBodyText|dbIndex|sqlLog|sqlLogMode|content|render'
;
const
TOKEN_VALID_LIST
=
'sql|
function|
twig|head|althead|altsql|tail|shead|stail|rbeg|rend|renr|rsep|fbeg|fend|fsep|fskipwrap|rbgd|debug|form|r|debugShowBodyText|dbIndex|sqlLog|sqlLogMode|content|render'
;
const
TOKEN_COLUMN_CTRL
=
'_'
;
...
...
@@ -1704,6 +1706,7 @@ const NAME_URL = 'url';
const
NAME_MAIL
=
'mail'
;
const
NAME_PAGE
=
'page'
;
const
NAME_UID
=
'uid'
;
const
NAME_SOURCE
=
'source'
;
const
NAME_TEXT
=
'text'
;
const
NAME_DROPDOWN
=
'dropdown'
;
const
NAME_DOWNLOAD
=
DOWNLOAD_EXPORT_FILENAME
;
...
...
@@ -1775,6 +1778,7 @@ const TOKEN_URL = 'u';
const
TOKEN_MAIL
=
'm'
;
const
TOKEN_PAGE
=
'p'
;
const
TOKEN_UID
=
'uid'
;
const
TOKEN_SOURCE
=
'source'
;
const
TOKEN_DOWNLOAD
=
'd'
;
const
TOKEN_COPY_TO_CLIPBOARD
=
'y'
;
const
TOKEN_DROPDOWN
=
'z'
;
...
...
@@ -2019,6 +2023,8 @@ const SETTING_TABLESORTER_MODE = 'mode';
const
SETTING_TABLESORTER_MODE_DELETE
=
'delete'
;
const
SETTING_TABLESORTER_CLEAR
=
'Clear'
;
const
COLUMN_FUNCTION_OUTPUT
=
'_output'
;
// Object: Type
const
T_LABEL
=
't_label'
;
const
T_INPUT
=
't_input'
;
...
...
extension/Classes/Core/Database/Database.php
View file @
abd9cdee
...
...
@@ -54,7 +54,8 @@ class Database {
*/
private
$sqlLogModePrio
=
[
SQL_LOG_MODE_NONE
=>
1
,
SQL_LOG_MODE_ERROR
=>
2
,
SQL_LOG_MODE_MODIFY
=>
3
,
SQL_LOG_MODE_ALL
=>
4
];
private
$dbName
=
''
;
private
$dbName
=
null
;
private
$dbIndex
=
null
;
/**
* Returns current data base handle from Store[System][SYSTEM_DBH].
...
...
@@ -72,6 +73,7 @@ class Database {
if
(
empty
(
$dbIndex
))
{
$dbIndex
=
DB_INDEX_DEFAULT
;
}
$this
->
dbIndex
=
$dbIndex
;
$this
->
store
=
Store
::
getInstance
();
$storeSystem
=
$this
->
store
->
getStore
(
STORE_SYSTEM
);
...
...
@@ -98,6 +100,13 @@ class Database {
}
}
/**
* @return mixed|string
*/
public
function
getDbIndex
()
{
return
$this
->
dbIndex
;
}
/**
* @return mixed|string
*/
...
...
@@ -1076,8 +1085,7 @@ class Database {
* @throws \DbException
* @throws \UserFormException
*/
public
function
selectFormByName
(
string
$formName
,
array
$columnsToSelect
=
null
)
{
public
function
selectFormByName
(
string
$formName
,
array
$columnsToSelect
=
null
)
{
// make sure to select column 'name'
if
(
is_array
(
$columnsToSelect
)
&&
!
in_array
(
F_NAME
,
$columnsToSelect
))
{
$columnsToSelect
[]
=
F_NAME
;
...
...
@@ -1102,4 +1110,25 @@ class Database {
}
}
/**
* Load tt-content record with subheader=$uid or uid=$uid (depending if $uid is numeric).
* It's important that the current DB class has access to the Typo3 DB.
*
* @param $uid
* @return array // The full T3 tt-content record.
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
public
function
getBodyText
(
$uid
)
{
$column
=
(
is_numeric
(
$uid
))
?
'uid'
:
'subheader'
;
$dbT3
=
$this
->
store
->
getVar
(
SYSTEM_DB_NAME_T3
,
STORE_SYSTEM
);
$sql
=
"SELECT * FROM `
$dbT3
`.`tt_content` WHERE `
$column
` = ?"
;
$arr
=
$this
->
sql
(
$sql
,
ROW_EXPECT_1
,
[
$uid
],
'Function "'
.
$column
.
'='
.
$uid
.
'" not found or more than one found.'
);
return
(
$arr
);
}
}
\ No newline at end of file
extension/Classes/Core/Helper/KeyValueStringParser.php
View file @
abd9cdee
...
...
@@ -216,16 +216,16 @@ class KeyValueStringParser {
*
* E.g.: "a,b,'c,d',e" with delimiter ',' will result in [ 'a', 'b', 'c,d', 'e' ]
*
* @param $delim
e
ter
* @param $delim
i
ter
* @param $str
* @param int $limit
*
* @return array|bool
* @throws \CodeException
*/
public
static
function
explodeWrapped
(
$delim
e
ter
,
$str
,
$limit
=
PHP_INT_MAX
)
{
public
static
function
explodeWrapped
(
$delim
i
ter
,
$str
,
$limit
=
PHP_INT_MAX
)
{
if
(
$delim
e
ter
==
''
)
{
if
(
$delim
i
ter
==
''
)
{
return
false
;
}
...
...
@@ -242,7 +242,7 @@ class KeyValueStringParser {
$onHold
=
''
;
$cnt
=
0
;
$arr
=
explode
(
$delim
e
ter
,
$str
,
PHP_INT_MAX
);
$arr
=
explode
(
$delim
i
ter
,
$str
,
PHP_INT_MAX
);
foreach
(
$arr
as
$value
)
{
$trimmed
=
trim
(
$value
);
if
(
$value
==
''
&&
$startToken
==
''
)
{
...
...
@@ -269,19 +269,19 @@ class KeyValueStringParser {
}
if
(
$cnt
>=
$limit
)
{
$final
[
$cnt
-
1
]
.
=
$delim
e
ter
.
$value
;
$final
[
$cnt
-
1
]
.
=
$delim
i
ter
.
$value
;
}
else
{
$final
[]
=
$value
;
$cnt
++
;
}
continue
;
}
else
{
$onHold
.
=
$delim
e
ter
.
$value
;
$onHold
.
=
$delim
i
ter
.
$value
;
$lastChar
=
substr
(
$trimmed
,
-
1
);
if
(
$startToken
==
$lastChar
)
{
if
(
$cnt
>=
$limit
)
{
$final
[
$cnt
-
1
]
.
=
$delim
e
ter
.
$onHold
;
$final
[
$cnt
-
1
]
.
=
$delim
i
ter
.
$onHold
;
}
else
{
$final
[]
=
$onHold
;
$cnt
++
;
...
...
extension/Classes/Core/Helper/OnArray.php
View file @
abd9cdee
...
...
@@ -130,7 +130,7 @@ class OnArray {
/**
* Converts a onedimensional array by using htmlentities on all elements
* Converts a one
-
dimensional array by using html
entities on all elements
.
*
* @param array $arr
*
...
...
extension/Classes/Core/Helper/OnString.php
View file @
abd9cdee
...
...
@@ -337,4 +337,40 @@ class OnString {
public
static
function
strContains
(
string
$haystack
,
string
$needle
):
bool
{
return
strpos
(
$haystack
,
$needle
)
!==
false
;
}
/**
* Split a cmd "getFeUser(pId, pName, ...) : accountId, feUserUid, ..." into:
* rcFunctionName = getFeUser
* rcFunctionParam = [ 'pId', 'pName', ... ]
* rcReturnParam = [ 'accountId', 'feUserUid', ... ]
*
* @param $cmd
* @param $rcFunctionName
* @param $rcFunctionParam
* @param $rcReturnParam
*/
public
static
function
splitFunctionCmd
(
$cmd
,
&
$rcFunctionName
,
&
$rcFunctionParam
,
&
$rcReturnParam
)
{
$rcFunctionName
=
''
;
$rcFunctionParam
=
array
();
$rcReturnParam
=
array
();
if
(
$cmd
==
''
)
{
return
;
}
// $cmd = "getFeUser(pId, pName) : accountId, feUserUid"
$split
=
explode
(
'=>'
,
$cmd
,
2
);
// $split[0] = getFeUser(pId, pName), $split[1]=accountId, feUserUid
$functionArr
=
explode
(
'('
,
$split
[
0
],
2
);
// $functionArr[0]='getFeUser', $functionArr[1]='pId, pName) '
$args
=
explode
(
')'
,
$functionArr
[
1
]
??
''
,
2
);
// $args[0]='pId, pName', $args[1]=' '
$rcFunctionName
=
trim
(
$functionArr
[
0
]);
$rcFunctionParam
=
OnArray
::
trimArray
(
explode
(
','
,
$args
[
0
]
??
''
));
$rcReturnParam
=
OnArray
::
trimArray
(
explode
(
','
,
$split
[
1
]
??
''
));
}
}
extension/Classes/Core/Helper/Support.php
View file @
abd9cdee
...
...
@@ -840,6 +840,7 @@ class Support {
$store
=
Store
::
getInstance
();
// Some Defaults
self
::
setIfNotSet
(
$formElement
,
FE_INPUT_CLEAR_ME
,
$formSpec
[
F_INPUT_CLEAR_ME
]);
self
::
setIfNotSet
(
$formElement
,
FE_SHOW_SECONDS
,
'0'
);
self
::
setIfNotSet
(
$formElement
,
FE_TIME_IS_OPTIONAL
,
'0'
);
self
::
setIfNotSet
(
$formElement
,
FE_SHOW_ZERO
,
'0'
);
...
...
extension/Classes/Core/QuickFormQuery.php
View file @
abd9cdee
...
...
@@ -1476,6 +1476,7 @@ class QuickFormQuery {
FE_INPUT_EXTRA_BUTTON_INFO_CLASS
,
F_SHOW_ID_IN_FORM_TITLE
,
F_INPUT_CLEAR_ME
,
FE_FILE_MAX_FILE_SIZE
,
...
...
extension/Classes/Core/Report/Download.php
View file @
abd9cdee
...
...
@@ -353,6 +353,35 @@ class Download {
}
}
/**
* @param string $uid
* @param array $urlParam
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \DownloadException
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws \UserFormException
* @throws \UserReportException
*/
private
function
getEvaluatedBodytext
(
$uid
,
array
$urlParam
)
{
$bodyTextArr
=
$this
->
db
->
getBodytext
(
$uid
);
// Copy $urlParam to STORE_SIP
foreach
(
$urlParam
as
$key
=>
$paramValue
)
{
$this
->
store
->
setVar
(
$key
,
$paramValue
,
STORE_SIP
);
}
$qfq
=
new
QuickFormQuery
(
$bodyTextArr
,
false
,
false
);
return
$qfq
->
process
();
}
/**
* Interprets $element and fetches corresponding content, either as a file or the content in a variable.
*
...
...
@@ -387,7 +416,7 @@ class Download {
$token
=
$arr
[
0
];
$value
=
$arr
[
1
];
if
(
$token
===
TOKEN_UID
)
{
// extract uid
if
(
$token
===
TOKEN_UID
||
$token
===
TOKEN_SOURCE
)
{
// extract uid
$uidParamsArr
=
explode
(
'&'
,
$value
,
2
);
$uid
=
$uidParamsArr
[
0
];
$value
=
$uidParamsArr
[
1
]
??
''
;
// additional params
...
...
@@ -445,36 +474,6 @@ class Download {
return
$filename
;
}
/**
* @param $uid
* @param array $urlParam
*
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \DownloadException
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws \UserFormException
* @throws \UserReportException
*/
private
function
getEvaluatedBodyText
(
$uid
,
array
$urlParam
)
{
foreach
(
$urlParam
as
$key
=>
$paramValue
)
{
$this
->
store
->
setVar
(
$key
,
$paramValue
,
STORE_SIP
);
}
$dbT3
=
$this
->
store
->
getVar
(
SYSTEM_DB_NAME_T3
,
STORE_SYSTEM
);
$sql
=
"SELECT `bodytext` FROM `
$dbT3
`.`tt_content` WHERE `uid` = ?"
;
$tt_content
=
$this
->
db
->
sql
(
$sql
,
ROW_EXPECT_1
,
[
$uid
]);
$qfq
=
new
QuickFormQuery
([
T3DATA_BODYTEXT
=>
$tt_content
[
T3DATA_BODYTEXT
]],
false
,
false
);
return
$qfq
->
process
();
}
/**
* Creates a ZIP Files of all given $files
*
...
...
@@ -515,6 +514,63 @@ class Download {
return
$zipFile
;
}
/**
* Check $param for 'source:.<function name>&arg1=val1&arg2=val2,....'.
* For each found, expand it by fire the given QFQ function with the arguments.
* Be aware, the result might contain again a 'source:..' definition ... do it recursively.
*
* Returns a string withut any 'source:' definition.
*
* @param string $param
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \DownloadException
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws \UserFormException
* @throws \UserReportException
*/
private
function
checkAndExpandSource
(
$param
)
{
if
(
$param
==
''
)
{
return
''
;
}
$final
=
''
;
// $param = 'F:file.pdf|uid:123&pId=22|p:htmlcontent&appId=1|source:myFunction&accId=33'
$elements
=
explode
(
PARAM_DELIMITER
,
$param
);
// $elements = [ 'F:file.pdf', 'uid:123&pId=22;, 'p:htmlcontent&appId=1', 'source:myFunction&accId=33' ]
foreach
(
$elements
as
$element
)
{
// E.g.: $element = 'source:myFunction&accId=33' >>
$arr
=
explode
(
PARAM_TOKEN_DELIMITER
,
$element
,
2
);
// Check for 'source:...' - $arr[0] = 'source'
if
(
0
===
strcmp
(
$arr
[
0
],
TOKEN_SOURCE
))
{
// $arr[1] = 'myFunction&accId=33&grId=44'
$args
=
explode
(
'&'
,
$arr
[
1
],
2
);
$urlParam
=
KeyValueStringParser
::
parse
(
$args
[
1
]
??
''
,
'='
,
'&'
);
// Return a list of
$element
=
$this
->
checkAndExpandSource
(
$this
->
getEvaluatedBodytext
(
$args
[
0
],
$urlParam
));
if
(
$element
==
''
)
{
continue
;
}
}
$final
.
=
'|'
.
$element
;
}
return
substr
(
$final
,
1
);
}
/**
* $vars[DOWNLOAD_EXPORT_FILENAME] - Optional. '<new filename>'
* $vars[DOWNLOAD_MODE] - Optional. file | pdf | excel | thumbnail | monitor - default is a) 'file' in case of only one or b) 'pdf' in case of multiple sources.
...
...
@@ -563,7 +619,8 @@ class Download {
$vars
[
SIP_DOWNLOAD_PARAMETER
]
=
TOKEN_FILE
.
':'
.
$pathFilenameThumbnail
;
}
$elements
=
explode
(
PARAM_DELIMITER
,
$vars
[
SIP_DOWNLOAD_PARAMETER
]);
// Check and expand 'source:...'
$elements
=
explode
(
PARAM_DELIMITER
,
$this
->
checkAndExpandSource
(
$vars
[
SIP_DOWNLOAD_PARAMETER
]));
// Get all files / content
$tmpData
=
array
();
...
...
extension/Classes/Core/Report/Link.php
View file @
abd9cdee
...
...
@@ -147,6 +147,7 @@ class Link {
TOKEN_MAIL
=>
NAME_MAIL
,
TOKEN_PAGE
=>
NAME_PAGE
,
TOKEN_UID
=>
NAME_UID
,
TOKEN_SOURCE
=>
NAME_SOURCE
,
TOKEN_DROPDOWN
=>
NAME_DROPDOWN
,
TOKEN_DOWNLOAD
=>
NAME_DOWNLOAD
,
TOKEN_DOWNLOAD_MODE
=>
NAME_DOWNLOAD_MODE
,
...
...
@@ -814,8 +815,8 @@ class Link {
// Store value
if
((
isset
(
$rcTokenGiven
[
TOKEN_DOWNLOAD
])
||
isset
(
$rcTokenGiven
[
TOKEN_COPY_TO_CLIPBOARD
]))
&&
(
$key
==
TOKEN_PAGE
||
$key
==
TOKEN_URL
||
$key
==
TOKEN_URL_PARAM
||
$key
==
TOKEN_UID
||
$key
==
TOKEN_FILE
||
$key
==
TOKEN_FILE_DEPRECATED
))
{
(
$key
==
TOKEN_PAGE
||
$key
==
TOKEN_URL
||
$key
==
TOKEN_URL_PARAM
||
$key
==
TOKEN_UID
||
$key
==
TOKEN_SOURCE
||
$key
==
TOKEN_FILE
||
$key
==
TOKEN_FILE_DEPRECATED
))
{
$vars
[
NAME_COLLECT_ELEMENTS
][]
=
$key
.
':'
.
$value
;
...
...
extension/Classes/Core/Report/Report.php
View file @
abd9cdee
...
...
@@ -23,6 +23,7 @@
namespace
IMATHUZH\Qfq\Core\Report
;
use
IMATHUZH\Qfq\Core\BodytextParser
;
use
IMATHUZH\Qfq\Core\Database\Database
;
use
IMATHUZH\Qfq\Core\Evaluate
;
use
IMATHUZH\Qfq\Core\Form\FormAsFile
;
...
...
@@ -60,6 +61,11 @@ class Report {
*/
private
$store
=
null
;
/**
* @var Evaluate
*/
private
$evaluate
=
null
;
/**
* @var string
*/
...
...
@@ -117,19 +123,19 @@ class Report {
* Report constructor.
*
* @param array $t3data
* @param Evaluate $eval
* @param Evaluate $eval
uate
* @param bool $phpUnit
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
public
function
__construct
(
array
$t3data
,
Evaluate
$eval
,
$phpUnit
=
false
)
{
public
function
__construct
(
array
$t3data
,
Evaluate
$eval
uate
,
$phpUnit
=
false
)
{
#TODO: rewrite $phpUnit to: "if (!defined('PHPUNIT_QFQ')) {...}"
$this
->
phpUnit
=
$phpUnit
;
Support
::
setIfNotSet
(
$t3data
,
"uid"
,
0
)
;
$t3data
[
"uid"
]
=
$t3data
[
"uid"
]
??
0
;
$this
->
sip
=
new
Sip
(
$phpUnit
);
if
(
$phpUnit
)
{
...
...
@@ -138,6 +144,7 @@ class Report {
$_SERVER
[
'REQUEST_URI'
]
=
'localhost'
;
}
$this
->
evaluate
=
$evaluate
;
$this
->
store
=
Store
::
getInstance
();
$this
->
showDebugInfoFlag
=
(
Support
::
findInSet
(
SYSTEM_SHOW_DEBUG_INFO_YES
,
$this
->
store
->
getVar
(
SYSTEM_SHOW_DEBUG_INFO
,
STORE_SYSTEM
)));
...
...
@@ -167,7 +174,7 @@ class Report {
}
$this
->
db
=
new
Database
(
$this
->
dbIndexData
);
$this
->
variables
=
new
Variables
(
$eval
,
$t3data
[
"uid"
]);
$this
->
variables
=
new
Variables
(
$eval
uate
,
$t3data
[
"uid"
]);
$this
->
link
=
new
Link
(
$this
->
sip
,
$this
->
dbIndexData
,
$phpUnit
);
...
...
@@ -279,7 +286,7 @@ class Report {
// frCmd = "sql"
$frCmd
=
$arrKey
[
count
(
$arrKey
)
-
1
];
// Check if token is known
if
(
strpos
(
'|'
.
strtolower
(
TOKEN_VALID_LIST
)
.
'|'
,
'|'
.
$frCmd
.
'|'
)
===
false
)
{
throw
new
\
UserReportException
(
"Unknown token:
$frCmd
in Line '
$ttLine
''"
,
ERROR_UNKNOWN_TOKEN
);
}
...
...
@@ -307,7 +314,7 @@ class Report {
$index
=
$level
.
"."
.
$frCmd
;
// throw exception if this level was already defined
if
(
!
empty
(
$this
->
frArray
[
$index
]))
{
if
(
!
empty
(
$this
->
frArray
[
$index
]))
{
throw
new
\
UserReportException
(
"Double definition:
$index
is defined more than once."
,
ERROR_DOUBLE_DEFINITION
);
}
// store complete line reformatted in frArray
...
...
@@ -315,9 +322,7 @@ class Report {
// per sql command
//pro sql cmd wird der Indexarray abgefüllt. Dieser wird später verwendet um auf den $frArray zuzugreifen
//if(preg_match("/^sql/i", $frCmd) == 1){
// if ($frCmd === TOKEN_FORM || $frCmd === TOKEN_SQL) {
if
(
$frCmd
===
TOKEN_SQL
)
{
if
(
$frCmd
===
TOKEN_SQL
||
$frCmd
===
TOKEN_FUNCTION
)
{
// Remember max level
$this
->
levelCount
=
max
(
substr_count
(
$level
,
'.'
)
+
1
,
$this
->
levelCount
);
// $indexArray[10][50][5]
...
...
@@ -417,6 +422,85 @@ class Report {
return
$sortArg
;
}
/**
* Split $cmd into a) function name, b) call parameter and c) return values.
* Fire function: tt-content QFQ report
* Return 'return values' in STORE_RECORD and QFQ function output in {{_output:R}}.
* BTW: the QFQ function is cached and read only once. The evaluation is not cached.
*
* @param $cmd # 'getFirstName(pId) => firstName, myLink'
* @throws \CodeException
* @throws \DbException
* @throws \DownloadException
* @throws \PhpOffice\PhpSpreadsheet\Exception
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
* @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
* @throws \UserFormException
* @throws \UserReportException
*/
private
function
doQfqFunction
(
$cmd
)
{
// QFQ function cache
static
$functionCache
=
array
();
// Explode cmd
OnString
::
splitFunctionCmd
(
$cmd
,
$rcFunctionName
,
$rcFunctionParam
,
$rcReturnParam
);