Commit 47fa3b4a authored by Carsten  Rose's avatar Carsten Rose
Browse files

[NOTE] Feature #4431 / FE.type=note: QFQ Report Syntax in 'FE.value' and 'FE.note'

Manual.rst: describe how to activate 'report' syntax.
Support.php: implement 'unWrapTag()'
Report: Code reformat
FillStoreForm.php: remove unwanted '<p>' tag around content if TinyMCE is used, before saving the content
AbstractBuildForm.php: new processReportSyntax().
formEditor.sql: Change FormElement Editor column 'note' from Editor (TinyMCE) to ordinary TextArea. This was necessary cause TinyMCE is based on HTML and linebreaks are completely replaced by <br>. It's difficult to support both, HTML and plain text at the same time.
parent 3f7d0b5b
......@@ -2185,6 +2185,20 @@ to edit, on the same form, a corresponding person email address (which is in a s
{{SELECT a.email FROM Address AS a WHERE a.pId={{id:R0}} ORDER BY a.id LIMIT 1}}
FE: 'Report' notation
^^^^^^^^^^^^^^^^^^^^^
The FE fields 'value' and 'note' understand the `Report`_ syntax. Nested SQL queries as well as links with SIP encoding
are possible. To distinguish between 'Form' and 'Report' syntax, the first line has to be `#!report` ::
#!report
10.sql = SELECT ...
20 {
sql = SELECT ...
5.sql = SELECT ...
}
.. _fe-parameter-attributes:
......
......@@ -16,6 +16,8 @@ use qfq;
require_once(__DIR__ . '/store/Store.php');
require_once(__DIR__ . '/Constants.php');
require_once(__DIR__ . '/Evaluate.php');
require_once(__DIR__ . '/BodytextParser.php');
require_once(__DIR__ . '/exceptions/DbException.php');
require_once(__DIR__ . '/exceptions/UserFormException.php');
require_once(__DIR__ . '/database/Database.php');
......@@ -24,6 +26,7 @@ require_once(__DIR__ . '/helper/Support.php');
require_once(__DIR__ . '/helper/OnArray.php');
require_once(__DIR__ . '/helper/Ldap.php');
require_once(__DIR__ . '/report/Link.php');
require_once(__DIR__ . '/report/Report.php');
/**
* Class AbstractBuildForm
......@@ -58,6 +61,14 @@ abstract class AbstractBuildForm {
* @var Sip
*/
private $sip = null;
/**
* @var Report
*/
private $report = null;
/**
* @var BodytextParser
*/
private $bodytextParser = null;
/**
* AbstractBuildForm constructor.
......@@ -434,6 +445,25 @@ abstract class AbstractBuildForm {
abstract public function getProcessFilter();
private function processReportSyntax($value) {
if (substr($value, 0, 8) == SHEBANG_REPORT) {
if ($this->report === null) {
$this->report = new Report(array(), $this->evaluate, false);
}
if ($this->bodytextParser === null) {
$this->bodytextParser = new BodytextParser();
}
$value = $this->report->process($this->bodytextParser->process($value));
}
return $value;
}
/**
* Process all FormElements in $this->feSpecNative: Collect and return all HTML code & JSON.
*
......@@ -502,6 +532,9 @@ abstract class AbstractBuildForm {
$this->store->setVar(VAR_SLAVE_ID, $slaveId, STORE_VAR);
}
$fe[FE_VALUE] = $this->processReportSyntax($fe[FE_VALUE]);
$fe[FE_NOTE] = $this->processReportSyntax($fe[FE_NOTE]);
// ** evaluate current FormElement **
$formElement = $this->evaluate->parseArray($fe, $skip, $debugStack);
$formElement = HelperFormElement::setLanguage($formElement, $parameterLanguageFieldName);
......@@ -515,7 +548,6 @@ abstract class AbstractBuildForm {
// $fe[FE_MODE_SQL] = '';
// }
if ($flagOutput === true) {
$this->fillWrapLabelInputNote($formElement[FE_BS_LABEL_COLUMNS], $formElement[FE_BS_INPUT_COLUMNS], $formElement[FE_BS_NOTE_COLUMNS]);
}
......
......@@ -953,6 +953,8 @@ const FE_TYPE_PASTE = 'paste';
const FE_TYPE_TEMPLATE_GROUP = 'templateGroup';
const SHEBANG_REPORT = '#!report';
// SUPPORT
const PARAM_T3_ALL = 't3 all';
const PARAM_T3_NO_ID = "t3 no id";
......
......@@ -98,6 +98,37 @@ class Support {
return $tag . $value . $closing;
}
/**
* Removes '$tag' and closing $tag from $value, if they are the outermost.
* E.g. unWrapTag('<p>', '<p>Hello World</p>') returns 'Hello World'
*
* @param string $tag
* @param string $value
*
* @return string
*/
public static function unWrapTag($tag, $value) {
if ($tag == '' || $value == '') {
return $value;
}
$lenTag = strlen($tag);
$lenValue = strlen($value);
if ($lenValue < $lenTag + $lenTag + 1) {
return $value;
}
$closeTag = $tag[0] . '/' . substr($tag, 1);
if (substr($value, 0, $lenTag) == $tag && substr($value, $lenValue - $lenTag - 1) == $closeTag) {
$value = substr($value, $lenTag, $lenValue - $lenTag - $lenTag - 1);
}
return $value;
}
/**
* Wraps some $inner fragment with a CSS styled $tooltipText . CSS is configured in 'Resources/Public/qfq-jqw.css'.
*
......
......@@ -199,15 +199,17 @@ class Report {
$arr = explode("=", trim($ttLine), 2);
// no elements or only one: do nothing
if (count($arr) < 2)
if (count($arr) < 2) {
return;
}
// 10.50.5.sql
$key = strtolower(trim($arr[0]));
// comment ?
if (empty($key) || $key[0] === "#")
if (empty($key) || $key[0] === "#") {
return;
}
// select ...
$value = trim($arr[1]);
......@@ -259,11 +261,12 @@ class Report {
if ($frCmd === TOKEN_SQL) {
$arr = explode('|', TOKEN_VALID_LIST);
foreach ($arr as $key) {
if (!isset($this->frArray[$level . "." . $key]))
if (!isset($this->frArray[$level . "." . $key])) {
$this->frArray[$level . "." . $key] = '';
}
}
}
}
/**
* Sorts the associative array.
......@@ -439,8 +442,9 @@ class Report {
}
// HEAD: If there is at least one record, do 'head'.
if ($rowTotal > 0)
if ($rowTotal > 0) {
$content .= $this->variables->doVariables($this->frArray[$full_level . "." . TOKEN_HEAD]);
}
// Prepare row alteration
$arrRbgd = explode("|", $this->frArray[$full_level . "." . TOKEN_RBGD]);
......@@ -713,7 +717,9 @@ class Report {
$t1 = explode("@", $mailarr[0], 2);
$content .= "<script language=javascript><!--" . chr(10);
if (empty($mailarr[1])) $mailarr[1] = $mailarr[0];
if (empty($mailarr[1])) {
$mailarr[1] = $mailarr[0];
}
$content .= 'var contact = "' . substr($mailarr[1], 0, 2) . '"' . chr(10);
$content .= 'var contact1 = "' . substr($mailarr[1], 2) . '"' . chr(10);
......@@ -833,8 +839,9 @@ class Report {
exec($cmd, $arr, $rc);
$output = implode('<BR>', $arr);
if ($rc != 0)
if ($rc != 0) {
$output = $rc . " - " . $output;
}
return ($output);
}
......
......@@ -216,15 +216,21 @@ class FillStoreForm {
if (isset($clientValues[$clientFieldName])) {
if ($formElement[FE_DYNAMIC_UPDATE] === 'yes' || $formElement[FE_MODE] === FE_MODE_REQUIRED || $formElement[FE_MODE] === FE_MODE_SHOW) {
switch ($formElement[FE_TYPE]) {
case 'date':
case 'datetime':
case 'time':
case FE_TYPE_DATE:
case FE_TYPE_DATETIME:
case FE_TYPE_TIME:
if ($clientValues[$clientFieldName] !== '') // do not check empty values
$newValues[$formElement[FE_NAME]] = $this->doDateTime($formElement, $clientValues[$clientFieldName]);
break;
default:
$val = $clientValues[$clientFieldName];
// Check only if their is something
if ($formElement[FE_TYPE] == FE_TYPE_EDITOR) {
// Tiny MCE always wrap a '<p>' around the content. Remove it before saving.
$val = Support::unWrapTag('<p>', $val);
}
// Check only if their is something.
if ($val !== '') {
$val = Sanitize::sanitize($val, $formElement[FE_CHECK_TYPE], $formElement[FE_CHECK_PATTERN], SANITIZE_EXCEPTION);
if ($formElement[FE_ENCODE] === FE_ENCODE_SPECIALCHAR) {
......
......@@ -332,9 +332,7 @@ VALUES
(2, 'bsNoteColumns', 'BS Note Columns', 'show', 'text', 'all', 'native', 430, 0, 0, '', '', '', '', '', 102, '', 'no', '', '', '', '', '{{bsNoteColumns:Y}}', 'specialchar'),
(2, 'rowLabelInputNote', 'Label / Input / Note', 'show', 'checkbox', 'alnumx', 'native', 440, 0, 10, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-rowLabelInputNote">Info</a>', '', '', '', '', 102, '', 'no', '', '', '', '', '', 'specialchar'),
(2, 'maxLength', 'Maxlength', 'show', 'text', 'all', 'native', 450, 0, 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-maxLength">Info</a>', '', '', '', '', 102, '', 'no', '', '', '', '', '', 'specialchar'),
(2, 'note', 'Note', 'show', 'editor', 'all', 'native', 460, '', 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-note">Info</a>', '', '', '',
'editor-plugins=code link table textcolor textpattern\neditor-toolbar=code | styleselect link table | bullist numlist | forecolor backcolor bold italic\neditor-menubar=false\neditor-statusbar=false',
102, '', 'no', '', '', '', '', '', 'none'),
(2, 'note', 'Note', 'show', 'text', 'all', 'native', 460, '40,5', 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-note">Info</a>', '', '', '', '', 102, '', 'no', '', '', '', '', '', 'none'),
(2, 'tooltip', 'Tooltip', 'show', 'text', 'all', 'native', 470, 0, 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-tooltip">Info</a>', '', '', '', '', 102, '', 'no', '', '', '', '', '', 'none'),
(2, 'placeholder', 'Placeholder', 'show', 'text', 'all', 'native', 480, 0, 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-placeholder">Info</a>', '', '', '', '', 102, '', 'no', '', '', '', '', '', 'none'),
(2, 'value', 'value', 'show', 'text', 'all', 'native', 500, '40,2', 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-value">Info</a>', '', '', '', '', 103, '', 'no', '', '', '', '', '', 'none'),
......@@ -354,6 +352,8 @@ VALUES
(2, 'created', 'Created', 'readonly', 'text', 'all', 'native', 640, 0, 20, '', '', '', '', '', 104, '', 'no', '',
'', '', '', '', 'specialchar');
#(2, 'note', 'Note', 'show', 'editor', 'all', 'native', 460, '', 0, '<a href="{{DOCUMENTATION_QFQ:Y}}#field-note">Info</a>', '', '', '',
#'editor-plugins=code link table textcolor textpattern\neditor-toolbar=code | styleselect link table | bullist numlist | forecolor backcolor bold italic\neditor-menubar=false\neditor-statusbar=false',
# ----------------------------------------
# MailLog
......
......@@ -559,6 +559,14 @@ class SupportTest extends \PHPUnit_Framework_TestCase {
}
public function testUnWrapTag() {
$this->assertEquals('', Support::unWrapTag('', ''));
$this->assertEquals('', Support::unWrapTag('<p>', ''));
$this->assertEquals('Hello World', Support::unWrapTag('<p>', 'Hello World'));
$this->assertEquals('Hello World', Support::unWrapTag('<p>', '<p>Hello World</p>'));
}
protected function setUp() {
parent::setUp();
......
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