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'
* 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
'[STORE_EXTRA][<uploadSip>][FILES_TMP_NAME].cached'.
* The upload action will be saved in the user session.
* [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME|FILES_NAME|FILES_ERROR|FILE_SIZE]
* The upload action will be saved in the user session:
[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:
* 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 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.
Form save
.........
* Step 1: insert /update the record.
* Step 1: insert / update the record.
* Step 2: process all 'uploads'.
* 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.
* Calculate <destination>
* mv <file>.cached <destination>
* clientvalue[<feName>] = <destination>
* Get every uniq uploadSip (=[STORE_CLIENT][<feName>]) of every upload formElement. Get the corresponding temporary uploaded filename.
* If [STORE_EXTRA][<uploadSip>][FILES_FLAG_DELETE]='1' is set, delete previous uploaded file.
* If [STORE_EXTRA][<uploadSip>][FILES_TMP_NAME]!='': indicates that there is an upload.
* Calculate <fileDestination>
* mv <file>.cached <fileDestination>
* clientvalue[<feName>] = <fileDestination>
* delete [STORE_EXTRA][<uploadSip>]
* Step 3: update record with final `FileDestination'
* Step 3: update record with final <fileDestination>
Formelement type: DATE / DATETIME / TIME
----------------------------------------
......
......@@ -373,11 +373,9 @@ abstract class AbstractBuildForm {
// for Upload FormElements, it's necessary to precalculate an optional given 'slaveId'.
if ($fe[FE_TYPE] === FE_TYPE_UPLOAD) {
$slaveId = $this->evaluate->parse($fe[FE_SLAVE_ID]);
if (is_numeric($slaveId)) {
$slaveId = Support::falseEmptyToZero($this->evaluate->parse($fe[FE_SLAVE_ID]));
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR);
}
}
// evaluate current FormElement
$formElement = $this->evaluate->parseArray($fe, $skip, $debugStack);
......
......@@ -580,6 +580,12 @@ const QUERY_TYPE_CONTROL = 'type: set';
const FORMAT_DATE_INTERNATIONAL = 'yyyy-mm-dd';
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
const FILES_NAME = 'name';
const FILES_TMP_NAME = 'tmp_name';
......
......@@ -60,6 +60,7 @@ class Evaluate {
foreach ($tokenArray as $key => $value) {
if (array_search($key, $skip) !== false) {
$arr[$key] = $value;
continue;
}
......
......@@ -111,6 +111,7 @@ class File {
}
$statusUpload[FILES_TMP_NAME] = '';
}
$statusUpload[FILES_FLAG_DELETE] = '1';
$this->store->setVar($sipUpload, $statusUpload, STORE_EXTRA);
}
......
......@@ -188,8 +188,9 @@ class Save {
if (count($values) === 0)
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);
}
// $paramList = str_repeat('?, ', count($values));
// $paramList = substr($paramList, 0, strlen($paramList) - 2);
......@@ -233,7 +234,7 @@ class Save {
$this->store->setVar(SYSTEM_FORM_ELEMENT, Logger::formatFormElementName($formElement), STORE_SYSTEM);
$column = $formElement['name'];
$pathFileName = $this->doUpload($formElement, $formValues[$column], $sip);
$pathFileName = $this->doUpload($formElement, $formValues[$column], $sip, $modeUpload);
// Upload Type: Simple or Advanced
if (isset($primaryRecord[$column])) {
......@@ -243,7 +244,7 @@ class Save {
}
} else {
// 'Advanced Upload'
$this->doUploadSlave($formElement, $recordId, $pathFileName);
$this->doUploadSlave($formElement, $modeUpload);
}
}
......@@ -261,12 +262,16 @@ class Save {
*
* @param array $formElement FormElement 'upload'
* @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 UserFormException
* @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
$statusUpload = $this->store->getVar($sipUpload, STORE_EXTRA);
......@@ -290,6 +295,14 @@ class Save {
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);
......@@ -300,7 +313,6 @@ class Save {
$this->store->setVar($sipUpload, array(), STORE_EXTRA);
return $pathFileName;
}
/**
......@@ -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 bool $flagNewUpload
* @return int
* @throws CodeException
* @throws UserFormException
*/
private function doUploadSlave(array $fe, $recordId, $pathFileName) {
private function doUploadSlave(array $fe, $modeUpload) {
$sql = '';
$flagUpdateSlaveId = false;
$flagSlaveDeleted = false;
// Get the slaveId
$slaveId = $this->evaluate->parse($fe[FE_SLAVE_ID]);
if ($slaveId === '' || $slaveId === false) {
$slaveId = 0;
}
$slaveId = Support::falseEmptyToZero($this->evaluate->parse($fe[FE_SLAVE_ID]));
// Store the slaveId: it's used and replaced in the update statement.
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR, true);
// If given: fire a sqlAfter query
$this->evaluate->parse($fe[FE_SQL_BEFORE]);
if ($slaveId == 0 && $pathFileName != '') {
$mode = ($slaveId == '0') ? 'I' : 'U'; // I=Insert, U=Update
$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'.
switch ($mode) {
case 'IN':
$sql = $fe[FE_SQL_INSERT];
$flagUpdateSlaveId = true;
}
if ($slaveId > 0 && $pathFileName != '') {
break;
case 'UN':
$sql = $fe[FE_SQL_UPDATE];
}
if ($slaveId > 0 && $pathFileName == '') {
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 given: fire a sqlBefore query
$this->evaluate->parse($fe[FE_SQL_BEFORE]);
$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) {
// Store the slaveId: it's used and replaced in the update statement.
......
......@@ -644,4 +644,12 @@ class Support {
$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 {
$data = [
'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 = [
'formName' => 'MyTestForm',
'title' => 'Person: John Doe / Employee'
'title' => 'Person: John Doe / Employee',
'key1' => 'Hello',
'key2' => 'World'
];
$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() {
$eval = new \qfq\Evaluate($this->store, $this->db);
$data = [
......
......@@ -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']];
$b = HelperFormElement::duplicateRetypeElements($a);
......@@ -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