Commit 6f5a988f authored by Carsten  Rose's avatar Carsten Rose
Browse files

Download: columns _pPdf,_zZip, _fFile implemented. _dDownload removed.

Handling of filenames in Zip's optimized. Spoken filename (no cryptic tempnames anymore). Correct filename extension, based on the mimetype.

Manual.rst: updated doc for columns  _pPdf,_zZip, _fFile. Remove doc for '_dDownload'.
Download.php: new function targetFilenameExtension(). Replace cryptic temporary filenames against file-1, ...
Link.php: reorder param array, to make TOKEN_DOWNLOAD position independet
Report.php: Implemented _pPdf,_zZip, _fFile.
parent 59bbdc8c
......@@ -3508,7 +3508,7 @@ Parameter and (element) sources
* *file*: `f:<pathFilename>` - relative or absolute pathFilename offered for a) download (single), or to be concatenated
in a PDF or ZIP.
* *urlParam*: `U:id=<t3 page>&<key 1>=<value 1>&<key 2>=<value 2>&...&<key n>=<value n>
* *urlParam*: `U:id=<t3 page>&<key 1>=<value 1>&<key 2>=<value 2>&...&<key n>=<value n>`
* *url*: `u:<url>` - any URL, pointing to an internal or external destination.
......@@ -3775,7 +3775,6 @@ Easily create Email links.
..
Column: _sendmail
^^^^^^^^^^^^^^^^^
......@@ -3937,39 +3936,52 @@ Runs batch files or executables on the webserver. In case of an error, returncod
..
Column: _download
^^^^^^^^^^^^^^^^^
Column: _pdf | _file | _zip
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Most of the other Link-Class attributes can be used to customize the link. Most usefull:
Most of the other Link-Class attributes can be used to customize the link.
::
SELECT "[options]" AS _download
SELECT "[options]" AS _pdf, "[options]" AS _file, "[options]" AS _zip
with: [options] = U:<params>[t:<text>]|[o:<tooltip>]|[c:<class>]|[g:<target>]|[r:<render mode>]
with: [options] = [d:<exportFilename]|[U:<params>]|[u:<url>]|[f:file]|[t:<text>]|[a:<message>]|[o:<tooltip>]|[c:<class>]|[r:<render mode>]
* Parameter are position independent.
* *<params>*: see ref:`download-parameter-files`
* For column `_pdf` and `_zip`, the element sources `U:...`, `u:...`, `f:...` might repeated multiple times.
* Example: ::
SELECT "U:exportFilename=file.pdf&mode=pdf&1_id=xRequest&2_id=123&2_r=456&3_file=fileadmin/test.pdf|t:PDF download|o:Click to view the PDF" AS _download
SELECT "f:fileadmin/test.pdf" as _pdf, "f:fileadmin/test.pdf" as _file, "f:fileadmin/test.pdf" as _zip
SELECT "U:id=export&r=1" as _pdf, "U:id=export&r=1" as _file, "U:id=export&r=1" as _zip
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
SELECT "t:Download PDF|U:id=export&r=1" as _pdf, "t:Download PDF|U:id=export&r=1" as _file, "t:Download ZIP|U:id=export&r=1" as _zip
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
SELECT "d:complete.pdf|t:Download PDF|f:fileadmin/test.pdf|U:id=export&r=1|u:www.w3c.org" AS _pdf
..
Column: _Download
^^^^^^^^^^^^^^^^^
Column: _Pdf | _File | _Zip
^^^^^^^^^^^^^^^^^^^^^^^^^^^
A limited set of attributes is supported: ::
SELECT "[options]" AS _Download
SELECT "[options]" AS _Pdf, "[options]" AS _File, "[options]" AS _Zip
with: [options] =<params>|[<text>]|[<tooltip>]|[<class>]|[<target>]|[<render mode>]
with: [options] = [<exportFilename>]|[<text>]|[<1: urlparam|file>]|[<2: urlparam|file>]| ... |[<n: urlparam|file>]
* Parameter are position dependent and therefore without a qualifier!
* *<params>*: see ref:`download-parameter-files`
* `<urlparam>` or `<file>` might be given.
* If there is more than one `<urlparam|file>`, only `_Pdf` or `_Zip` is possible.
* Example: ::
SELECT "exportFilename=file.pdf&mode=pdf&1_id=xRequest&2_id=123&2_r=456&3_file=fileadmin/test.pdf|PDF download|Click to view the PDF" AS _download
SELECT "||fileadmin/test.pdf" AS _File, "||fileadmin/test.pdf" AS _Pdf, "||fileadmin/test.pdf" AS _Zip
SELECT "output.pdf|Download PDF|fileadmin/test.pdf" AS _File, "output.pdf|Download PDF|fileadmin/test.pdf" AS _Pdf, "output.zip|Download ZIP|fileadmin/test.pdf" AS _Zip
SELECT "complete.pdf|Download ZIP|fileadmin/test1.pdf|fileadmin/test2.pdf|id=export&r=1" AS _pdf
..
......
......@@ -842,7 +842,9 @@ const COLUMN_PPAGEH = "Pageh";
const COLUMN_PPAGEI = "Pagei";
const COLUMN_PPAGEN = "Pagen";
const COLUMN_PPAGES = "Pages";
const COLUMN_DDOWNLOAD = "Download";
const COLUMN_PPDF = "Pdf";
const COLUMN_ZZIP = "Zip";
const COLUMN_FFILE = "File";
const COLUMN_PAGE = "page";
const COLUMN_PAGEC = "pagec";
......@@ -852,7 +854,9 @@ const COLUMN_PAGEH = "pageh";
const COLUMN_PAGEI = "pagei";
const COLUMN_PAGEN = "pagen";
const COLUMN_PAGES = "pages";
const COLUMN_DOWNLOAD = "download";
const COLUMN_PDF = "pdf";
const COLUMN_FILE = "file";
const COLUMN_ZIP = "zip";
const FORM_NAME_FORM = 'form';
const FORM_NAME_FORM_ELEMENT = 'formElement';
......
......@@ -108,23 +108,48 @@ class Download {
}
/**
* Set header type and output $filename. Be careful not to send any additional characters.
* Get the mimetype of $filename and store them in $rcMimetype.
* Checks if the extension of $outputFilename fit's to the mimetype. If not, append the mimetype extension.
*
* @param $filename
* @param $outputFilename
* @param string $filename
* @param string $outputFilename
* @param string $rcMimetype
* @return string possible updated $outputFilename, according the mimetype.
*/
private function outputFile($filename, $outputFilename) {
private function targetFilenameExtension($filename, $outputFilename, &$rcMimetype) {
$length = filesize($filename);
$mimetype = mime_content_type($filename);
$rcMimetype = mime_content_type($filename);
// In case there is a wrong filenameextension on the outputFilename: extend it.
$ext = '.' . substr($mimetype, strrpos($mimetype, '/') + 1);
$ext = '.' . substr($rcMimetype, strrpos($rcMimetype, '/') + 1); // very very dirty way of getting an extension - only valid for a limited set of mimetypes
$len = strlen($ext);
if (substr($outputFilename, 0 - $len) != $ext) {
$outputFilename .= $ext;
}
return $outputFilename;
}
/**
* Set header type and output $filename. Be careful not to send any additional characters.
*
* @param $filename
* @param $outputFilename
*/
private function outputFile($filename, $outputFilename) {
$length = filesize($filename);
// $mimetype = mime_content_type($filename);
$outputFilename = $this->targetFilenameExtension($filename, $outputFilename, $mimetype);
// // In case there is a wrong filenameextension on the outputFilename: extend it.
// $ext = '.' . substr($mimetype, strrpos($mimetype, '/') + 1);
// $len = strlen($ext);
// if (substr($outputFilename, 0 - $len) != $ext) {
// $outputFilename .= $ext;
// }
header("Content-type: $mimetype");
header("Content-Length: $length");
// No idea if 'attachment' has disadvantages.
......@@ -208,8 +233,17 @@ class Download {
throw new DownloadException("Error creating/opening new empty zip file: $zipFile", ERROR_IO_OPEN);
}
$len = strlen(DOWNLOAD_FILE_PREFIX);
$ii = 1;
foreach ($files AS $filename) {
$localname = substr($filename, strrpos($filename, '/'));
$localname = substr($filename, strrpos($filename, '/') + 1);
if (substr($localname, 0, $len) == DOWNLOAD_FILE_PREFIX) {
$localname = 'file-' . $ii;
$ii++;
}
$localname = $this->targetFilenameExtension($filename, $localname, $mimetype);
$zip->addFile($filename, $localname);
}
$zip->close();
......
......@@ -356,6 +356,29 @@ class Link {
return $link;
}
/**
* Order $param
*
* @param array $param
* @return array
*/
private function paramPriority(array $param) {
$prio = array();
$regular = array();
foreach ($param as $value) {
switch (substr($value, 0, 1)) {
case TOKEN_DOWNLOAD:
$prio[] = $value;
break;
default:
$regular[] = $value;
break;
}
}
return array_merge($prio, $regular);
}
/**
* @param string $str
* @param array $tokenGiven
......@@ -371,6 +394,8 @@ class Link {
// str="u:http://www.example.com|c:i|t:Hello World|q:Do you really want to delete the record 25:warn:yes:no"
$param = explode(PARAM_DELIMITER, $str);
$param = $this->paramPriority($param);
// Parse all parameter, fill variables.
foreach ($param as $item) {
......
......@@ -585,9 +585,9 @@ class Report {
case COLUMN_PPAGEI:
case COLUMN_PPAGEN:
case COLUMN_PPAGES:
$pageColumnName = strtolower($columnName);
$lowerColumnName = strtolower($columnName);
$tokenizedValue = $this->doFixColPosPage($columnName, $columnValue);
$linkValue = $this->doPage($pageColumnName, $tokenizedValue);
$linkValue = $this->doPage($lowerColumnName, $tokenizedValue);
$content .= $this->link->renderLink($linkValue);
break;
......@@ -604,14 +604,19 @@ class Report {
$content .= $this->link->renderLink($linkValue);
break;
case COLUMN_DDOWNLOAD:
case COLUMN_PPDF:
case COLUMN_FFILE:
case COLUMN_ZZIP:
$lowerColumnName = strtolower($columnName);
$tokenizedValue = $this->doFixColPosDownload($columnValue);
$linkValue = $this->doDownload($tokenizedValue);
$linkValue = $this->doDownload($lowerColumnName, $tokenizedValue);
$content .= $this->link->renderLink($linkValue);
break;
case COLUMN_DOWNLOAD:
$linkValue = $this->doDownload($columnValue);
case COLUMN_PDF:
case COLUMN_FILE:
case COLUMN_ZIP:
$linkValue = $this->doDownload($columnName, $columnValue);
$content .= $this->link->renderLink($linkValue);
break;
......@@ -882,21 +887,10 @@ class Report {
/**
* Renders Download: convert position content to token content. Respect default values.
* <exportFilename> | <text> | <1: urlparam|file> | <2: urlparam|file> | ... | <n: urlparam|file>
*
* @param string $columnValue
* @param string $columnValue
* @return string rendered link
*
* $columnValue:
* -------------
* <params> | [<text>] | [<tooltip>] | [<class>] | [<target>] | [<render mode>]
*
* param[0]: params
* param[1]: text
* param[2]: tooltip
* param[3]: class
* param[4]: target
* param[5]: render mode
*
* @throws SyntaxReportException
*/
private function doFixColPosDownload($columnValue) {
......@@ -904,36 +898,27 @@ class Report {
$tokenList = '';
if ($columnValue == '') {
throw new SyntaxReportException ("Missing parameter for " . COLUMN_DDOWNLOAD, ERROR_MISSING_REQUIRED_PARAMETER, null, __FILE__, __LINE__, $this->fr_error);
throw new SyntaxReportException ("Missing parameter for " . DOWNLOAD_MODE_PDF . '/' . DOWNLOAD_MODE_FILE .
'/' . DOWNLOAD_MODE_ZIP, ERROR_MISSING_REQUIRED_PARAMETER, null, __FILE__, __LINE__, $this->fr_error);
}
// Split definition
$allParam = explode('|', $columnValue);
if ($columnValue == '') {
throw new SyntaxReportException ("Missing parameter for " . COLUMN_DDOWNLOAD, ERROR_MISSING_REQUIRED_PARAMETER, null, __FILE__, __LINE__, $this->fr_error);
}
$tokenList .= $this->composeLinkPart(TOKEN_URL_PARAM, $allParam[0]);
if (isset($allParam[1]) && $allParam[1] !== '') {
$tokenList .= $this->composeLinkPart(TOKEN_TEXT, $allParam[1]); // -- Text --
}
if (isset($allParam[2]) && $allParam[2] !== '') {
$tokenList .= $this->composeLinkPart(TOKEN_TOOL_TIP, $allParam[2]); // -- tooltip --
}
if (isset($allParam[3]) && $allParam[3] !== '') {
$tokenList .= $this->composeLinkPart(TOKEN_CLASS, $allParam[3]); // -- class --
$value = array_shift($allParam);
if ($value !== null) {
$tokenList .= $this->composeLinkPart(TOKEN_DOWNLOAD, $value); // -- d:<exportFilename> --
}
if (isset($allParam[5]) && $allParam[5] !== '') {
$tokenList .= $this->composeLinkPart(TOKEN_TARGET, $allParam[4]); // -- target --
$value = array_shift($allParam);
if ($value !== null) {
$tokenList .= $this->composeLinkPart(TOKEN_TEXT, $value); // -- t:<text> --
}
if (isset($allParam[6]) && $allParam[6] !== '') {
$tokenList .= $this->composeLinkPart(TOKEN_RENDER, $allParam[5]); // -- render mode --
// Take all remaining parameter as TOKEN_URL_PARAM or TOKEN_FILE
while (null !== ($value = array_shift($allParam))) {
$token = (strpos($value, '=')) ? TOKEN_URL_PARAM : TOKEN_FILE;
$tokenList .= $this->composeLinkPart($token, $value); // -- U:<value> | f:<value> --
}
return ($tokenList);
......@@ -1043,15 +1028,24 @@ class Report {
/**
* Renders _download: extract token and determine if any default value has to be applied
* [d:<exportFilename][U:<params>][u:<url>][f:file][t:<text>][a:<message>]|[o:<tooltip>]|[c:<class>]|[r:<render mode>]
*
* @param string $columnValue
*
* @return string rendered link
* @param string $columnName
* @param string $columnValue
* @return string rendered link
* @throws CodeException
*/
private function doDownload($columnValue) {
private function doDownload($columnName, $columnValue) {
$columNameToMode = [COLUMN_PDF => DOWNLOAD_MODE_PDF, COLUMN_FILE => DOWNLOAD_MODE_FILE, COLUMN_ZIP => DOWNLOAD_MODE_ZIP];
$param = explode('|', $columnValue);
// Depending on the $columnName, get mode.
if (!isset($columNameToMode[$columnName])) {
throw new CodeException("Unexpected columnname: $columnName", ERROR_UNEXPECTED_TYPE);
}
$defaultMode = TOKEN_DOWNLOAD_MODE . ':' . $columNameToMode[$columnName];
# get all default values, depending on the columnname
$defaultSip = TOKEN_SIP;
$defaultDownload = TOKEN_DOWNLOAD;
......@@ -1059,13 +1053,17 @@ class Report {
foreach ($param as $key) {
switch (substr($key, 0, 1)) {
case TOKEN_SIP:
$defaultSip = ''; // if any of the img token is given: no default
$defaultSip = '';
break;
case TOKEN_DOWNLOAD:
$defaultDownload = '';
break;
case TOKEN_DOWNLOAD_MODE:
$defaultMode = '';
break;
default:
break;
}
......@@ -1081,6 +1079,10 @@ class Report {
$columnValue .= $defaultDownload . "|";
}
if ($defaultMode !== '') {
$columnValue .= $defaultMode . "|";
}
return ($columnValue);
}
......
Supports Markdown
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