Commit 123a701d authored by Carsten  Rose's avatar Carsten Rose
Browse files

DragAndDrop: initial creation of PHP classes.

parent 39f1f986
<?php
/**
* Created by PhpStorm.
* User: ep
* Date: 12/23/15
* Time: 6:17 PM
*/
namespace qfq;
use qfq;
require_once(__DIR__ . '/../qfq/store/Store.php');
require_once(__DIR__ . '/../qfq/Constants.php');
require_once(__DIR__ . '/../qfq/QuickFormQuery.php');
/**
* Return JSON encoded answer
*
* status: success|error
* message: <message>
* redirect: client|url|no
* redirect-url: <url>
* field-name: <field name>
* field-message: <message>
* form-data: [ fieldname1 => value1, fieldname2 => value2, ... ]
* form-control: [ fieldname1 => status1, fieldname2 => status2, ... ] status: show|hide, enabled|disabled,
* readonly|readwrite
*
* Description:
*
* Save successful. Button 'close', 'new'. Form.forward: 'auto'. Client logic decide to redirect or not. Show message
* if no redirect. status = 'success' message = <message> redirect = 'client'
*
* Save successful. Button 'close': Form.forward: 'page'. Client redirect to url.
* status = 'success'
* message = <message>
* redirect = 'url'
* redirect-url = <URL>
*
* Save failed: Button: any. Show message and set 'alert' on _optional_ specified form element. Bring 'pill' of
* specified form element to front. status = 'error' message = <message> redirect = 'no' Optional: field-name = <field
* name> field-message = <message appearing as tooltip (or similar) near the form element>
*/
$answer = array();
$answer[API_REDIRECT] = API_ANSWER_REDIRECT_NO;
$answer[API_STATUS] = API_ANSWER_STATUS_ERROR;
$answer[API_MESSAGE] = '';
try {
$qfq = new QuickFormQuery(['bodytext' => '']);
$data = $qfq->dragAndDrop();
// $answer[API_REDIRECT] = $qfq->getForwardMode($answer[API_REDIRECT_URL]);
$answer[API_STATUS] = API_ANSWER_STATUS_SUCCESS;
$answer[API_MESSAGE] = 'load: success';
$answer[API_FORM_UPDATE] = $data[API_FORM_UPDATE];
$answer[API_ELEMENT_UPDATE] = $data[API_ELEMENT_UPDATE];
// unset($answer[API_FORM_UPDATE][API_ELEMENT_UPDATE]);
} catch (qfq\UserFormException $e) {
$answer[API_MESSAGE] = $e->formatMessage();
$val = Store::getVar(SYSTEM_FORM_ELEMENT, STORE_SYSTEM);
if ($val !== false)
$answer[API_FIELD_NAME] = $val;
$val = Store::getVar(SYSTEM_FORM_ELEMENT_MESSAGE, STORE_SYSTEM);
if ($val !== false)
$answer[API_FIELD_MESSAGE] = $val;
} catch (qfq\CodeException $e) {
$answer[API_MESSAGE] = $e->formatMessage();
} catch (qfq\DbException $e) {
$answer[API_MESSAGE] = $e->formatMessage();
} catch (\Exception $e) {
$answer[API_MESSAGE] = "Generic Exception: " . $e->getMessage();
}
header("Content-Type: application/json");
echo json_encode($answer);
......@@ -33,6 +33,7 @@ const FORM_LOAD = 'form_load';
const FORM_SAVE = 'form_save';
const FORM_UPDATE = 'form_update';
const FORM_DELETE = 'form_delete';
const FORM_DRAG_AND_DROP = 'form_drag_and_drop';
const FORM_PERMISSION_SIP = 'sip';
const FORM_PERMISSION_LOGGED_IN = 'logged_id';
const FORM_PERMISSION_LOGGED_OUT = 'logged_out';
......@@ -143,7 +144,7 @@ const ERROR_DEBUG = 1031;
const ERROR_UNKNOWN_MODE = 1032;
const ERROR_NOT_IMPLEMENTED = 1033;
const ERROR_RESERVED_KEY_NAME = 1034;
const ERROR_MISSING_FORM = 1035;
const ERROR_UNKNOWN_FORWARD_MODE = 1036;
const ERROR_MISSING_HIDDEN_FIELD_IN_SIP = 1038;
......@@ -851,6 +852,8 @@ const F_NEW_BUTTON_GLYPH_ICON = SYSTEM_NEW_BUTTON_GLYPH_ICON;
const F_ENTER_AS_SUBMIT = SYSTEM_ENTER_AS_SUBMIT;
const F_DRAG_AND_DROP_ORDER_SQL = 'dragAndDropOrderSql';
// FORM_ELEMENT_STATI
const FE_MODE_SHOW = 'show';
const FE_MODE_READONLY = 'readonly';
......
......@@ -32,6 +32,7 @@ class Delete {
* @param bool $dbIndexData
* @param bool $phpUnit
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
public function __construct($dbIndexData = false, $phpUnit = false) {
......
......@@ -61,7 +61,8 @@ require_once(__DIR__ . '/form/Dirty.php');
* Class Qfq
* @package qfq
*/
class QuickFormQuery {
class QuickFormQuery
{
/**
* @var \qfq\Store instantiated class
......@@ -126,7 +127,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function __construct(array $t3data = array(), $phpUnit = false) {
public function __construct(array $t3data = array(), $phpUnit = false)
{
$this->phpUnit = $phpUnit;
......@@ -195,7 +197,8 @@ class QuickFormQuery {
* @throws CodeException
* @throws UserFormException
*/
public function getForwardMode() {
public function getForwardMode()
{
$forwardPage = $this->formSpec[F_FORWARD_PAGE];
......@@ -222,7 +225,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function process() {
public function process()
{
$html = '';
if ($this->store->getVar(TYPO3_DEBUG_SHOW_BODY_TEXT, STORE_TYPO3) === 'yes') {
......@@ -249,7 +253,8 @@ class QuickFormQuery {
/**
* Determine the name of the language parameter field, which has to be taken to fill language specific defintions.
*/
private function setParameterLanguageFieldName() {
private function setParameterLanguageFieldName()
{
$typo3PageLanguage = $this->store->getVar(TYPO3_PAGE_LANGUAGE, STORE_TYPO3);
if (empty($typo3PageLanguage)) {
......@@ -265,6 +270,7 @@ class QuickFormQuery {
}
}
/**
* Process form.
* $mode=
......@@ -281,12 +287,13 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
private function doForm($formMode) {
private function doForm($formMode)
{
$data = '';
$foundInStore = '';
// Fill STORE_FORM
if ($formMode === FORM_UPDATE || $formMode === FORM_SAVE) {
if ($formMode === FORM_UPDATE || $formMode === FORM_SAVE || $formMode === FORM_DRAG_AND_DROP) {
$fillStoreForm = new FillStoreForm();
$fillStoreForm->process($formMode);
}
......@@ -295,9 +302,15 @@ class QuickFormQuery {
$this->setParameterLanguageFieldName();
$formName = $this->loadFormSpecification($formMode, $recordId, $foundInStore);
if ($formName === false && $formMode !== FORM_DELETE) {
// No form found: do nothing
return '';
if ($formName === false) {
switch ($formName) {
case FORM_DELETE:
break;
case FORM_DRAG_AND_DROP:
throw new CodeException('Missing form in SIP', ERROR_MISSING_FORM);
default:
return '';// No form found: do nothing
}
}
if ($formName !== false) {
......@@ -310,6 +323,7 @@ class QuickFormQuery {
if ($table === false) {
throw new UserFormException("No 'form' and no 'table' definition found.", ERROR_MISSING_VALUE);
}
$sipFound = true;
$this->formSpec[F_NAME] = '';
$this->formSpec[F_TABLE_NAME] = $table;
......@@ -476,6 +490,14 @@ class QuickFormQuery {
}
break;
case FORM_DRAG_AND_DROP:
$formAction->elements($recordId, $this->feSpecAction, FE_TYPE_BEFORE_LOAD);
$draganddrop = new DragAndDrop();
$draganddrop->process($this->formSpec[F_TABLE_NAME], $this->formSpec[F_DRAG_AND_DROP_ORDER_SQL]);
$formAction->elements($recordId, $this->feSpecAction, FE_TYPE_AFTER_LOAD);
break;
default:
throw new CodeException("This statement should never be reached", ERROR_CODE_SHOULD_NOT_HAPPEN);
......@@ -511,7 +533,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
private function setForwardModePage() {
private function setForwardModePage()
{
if ('url' != substr($this->formSpec[F_FORWARD_MODE], 0, 3)) {
return false;
......@@ -569,7 +592,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
private function pasteClipboard($formId, FormAction $formAction) {
private function pasteClipboard($formId, FormAction $formAction)
{
if (!$this->isPasteRecord()) {
return;
......@@ -594,7 +618,8 @@ class QuickFormQuery {
/**
* @return bool true if there is at least one paste record, else false.
*/
private function isPasteRecord() {
private function isPasteRecord()
{
foreach ($this->feSpecAction as $formElement) {
if ($formElement[FE_TYPE] == FE_TYPE_PASTE) {
......@@ -617,7 +642,8 @@ class QuickFormQuery {
* @throws CodeException
* @throws UserFormException
*/
private function buildNSetReloadUrl(array $formSpec, $recordId) {
private function buildNSetReloadUrl(array $formSpec, $recordId)
{
$formSpec[F_FORWARD_MODE] = API_ANSWER_REDIRECT_URL_SKIP_HISTORY;
......@@ -655,7 +681,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
private function loadFormSpecification($mode, $recordId, &$foundInStore = '') {
private function loadFormSpecification($mode, $recordId, &$foundInStore = '')
{
// formName
if (false === ($formName = $this->getFormName($mode, $foundInStore))) {
......@@ -764,7 +791,7 @@ class QuickFormQuery {
case FORM_SAVE:
case FORM_UPDATE:
$feSpecNative = $this->getNativeFormElements(SQL_FORM_ELEMENT_NATIVE_TG_COUNT, [$this->formSpec[F_ID]], $this->formSpec);
$feSpecNative = $this->getNativeFormElements(SQL_FORM_ELEMENT_NATIVE_TG_COUNT, [$this->formSpec[F_ID]], $this->formSpec);
break;
case FORM_DELETE:
......@@ -796,7 +823,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function getNativeFormElements($sql, array $param, $formSpec) {
public function getNativeFormElements($sql, array $param, $formSpec)
{
$feSpecNative = $this->dbArray[$this->dbIndexQfq]->sql($sql, ROW_REGULAR, $param);
......@@ -836,7 +864,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
private function explodeTemplateGroupElements(array $elements) {
private function explodeTemplateGroupElements(array $elements)
{
$new = array();
// No FormElements or no NAME_TG_COPIES column: nothing to do, return.
......@@ -892,7 +921,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function getFormName($mode, &$foundInStore = '') {
public function getFormName($mode, &$foundInStore = '')
{
$dummy = array();
switch ($mode) {
......@@ -930,7 +960,8 @@ class QuickFormQuery {
* @throws CodeException
* @throws UserFormException
*/
private function modeCleanFormConfig($mode, array $form) {
private function modeCleanFormConfig($mode, array $form)
{
switch ($mode) {
case FORM_DELETE:
......@@ -961,7 +992,8 @@ class QuickFormQuery {
* @throws CodeException
* @throws UserFormException
*/
private function syncSystemFormConfig(array $formSpec) {
private function syncSystemFormConfig(array $formSpec)
{
$keys = [F_BS_COLUMNS,
F_BS_LABEL_COLUMNS,
......@@ -1031,7 +1063,8 @@ class QuickFormQuery {
* @throws CodeException
* @throws UserFormException
*/
private function initForm(array $formSpec) {
private function initForm(array $formSpec)
{
Support::setIfNotSet($formSpec, F_EXTRA_DELETE_FORM, '');
Support::setIfNotSet($formSpec, F_SUBMIT_BUTTON_TEXT, '');
......@@ -1072,7 +1105,8 @@ class QuickFormQuery {
* @throws \qfq\UserFormException
* @internal param $foundInStore
*/
private function validateForm($formNameFoundInStore, $formMode) {
private function validateForm($formNameFoundInStore, $formMode)
{
// Retrieve record_id either from SIP (prefered) or via URL
$r = $this->store->getVar(SIP_RECORD_ID, STORE_SIP . STORE_TYPO3 . STORE_CLIENT, '', $recordIdFoundInStore);
......@@ -1167,7 +1201,8 @@ class QuickFormQuery {
* @throws DbException
* @throws UserFormException
*/
private function fillStoreWithRecord($table, $recordId, $store = STORE_RECORD) {
private function fillStoreWithRecord($table, $recordId, $store = STORE_RECORD)
{
if ($recordId !== false && $recordId > 0) {
$record = $this->dbArray[$this->dbIndexData]->sql("SELECT * FROM $table WHERE id = ?", ROW_EXPECT_1, [$recordId]);
$this->store->setStore($record, $store, true);
......@@ -1182,7 +1217,8 @@ class QuickFormQuery {
*
* @return array to build JSON
*/
private function groupElementUpdateEntries(array $dataArray) {
private function groupElementUpdateEntries(array $dataArray)
{
$collect = array();
foreach ($dataArray as $data) {
......@@ -1211,7 +1247,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
private function doReport() {
private function doReport()
{
$report = new Report($this->t3data, $this->eval, $this->phpUnit);
......@@ -1230,7 +1267,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function saveForm() {
public function saveForm()
{
$json = $this->doForm(FORM_SAVE);
......@@ -1246,13 +1284,31 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function updateForm() {
public function updateForm()
{
$json = $this->doForm(FORM_UPDATE);
return $json;
}
/**
* Update FormElements and form values. Receives the current form values via POST.
*
* @return array
* @throws CodeException
* @throws DbException
* @throws UserFormException
* @throws UserReportException
*/
public function dragAndDrop()
{
$json = $this->doForm(FORM_DRAG_AND_DROP);
return $json;
}
/**
* Delete a record (tablename and recordid are given) or process a 'delete form'
*
......@@ -1262,7 +1318,8 @@ class QuickFormQuery {
* @throws UserFormException
* @throws UserReportException
*/
public function delete() {
public function delete()
{
return $this->doForm(FORM_DELETE);
......@@ -1276,7 +1333,8 @@ class QuickFormQuery {
* @throws CodeException
* @throws UserFormException
*/
private function newRecordCreateSip(array $sipArray, $recordId) {
private function newRecordCreateSip(array $sipArray, $recordId)
{
$tmpParam = array();
......@@ -1314,7 +1372,8 @@ class QuickFormQuery {
/**
* @return string
*/
private function getModalCode() {
private function getModalCode()
{
$code = <<<EOF
<!-- Modal -->
......
<?php
/**
* Created by PhpStorm.
* User: crose
* Date: 3/13/17
* Time: 9:29 PM
*/
namespace qfq;
//use TYPO3\CMS\Core\FormProtection\Exception;
require_once(__DIR__ . '/../store/Sip.php');
require_once(__DIR__ . '/../store/Session.php');
require_once(__DIR__ . '/../Constants.php');
require_once(__DIR__ . '/../helper/Ldap.php');
require_once(__DIR__ . '/../database/Database.php');
/**
* Class DragAndDrop
* @package qfq
*/
class DragAndDrop {
/**
* @var Database instantiated class
*/
private $db = null;
/**
* @var array
*/
private $vars = array();
/**
* @return array|int
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
public function process($tableName, $dragAndDropOrderSql) {
$arr = array();
$dbIndex = DB_INDEX_DEFAULT; //TODO hier muss noch die aktuelle DB ermittelt werden (kann im iform angegeben sein)
$sipClass = new Sip();
$sipVars = $sipClass->getVarsFromSip($this->vars[TYPEAHEAD_API_SIP]);
// Check for an optional given dbIndex: '[<int>]SELECT ...'
$sql = $sipVars[FE_TYPEAHEAD_SQL];
if ($sql[0] === '[') {
$pos = strpos($sql, ']');
$dbIndex = substr($sql, 1, $pos - 1);
$sipVars[FE_TYPEAHEAD_SQL] = substr($sql, $pos + 1);
}
$this->db = new Database($dbIndex);
if (isset($sipVars[FE_TYPEAHEAD_SQL])) {
if($this->vars[TYPEAHEAD_API_PREFETCH] == '') {
$arr = $this->typeAheadSql($sipVars, $this->vars[TYPEAHEAD_API_QUERY]);
} else {
$arr = $this->typeAheadSqlPrefetch($sipVars, $this->vars[TYPEAHEAD_API_PREFETCH]);
}
} elseif (isset($sipVars[FE_LDAP_SERVER])) {
$ldap = new Ldap();
if ($this->vars[TYPEAHEAD_API_PREFETCH] == '') {
$mode = MODE_LDAP_MULTI;
$key = $this->vars[TYPEAHEAD_API_QUERY];
} else {
$mode = MODE_LDAP_PREFETCH;
$key = $this->vars[TYPEAHEAD_API_PREFETCH];
}
$arr = $ldap->process($sipVars, $key, $mode);
}
return $arr;
}
/**
* Do a wildcard search on the prepared statement $config[FE_TYPEAHEAD_SQL].
* All '?' will be replaced by '%$value%'.
* If there is no 'LIMIT x' defined, append it.
* Returns an dict array [ API_TYPEAHEAD_KEY => key, API_TYPEAHEAD_VALUE => value ]
*
* @param array $config
* @param string $value
*
* @return array
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
private function typeAheadSql(array $config, $value) {
$values = array();
$sql = $config[FE_TYPEAHEAD_SQL];
$value = '%' . $value . '%';
$cnt = substr_count($sql, '?');
if ($cnt == 0) {
throw new UserFormException("Missing at least one '?' in " . FE_TYPEAHEAD_SQL);
}
for ($ii = 0; $ii < $cnt; $ii++) {
$values[] = $value;
}
if (!$this->db->hasLimit($sql)) {
$sql .= ' LIMIT ' . $config[FE_TYPEAHEAD_LIMIT];
}
$arr = $this->db->sql($sql, ROW_REGULAR, $values);
if ($arr == false || count($arr) == 0) {
return array();
}
return $this->db->makeArrayDict($arr, TYPEAHEAD_SQL_KEY_NAME, API_TYPEAHEAD_VALUE, API_TYPEAHEAD_KEY, API_TYPEAHEAD_VALUE);
}
/**
* Returns a dict array [ API_TYPEAHEAD_KEY => key, API_TYPEAHEAD_VALUE => value ] with the prefetch result
*
* @param array $config
* @param string $key
*
* @return array
* @throws CodeException
* @throws DbException
* @throws UserFormException
*/
private function typeAheadSqlPrefetch(array $config, $key) {
$keys = array();
$sql = $config[FE_TYPEAHEAD_SQL_PREFETCH];
if ($config[FE_TYPEAHEAD_SQL_PREFETCH] == '') {
throw new UserFormException("Missing definition for `" . FE_TYPEAHEAD_SQL_PREFETCH . "`", ERROR_MISSING_TYPE_AHEAD_SQL_PREFETCH);
}
$cnt = substr_count($sql, '?');
if ($cnt == 0) {
throw new UserFormException("Missing at least one '?' in " . FE_TYPEAHEAD_SQL_PREFETCH);
}
for ($ii = 0; $ii < $cnt; $ii++) {
$keys[] = $key;
}
$arr = $this->db->sql($sql, ROW_REGULAR, $keys);
if ($arr == false || count($arr) == 0) {
return array();
}
// return first result as key-value pair (concatenate columns)
$value = '';
foreach($arr[0] AS $name => $column) {
$value .= $column;
}
return [ [ API_TYPEAHEAD_KEY => $key, API_TYPEAHEAD_VALUE => $value ] ];
}
}
\ No newline at end of file