Skip to content
GitLab
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
5c7c1e2d
Commit
5c7c1e2d
authored
Feb 20, 2019
by
Carsten Rose
Browse files
REST: first successful POST
parent
446e7e7f
Pipeline
#1547
passed with stage
in 2 minutes and 25 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
extension/Source/api/rest.php
View file @
5c7c1e2d
...
...
@@ -15,40 +15,40 @@ require_once(__DIR__ . '/../core/exceptions/UserFormException.php');
require_once
(
__DIR__
.
'/../core/exceptions/CodeException.php'
);
require_once
(
__DIR__
.
'/../core/exceptions/DbException.php'
);
$restId
=
array
();
$restForm
=
array
();
$restId
=
array
();
$restForm
=
array
();
$status
=
'HTTP/1.0 409 Bad Request'
;
$status
=
'HTTP/1.0 409 Bad Request'
;
try
{
try
{
$form
=
OnString
::
splitPathInfoToIdForm
(
$_SERVER
[
'PATH_INFO'
],
$restId
,
$restForm
);
// get latest `ìd`
$id
=
end
(
$restId
);
$id
=
end
(
$restId
);
// Fake Bodytext setup
$bodytext
=
TYPO3_RECORD_ID
.
'='
.
$id
.
PHP_EOL
;
$bodytext
.
=
TYPO3_FORM
.
'='
.
$form
.
PHP_EOL
;
$method
=
$_SERVER
[
'REQUEST_METHOD'
];
switch
(
$method
){
$method
=
$_SERVER
[
'REQUEST_METHOD'
];
switch
(
$method
)
{
case
REQUEST_METHOD_GET
:
break
;
case
REQUEST_METHOD_POST
:
if
(
$id
!=
0
){
if
(
$id
!=
0
)
{
throw
new
UserFormException
(
'Method POST needs no id or id=0'
,
ERROR_REST_INVALID_ID
);
}
$_POST
=
json_decode
(
file_get_contents
(
'php://input'
),
true
);
$_POST
=
json_decode
(
file_get_contents
(
'php://input'
),
true
);
break
;
case
REQUEST_METHOD_PUT
:
if
(
$id
==
0
){
if
(
$id
==
0
)
{
throw
new
UserFormException
(
'Method PUT needs an id>0'
,
ERROR_REST_INVALID_ID
);
}
$_POST
=
json_decode
(
file_get_contents
(
'php://input'
),
true
);
break
;
case
REQUEST_METHOD_DELETE
:
if
(
$id
==
0
){
if
(
$id
==
0
)
{
throw
new
UserFormException
(
'Method DELETE needs an id>0'
,
ERROR_REST_INVALID_ID
);
}
break
;
...
...
@@ -58,7 +58,7 @@ try {
$qfq
=
new
QuickFormQuery
([
'bodytext'
=>
$bodytext
]);
$answer
=
$qfq
->
rest
(
$restId
,
$restForm
);
$status
=
'HTTP/1.0 200 OK'
;
$status
=
'HTTP/1.0 200 OK'
;
}
catch
(
qfq\CodeException
$e
)
{
$answer
[
API_MESSAGE
]
=
$e
->
formatMessage
();
...
...
extension/Source/core/QuickFormQuery.php
View file @
5c7c1e2d
...
...
@@ -344,9 +344,13 @@ class QuickFormQuery {
$flagApiStructureReGroup
=
true
;
// Fill STORE_FORM
if
(
$formMode
===
FORM_UPDATE
||
$formMode
===
FORM_SAVE
)
{
$fillStoreForm
=
new
FillStoreForm
();
$fillStoreForm
->
process
(
$formMode
);
switch
(
$formMode
)
{
case
FORM_UPDATE
:
case
FORM_SAVE
:
case
FORM_REST
:
$fillStoreForm
=
new
FillStoreForm
();
$fillStoreForm
->
process
(
$formMode
);
break
;
}
$recordId
=
$this
->
store
->
getVar
(
SIP_RECORD_ID
,
STORE_SIP
.
STORE_TYPO3
.
STORE_CLIENT
.
STORE_ZERO
);
...
...
@@ -372,8 +376,9 @@ class QuickFormQuery {
Session
::
checkSessionExpired
(
$this
->
formSpec
[
F_SESSION_TIMEOUT_SECONDS
]);
if
(
$formName
!==
false
)
{
// Validate only if there is a 'real' form (not a FORM_DELETE with only a tablename).
$sipFound
=
$this
->
validateForm
(
$foundInStore
,
$formMode
);
// Validate (only if there is a 'real' form, not a FORM_DELETE with only a tablename).
// Attention: $formModeNew will be set
$sipFound
=
$this
->
validateForm
(
$foundInStore
,
$formMode
,
$formModeNew
);
}
else
{
// FORM_DELETE without a form definition: Fake the form with only a tableName.
...
...
@@ -414,10 +419,10 @@ class QuickFormQuery {
}
// Check (and release) dirtyRecord.
if
(
$formMode
===
FORM_DELETE
||
$formMode
===
FORM_SAVE
)
{
if
(
$formMode
New
===
FORM_DELETE
||
$formMode
New
===
FORM_SAVE
)
{
$dirty
=
new
Dirty
(
false
,
$this
->
dbIndexData
,
$this
->
dbIndexQfq
);
$answer
=
$dirty
->
checkDirtyAndRelease
(
$formMode
,
$this
->
formSpec
[
F_RECORD_LOCK_TIMEOUT_SECONDS
],
$answer
=
$dirty
->
checkDirtyAndRelease
(
$formMode
New
,
$this
->
formSpec
[
F_RECORD_LOCK_TIMEOUT_SECONDS
],
$this
->
formSpec
[
F_DIRTY_MODE
],
$this
->
formSpec
[
F_TABLE_NAME
],
$this
->
formSpec
[
F_PRIMARY_KEY
],
$recordId
,
true
);
// In case of a conflict, return immediately
...
...
@@ -429,7 +434,7 @@ class QuickFormQuery {
}
// FORM_LOAD: if there is a foreign exclusive record lock - show form in F_MODE_READONLY mode.
if
(
$formMode
===
FORM_LOAD
)
{
if
(
$formMode
New
===
FORM_LOAD
)
{
$dirty
=
new
Dirty
(
false
,
$this
->
dbIndexData
,
$this
->
dbIndexQfq
);
$recordDirty
=
array
();
$rcLockFound
=
$dirty
->
getCheckDirty
(
$this
->
formSpec
[
F_TABLE_NAME
],
$recordId
,
$recordDirty
,
$msg
);
...
...
@@ -438,7 +443,7 @@ class QuickFormQuery {
}
}
switch
(
$formMode
)
{
switch
(
$formMode
New
)
{
case
FORM_DELETE
:
$build
=
new
Delete
(
$this
->
dbIndexData
);
break
;
...
...
@@ -471,10 +476,10 @@ class QuickFormQuery {
}
$formAction
=
new
FormAction
(
$this
->
formSpec
,
$this
->
dbArray
[
$this
->
dbIndexData
],
$this
->
phpUnit
);
switch
(
$formMode
)
{
switch
(
$formMode
New
)
{
case
FORM_LOAD
:
$formAction
->
elements
(
$recordId
,
$this
->
feSpecAction
,
FE_TYPE_BEFORE_LOAD
);
$data
=
$build
->
process
(
$formMode
);
$data
=
$build
->
process
(
$formMode
New
);
$tmpClass
=
is_numeric
(
$this
->
formSpec
[
F_BS_COLUMNS
])
?
(
'col-md-'
.
$this
->
formSpec
[
F_BS_COLUMNS
])
:
$this
->
formSpec
[
F_BS_COLUMNS
];
// $data = Support::wrapTag("<div class='" . 'col-md-' . $this->formSpec[F_BS_COLUMNS] . "'>", $data);
$data
=
Support
::
wrapTag
(
'<div class="'
.
$tmpClass
.
'">'
,
$data
);
...
...
@@ -485,7 +490,7 @@ class QuickFormQuery {
case
FORM_UPDATE
:
$formAction
->
elements
(
$recordId
,
$this
->
feSpecAction
,
FE_TYPE_BEFORE_LOAD
);
// data['form-update']=....
$data
=
$build
->
process
(
$formMode
);
$data
=
$build
->
process
(
$formMode
New
);
$formAction
->
elements
(
$recordId
,
$this
->
feSpecAction
,
FE_TYPE_AFTER_LOAD
);
break
;
...
...
@@ -500,7 +505,7 @@ class QuickFormQuery {
case
FORM_SAVE
:
$this
->
logFormSubmitRequest
();
$recordId
=
$this
->
store
->
getVar
(
SIP_RECORD_ID
,
STORE_SIP
);
$recordId
=
$this
->
store
->
getVar
(
SIP_RECORD_ID
,
STORE_SIP
.
STORE_TYPO3
);
// Action: Before
$feTypeList
=
FE_TYPE_BEFORE_SAVE
.
','
.
(
$recordId
==
0
?
FE_TYPE_BEFORE_INSERT
:
FE_TYPE_BEFORE_UPDATE
);
...
...
@@ -539,6 +544,11 @@ class QuickFormQuery {
// Action: Sendmail
$formAction
->
elements
(
$rc
,
$this
->
feSpecAction
,
FE_TYPE_SENDMAIL
);
if
(
$formMode
==
FORM_REST
)
{
$data
=
[
'id'
=>
$rc
];
$flagApiStructureReGroup
=
false
;
break
;
}
$customForward
=
$this
->
setForwardModePage
();
...
...
@@ -563,10 +573,7 @@ class QuickFormQuery {
$feSpecNative
=
HelperFormElement
::
setLanguage
(
$feSpecNative
,
$parameterLanguageFieldName
);
$this
->
feSpecNative
=
HelperFormElement
::
setFeContainerFormElementId
(
$feSpecNative
,
$this
->
formSpec
[
F_ID
],
$recordId
);
// Retrieve FE Values as JSON
// $data['form-update']=...
// $data = $build->process($formMode, $htmlElementNameIdZero);
$data
=
$build
->
process
(
$formMode
,
false
,
$this
->
feSpecNative
);
$data
=
$build
->
process
(
$formModeNew
,
false
,
$this
->
feSpecNative
);
}
break
;
...
...
@@ -581,15 +588,15 @@ class QuickFormQuery {
break
;
case
FORM_REST
:
$flagApiStructureReGroup
=
false
;
$data
=
$this
->
doRestGet
();
$flagApiStructureReGroup
=
false
;
break
;
default
:
throw
new
CodeException
(
"This statement should never be reached"
,
ERROR_CODE_SHOULD_NOT_HAPPEN
);
}
if
(
$flagApiStructureReGroup
&&
is_array
(
$data
))
{
if
(
$flagApiStructureReGroup
&&
is_array
(
$data
)
)
{
// $data['element-update']=...
$data
=
$this
->
groupElementUpdateEntries
(
$data
);
}
...
...
@@ -1091,6 +1098,7 @@ class QuickFormQuery {
case
FORM_SAVE
:
case
FORM_UPDATE
:
case
FORM_REST
:
$feSpecNative
=
$this
->
getNativeFormElements
(
SQL_FORM_ELEMENT_NATIVE_TG_COUNT
,
[
$this
->
formSpec
[
F_ID
]],
$this
->
formSpec
);
break
;
...
...
@@ -1419,12 +1427,14 @@ class QuickFormQuery {
* @throws \qfq\UserFormException
* @internal param $foundInStore
*/
private
function
validateForm
(
$formNameFoundInStore
,
$formMode
)
{
private
function
validateForm
(
$formNameFoundInStore
,
$formMode
,
&
$formModeNew
)
{
$formModeNew
=
$formMode
;
// Retrieve record_id either from SIP (preferred) or via URL
$r
=
$this
->
store
->
getVar
(
SIP_RECORD_ID
,
STORE_SIP
.
STORE_TYPO3
.
STORE_CLIENT
,
''
,
$recordIdFoundInStore
);
//
n
o record id: Fake a definition in STORE_TYPO3.
//
N
o record id: Fake a definition in STORE_TYPO3.
if
(
$r
===
false
)
{
$r
=
0
;
$this
->
store
->
setVar
(
TYPO3_RECORD_ID
,
$r
,
STORE_TYPO3
);
...
...
@@ -1465,23 +1475,32 @@ class QuickFormQuery {
case
FORM_PERMISSION_NEVER
:
throw
new
UserFormException
(
"Loading form forbidden."
,
ERROR_FORM_FORBIDDEN
);
break
;
// case FORM_PERMISSION_REST:
// if ($formMode != FORM_REST) {
// throw new UserFormException("Try to load a REST form", ERROR_FORM_REST);
// }
// break;
default
:
throw
new
CodeException
(
"Unknown permission mode: '"
.
$permitMode
.
"'"
,
ERROR_FORM_UNKNOWN_PERMISSION_MODE
);
}
if
(
$formMode
==
FORM_REST
)
{
$method
=
strtolower
(
$this
->
store
::
getVar
(
CLIENT_REQUEST_METHOD
,
STORE_CLIENT
)
)
;
if
(
false
===
Support
::
findInSet
(
$method
,
$this
->
formSpec
[
F_REST_METHOD
]))
{
throw
new
UserFormException
(
"Form '"
.
$this
->
formSpec
[
F_NAME
]
.
"' is not allowed with method '
$method
'"
,
ERROR_FORM_REST
);
$method
=
$this
->
store
::
getVar
(
CLIENT_REQUEST_METHOD
,
STORE_CLIENT
);
if
(
false
===
Support
::
findInSet
(
strtolower
(
$method
)
,
$this
->
formSpec
[
F_REST_METHOD
]))
{
throw
new
UserFormException
(
"Form '"
.
$this
->
formSpec
[
F_NAME
]
.
"' is not allowed with method '
$method
'"
,
ERROR_FORM_REST
);
}
$this
->
restCheckAuthToken
(
$this
->
formSpec
[
F_REST_TOKEN
]
??
''
);
switch
(
$method
)
{
case
REQUEST_METHOD_GET
:
break
;
case
REQUEST_METHOD_POST
:
case
REQUEST_METHOD_PUT
:
$formModeNew
=
FORM_SAVE
;
break
;
case
REQUEST_METHOD_DELETE
:
$formModeNew
=
FORM_DELETE
;
break
;
default
:
throw
new
CodeException
(
'Unknown Request Method: '
.
$method
,
ERROR_UNKNOWN_MODE
);
}
}
// Form Definition valid?
...
...
@@ -1898,6 +1917,9 @@ EOF;
$ii
++
;
}
$this
->
store
::
setVar
(
SIP_FORM
,
end
(
$restForm
),
STORE_SIP
);
$this
->
store
::
setVar
(
SIP_RECORD_ID
,
end
(
$restId
),
STORE_SIP
);
return
$this
->
doForm
(
FORM_REST
);
}
...
...
extension/Source/core/Save.php
View file @
5c7c1e2d
...
...
@@ -64,7 +64,7 @@ class Save {
}
/**
* Starts save process.
On succcess, returns forwardmode/page
.
* Starts save process.
Returns recordId
.
*
* @return int
* @throws CodeException
...
...
extension/Source/core/store/FillStoreForm.php
View file @
5c7c1e2d
...
...
@@ -182,11 +182,12 @@ class FillStoreForm {
$formModeGlobal
=
$this
->
store
->
getVar
(
F_MODE_GLOBAL
,
STORE_SIP
.
STORE_EMPTY
);
if
(
$formMode
==
FORM_UPDATE
&&
$formModeGlobal
==
''
)
{
# During 'update': fake all elements to be not 'required'.
$formModeGlobal
=
F_MODE_REQUIRED_OFF
;
}
// If called through 'api/...': get STORE_TYPO3 via SIP parameter.
if
(
isset
(
$clientValues
[
CLIENT_TYPO3VARS
]))
{
if
(
isset
(
$clientValues
[
CLIENT_TYPO3VARS
])
&&
$formMode
!=
FORM_REST
)
{
$this
->
store
->
fillTypo3StoreFromSip
(
$clientValues
[
CLIENT_TYPO3VARS
]);
}
...
...
@@ -209,10 +210,12 @@ class FillStoreForm {
}
}
// Check if there is a 'new record already saved' situation:
// yes: the names of the input fields are submitted with '<fieldname>:0' instead of '<fieldname>:<id>'
// no: regular situation, take real 'recordid'
$fakeRecordId
=
isset
(
$sipValues
[
SIP_MAKE_URLPARAM_UNIQ
])
?
0
:
$sipValues
[
SIP_RECORD_ID
];
if
(
$formMode
!=
FORM_REST
)
{
// Check if there is a 'new record already saved' situation:
// yes: the names of the input fields are submitted with '<fieldname>:0' instead of '<fieldname>:<id>'
// no: regular situation, take real 'recordid'
$fakeRecordId
=
isset
(
$sipValues
[
SIP_MAKE_URLPARAM_UNIQ
])
?
0
:
$sipValues
[
SIP_RECORD_ID
];
}
// Iterate over all FormElements. Sanatize values. Built an assoc array $newValues.
foreach
(
$this
->
feSpecNative
AS
$formElement
)
{
...
...
@@ -229,7 +232,7 @@ class FillStoreForm {
$formElement
=
$this
->
evaluate
->
parseArray
(
$formElement
,
$skip
,
$debugStack
);
// Get related formElement. Construct the field name used in the form.
$clientFieldName
=
HelperFormElement
::
buildFormElementName
(
$formElement
,
$fakeRecordId
);
$clientFieldName
=
(
$formMode
==
FORM_REST
)
?
$formElement
[
FE_NAME
]
:
HelperFormElement
::
buildFormElementName
(
$formElement
,
$fakeRecordId
);
// Some Defaults
$formElement
=
Support
::
setFeDefaults
(
$formElement
,
[
F_MODE
=>
$formModeGlobal
]);
...
...
@@ -309,7 +312,7 @@ class FillStoreForm {
// Check only if there is something.
if
(
$val
!==
''
&&
$formMode
!=
FORM_UPDATE
&&
$formElement
[
FE_MODE
]
!=
FE_MODE_HIDDEN
)
{
$val
=
Sanitize
::
sanitize
(
$val
,
$formElement
[
FE_CHECK_TYPE
],
$formElement
[
FE_CHECK_PATTERN
],
$formElement
[
FE_DECIMAL_FORMAT
],
SANITIZE_EXCEPTION
,
$formElement
[
F_FE_DATA_PATTERN_ERROR
]
??
''
);
$formElement
[
FE_DECIMAL_FORMAT
],
SANITIZE_EXCEPTION
,
$formElement
[
F_FE_DATA_PATTERN_ERROR
]
??
''
);
if
(
$formElement
[
FE_ENCODE
]
===
FE_ENCODE_SPECIALCHAR
)
{
// $val = htmlspecialchars($val, ENT_QUOTES);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment