Commit 0a4f7aa3 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Merge branch 'B12015FormInsteadOfFormInOldFormListReport' into 'develop'

B12015 add formEditor as a system QFQ report and enforce formEditor existence

See merge request !312
parents bd8f4628 005154f8
Pipeline #5024 passed with stages
in 4 minutes and 35 seconds
......@@ -272,38 +272,9 @@ Setup a *report* to manage all *forms*:
* Create a Typo3 page.
* Set the 'URL Alias' to `form` (recommended) or the individual defined value in parameter `editFormPage` (configuration_).
* Insert a content record of type *qfq*.
* In the bodytext insert the following code::
# If there is a form given by SIP: show
form={{form:SE}}
# In case indexQfq != indexData, set dbIndex=indexQfq.
dbIndex = {{indexQfq:Y}}
10 {
# Table header.
sql = SELECT CONCAT('p:{{pageAlias:T}}&form=form|A:data-reference=newForm') as _pagen, '#', 'Name', 'Title', 'Table', ''
head = {{'b|p:id={{pageAlias:T}}&form=copyFormFromExt|t:Copy form from ExtForm|A:data-reference=copyForm' AS _link}}
<table class="table table-hover qfq-table-50 tablesorter tablesorter-filter" id="{{pageAlias:T}}-form">
tail = </table>
rbeg = <thead class="qfq-sticky"><tr>
rend = </tr></thead>
fbeg = <th>
fend = </th>
10 {
# All forms
sql = SELECT CONCAT('p:{{pageAlias:T}}&form=form&r=', f.id, '|A:data-reference=editForm', f.name) as _pagee
, f.id, f.name, QMORE(strip_tags(f.title), 50), f.tableName
, CONCAT('U:form=form&r=', f.id, '|A:data-reference=deletForm') as _paged
FROM Form AS f
ORDER BY f.name
rbeg = <tr>
rend = </tr>
fbeg = <td>
fend = </td>
}
}
* In the bodytext insert the following code (see explanation of code: :ref:`reportAsFile`)::
file=_formEditor
To keep the overview about all forms, it's useful to know which form has been used, how often, on which
page and when. Find these information included in the :ref:`form-editor-usage` report.
......
......@@ -2863,9 +2863,17 @@ Report As File
--------------
* If the toplevel token `file` is present inside the body of a QFQ tt-content element then the given report file is loaded and rendered.
* The tt-content body is ignored in that case.
* The path to the report file must be given relative to the report directory inside the qfq project directory. See :ref:`qfq-project-path-php`
* QFQ provides some special system reports which are located inside the extension directory `typo3conf/ext/qfq/Resources/Private/Report` and can be directly rendered by prepending an underscore and omitting the file extension:
* `file=_formEditor` will render the standard formEditor report
* If the QFQ setting `reportAsFileAutoExport` (see :ref:`extension-manager-qfq-configuration`) is enabled, then every QFQ tt-content element which does not contain the `file` keyword is exported automatically when the report is rendered the first time.
* The path of the created file is given by the typo3 page structure
* The tt-content element body is replaced with `file=<path-to-new-file>`
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -129,6 +129,7 @@ class DatabaseUpdate {
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
public function checkNupdate($dbUpdate) {
......@@ -145,6 +146,10 @@ class DatabaseUpdate {
if ($dbUpdate === SYSTEM_DB_UPDATE_ALWAYS || ($dbUpdate === SYSTEM_DB_UPDATE_AUTO && $new != $old)) {
if (version_compare($old, '21.2.0') < 1 && !defined('PHPUNIT_QFQ')) {
$this->enforceExistenceOfFormEditorReport();
}
$newFunctionHash = $this->updateSqlFunctions($versionInfo[QFQ_VERSION_KEY_FUNCTION_HASH] ?? '');
if (null !== $newFunctionHash) {
$versionInfo[QFQ_VERSION_KEY_FUNCTION_HASH] = $newFunctionHash;
......@@ -205,6 +210,31 @@ class DatabaseUpdate {
T3Handler::updateT3QfqConfig(SYSTEM_RENDER, SYSTEM_RENDER_BOTH); //Legacy behaviour.
}
}
/**
* Throws exception if no tt-content record exists which contains "file=_formEditor"
*
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
private function enforceExistenceOfFormEditorReport() {
$dbT3 = $this->store->getVar(SYSTEM_DB_NAME_T3, STORE_SYSTEM);
$sql = "SELECT `uid` FROM " . $dbT3 . ".`tt_content` WHERE `CType`='qfq_qfq' AND `deleted`=0 AND `bodytext` LIKE '%file=_formEditor%'";
$res = $this->db->sql($sql);
if (empty($res)) {
$message = '<h2>FormEditor Report not found</h2>'
. 'Please create a Typo3 QFQ content element with the following content:'
. '<pre>file=_formEditor</pre>'
. 'More information: See Section "FormEditor" of the QFQ Documentation.';
$errorMsg[ERROR_MESSAGE_TO_USER] = 'Error while updating qfq.';
$errorMsg[ERROR_MESSAGE_TO_DEVELOPER] = $message;
$errorMsg[ERROR_MESSAGE_TO_DEVELOPER_SANITIZE] = false;
throw new \DbException(json_encode($errorMsg), E_ERROR);
}
}
/**
* Check if there are special columns without prepended underscore in the QFQ application. If yes, then throw an error.
* A link is provided to automatically prepend all found special columns. And another link to skip the auto-replacement.
......
......@@ -34,6 +34,9 @@ class Path
// API
const EXT_TO_API = 'Classes/Api';
// Report
const EXT_TO_REPORT_SYSTEM = 'Resources/Private/Report';
// Javascript
const EXT_TO_JAVASCRIPT = 'Resources/Public/JavaScript';
const JAVASCRIPT_TO_EXT = '../../../';
......
......@@ -5,6 +5,7 @@ namespace IMATHUZH\Qfq\Core\Report;
use IMATHUZH\Qfq\Core\Database\Database;
use IMATHUZH\Qfq\Core\Exception\Thrower;
use IMATHUZH\Qfq\Core\Helper\HelperFile;
use IMATHUZH\Qfq\Core\Helper\OnString;
use IMATHUZH\Qfq\Core\Helper\Path;
use IMATHUZH\Qfq\Core\Helper\Sanitize;
use IMATHUZH\Qfq\Core\Store\Store;
......@@ -12,7 +13,8 @@ use IMATHUZH\Qfq\Core\Store\Store;
class ReportAsFile
{
/**
* Finds the keyword file=<pathFileName> and returns pathFileName of report relative to CWD.
* Finds the keyword file=<pathFileName> and returns pathFileName of report.
* If the given path starts with an underscore and a system report with the given path exists, then the path of the system file is returned instead.
* Returns null if the keyword is not present.
*
* @param string $bodyText
......@@ -22,7 +24,14 @@ class ReportAsFile
public static function parseFileKeyword(string $bodyText) // : ?string
{
if (preg_match('/^\s*' . TOKEN_REPORT_FILE . '\s*=\s*([^\s]*)/m', $bodyText, $matches)) {
return HelperFile::joinPathFilename(self::reportPath(), $matches[1]);
$providedPathFileName = $matches[1];
if(isset($providedPathFileName[0]) && $providedPathFileName[0] === '_') {
$pathFileNameSystem = Path::absoluteExt(Path::EXT_TO_REPORT_SYSTEM, substr($providedPathFileName, 1) . REPORT_FILE_EXTENSION);
if(HelperFile::isReadableException($pathFileNameSystem)) {
return $pathFileNameSystem;
}
}
return Path::join(self::reportPath(), $providedPathFileName);
} else {
return null;
}
......
# If there is a form given by SIP: show
form={{form:SE}}
# In case indexQfq != indexData, set dbIndex=indexQfq.
dbIndex = {{indexQfq:Y}}
10 {
# Table header.
sql = SELECT CONCAT('p:{{pageAlias:T}}&form=form|A:data-reference=newForm') as _pagen, '#', 'Name', 'Title', 'Table', ''
head = {{'b|p:id={{pageAlias:T}}&form=copyFormFromExt|t:Copy form from ExtForm|A:data-reference=copyForm' AS _link}}
<table class="table table-hover qfq-table-50 tablesorter tablesorter-filter" id="{{pageAlias:T}}-form">
tail = </table>
rbeg = <thead class="qfq-sticky"><tr>
rend = </tr></thead>
fbeg = <th>
fend = </th>
10 {
# All forms
sql = SELECT CONCAT('p:{{pageAlias:T}}&form=form&r=', f.id, '|A:data-reference=editForm', f.name) as _pagee
, f.id, f.name, QMORE(strip_tags(f.title), 50), f.tableName
, CONCAT('U:form=form&r=', f.id, '|A:data-reference=deletForm') as _paged
FROM Form AS f
ORDER BY f.name
rbeg = <tr>
rend = </tr>
fbeg = <td>
fend = </td>
}
}
\ No newline at end of file
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