Commit 1467b137 authored by Carsten  Rose's avatar Carsten Rose
Browse files

CODING.md: small updates in upload part

Support.php, AbstractBuildForm.php: new function falseemptyToZero().
Constants.php: New UPLOAD_MODE_*
Evaluate.php: fixed bug in 'skip' logic of evaluate->parseArray()
Save.php: doUpload() now returns $modeUpload, which are needed in doUploadSlave(), rewrote logic of doUploadSlave(),
parent 2e7b75b6
...@@ -127,25 +127,30 @@ Upload to server, before 'save' ...@@ -127,25 +127,30 @@ Upload to server, before 'save'
* The uploaded file will be checked: maxsize, mime type, check script. * The uploaded file will be checked: maxsize, mime type, check script.
* The uploaded file is still temporary. It has been renamed from '[STORE_EXTRA][<uploadSip>][FILES_TMP_NAME]' to * The uploaded file is still temporary. It has been renamed from '[STORE_EXTRA][<uploadSip>][FILES_TMP_NAME]' to
'[STORE_EXTRA][<uploadSip>][FILES_TMP_NAME].cached'. '[STORE_EXTRA][<uploadSip>][FILES_TMP_NAME].cached'.
* The upload action will be saved in the user session. * The upload action will be saved in the user session:
* [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME|FILES_NAME|FILES_ERROR|FILE_SIZE] [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME]
[STORE_EXTRA][<uploadSip>][FILES_NAME]
[STORE_EXTRA][<uploadSip>][FILES_ERROR]
[STORE_EXTRA][<uploadSip>][FILE_SIZE]
* Clicks the user on delete button: * Clicks the user on delete button:
* In the usersession a flagDelete will be set: [STORE_EXTRA][<uploadSip>]['flagDelete']='1' * In the usersession a flagDelete will be set:
[STORE_EXTRA][<uploadSip>][FILES_FLAG_DELETE]='1'
* An optional previous upload file (still not saved on the final place) will be deleted. * An optional previous upload file (still not saved on the final place) will be deleted.
* An optional existing variable [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME] will be deleted. The 'flagDelete' must not * An optional existing variable [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME] will be deleted. The 'flagDelete' must not
be change - it's later needed to detect to delete earlier uploaded files. be change - it's later needed to detect to delete earlier uploaded files.
Form save Form save
......... .........
* Step 1: insert /update the record. * Step 1: insert / update the record.
* Step 2: process all 'uploads'. * Step 2: process all 'uploads'.
* Get every uniq uploadSip (=[STORE_CLIENT][[<feName>]) of every upload formElement. Get the corresponding temporary uploaded filename. * Get every uniq uploadSip (=[STORE_CLIENT][<feName>]) of every upload formElement. Get the corresponding temporary uploaded filename.
* If [STORE_EXTRA][<uploadSip>]['flagDelete']='1' is set, delete previous uploaded file. * If [STORE_EXTRA][<uploadSip>][FILES_FLAG_DELETE]='1' is set, delete previous uploaded file.
* Calculate <destination> * If [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME]!='': indicates that there is an upload.
* mv <file>.cached <destination> * Calculate <fileDestination>
* clientvalue[<feName>] = <destination> * mv <file>.cached <fileDestination>
* clientvalue[<feName>] = <fileDestination>
* delete [STORE_EXTRA][<uploadSip>] * delete [STORE_EXTRA][<uploadSip>]
* Step 3: update record with final `FileDestination' * Step 3: update record with final <fileDestination>
Formelement type: DATE / DATETIME / TIME Formelement type: DATE / DATETIME / TIME
---------------------------------------- ----------------------------------------
......
...@@ -373,10 +373,8 @@ abstract class AbstractBuildForm { ...@@ -373,10 +373,8 @@ abstract class AbstractBuildForm {
// for Upload FormElements, it's necessary to precalculate an optional given 'slaveId'. // for Upload FormElements, it's necessary to precalculate an optional given 'slaveId'.
if ($fe[FE_TYPE] === FE_TYPE_UPLOAD) { if ($fe[FE_TYPE] === FE_TYPE_UPLOAD) {
$slaveId = $this->evaluate->parse($fe[FE_SLAVE_ID]); $slaveId = Support::falseEmptyToZero($this->evaluate->parse($fe[FE_SLAVE_ID]));
if (is_numeric($slaveId)) { $this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR);
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR);
}
} }
// evaluate current FormElement // evaluate current FormElement
......
...@@ -580,6 +580,12 @@ const QUERY_TYPE_CONTROL = 'type: set'; ...@@ -580,6 +580,12 @@ const QUERY_TYPE_CONTROL = 'type: set';
const FORMAT_DATE_INTERNATIONAL = 'yyyy-mm-dd'; const FORMAT_DATE_INTERNATIONAL = 'yyyy-mm-dd';
const FORMAT_DATE_GERMAN = 'dd.mm.yyyy'; const FORMAT_DATE_GERMAN = 'dd.mm.yyyy';
// Upload
const UPLOAD_MODE_UNCHANGED = 'unchanged';
const UPLOAD_MODE_NEW = 'new';
const UPLOAD_MODE_DELETEOLD = 'deleteOld';
const UPLOAD_MODE_DELETEOLD_NEW = 'deleteOld+new';
// $_FILES // $_FILES
const FILES_NAME = 'name'; const FILES_NAME = 'name';
const FILES_TMP_NAME = 'tmp_name'; const FILES_TMP_NAME = 'tmp_name';
......
...@@ -60,6 +60,7 @@ class Evaluate { ...@@ -60,6 +60,7 @@ class Evaluate {
foreach ($tokenArray as $key => $value) { foreach ($tokenArray as $key => $value) {
if (array_search($key, $skip) !== false) { if (array_search($key, $skip) !== false) {
$arr[$key] = $value;
continue; continue;
} }
......
...@@ -111,6 +111,7 @@ class File { ...@@ -111,6 +111,7 @@ class File {
} }
$statusUpload[FILES_TMP_NAME] = ''; $statusUpload[FILES_TMP_NAME] = '';
} }
$statusUpload[FILES_FLAG_DELETE] = '1'; $statusUpload[FILES_FLAG_DELETE] = '1';
$this->store->setVar($sipUpload, $statusUpload, STORE_EXTRA); $this->store->setVar($sipUpload, $statusUpload, STORE_EXTRA);
} }
......
...@@ -188,8 +188,9 @@ class Save { ...@@ -188,8 +188,9 @@ class Save {
if (count($values) === 0) if (count($values) === 0)
return 0; // nothing to write, 0 rows affected return 0; // nothing to write, 0 rows affected
if ($recordId === 0) if ($recordId === 0) {
throw new CodeException('RecordId=0 - this is not possible for update.', ERROR_RECORDID_0_FORBIDDEN); throw new CodeException('RecordId=0 - this is not possible for update.', ERROR_RECORDID_0_FORBIDDEN);
}
// $paramList = str_repeat('?, ', count($values)); // $paramList = str_repeat('?, ', count($values));
// $paramList = substr($paramList, 0, strlen($paramList) - 2); // $paramList = substr($paramList, 0, strlen($paramList) - 2);
...@@ -233,7 +234,7 @@ class Save { ...@@ -233,7 +234,7 @@ class Save {
$this->store->setVar(SYSTEM_FORM_ELEMENT, Logger::formatFormElementName($formElement), STORE_SYSTEM); $this->store->setVar(SYSTEM_FORM_ELEMENT, Logger::formatFormElementName($formElement), STORE_SYSTEM);
$column = $formElement['name']; $column = $formElement['name'];
$pathFileName = $this->doUpload($formElement, $formValues[$column], $sip); $pathFileName = $this->doUpload($formElement, $formValues[$column], $sip, $modeUpload);
// Upload Type: Simple or Advanced // Upload Type: Simple or Advanced
if (isset($primaryRecord[$column])) { if (isset($primaryRecord[$column])) {
...@@ -243,7 +244,7 @@ class Save { ...@@ -243,7 +244,7 @@ class Save {
} }
} else { } else {
// 'Advanced Upload' // 'Advanced Upload'
$this->doUploadSlave($formElement, $recordId, $pathFileName); $this->doUploadSlave($formElement, $modeUpload);
} }
} }
...@@ -261,12 +262,16 @@ class Save { ...@@ -261,12 +262,16 @@ class Save {
* *
* @param array $formElement FormElement 'upload' * @param array $formElement FormElement 'upload'
* @param string $sipUpload SIP * @param string $sipUpload SIP
* @return string|false New pathFilename or false on error * @param Sip $sip
* @param string $modeUpload UPLOAD_MODE_UNCHANGED | UPLOAD_MODE_NEW | UPLOAD_MODE_DELETEOLD | UPLOAD_MODE_DELETEOLD_NEW
* @return false|string New pathFilename or false on error
* @throws CodeException * @throws CodeException
* @throws UserFormException * @throws UserFormException
* @internal param $recordId * @internal param $recordId
*/ */
private function doUpload($formElement, $sipUpload, Sip $sip) { private function doUpload($formElement, $sipUpload, Sip $sip, &$modeUpload) {
$flagDelete = false;
$modeUpload = UPLOAD_MODE_UNCHANGED;
// Status information about upload file // Status information about upload file
$statusUpload = $this->store->getVar($sipUpload, STORE_EXTRA); $statusUpload = $this->store->getVar($sipUpload, STORE_EXTRA);
...@@ -290,6 +295,14 @@ class Save { ...@@ -290,6 +295,14 @@ class Save {
throw new UserFormException('Unlink file failed: ' . $oldFile, ERROR_IO_UNLINK); throw new UserFormException('Unlink file failed: ' . $oldFile, ERROR_IO_UNLINK);
} }
} }
$flagDelete = ($oldFile != '');
}
// Set $modeUpload
if (isset($statusUpload[FILES_TMP_NAME]) && $statusUpload[FILES_TMP_NAME] != '') {
$modeUpload = $flagDelete ? UPLOAD_MODE_DELETEOLD_NEW : UPLOAD_MODE_NEW;
} else {
$modeUpload = $flagDelete ? UPLOAD_MODE_DELETEOLD : UPLOAD_MODE_UNCHANGED;
} }
$pathFileName = $this->copyUploadFile($formElement, $statusUpload); $pathFileName = $this->copyUploadFile($formElement, $statusUpload);
...@@ -300,7 +313,6 @@ class Save { ...@@ -300,7 +313,6 @@ class Save {
$this->store->setVar($sipUpload, array(), STORE_EXTRA); $this->store->setVar($sipUpload, array(), STORE_EXTRA);
return $pathFileName; return $pathFileName;
} }
/** /**
...@@ -359,44 +371,56 @@ class Save { ...@@ -359,44 +371,56 @@ class Save {
} }
/** /**
* Create the slave record. First try to evaluate a slaveId. Depending if the slaveId > 0 choose `sqlUpdate` or `sqlInsert` * Create/update or delete the slave record.
* *
* @param array $fe * @param array $fe
* @param bool $flagNewUpload
* @return int * @return int
* @throws CodeException * @throws CodeException
* @throws UserFormException * @throws UserFormException
*/ */
private function doUploadSlave(array $fe, $recordId, $pathFileName) { private function doUploadSlave(array $fe, $modeUpload) {
$sql = ''; $sql = '';
$flagUpdateSlaveId = false; $flagUpdateSlaveId = false;
$flagSlaveDeleted = false;
// Get the slaveId // Get the slaveId
$slaveId = $this->evaluate->parse($fe[FE_SLAVE_ID]); $slaveId = Support::falseEmptyToZero($this->evaluate->parse($fe[FE_SLAVE_ID]));
if ($slaveId === '' || $slaveId === false) {
$slaveId = 0;
}
// Store the slaveId: it's used and replaced in the update statement. // Store the slaveId: it's used and replaced in the update statement.
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR, true); $this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR, true);
// If given: fire a sqlAfter query $mode = ($slaveId == '0') ? 'I' : 'U'; // I=Insert, U=Update
$this->evaluate->parse($fe[FE_SQL_BEFORE]); $mode .= ($modeUpload == UPLOAD_MODE_NEW || $modeUpload == UPLOAD_MODE_DELETEOLD_NEW) ? 'N' : ''; // N=New File, '' if no new file.
$mode .= ($modeUpload == UPLOAD_MODE_DELETEOLD) ? 'D' : ''; // Delete slave record only if there is no new and not 'unchanged'.
if ($slaveId == 0 && $pathFileName != '') { switch ($mode) {
$sql = $fe[FE_SQL_INSERT]; case 'IN':
$flagUpdateSlaveId = true; $sql = $fe[FE_SQL_INSERT];
} $flagUpdateSlaveId = true;
break;
if ($slaveId > 0 && $pathFileName != '') { case 'UN':
$sql = $fe[FE_SQL_UPDATE]; $sql = $fe[FE_SQL_UPDATE];
break;
case 'I':
case 'U':
$sql = ''; // no old file and no new file.
break;
case 'UD':
$sql = $fe[FE_SQL_DELETE];
$flagSlaveDeleted = true;
break;
default:
throw new CodeException('Unknown mode: ' . $mode, ERROR_UNKNOWN_MODE);
} }
if ($slaveId > 0 && $pathFileName == '') { // If given: fire a sqlBefore query
$sql = $fe[FE_SQL_DELETE]; $this->evaluate->parse($fe[FE_SQL_BEFORE]);
}
$rc = $this->evaluate->parse($sql); $rc = $this->evaluate->parse($sql);
// Check if the slave record has been deleted: if yes, set slaveId=0
if ($flagSlaveDeleted && $rc > 0) {
$rc = 0;
$flagUpdateSlaveId = true;
}
if ($flagUpdateSlaveId) { if ($flagUpdateSlaveId) {
// Store the slaveId: it's used and replaced in the update statement. // Store the slaveId: it's used and replaced in the update statement.
......
...@@ -644,4 +644,12 @@ class Support { ...@@ -644,4 +644,12 @@ class Support {
$path .= "/"; $path .= "/";
} }
} }
/**
* @param $val
* @return string
*/
public static function falseEmptyToZero($val) {
return ($val == '' || $val == false) ? '0' : $val;
}
} }
\ No newline at end of file
...@@ -107,16 +107,32 @@ class EvaluateTest extends \AbstractDatabaseTest { ...@@ -107,16 +107,32 @@ class EvaluateTest extends \AbstractDatabaseTest {
$data = [ $data = [
'formName' => 'MyTestForm', 'formName' => 'MyTestForm',
'title' => 'Person: {{SELECT firstname, " ", name FROM Person LIMIT 1}} / Employee' 'title' => 'Person: {{SELECT firstname, " ", name FROM Person LIMIT 1}} / Employee',
'key1' => 'Hello',
'key2' => 'World'
]; ];
$expected = [ $expected = [
'formName' => 'MyTestForm', 'formName' => 'MyTestForm',
'title' => 'Person: John Doe / Employee' 'title' => 'Person: John Doe / Employee',
'key1' => 'Hello',
'key2' => 'World'
]; ];
$this->assertEquals($expected, $eval->parseArray($data)); $this->assertEquals($expected, $eval->parseArray($data));
$expected2 = $expected;
$expected2['title'] = $data['title'];
$this->assertEquals($expected2, $eval->parseArray($data, [ 'formName', 'title' ]));
$expected2 = $expected;
$data['formName'] = "SELECT FROM unknown garbage with missing parameter";
$expected2['formName'] = $data['formName'];
$expected2['title'] = $data['title'];
$this->assertEquals($expected2, $eval->parseArray($data, [ 'formName', 'title' ]));
} }
public function testParseArrayOfArray() { public function testParseArrayOfArray() {
$eval = new \qfq\Evaluate($this->store, $this->db); $eval = new \qfq\Evaluate($this->store, $this->db);
$data = [ $data = [
......
...@@ -53,7 +53,10 @@ class HelperFormElementTest extends \PHPUnit_Framework_TestCase { ...@@ -53,7 +53,10 @@ class HelperFormElementTest extends \PHPUnit_Framework_TestCase {
} }
public function testduplicateRetypeElements() { /**
*
*/
public function testDuplicateRetypeElements() {
$a = [0 => [FE_NAME => 'hello', FE_LABEL => 'my label', FE_NOTE => 'my note']]; $a = [0 => [FE_NAME => 'hello', FE_LABEL => 'my label', FE_NOTE => 'my note']];
$b = HelperFormElement::duplicateRetypeElements($a); $b = HelperFormElement::duplicateRetypeElements($a);
...@@ -92,5 +95,69 @@ class HelperFormElementTest extends \PHPUnit_Framework_TestCase { ...@@ -92,5 +95,69 @@ class HelperFormElementTest extends \PHPUnit_Framework_TestCase {
} }
/**
*
*/
public function testInitActionFormElement() {
$list = [FE_TYPE, FE_SLAVE_ID, FE_SQL_VALIDATE, FE_SQL_BEFORE, FE_SQL_INSERT, FE_SQL_UPDATE, FE_SQL_DELETE,
FE_SQL_AFTER, FE_EXPECT_RECORDS, FE_REQUIRED_LIST, FE_MESSAGE_FAIL, FE_SENDMAIL_TO, FE_SENDMAIL_CC,
FE_SENDMAIL_BCC, FE_SENDMAIL_FROM, FE_SENDMAIL_SUBJECT, FE_SENDMAIL_REPLY_TO, FE_SENDMAIL_FLAG_AUTO_SUBMIT,
FE_SENDMAIL_GR_ID, FE_SENDMAIL_X_ID];
$expect = array();
foreach($list as $key) {
$expect[$key] = '';
}
// Complete empty
$result = HelperFormElement::initActionFormElement(array());
$this->assertEquals($expect, $result, "Both arrays should be equal");
// Two known elements
$fe = array();
$fe[FE_TYPE] = FE_TYPE_AFTER_DELETE;
$fe[FE_SENDMAIL_TO] = 'info@example.com';
$expect[FE_TYPE] = $fe[FE_TYPE];
$expect[FE_SENDMAIL_TO] = $fe[FE_SENDMAIL_TO];
$result = HelperFormElement::initActionFormElement($fe);
$this->assertEquals($expect, $result, "Both arrays should be equal");
$fe['unknown'] = 'unknown';
$expect['unknown'] = 'unknown';
$result = HelperFormElement::initActionFormElement($fe);
$this->assertEquals($expect, $result, "Both arrays should be equal");
}
/**
*
*/
public function testInitUploadFormElement() {
$list = [ FE_SQL_BEFORE, FE_SQL_INSERT, FE_SQL_UPDATE, FE_SQL_DELETE, FE_SQL_AFTER ];
$expect = array();
foreach($list as $key) {
$expect[$key] = '';
}
// Complete empty
$result = HelperFormElement::initUploadFormElement(array());
$this->assertEquals($expect, $result, "Both arrays should be equal");
// Two known elements
$fe = array();
$fe[FE_SQL_BEFORE] = 'SELECT willi';
$fe[FE_SQL_AFTER] = 'UPDATE jane';
$expect[FE_SQL_BEFORE] = $fe[FE_SQL_BEFORE];
$expect[FE_SQL_AFTER] = $fe[FE_SQL_AFTER];
$result = HelperFormElement::initUploadFormElement($fe);
$this->assertEquals($expect, $result, "Both arrays should be equal");
$fe['unknown'] = 'unknown';
$expect['unknown'] = 'unknown';
$result = HelperFormElement::initUploadFormElement($fe);
$this->assertEquals($expect, $result, "Both arrays should be equal");
}
} }
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