Commit 169e3bf4 authored by Benjamin Baer's avatar Benjamin Baer
Browse files

Merge branch 'f12439-CharacterCount' of git.math.uzh.ch:typo3/qfq into f12439-CharacterCount

parents d8281386 50a06278
Pipeline #6793 failed with stages
in 2 minutes and 8 seconds
......@@ -1545,7 +1545,7 @@ Explanation:
Type: editor
^^^^^^^^^^^^
* TinyMCE (https://www.tinymce.com, community edition) is used as the QFQ Rich Text Editor.
* TinyMCE (https://www.tinymce.com, community edition) is used as QFQ Rich Text Editor.
* The content will be saved as HTML inside the database.
* All configuration and plugins will be configured via the 'parameter' field. Just prepend the word 'editor-' in front
of each TinyMCE keyword. Check possible options under:
......@@ -1558,7 +1558,8 @@ Type: editor
* Top: *menubar* - by default hidden.
* Top: *toolbar* - by default visible.
* Bottom: *statusbar* - by default hidden, exception: *min_height* and *max_height* are given via size parameter.
* Bottom: *statusbar* - by default hidden, exception: *min_height* and *max_height* are given via size parameter or
*maxLength* is given.
* The default setting in *FormElement.parameter* is::
......@@ -1581,6 +1582,15 @@ Type: editor
editor-content_css = fileadmin/custom.css
* *FormElement.size* = <min_height>,<max_height>: in pixels, including top and bottom bars. E.g.: 300,600
* *FormElement.maxLength* = <max in browser>[,<max on server>] - e.g.: 1000 or 1000,1500
* *max in browser*: Only text, without any formatting, is counted. The value here is neither number of characters
nor number of bytes (in UTF8 bytes and characters don't have to be equal). For the counting, all HTML tags are skipped.
The current count is displayed in the status bar at the bottom. When the content is saved, all HTML tags are saved too.
Therefore you should definitely reserve some extra space in the table column.
* *max on server*: This can be upto the size of the table column. It is the real maximum which will be stored. Every
character is counted. Again be careful, UTF8 character might need several bytes.
Type: annotate
......
......@@ -334,20 +334,23 @@ qfq.json
* Additionally to the keywords bellow one can also override the configuration values defined in the Typo3 extension manager: :ref:`extension-manager-qfq-configuration`
* e.g. if `qfq.json` contains `"flagProduction":"no"` then this value is taken instead of the one set in the extension manager.
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| Keyword | Example | Description |
+===============================+=======================================================+============================================================================+
| DB_<n>_USER | DB_1_USER=qfqUser | Credentials configured in MySQL |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| DB_<n>_PASSWORD | DB_1_PASSWORD=1234567890 | Credentials configured in MySQL |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| DB_<n>_SERVER | DB_1_SERVER=localhost | Hostname of MySQL Server |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| DB_<n>_NAME | DB_1_NAME=qfq_db | Database name |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
| LDAP_1_RDN | LDAP_1_RDN='ou=Admin,ou=example,dc=com' | Credentials for non-anonymous LDAP access. Only one set supported. |
| LDAP_1_PASSWORD | LDAP_1_PASSWORD='mySecurePassword' | |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------+
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| Keyword | Example | Description |
+===============================+=======================================================+==========================================================================================================+
| DB_<n>_USER | "DB_1_USER"="qfqUser" | Credentials configured in MySQL |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| DB_<n>_PASSWORD | "DB_1_PASSWORD"="1234567890" | Credentials configured in MySQL |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| DB_<n>_SERVER | "DB_1_SERVER"="localhost" | Hostname of MySQL Server |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| DB_<n>_NAME | "DB_1_NAME"="qfq_db" | Database name |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| LDAP_1_RDN | "LDAP_1_RDN"="ou=Admin,ou=example,dc=com " | Credentials for non-anonymous LDAP access. Only one set supported. |
| LDAP_1_PASSWORD | "LDAP_1_PASSWORD"="mySecurePassword" | |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| PASSWORD_HASH_TYPE | "PASSWORD_HASH_TYPE"="PASSWORD_BCRYPT" | Password hashing algorithm used for "p" action class. See: :ref:`variable-escape` |
| | | Possible values: "PASSWORD_ARGON2I" (QFQ default), "PASSWORD_BCRYPT", "PASSWORD_DEFAULT" (PHP default) |
+-------------------------------+-------------------------------------------------------+----------------------------------------------------------------------------------------------------------+
Example: *fileadmin/protected/qfqProject/qfq.json*: ::
......
......@@ -1256,22 +1256,22 @@ Attachment
The following options are provided to attach files to an email:
+-------+------------------------------------------------------+--------------------------------------------------------+
| Token | Example | Comment |
+=======+======================================================+========================================================+
| F | F:fileadmin/file3.pdf | Single file to attach |
+-------+------------------------------------------------------+--------------------------------------------------------+
| u | u:www.example.com/index.html?key=value&... | A URL, will be converted to a PDF and than attached. |
+-------+------------------------------------------------------+--------------------------------------------------------+
| p | p:?id=export&r=123&_sip=1 | A SIP protected local T3 page. |
| | | Will be converted to a PDF and than attached. |
+-------+------------------------------------------------------+--------------------------------------------------------+
| d | d:myfile.pdf | Name of the attachment in the email. |
+-------+------------------------------------------------------+--------------------------------------------------------+
| C | C|u:http://www.example.com|F:file1.pdf|C|F:file2.pdf | Concatenate all named sources to one PDF file. The |
| | | souces has to be PDF files or a web page, which will be|
| | | converted to a PDF first. |
+-------+------------------------------------------------------+--------------------------------------------------------+
+-------+----------------------------------------------------------+--------------------------------------------------------+
| Token | Example | Comment |
+=======+==========================================================+========================================================+
| F | ``F:fileadmin/file3.pdf`` | Single file to attach |
+-------+----------------------------------------------------------+--------------------------------------------------------+
| u | ``u:www.example.com/index.html?key=value&...`` | A URL, will be converted to a PDF and than attached. |
+-------+----------------------------------------------------------+--------------------------------------------------------+
| p | ``p:?id=export&r=123&_sip=1`` | A SIP protected local T3 page. |
| | | Will be converted to a PDF and than attached. |
+-------+----------------------------------------------------------+--------------------------------------------------------+
| d | ``d:myfile.pdf`` | Name of the attachment in the email. |
+-------+----------------------------------------------------------+--------------------------------------------------------+
| C | ``C|u:http://www.example.com|F:file1.pdf|C|F:file2.pdf`` | Concatenate all named sources to one PDF file. The |
| | | souces has to be PDF files or a web page, which will be|
| | | converted to a PDF first. |
+-------+----------------------------------------------------------+--------------------------------------------------------+
Any combination (incl. repeating them) are possible. Any source will be added as a single attachment.
......@@ -2889,6 +2889,8 @@ Customization of tablesorter
+-----------------------------+----------------------------------------------------------------------------------------+
| Description | Syntax |
+=============================+========================================================================================+
| Header sticky | ``<thead class="qfq-sticky">...`` (see `_qfq-css-classes`) |
+-----------------------------+----------------------------------------------------------------------------------------+
| Disable sorter | ``<th class="sorter-false">...`` |
+-----------------------------+----------------------------------------------------------------------------------------+
| Disable filter | ``<th class="filter-false">...`` |
......
......@@ -221,7 +221,7 @@ The following `escape` & `action` types are available:
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| m | `real_escape_string() <http://php.net/manual/en/mysqli.real-escape-string.php>`_ (m = mysql) |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| p | Password hashing: depends on the hashing type in the Typo3 installation, includes salting if configured. |
| p | Password hashing with salting. Password hashing algorithm may be configured in: :ref:`qfq.json` (default is Argon2i) |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
| s | Single ticks ``'`` will be escaped by ``\'``. |
+-------+----------------------------------------------------------------------------------------------------------------------------------+
......
......@@ -525,7 +525,7 @@ module.exports = function (grunt) {
},
qfqTinyMCECharCount: {
src: ['javascript/src/Plugins/tinymce.charcount.js'],
dest: typo3_js + 'qfq.charcount.min.js'
dest: typo3_js + 'plugins/charactercount/plugin.min.js'
}
},
jshint: {
......
......@@ -107,17 +107,20 @@ fi
### Write config files ###
# QFQ config
echo "
<?php
return [
'DB_1_USER' => '${MYSQL_USER}',
'DB_1_SERVER' => 'db',
'DB_1_PASSWORD' => '${MYSQL_PASSWORD}',
'DB_1_NAME' => '${QFQ_DATABASE}',
];" > config.qfq.php
docker cp config.qfq.php ${T3_CONTAINER}:/var/www/html/typo3conf/config.qfq.php
rm config.qfq.php
docker exec ${T3_CONTAINER} chown www-data:www-data /var/www/html/typo3conf/config.qfq.php
# NOTE: If the baseUrl is empty QFQ throws an exception. (The space is a hack to circumvent that)
cat <<EOT >> qfq.json
{
"DB_1_USER": "${MYSQL_USER}",
"DB_1_SERVER": "db",
"DB_1_PASSWORD": "${MYSQL_PASSWORD}",
"DB_1_NAME": "${QFQ_DATABASE}",
"baseUrl": " "
}
EOT
docker exec ${T3_CONTAINER} mkdir -p "/var/www/html/fileadmin/protected/qfqProject/conf"
docker cp qfq.json ${T3_CONTAINER}:/var/www/html/fileadmin/protected/qfqProject/conf/qfq.json
rm qfq.json
docker exec ${T3_CONTAINER} chown -R www-data:www-data /var/www/html/fileadmin/protected
# Typo3 config
docker exec ${T3_CONTAINER} sed -i -e "s/<MYSQL_USER>/${MYSQL_USER}/g" /var/www/html/typo3conf/LocalConfiguration.php
......
......@@ -643,7 +643,7 @@ abstract class AbstractBuildForm {
*/
public function getActionUrl() {
return Path::appToApi(API_SAVE_PHP);
return Path::urlApi(API_SAVE_PHP);
}
/**
......@@ -2569,7 +2569,7 @@ abstract class AbstractBuildForm {
}
if (isset($control[SUBRECORD_COLUMN_ICON][$columnName])) {
$cell = ($cell === '') ? '' : "<image src='" . Path::appToExt(Path::EXT_TO_PATH_ICONS) . "/$cell'>";
$cell = ($cell === '') ? '' : "<image src='" . Path::urlExt(Path::EXT_TO_PATH_ICONS, $cell) . "'>";
}
if (isset($control[SUBRECORD_COLUMN_MAILTO][$columnName])) {
......@@ -2619,7 +2619,7 @@ abstract class AbstractBuildForm {
$sip = $this->store->getSipInstance();
return $sip->queryStringToSip($queryString, $mode, Path::appToApi(API_DELETE_PHP));
return $sip->queryStringToSip($queryString, $mode, Path::urlApi(API_DELETE_PHP));
}
/**
......@@ -2907,8 +2907,8 @@ abstract class AbstractBuildForm {
$attributeFabric = Support::doAttribute('class', ANNOTATE_GRAPHIC_CSS_CLASS);
$attributeFabric .= Support::doAttribute('data-background-image', $this->fileToSipUrl($formElement[FE_IMAGE_SOURCE]));
$attributeFabric .= Support::doAttribute('data-control-name', $formElement[FE_HTML_ID]);
$attributeFabric .= Support::doAttribute('data-buttons', Path::appToExt('Resources/Public/Json/fabric.buttons.json'));
$attributeFabric .= Support::doAttribute('data-emojis', Path::appToExt('Resources/Public/Json/qfq.emoji.json'));
$attributeFabric .= Support::doAttribute('data-buttons', Path::urlExt('Resources/Public/Json/fabric.buttons.json'));
$attributeFabric .= Support::doAttribute('data-emojis', Path::urlExt('Resources/Public/Json/qfq.emoji.json'));
$attributeFabric .= Support::doAttribute('data-fabric-color', HelperFormElement::penColorToHex($formElement));
$attributeFabric .= HelperFormElement::getAttributeFeMode($formElement[FE_MODE]);
if ($formElement[FE_MODE] == FE_MODE_READONLY) {
......@@ -2973,7 +2973,7 @@ abstract class AbstractBuildForm {
// data-image-output="target-png">
// </div>
$attributeFabric = Support::doAttribute('class', ANNOTATE_GRAPHIC_CSS_CLASS);
$attributeFabric .= Support::doAttribute('data-buttons', Path::appToExt('Resources/Public/Json/fabric.editor.buttons.json'));
$attributeFabric .= Support::doAttribute('data-buttons', Path::urlExt('Resources/Public/Json/fabric.editor.buttons.json'));
$attributeFabric .= Support::doAttribute('data-edit-image', 'true');
$attributeFabric .= Support::doAttribute('data-background-image', $imageFileName);
$attributeFabric .= Support::doAttribute('data-control-name', $htmlFabricId);
......@@ -3019,7 +3019,7 @@ abstract class AbstractBuildForm {
$param[DOWNLOAD_MODE] = DOWNLOAD_MODE_FILE;
$param[SIP_DOWNLOAD_PARAMETER] = base64_encode(TOKEN_FILE . PARAM_TOKEN_DELIMITER . $pathFileName);
$url = $this->sip->queryStringToSip(Path::appToApi(API_DOWNLOAD_PHP) . '?' . KeyValueStringParser::unparse($param, '=', '&'), RETURN_URL);
$url = $this->sip->queryStringToSip(Path::urlApi(API_DOWNLOAD_PHP) . '?' . KeyValueStringParser::unparse($param, '=', '&'), RETURN_URL);
return $url;
}
......@@ -3394,9 +3394,11 @@ abstract class AbstractBuildForm {
}
// If a maxLength is given: set it
if ($formElement[FE_MAX_LENGTH] > 0) {
if ($formElement[FE_MAX_LENGTH] != '') {
// $formElement[FE_MAX_LENGTH] = <max in browser>[,<max on server>]
$arr = explode(',', $formElement[FE_MAX_LENGTH], 2);
$formElement[FE_EDITOR_PREFIX . 'plugins'] = OnString::addAttribute($formElement[FE_EDITOR_PREFIX . 'plugins'], 'charactercount');
$formElement[FE_EDITOR_PREFIX . 'max_characters'] = $formElement[FE_MAX_LENGTH] ?? '';
$formElement[FE_EDITOR_PREFIX . 'max_characters'] = trim($arr[0]) ?? '';
// Currently this is hardcoded: might become a dedicated option.
$formElement[FE_EDITOR_PREFIX . 'allow_writing_past_limit'] = 'true';
}
......
......@@ -657,14 +657,14 @@ class BuildFormBootstrap extends AbstractBuildForm {
$actionUpload = FILE_ACTION . '=' . FILE_ACTION_UPLOAD;
$actionDelete = FILE_ACTION . '=' . FILE_ACTION_DELETE;
$apiDeletePhp = Path::appToApi(API_DELETE_PHP);
$apiDeletePhp = Path::urlApi(API_DELETE_PHP);
$dirtyAction = ($this->formSpec[F_DIRTY_MODE] == DIRTY_MODE_NONE) ? '' : "dirtyUrl: '" . Path::appToApi(API_DIRTY_PHP) . "',";
$dirtyAction = ($this->formSpec[F_DIRTY_MODE] == DIRTY_MODE_NONE) ? '' : "dirtyUrl: '" . Path::urlApi(API_DIRTY_PHP) . "',";
$submitTo = Path::appToApi(API_SAVE_PHP);
$refreshUrl = Path::appToApi(API_LOAD_PHP);
$fileUploadTo = Path::appToApi(API_FILE_PHP) . '?' . $actionUpload;
$fileDeleteUrl = Path::appToApi(API_FILE_PHP) . '?' . $actionDelete;
$submitTo = Path::urlApi(API_SAVE_PHP);
$refreshUrl = Path::urlApi(API_LOAD_PHP);
$fileUploadTo = Path::urlApi(API_FILE_PHP) . '?' . $actionUpload;
$fileDeleteUrl = Path::urlApi(API_FILE_PHP) . '?' . $actionDelete;
$html .= '</form>'; // <form class="form-horizontal" ...
$html .= <<<EOF
......
......@@ -154,7 +154,7 @@ const ERROR_CODE_SHOULD_NOT_HAPPEN = 1003;
const ERROR_PHP_VERSION = 1005;
const ERROR_SIP_INVALID = 1006;
const ERROR_MISSING_RECORD_ID = 1007;
const ERROR_IN_SQL_STATEMENT = 1008;
const ERROR_STRING_TO_LONG = 1008;
const ERROR_MISSING_REQUIRED_PARAMETER = 1009;
const ERROR_FE_NESTED_TOO_MUCH = 1010;
const ERROR_BROKEN_PARAMETER = 1011;
......@@ -552,6 +552,8 @@ const SYSTEM_FORM_BS_NOTE_COLUMNS = 'formBsNoteColumns';
const SYSTEM_BASE_URL = 'baseUrl';
const SYSTEM_PASWORD_HASH_TYPE = 'PASSWORD_HASH_TYPE';
const SYSTEM_SEND_E_MAIL_OPTIONS = 'sendEMailOptions';
const SYSTEM_EDIT_FORM_PAGE = 'editFormPage';
......@@ -1118,7 +1120,8 @@ const FE_BS_LABEL_COLUMNS = F_BS_LABEL_COLUMNS;
const FE_BS_INPUT_COLUMNS = F_BS_INPUT_COLUMNS;
const FE_BS_NOTE_COLUMNS = F_BS_NOTE_COLUMNS;
const FE_WRAP_ROW_LABEL_INPUT_NOTE = 'rowLabelInputNote';
const FE_MAX_LENGTH = 'maxLength';
const FE_MAX_LENGTH = 'maxLength'; // Value defined by QFQ application developer. Optional two values: [client max][,server max]
const FE_MAX_LENGTH_COLUMN = 'maxLengthColumn'; // QFQ internal. Will be determined dynamically during save. Not filled by QFQ application developer
const FE_PARAMETER = 'parameter';
const FE_ENCODE = 'encode';
const FE_CHECK_TYPE = 'checkType';
......@@ -1217,7 +1220,6 @@ const FE_SQL_INSERT = 'sqlInsert'; // Action: Insert Statement to create slave r
const FE_SQL_DELETE = 'sqlDelete'; // Action: Delete Statement to delete unused slave record.
const FE_SQL_HONOR_FORM_ELEMENTS = 'sqlHonorFormElements'; // Action: Honor given list of FormElements for sqlInsert|Update|Delete
const FE_EDITOR_PREFIX = 'editor-'; // TinyMCE configuration settings.
const FE_EDITOR_PLUGINS_DEFAULT = 'code link lists searchreplace table textcolor textpattern visualchars paste'; // TinyMCE Default plugins
const FE_EDITOR_TYPE = 'editorType'; // tinymce | codemirror
const FE_EDITOR_TYPE_TINYMCE = 'tinymce';
const FE_EDITOR_TYPE_CODEMIRROR = 'codemirror';
......@@ -2061,3 +2063,6 @@ const I_UNCHECKED = 'unchecked';
// Rest Client
const HTTP_STATUS = 'http-status';
const ERROR_MESSAGE = 'error-message';
// Misc
const BASE_DIR_FAKE = 'http://xxxxxxxxxxxxxxxxxxxxxxxxxxxx/qfq/';
......@@ -318,7 +318,7 @@ class Evaluate {
$this->store::setVar(SYSTEM_DRAG_AND_DROP_JS, 'true', STORE_SYSTEM);
// data-dnd-api="typo3conf/ext/qfq/qfq/Api/dragAndDrop.php?s={{'U:form=<form name>[&paramX=<any value>]|s|r:8' AS _link}}"
return DND_DATA_DND_API . '="' . Path::appToApi(API_DRAG_AND_DROP_PHP) . '?s=' . $s . '"';
return DND_DATA_DND_API . '="' . Path::urlApi(API_DRAG_AND_DROP_PHP) . '?s=' . $s . '"';
}
/**
......
......@@ -457,7 +457,7 @@ class HelperFile {
}
if (isset($extToFileType[$ext])) {
return Path::appToExt(Path::EXT_TO_HIGHLIGHT_JSON) . '/' . $extToFileType[$ext];
return Path::urlExt(Path::EXT_TO_HIGHLIGHT_JSON) . '/' . $extToFileType[$ext];
}
return '';
......
......@@ -9,8 +9,11 @@ namespace IMATHUZH\Qfq\Core\Helper;
* - Ext: directory in which the QFQ extension is loacted. e.g. the folder Classes is in there.
* - API: api folder of qfq extension
*
* Naming convention of path constants/functions/variables:
* 1) name a path by its origin and its destination separated by 'to'. E.g. APP_TO_SYSTEM_LOG, $appToProject.
* Conventions of Path class:
* 1) naming conventions of of path constants/functions/variables:
* a) name a path by its origin and its destination separated by 'to'. E.g. APP_TO_SYSTEM_LOG, $appToProject.
* b) Or only by its destination and prefix "absolute" if the path is absolute e.g. absoluteApp().
* c) Or by its destination and prefix "url" if the path returns a fully qualified url using the base path e.g. urlExt().
* 2) if the destination is a file, append "File". E.g. APP_TO_SYSTEM_QFQ_LOG_FILE.
* 3) if a path has to be variable, create a setter and getter. E.g. self::setAbsoluteApp(), self::absoluteApp(), private static $absoluteApp.
* 4) a path getter appends the given arguments to the requested path using self::join(..., func_get_args()). E.g. see absoluteApp().
......@@ -22,11 +25,10 @@ namespace IMATHUZH\Qfq\Core\Helper;
use IMATHUZH\Qfq\Core\Exception\Thrower;
use IMATHUZH\Qfq\Core\Store\Config;
class Path
{
class Path {
// App
// This is manually set in self::setMainPaths()
private static $absoluteApp = null;
private static $absoluteApp = null; // This is manually set in self::setMainPaths()
private static $urlApp = null;
// Extension
const APP_TO_EXT = 'typo3conf/ext/qfq';
......@@ -97,8 +99,7 @@ class Path
* @throws \CodeException
* @throws \UserFormException
*/
public static function setMainPaths(string $absoluteApp = null)
{
public static function setMainPaths(string $absoluteApp = null) {
if (is_null($absoluteApp)) {
$absoluteApp = self::findAbsoluteApp();
}
......@@ -114,8 +115,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteApp(...$pathPartsToAppend): string
{
public static function absoluteApp(...$pathPartsToAppend): string {
self::enforcePathIsSet(self::$absoluteApp);
return self::join(self::$absoluteApp, $pathPartsToAppend);
}
......@@ -125,8 +125,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteExt(...$pathPartsToAppend): string
{
public static function absoluteExt(...$pathPartsToAppend): string {
return self::absoluteApp(self::appToExt(), $pathPartsToAppend);
}
......@@ -135,8 +134,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteLog(...$pathPartsToAppend): string
{
public static function absoluteLog(...$pathPartsToAppend): string {
if (is_null(self::$absoluteLog)) {
self::findAbsoluteLog();
}
......@@ -148,8 +146,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteSqlLogFile(): string
{
public static function absoluteSqlLogFile(): string {
if (is_null(self::$overloadAbsoluteSqlLogFile)) {
return self::absoluteLog(self::LOG_TO_SQL_LOG_FILE_DEFAULT);
}
......@@ -160,8 +157,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteQfqLogFile(): string
{
public static function absoluteQfqLogFile(): string {
if (is_null(self::$overloadAbsoluteQfqLogFile)) {
return self::absoluteLog(self::LOG_TO_QFQ_LOG_FILE_DEFAULT);
}
......@@ -172,8 +168,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteMailLogFile(): string
{
public static function absoluteMailLogFile(): string {
if (is_null(self::$overloadAbsoluteMailLogFile)) {
return self::absoluteLog(self::LOG_TO_MAIL_LOG_FILE_DEFAULT);
}
......@@ -185,8 +180,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function appToProject(...$pathPartsToAppend): string
{
public static function appToProject(...$pathPartsToAppend): string {
self::enforcePathIsSet(self::$appToProject);
return self::join(self::$appToProject, $pathPartsToAppend);
}
......@@ -196,8 +190,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteProject(...$pathPartsToAppend): string
{
public static function absoluteProject(...$pathPartsToAppend): string {
return self::absoluteApp(self::appToProject($pathPartsToAppend));
}
......@@ -206,8 +199,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function absoluteConf(...$pathPartsToAppend): string
{
public static function absoluteConf(...$pathPartsToAppend): string {
return self::absoluteProject(self::PROJECT_TO_CONF, $pathPartsToAppend);
}
......@@ -216,19 +208,30 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function appToExt(...$pathPartsToAppend): string
{
public static function appToExt(...$pathPartsToAppend): string {
return self::join(self::APP_TO_EXT, $pathPartsToAppend);
}
/**
* @param mixed ...$pathPartsToAppend
* @return string
* @throws \UserFormException
*/
public static function urlApp(...$pathPartsToAppend): string {
// ensure base url is configured
if (is_null(self::$urlApp) || self::$urlApp === '') {
Thrower::userFormException('Base url not configured.', 'Go to QFQ extension configuration in the Typo3 backend and fill in a value for config.baseUrl');
}
return self::join(self::$urlApp, $pathPartsToAppend);
}
/**
* @param array $pathPartsToAppend
* @return string
* @throws \UserFormException
*/
public static function extToApi(...$pathPartsToAppend): string
{
return self::join(self::EXT_TO_API, $pathPartsToAppend);
public static function urlExt(...$pathPartsToAppend): string {
return self::urlApp(self::appToExt($pathPartsToAppend));
}
/**
......@@ -236,17 +239,24 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function appToApi(...$pathPartsToAppend): string
{
public static function appToApi(...$pathPartsToAppend): string {
return self::join(self::APP_TO_EXT, self::EXT_TO_API, $pathPartsToAppend);
}
/**
* @param array $pathPartsToAppend
* @return string
* @throws \UserFormException
*/
public static function urlApi(...$pathPartsToAppend): string {
return self::urlApp(self::appToApi($pathPartsToAppend));
}
/**
* @param mixed ...$pathPartsToAppend
* @return string
*/
public static function projectToForm(...$pathPartsToAppend) : string
{
public static function projectToForm(...$pathPartsToAppend): string {
$projectToForm = is_null(self::$projectToForm) ? self::PROJECT_TO_FORM_DEFAULT : self::$projectToForm;
return self::join($projectToForm, $pathPartsToAppend);
}
......@@ -255,8 +265,7 @@ class Path
* @param mixed ...$pathPartsToAppend
* @return string
*/
public static function projectToReport(...$pathPartsToAppend) : string
{
public static function projectToReport(...$pathPartsToAppend): string {
$projectToReport = is_null(self::$projectToReport) ? self::PROJECT_TO_REPORT_DEFAULT : self::$projectToReport;
return self::join($projectToReport, $pathPartsToAppend);
}
......@@ -264,16 +273,14 @@ class Path
/**
* @param string $newPath
*/
public static function setProjectToForm(string $newPath)
{
public static function setProjectToForm(string $newPath) {
self::$projectToForm = $newPath;
}
/**
* @param string $newPath
*/
public static function setProjectToReport(string $newPath)
{
public static function setProjectToReport(string $newPath) {
self::$projectToReport = $newPath;
}
......@@ -281,8 +288,7 @@ class Path
* @param string $newPath
* @throws \UserFormException
*/
public static function setAbsoluteSqlLogFile(string $newPath)
{
public static function setAbsoluteSqlLogFile(string $newPath) {
self::enforcePathIsAbsolute($newPath);
self::$overloadAbsoluteSqlLogFile = $newPath;
}
......@@ -291,8 +297,7 @@ class Path
* @param string $newPath
* @throws \UserFormException
*/
public static function setAbsoluteQfqLogFile(string $newPath)
{
public static function setAbsoluteQfqLogFile(string $newPath) {
self::enforcePathIsAbsolute($newPath);
self::$overloadAbsoluteQfqLogFile = $newPath;
}
......@@ -301,12 +306,18 @@ class Path
* @param string $newPath
* @throws \UserFormException
*/
public static function setAbsoluteMailLogFile(string $newPath)
{
public static function setAbsoluteMailLogFile(string $newPath) {
self::enforcePathIsAbsolute($newPath);
self::$overloadAbsoluteMailLogFile = $newPath;
}
/**
* @param $urlApp
*/
public static function setUrlApp($urlApp) {
self::$urlApp = $urlApp;
}
/**
* Override the paths of sql.log, qfq.log, mail.log using the values from the config file or Typo3.
*
......@@ -314,8 +325,7 @@ class Path
* @throws \UserFormException
* @throws \UserReportException
*/
public static function overrideLogPathsFromConfig()
{
public static function overrideLogPathsFromConfig() {
// QFQ log
$absoluteQfqLogFile = Config::get(SYSTEM_QFQ_LOG_PATHFILENAME);
if (!empty($absoluteQfqLogFile)) {
......@@ -343,8 +353,7 @@ class Path
* @return string
* @throws \UserFormException
*/
public static function joinIfNotAbsolute (string $path1, string $path2): string
{
public static function joinIfNotAbsolute(string $path1, string $path2): string {
if ($path2 !== '' && $path2[0] === '/') {
return $path2;
}
......@@ -360,8 +369,7 @@ class Path
* @param array $pathPartsToAppend
* @return string
*/
public static function join(...$pathPartsToAppend): string
{
public static function join(...$pathPartsToAppend): string {