Commit 140e1358 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'F6793_RenameFilesInZip' into 'master'

F6793 rename files in zip

See merge request !297
parents c0d5f8d1 59a461c2
Pipeline #4868 passed with stages
in 3 minutes and 44 seconds
...@@ -54,6 +54,7 @@ selenium: ...@@ -54,6 +54,7 @@ selenium:
script: script:
- unzip -q build/qfq.zip -d qfq - unzip -q build/qfq.zip -d qfq
- cd docker/ - cd docker/
# Required docker images: https://systemvcs.math.uzh.ch/megger/qfq_docker.git
- ./run_qfq_docker.sh -no-deploy - ./run_qfq_docker.sh -no-deploy
- ./deploy_to_container.sh ../qfq - ./deploy_to_container.sh ../qfq
- ./run_selenium_tests_docker.sh - ./run_selenium_tests_docker.sh
......
...@@ -46,6 +46,8 @@ The following features are only tested / supported on linux hosts: ...@@ -46,6 +46,8 @@ The following features are only tested / supported on linux hosts:
* PDF decrypt (used for merge with pdfunite) - command `qpdf`. * PDF decrypt (used for merge with pdfunite) - command `qpdf`.
* PDF decrypt (used for merge with pdfunite) - command `gs` - in case `qpdf` is not successful. * PDF decrypt (used for merge with pdfunite) - command `gs` - in case `qpdf` is not successful.
* Mime type detection for uploads - command `file`. * Mime type detection for uploads - command `file`.
* Split PDF into JPG - command `convert`.
* Repair PDF - command `pdftocairo`.
.. _`preparation`: .. _`preparation`:
...@@ -401,7 +403,11 @@ Extension Manager: QFQ Configuration ...@@ -401,7 +403,11 @@ Extension Manager: QFQ Configuration
+-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| cmdInkscape | inkscape | If inkscape is not available, specify an empty string. | | cmdInkscape | inkscape | If inkscape is not available, specify an empty string. |
+-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| cmdConvert | convert | GraphicsMagics 'convert' is recommended. | | cmdConvert | convert | Image-/GraphicsMagics 'convert' is recommended. |
+-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| cmdPdf2svg | pdf2svg | Convert PDF to SVG. |
+-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| cmdPdftocairo | pdftocairo | Poppler based. |
+-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| cmdWkhtmltopdf | /usr/bin/wkhtmltopdf | PathFilename of wkhtmltopdf. Optional variables like LD_LIBRARY_PATH=... | | cmdWkhtmltopdf | /usr/bin/wkhtmltopdf | PathFilename of wkhtmltopdf. Optional variables like LD_LIBRARY_PATH=... |
+-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+ +-----------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
......
...@@ -73,10 +73,9 @@ Date: 06.09.2020 ...@@ -73,10 +73,9 @@ Date: 06.09.2020
Notes Notes
^^^^^ ^^^^^
New table 'uniq' to guarantee uniq random strings. * New SIP protected AJAX calls.
New SIP protected AJAX calls. * Report now fires calls to websocket (remote hosts).
Report now fires calls to websocket (remote hosts). * Report now fires REST calls to remote hosts.
Report now fires REST calls to remote hosts.
Features Features
^^^^^^^^ ^^^^^^^^
...@@ -209,9 +208,9 @@ Notes ...@@ -209,9 +208,9 @@ Notes
* Add new keyword 'render' in tt-content Report and QFQ config. 'render' will control if a) only Form OR Report will be * Add new keyword 'render' in tt-content Report and QFQ config. 'render' will control if a) only Form OR Report will be
rendered (render=single) or b) as previous Form AND Report together (render=both). rendered (render=single) or b) as previous Form AND Report together (render=both).
Advantage: with 'render=single' no more SELECT ... FROM (SELECT '') AS fake WHERE '{{form:SE}}'=''. * Advantage: with 'render=single' no more SELECT ... FROM (SELECT '') AS fake WHERE '{{form:SE}}'=''.
Attention: NEW default behaviour in new QFQ installations - render=single. Behaviour in old installations is unchanged. * Attention: NEW default behaviour in new QFQ installations - render=single. Behaviour in old installations is unchanged.
* tt-content records with 'render = api' can stay on the same page as the link to get the content (e.g. Excel Export). * tt-content records with 'render = api' can stay on the same page as the link to get the content (e.g. Excel Export).
* Change default doc page to qfq.io/doc. * Change default doc page to qfq.io/doc.
...@@ -338,9 +337,6 @@ Version 19.11.3 ...@@ -338,9 +337,6 @@ Version 19.11.3
Date: 29.11.2019 Date: 29.11.2019
Notes
^^^^^
Features Features
^^^^^^^^ ^^^^^^^^
...@@ -388,7 +384,7 @@ Notes ...@@ -388,7 +384,7 @@ Notes
* Enhance formModeGlobal=requiredOff/-ButMark (temporarily skipRequiredCheck): fill's '{{allRequiredGiven:V}}' before * Enhance formModeGlobal=requiredOff/-ButMark (temporarily skipRequiredCheck): fill's '{{allRequiredGiven:V}}' before
save to 1 (all given) else 0. save to 1 (all given) else 0.
Offers user to save form, even if not all required data are given and offers application logic to check easily if all * Offers user to save form, even if not all required data are given and offers application logic to check easily if all
required fields has been filled. required fields has been filled.
Features Features
...@@ -575,9 +571,6 @@ Version 19.8.0 ...@@ -575,9 +571,6 @@ Version 19.8.0
Date: 28.08.2019 Date: 28.08.2019
Notes
^^^^^
Features Features
^^^^^^^^ ^^^^^^^^
...@@ -1082,9 +1075,6 @@ Version 19.1.0 ...@@ -1082,9 +1075,6 @@ Version 19.1.0
Date: 03.01.2019 Date: 03.01.2019
Notes
^^^^^
Features Features
^^^^^^^^ ^^^^^^^^
...@@ -1697,7 +1687,7 @@ Features ...@@ -1697,7 +1687,7 @@ Features
Bug Fixes Bug Fixes
^^^^^^^^^ ^^^^^^^^^
* #5706 / Fixed that problematic characters in 'fileDestination' has not been sanatized. * #5706 / Fixed that problematic characters in 'fileDestination' has not been sanitized.
* Fixed problem with buttons clipping trough alert. * Fixed problem with buttons clipping trough alert.
* Client: wrong variable, updated CSS for long errors. * Client: wrong variable, updated CSS for long errors.
...@@ -1845,7 +1835,7 @@ Notes ...@@ -1845,7 +1835,7 @@ Notes
Features Features
^^^^^^^^ ^^^^^^^^
* #5022 / Variable violates sanatize class: 'msg' instead of empty string - new identifier "!!<sanitize class>!!". * #5022 / Variable violates santize class: 'msg' instead of empty string - new identifier "!!<sanitize class>!!".
* #4813 / Exception during form load: show 'form edit link' if editor is logged in. * #4813 / Exception during form load: show 'form edit link' if editor is logged in.
* formEditor.sql: Increas size of Form.title to give more room for SQL statements in. * formEditor.sql: Increas size of Form.title to give more room for SQL statements in.
* Manual.rst: enhance debug tipps. * Manual.rst: enhance debug tipps.
...@@ -2418,7 +2408,7 @@ Bug Fixes ...@@ -2418,7 +2408,7 @@ Bug Fixes
^^^^^^^^^ ^^^^^^^^^
* #3953 / Radio buttons: Auswahl nicht angezeigt, wenn per itemList definiert. * #3953 / Radio buttons: Auswahl nicht angezeigt, wenn per itemList definiert.
* #3982 / Filename Sanatize: remove spaces. Filename not properbly enclosed by double ticks. * #3982 / Filename Santize: remove spaces. Filename not properbly enclosed by double ticks.
Version 0.18.6 Version 0.18.6
-------------- --------------
...@@ -2612,7 +2602,7 @@ Features ...@@ -2612,7 +2602,7 @@ Features
* #3218, #3600 / download.php / export: QFQ is now able to create PDFs and ZIPs on the fly. The sources might be * #3218, #3600 / download.php / export: QFQ is now able to create PDFs and ZIPs on the fly. The sources might be
uploaded PDFs or Websites (local or remote) which will be converted to PDFs. uploaded PDFs or Websites (local or remote) which will be converted to PDFs.
* Implement 'encode=specialchar' - new option per FormElement which is now the default for every FormElement. * Implement 'encode=specialchar' - new option per FormElement which is now the default for every FormElement.
* Sanatize.php: New function urlDecodeArr(). Decode all _GET vars. * Santize.php: New function urlDecodeArr(). Decode all _GET vars.
* Implemented max GET parameter lenght. Default: 50. * Implemented max GET parameter lenght. Default: 50.
* Implemented new escape class 'mysql' (realEscapeString). * Implemented new escape class 'mysql' (realEscapeString).
* LICENSE.txt: Add GPLv3. * LICENSE.txt: Add GPLv3.
...@@ -2699,8 +2689,8 @@ Bug Fixes ...@@ -2699,8 +2689,8 @@ Bug Fixes
new `explodeTemplateGroupElements()` new `explodeTemplateGroupElements()`
* TypeAhead.js: Handle <ENTER> key properly. * TypeAhead.js: Handle <ENTER> key properly.
* #3462 / FormElement.parameter: requiredList not ok for non numeric content. STORE_FORM had been called without 'sanatize class'. * #3462 / FormElement.parameter: requiredList not ok for non numeric content. STORE_FORM had been called without 'santize class'.
Therefore, all non numeric values has been sanatized by default. New: SANATIZE_ALLOW_ALL. Therefore, all non numeric values has been sanitized by default. New: SANITIZE_ALLOW_ALL.
* Corrected error message to use 'itemList' instead of 'itemValues'. Renamed constant too. * Corrected error message to use 'itemList' instead of 'itemValues'. Renamed constant too.
* #2542 / FormElement-Typ 'note' funktioniert nicht mit dynamic update. 'Label' and 'note' are fixed - 'value' is still not updated, open. * #2542 / FormElement-Typ 'note' funktioniert nicht mit dynamic update. 'Label' and 'note' are fixed - 'value' is still not updated, open.
...@@ -2911,7 +2901,7 @@ Features ...@@ -2911,7 +2901,7 @@ Features
* Multiple / Advanced Upload: new logic implements slaveId, sqlInsert, sqlUpdate, sqlDelete. * Multiple / Advanced Upload: new logic implements slaveId, sqlInsert, sqlUpdate, sqlDelete.
* FormElement.parameter: sqlBefore / sqlAfter fired during 'Form' save for action elements. * FormElement.parameter: sqlBefore / sqlAfter fired during 'Form' save for action elements.
* STORE FORM: variable 'filename' moved to STORE VAR - sanatize class needs no longer specified. * STORE FORM: variable 'filename' moved to STORE VAR - sanitize class needs no longer specified.
* STORE VAR: two new variables 'filename' and 'fileDestination' valid during processing of current upload FormElement. * STORE VAR: two new variables 'filename' and 'fileDestination' valid during processing of current upload FormElement.
* Default store priority list changed. Old: 'FSRD', New: 'FSRVD'. * Default store priority list changed. Old: 'FSRD', New: 'FSRVD'.
* CODING.md: update doc for FormElement 'upload' and general 'Form' rendering & save (recursive rendering). * CODING.md: update doc for FormElement 'upload' and general 'Form' rendering & save (recursive rendering).
...@@ -2971,7 +2961,7 @@ Features ...@@ -2971,7 +2961,7 @@ Features
* Added STORE_BEFORE, #3146 - Mainly used to compare old and new values during a form 'save' action. * Added STORE_BEFORE, #3146 - Mainly used to compare old and new values during a form 'save' action.
* Added 'best practice' for defining and using of 'Central configure values' in UserManual. * Added 'best practice' for defining and using of 'Central configure values' in UserManual.
* Added accent characters to sanatize class 'alnumx', #3183. * Added accent characters to sanitize class 'alnumx', #3183.
* Set default all QFQ send mails to 'auto-submit'. * Set default all QFQ send mails to 'auto-submit'.
* Added possibility to customize error messages ('data-pattern-error', 'data-rquired-error', 'data-match-error', * Added possibility to customize error messages ('data-pattern-error', 'data-rquired-error', 'data-match-error',
'data-error') if validation fails. Customization can be done on global level (config.qfq.ini), per Form or per FormElement. 'data-error') if validation fails. Customization can be done on global level (config.qfq.ini), per Form or per FormElement.
......
...@@ -1322,15 +1322,15 @@ Renders images. Allows to define an alternative text and a title attribute for t ...@@ -1322,15 +1322,15 @@ Renders images. Allows to define an alternative text and a title attribute for t
10.sql = SELECT "<path to image>|[<alt text>]|[<title text>]" AS _img 10.sql = SELECT "<path to image>|[<alt text>]|[<title text>]" AS _img
+-------------+-------------------------------------------------------------------------------------------+---------------------------+ +--------------+-------------------------------------------------------------------------------------------+-----------------------------+
|**Parameter**|**Description** |**Default value/behaviour**| |**Parameter** |**Description** | **Default value/behaviour** |
+=============+===========================================================================================+===========================+ +==============+===========================================================================================+=============================+
|<pathtoimage>|The path to the image file. |none | |<pathtoimage> |The path to the image file. | none |
+-------------+-------------------------------------------------------------------------------------------+---------------------------+ +--------------+-------------------------------------------------------------------------------------------+-----------------------------+
|<alttext> |Alternative text. Will be displayed if image can't be loaded (alt attribute of img tag). |empty string | |<alttext> |Alternative text. Will be displayed if image can't be loaded (alt attribute of img tag). | empty string |
+-------------+-------------------------------------------------------------------------------------------+---------------------------+ +--------------+-------------------------------------------------------------------------------------------+-----------------------------+
|<titletext> |Text that will be set as image title in the title attribute of the img tag. |no title attribute rendered| |<titletext> |Text that will be set as image title in the title attribute of the img tag. | no title attribute rendered |
+-------------+-------------------------------------------------------------------------------------------+---------------------------+ +--------------+-------------------------------------------------------------------------------------------+-----------------------------+
**Minimal Example** :: **Minimal Example** ::
...@@ -1506,24 +1506,40 @@ Most of the other Link-Class attributes can be used to customize the link. :: ...@@ -1506,24 +1506,40 @@ Most of the other Link-Class attributes can be used to customize the link. ::
10.sql = SELECT "[options]" AS _pdf, "[options]" AS _file, "[options]" AS _zip 10.sql = SELECT "[options]" AS _pdf, "[options]" AS _file, "[options]" AS _zip
with: [options] = [d:<exportFilename][|p:<params>][|U:<params>][|u:<url>][|F:file][|t:<text>][|a:<message>][|o:<tooltip>][|c:<class>][|r:<render mode>] with: [options] = [d:<exportFilename][|p:<params>][|U:<params>][|u:<url>][|F:file[:path/file in zip]][|t:<text>][|a:<message>][|o:<tooltip>][|c:<class>][|r:<render mode>]
* Parameter are position independent. * Parameter are position independent.
* *<params>*: see :ref:`download-parameter-files` * *<params>*: see :ref:`download-parameter-files`
* For column `_pdf` and `_zip`, the element sources `p:...`, `U:...`, `u:...`, `F:...` might repeated multiple times. * For column `_pdf` and `_zip`, the element sources `p:...`, `U:...`, `u:...`, `F:...` might repeated multiple times.
* For column `_zip`, an optional parameter might define the path and filename inside the ZIP: `F:<orig filename>:<inside ZIP path and filename>`
* To only render the page content without menus add the parameter `type=2`. For example: `U:id=pageToPrint&type=2&_sip=1&r=', r.id` * To only render the page content without menus add the parameter `type=2`. For example: `U:id=pageToPrint&type=2&_sip=1&r=', r.id`
* Example:: * Example::
10.sql = SELECT "F:fileadmin/test.pdf" as _pdf, "F:fileadmin/test.pdf" as _file, "F:fileadmin/test.pdf" as _zip # ... AS _file
10.sql = SELECT "p:id=export&r=1" as _pdf, "p:id=export&r=1" as _file, "p:id=export&r=1" as _zip 10.sql = SELECT "F:fileadmin/test.pdf" as _pdf
20.sql = SELECT "p:id=export&r=1" as _pdf
10.sql = SELECT "t:Download PDF|F:fileadmin/test.pdf" as _pdf, "t:Download PDF|F:fileadmin/test.pdf" as _file, "t:Download ZIP|F:fileadmin/test.pdf" as _zip 30.sql = SELECT "t:Download PDF|F:fileadmin/test.pdf" as _pdf
10.sql = SELECT "t:Download PDF|p:id=export&r=1" as _pdf, "t:Download PDF|p:id=export&r=1" as _file, "t:Download ZIP|p:id=export&r=1" as _zip 40.sql = SELECT "t:Download PDF|p:id=export&r=1" as _pdf
50.sql = SELECT "d:complete.pdf|t:Download PDF|F:fileadmin/test1.pdf|F:fileadmin/test2.pdf" as _pdf
10.sql = SELECT "d:complete.pdf|t:Download PDF|F:fileadmin/test1.pdf|F:fileadmin/test2.pdf" as _pdf, "d:complete.zip|t:Download ZIP|F:fileadmin/test1.pdf|F:fileadmin/test2.pdf" as _zip 60.sql = SELECT "d:complete.pdf|t:Download PDF|F:fileadmin/test.pdf|p:id=export&r=1|u:www.example.com" AS _pdf
# ... AS _file
100.sql = SELECT "F:fileadmin/test.pdf" as _file
110.sql = SELECT "p:id=export&r=1" as _file
120.sql = SELECT "t:Download PDF|F:fileadmin/test.pdf" as _file
130.sql = SELECT "t:Download PDF|p:id=export&r=1" as _file
# ... AS _zip
200.sql = SELECT "F:fileadmin/test.pdf" as _zip
210.sql = SELECT "p:id=export&r=1" as _zip
220.sql = SELECT "t:Download ZIP|F:fileadmin/test.pdf" as _zip
230.sql = SELECT "t:Download ZIP|p:id=export&r=1" as _zip
# Several files
240.sql = SELECT "d:complete.zip|t:Download ZIP|F:fileadmin/test1.pdf|F:fileadmin/test2.pdf" as _zip
# Several files with new path/filename
250.sql = SELECT "d:complete.zip|t:Download ZIP|F:fileadmin/test1.pdf:data/file-1.pdf|F:fileadmin/test2.pdf:data/file-2.pdf" as _zip
10.sql = SELECT "d:complete.pdf|t:Download PDF|F:fileadmin/test.pdf|p:id=export&r=1|u:www.example.com" AS _pdf
.. _column-save-pdf: .. _column-save-pdf:
......
...@@ -127,7 +127,7 @@ For QFQ variables and FormElements: ...@@ -127,7 +127,7 @@ For QFQ variables and FormElements:
+------------------+------+-------+-----------------------------------------------------------------------------------------+ +------------------+------+-------+-----------------------------------------------------------------------------------------+
| Name | Form | Query | Pattern | | Name | Form | Query | Pattern |
+==================+======+=======+=========================================================================================+ +==================+======+=======+=========================================================================================+
| **alnumx** | Form | Query | [A-Za-z][0-9]@-_.,;: /() ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüÿçß | | **alnumx** | Form | Query | [A-Za-z][0-9]@-_.,;: /() ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüÿçß |
+------------------+------+-------+-----------------------------------------------------------------------------------------+ +------------------+------+-------+-----------------------------------------------------------------------------------------+
| **digit** | Form | Query | [0-9] | | **digit** | Form | Query | [0-9] |
+------------------+------+-------+-----------------------------------------------------------------------------------------+ +------------------+------+-------+-----------------------------------------------------------------------------------------+
......
...@@ -259,7 +259,7 @@ const ERROR_IO_CHMOD = 1314; ...@@ -259,7 +259,7 @@ const ERROR_IO_CHMOD = 1314;
const ERROR_IO_READ_FILE = 1315; const ERROR_IO_READ_FILE = 1315;
const ERROR_IO_WRITE_FILE = 1316; const ERROR_IO_WRITE_FILE = 1316;
const ERROR_PDF2SVG = 1320; const ERROR_PDF_SPLIT = 1320;
const ERROR_PDF2JPEG = 1321; const ERROR_PDF2JPEG = 1321;
//Report //Report
...@@ -648,6 +648,8 @@ const SYSTEM_SHOW_ID_IN_FORM_TITLE = 'showIdInFormTitle'; ...@@ -648,6 +648,8 @@ const SYSTEM_SHOW_ID_IN_FORM_TITLE = 'showIdInFormTitle';
const SYSTEM_CMD_WKHTMLTOPDF = 'cmdWkhtmltopdf'; const SYSTEM_CMD_WKHTMLTOPDF = 'cmdWkhtmltopdf';
const SYSTEM_CMD_INKSCAPE = 'cmdInkscape'; const SYSTEM_CMD_INKSCAPE = 'cmdInkscape';
const SYSTEM_CMD_CONVERT = 'cmdConvert'; const SYSTEM_CMD_CONVERT = 'cmdConvert';
const SYSTEM_CMD_PDF2SVG = 'cmdPdf2svg';
const SYSTEM_CMD_PDFTOCAIRO = 'cmdPdftocairo';
const SYSTEM_CMD_QPDF = 'cmdQpdf'; const SYSTEM_CMD_QPDF = 'cmdQpdf';
const SYSTEM_CMD_GS = 'cmdGs'; const SYSTEM_CMD_GS = 'cmdGs';
const SYSTEM_CMD_PDFUNITE = 'cmdPdfunite'; const SYSTEM_CMD_PDFUNITE = 'cmdPdfunite';
...@@ -778,7 +780,7 @@ const TOKEN_FOUND_STOP_REPLACE = 'stopReplace'; ...@@ -778,7 +780,7 @@ const TOKEN_FOUND_STOP_REPLACE = 'stopReplace';
const VAR_INDEX_VALUE = 0; const VAR_INDEX_VALUE = 0;
const VAR_INDEX_STORE = 1; const VAR_INDEX_STORE = 1;
const VAR_INDEX_SANATIZE = 2; const VAR_INDEX_SANITIZE = 2;
const VAR_INDEX_ESCAPE = 3; const VAR_INDEX_ESCAPE = 3;
const VAR_INDEX_DEFAULT = 4; const VAR_INDEX_DEFAULT = 4;
const VAR_INDEX_MESSAGE = 5; const VAR_INDEX_MESSAGE = 5;
......
...@@ -392,7 +392,7 @@ class Evaluate { ...@@ -392,7 +392,7 @@ class Evaluate {
$typeMessageViolate = ($arrToken[VAR_INDEX_MESSAGE] === null || $arrToken[VAR_INDEX_MESSAGE] === '') ? SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS : $arrToken[VAR_INDEX_MESSAGE]; $typeMessageViolate = ($arrToken[VAR_INDEX_MESSAGE] === null || $arrToken[VAR_INDEX_MESSAGE] === '') ? SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS : $arrToken[VAR_INDEX_MESSAGE];
// search for value in stores // search for value in stores
$value = $this->store::getVar($arrToken[VAR_INDEX_VALUE], $arrToken[VAR_INDEX_STORE], $arrToken[VAR_INDEX_SANATIZE], $value = $this->store::getVar($arrToken[VAR_INDEX_VALUE], $arrToken[VAR_INDEX_STORE], $arrToken[VAR_INDEX_SANITIZE],
$foundInStore, $typeMessageViolate, $arrToken[VAR_INDEX_DEFAULT]); $foundInStore, $typeMessageViolate, $arrToken[VAR_INDEX_DEFAULT]);
// escape ticks // escape ticks
......
...@@ -399,7 +399,7 @@ class FormAction { ...@@ -399,7 +399,7 @@ class FormAction {
* *
* @param string $listOfFormElementNames E.g.: 'city, street, number' * @param string $listOfFormElementNames E.g.: 'city, street, number'
* *
* @return bool true if at lease one of the named elements is non empty on STORE_FORM (use SANATIZE_ALLOW_ALL to * @return bool true if at lease one of the named elements is non empty on STORE_FORM (use SANITIZE_ALLOW_ALL to
* perform the check) * perform the check)
* @throws \CodeException * @throws \CodeException
* @throws \UserFormException * @throws \UserFormException
......
...@@ -336,7 +336,7 @@ class HelperFile { ...@@ -336,7 +336,7 @@ class HelperFile {
public static function rename($oldname, $newname) { public static function rename($oldname, $newname) {
if (false === @rename($oldname, $newname)) { if (false === @rename($oldname, $newname)) {
$msg = self::errorGetLastAsString() . " - rename($oldname ,$newname)"; $msg = self::errorGetLastAsString() . " - rename($oldname, $newname)";
throw new \UserFormException(json_encode([ERROR_MESSAGE_TO_USER => 'unlink failed', ERROR_MESSAGE_TO_DEVELOPER => $msg]), ERROR_IO_RENAME); throw new \UserFormException(json_encode([ERROR_MESSAGE_TO_USER => 'unlink failed', ERROR_MESSAGE_TO_DEVELOPER => $msg]), ERROR_IO_RENAME);
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
*/ */
namespace IMATHUZH\Qfq\Core\Helper; namespace IMATHUZH\Qfq\Core\Helper;
/** /**
...@@ -289,14 +288,19 @@ class Sanitize { ...@@ -289,14 +288,19 @@ class Sanitize {
*/ */
public static function digitCheckAndCleanGet($key) { public static function digitCheckAndCleanGet($key) {
if (isset($_GET[$key]) && !ctype_digit($_GET[$key])) { if (!isset($_GET[$key])) {
if (!empty($_GET[$key]) && ctype_digit($_GET[$key][0])) { $_GET[$key] = '';
$_GET[$key] = $_GET[$key][0]; return;
} else {
$_GET[$key] = '';
}
} }
} if (ctype_digit($_GET[$key])) {
return;
}
if (ctype_digit($_GET[$key][0] ?? '')) {
$_GET[$key] = $_GET[$key][0];
} else {
$_GET[$key] = '';
}
}
} }
\ No newline at end of file
...@@ -355,7 +355,7 @@ class Download { ...@@ -355,7 +355,7 @@ class Download {
/** /**
* Interprets $element and fetches corresponding content, either as a file or the content in a variable. * Interprets $element and fetches corresponding content, either as a file or the content in a variable.
* *
* @param string $element - U:id=myExport&r=12, u:http://www.nzz.ch/issue?nr=21, f:fileadmin/sample.pdf * @param string $element - U:id=myExport&r=12, u:http://www.nzz.ch/issue?nr=21, F:fileadmin/sample.pdf
* *
* @param string $downloadMode - DOWNLOAD_MODE_EXCEL | .... * @param string $downloadMode - DOWNLOAD_MODE_EXCEL | ....
* @param string $rcData - With $downloadMode=DOWNLOAD_MODE_EXCEL, this contains the rendered code from the given T3 page. * @param string $rcData - With $downloadMode=DOWNLOAD_MODE_EXCEL, this contains the rendered code from the given T3 page.
...@@ -497,15 +497,17 @@ class Download { ...@@ -497,15 +497,17 @@ class Download {
$len = strlen(TMP_FILE_PREFIX); $len = strlen(TMP_FILE_PREFIX);
$ii = 1; $ii = 1;
foreach ($files as $filename) { foreach ($files as $item) {
$localName = substr($filename, strrpos($filename, '/') + 1); $arr = explode(PARAM_TOKEN_DELIMITER, $item);
$filename = $arr[0] ?? '';
$localName = ($arr[1] == '') ? substr($filename, strrpos($filename, '/') + 1) : $arr[1];
if (substr($localName, 0, $len) == TMP_FILE_PREFIX) { if (substr($localName, 0, $len) == TMP_FILE_PREFIX) {
$localName = 'file-' . $ii; $localName = 'file-' . $ii;
$ii++; $ii++;
} }
$zip->addFile($filename, $localName); $zip->addFile($filename, Sanitize::safeFilename($localName, false, true));
} }
$zip->close(); $zip->close();
......
...@@ -1262,13 +1262,10 @@ class Save { ...@@ -1262,13 +1262,10 @@ class Save {
switch ($fileSplitType) { switch ($fileSplitType) {
case FE_FILE_SPLIT_SVG: case FE_FILE_SPLIT_SVG:
$cmd = 'pdf2svg "' . $newSrc . '" "' . $fileNameDest . '" all'; $cmd = $this->buildPdf2svg($newSrc, $fileNameDest);
break; break;
case FE_FILE_SPLIT_JPEG: case FE_FILE_SPLIT_JPEG:
if ($fileSplitTypeOptions == '') { $cmd = $this->buildConvertSplit($newSrc, $fileNameDest, $fileSplitTypeOptions);
$fileSplitTypeOptions = FE_FILE_SPLIT_OPTIONS_JPEG;
}
$cmd = "convert $fileSplitTypeOptions '$newSrc' '$fileNameDest'";
break; break;
default: default:
throw new \UserFormException("Unknown 'fileSplit' type: " . $formElement[FE_FILE_SPLIT], ERROR_UNKNOWN_TOKEN); throw new \UserFormException("Unknown 'fileSplit' type: " . $formElement[FE_FILE_SPLIT], ERROR_UNKNOWN_TOKEN);
...@@ -1276,13 +1273,30 @@ class Save { ...@@ -1276,13 +1273,30 @@ class Save {
// Split PDF // Split PDF
HelperFile::chdir($tempDir); HelperFile::chdir($tempDir);
$output = Support::qfqExec($cmd, $rc); $cnt = 0;
do {
$output = Support::qfqExec($cmd, $rc);
$cnt++;
if ($rc != 0) {
// Split failed
$cmdRepair = $this->buildPdftocairo($newSrc, $newSrc . '.1');
$output .= PHP_EOL . $cmdRepair . PHP_EOL;
$output .= Support::qfqExec($cmdRepair, $rc1);
if ($rc1 != 0) {
// Repair failed too: stop here.
break;
}
HelperFile::rename($newSrc . '.1', $newSrc);
}
} while ($rc != 0 && $cnt < 2);
HelperFile::chdir($cwd); HelperFile::chdir($cwd);
if ($rc != 0) { if ($rc != 0) {
throw new \UserFormException( throw new \UserFormException(
json_encode([ERROR_MESSAGE_TO_USER => 'pdf2svg failed', ERROR_MESSAGE_TO_DEVELOPER => "[$cwd][cmd=$cmd]$output"]), json_encode([ERROR_MESSAGE_TO_USER => 'pdf split failed', ERROR_MESSAGE_TO_DEVELOPER => "[$cwd][cmd=$cmd]$output"]),
ERROR_PDF2SVG); ERROR_PDF_SPLIT);
} }
$files = Helperfile::getSplitFileNames($tempDir); $files = Helperfile::getSplitFileNames($tempDir);
...@@ -1326,6 +1340,54 @@ class Save { ...@@ -1326,6 +1340,54 @@ class Save {
HelperFile::rmdir($tempDir); HelperFile::rmdir($tempDir);
} }
/**
* @param $src
* @param $dest
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
private function buildPdf2svg($src, $dest) {
$cmd = $this->store->getVar(SYSTEM_CMD_PDF2SVG, STORE_SYSTEM);
return "$cmd '$src' '$dest' all";
}
/**
* @param $src
* @param $dest
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
private function buildPdftocairo($src, $dest) {
$cmd = $this->store->getVar(SYSTEM_CMD_PDFTOCAIRO, STORE_SYSTEM);
return "$cmd -pdf '$src' '$dest'";
}
/**
* @param $src
* @param $dest
* @param $options
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException