From 732fec2f2757c0ccb63d63282113a2753b57aa09 Mon Sep 17 00:00:00 2001
From: enured <enis.nuredini@uzh.ch>
Date: Thu, 25 May 2023 16:02:09 +0200
Subject: [PATCH] S16285: WIP: Migration for PHP V8  refs #16285

---
 extension/Classes/Core/AbstractBuildForm.php  | 40 ++++++++++-------
 .../Core/Exception/AbstractException.php      |  4 +-
 extension/Classes/Core/Helper/DateTime.php    | 26 +++++------
 extension/Classes/Core/Report/Report.php      | 44 +++++++++++--------
 4 files changed, 66 insertions(+), 48 deletions(-)

diff --git a/extension/Classes/Core/AbstractBuildForm.php b/extension/Classes/Core/AbstractBuildForm.php
index 75cb5b9b8..1d9a05672 100644
--- a/extension/Classes/Core/AbstractBuildForm.php
+++ b/extension/Classes/Core/AbstractBuildForm.php
@@ -1197,7 +1197,8 @@ abstract class AbstractBuildForm {
 
         $sipValue = $sip->queryStringToSip($queryString, RETURN_SIP);
 
-        $json[] = $this->getFormElementForJson(CLIENT_SIP, $sipValue, [FE_MODE => FE_MODE_SHOW]);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json[] = $this->getFormElementForJson(CLIENT_SIP, $sipValue, [FE_MODE => FE_MODE_SHOW], $wrapSetupClass);
 
         return HelperFormElement::buildNativeHidden(CLIENT_SIP, $sipValue);
     }
@@ -1211,14 +1212,14 @@ abstract class AbstractBuildForm {
      * @param string $htmlFormElementName
      * @param string|array $value
      * @param array $formElement
-     *
+     * @param string $wrap
      * @param int $optionIdx
-     * @param string $class
+     * @param string $optionClass
      * @return array
      * @throws \CodeException
      * @throws \UserFormException
      */
-    public function getFormElementForJson($htmlFormElementName, $value, array $formElement, $optionIdx = 0, $optionClass = '') {
+    public static function getFormElementForJson(string $htmlFormElementName, mixed $value, array $formElement, mixed $wrap = '', mixed $optionIdx = 0, mixed $optionClass = ''): array {
         $addClassRequired = array();
 
         $json = HelperFormElement::getJsonFeMode($formElement[FE_MODE]); // disabled, required
@@ -1329,7 +1330,7 @@ abstract class AbstractBuildForm {
             if ($optionClass != '') {
                 $class = $optionClass;
             } else {
-                $class = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS];
+                $class = $wrap;
             }
 
             if ($formElement[FE_MODE] == FE_MODE_HIDDEN) {
@@ -1629,7 +1630,8 @@ abstract class AbstractBuildForm {
 
         $attribute .= Support::doAttribute('class', $class);
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass);
 
         $input = "$htmlTag $attribute>$textarea";
 
@@ -1983,7 +1985,8 @@ abstract class AbstractBuildForm {
 
         $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass);
 
         return $html;
     }
@@ -2006,7 +2009,7 @@ abstract class AbstractBuildForm {
      * @throws \UserFormException
      * @throws \UserReportException
      */
-    private function constructRadioPlain(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
+    private function constructRadioPlain(array $formElement, string $htmlFormElementName, $value, array &$json, string $mode = FORM_LOAD): string {
         $attributeBase = '';
         $html = '';
 
@@ -2096,7 +2099,8 @@ abstract class AbstractBuildForm {
             $jsonTmp[API_ELEMENT_UPDATE][$optionId][API_ELEMENT_ATTRIBUTE]['required'] = ($formElement[FE_MODE] == FE_MODE_REQUIRED) ? 'required' : 'false';
         }
 
-        $json = array_merge($this->getFormElementForJson($htmlFormElementName, $value, $formElement));
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = array_merge($this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass));
         $json[API_ELEMENT_UPDATE] = array_merge($json[API_ELEMENT_UPDATE], $jsonTmp[API_ELEMENT_UPDATE]);
 
 
@@ -2172,7 +2176,8 @@ abstract class AbstractBuildForm {
             $option .= '>' . $itemValue[$ii] . '</option>';
         }
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $jsonValues, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $jsonValues, $formElement, $wrapSetupClass);
 
         $formElement = HelperFormElement::prepareExtraButton($formElement, false);
         $attribute .= HelperFormElement::getAttributeFeMode($formElement[FE_MODE]);
@@ -2982,7 +2987,8 @@ abstract class AbstractBuildForm {
         $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE]);
 
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement); // Below, $formElement[FE_MODE]=FE_MODE_REQUIRED will be changed. Get the JSON unchanged
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass); // Below, $formElement[FE_MODE]=FE_MODE_REQUIRED will be changed. Get the JSON unchanged
 
         if ($value === '' || $value === false) {
             $textDeleteClass = 'hidden';
@@ -3504,7 +3510,8 @@ abstract class AbstractBuildForm {
         $attribute .= HelperFormElement::getAttributeFeMode($formElement[FE_MODE]);
         $attribute .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass);
 
         $html = Support::wrapTag("<textarea $attribute>", htmlentities($value), false);
         $formElement = HelperFormElement::prepareExtraButton($formElement, false);
@@ -3566,7 +3573,8 @@ abstract class AbstractBuildForm {
         $attribute .= HelperFormElement::getAttributeFeMode($formElement[FE_MODE]);
         $attribute .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass);
 
         $html = Support::wrapTag("<textarea $attribute>", htmlentities($value), false);
         $formElement = HelperFormElement::prepareExtraButton($formElement, false);
@@ -3879,7 +3887,8 @@ abstract class AbstractBuildForm {
      */
     public function buildNote(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass);
 
         $attribute = Support::doAttribute('id', $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_INPUT);
         $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE]);
@@ -3957,7 +3966,8 @@ abstract class AbstractBuildForm {
         // restore parent processed FE's
         $this->feSpecNative = $tmpStore;
 
-        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
+        $wrapSetupClass = $this->wrap[WRAP_SETUP_ELEMENT][WRAP_SETUP_CLASS] ?? '';
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement, $wrapSetupClass);
 
         return $html;
     }
diff --git a/extension/Classes/Core/Exception/AbstractException.php b/extension/Classes/Core/Exception/AbstractException.php
index 42cb6371d..84e905b70 100644
--- a/extension/Classes/Core/Exception/AbstractException.php
+++ b/extension/Classes/Core/Exception/AbstractException.php
@@ -184,7 +184,7 @@ class AbstractException extends \Exception {
                     'Debug', EXCEPTION_TABLE_CLASS);
 
                 $arrDebugHiddenClean = OnArray::htmlentitiesOnArray($arrDebugHidden);
-                $arrDebugHiddenClean[EXCEPTION_STACKTRACE] = implode($arrTrace, '<br>');
+                $arrDebugHiddenClean[EXCEPTION_STACKTRACE] = implode('<br>', $arrTrace);
 //                $arrDebugHiddenClean[EXCEPTION_EDIT_FORM] = implode($arrTrace, '<br>');
                 $hidden = OnArray::arrayToHtmlTable($arrDebugHiddenClean, 'Details', EXCEPTION_TABLE_CLASS);
 
@@ -195,7 +195,7 @@ class AbstractException extends \Exception {
         }
 
         $qfqLog = Path::absoluteQfqLogFile();
-        $arrDebugHidden[EXCEPTION_STACKTRACE] = PHP_EOL . implode($arrTrace, PHP_EOL);
+        $arrDebugHidden[EXCEPTION_STACKTRACE] = PHP_EOL . implode(PHP_EOL, $arrTrace);
         $arrLogAll = array_merge($arrMsg, $arrShow, $arrDebugShow, $arrDebugHidden);
         $logAll = OnArray::arrayToLog($arrLogAll);
         Logger::logMessage($logAll, $qfqLog);
diff --git a/extension/Classes/Core/Helper/DateTime.php b/extension/Classes/Core/Helper/DateTime.php
index 19f52329a..094a8eb45 100644
--- a/extension/Classes/Core/Helper/DateTime.php
+++ b/extension/Classes/Core/Helper/DateTime.php
@@ -29,7 +29,7 @@ class DateTime {
      * @throws \UserFormException
      * @throws \UserReportException
      */
-    public function buildDateTime(array $formElement, $htmlFormElementName, $value, array &$json, array $formSpec, Store $store, $mode = FORM_LOAD, $wrappedClass = ''): string {
+    public static function buildDateTime(array $formElement, $htmlFormElementName, $value, array &$json, array $formSpec, Store $store, $mode = FORM_LOAD, $wrappedClass = ''): string {
         $attribute = '';
         $placeholder = '';
         $datetimeKeys = array(
@@ -191,7 +191,7 @@ class DateTime {
 
         $attribute .= HelperFormElement::getAttributeList($formElement, [FE_MIN, FE_MAX]);
 
-        $json = AbstractBuildForm::getFormElementForJson($htmlFormElementName, $value, $formElement, null, $wrappedClass);
+        $json = AbstractBuildForm::getFormElementForJson($htmlFormElementName, $value, $formElement, null, null, $wrappedClass);
 
         $formElement = HelperFormElement::prepareExtraButton($formElement, true);
 
@@ -212,7 +212,7 @@ class DateTime {
      * @param $formSpec
      * @return string
      */
-    private function getDatePickerClassName($formElement, $formSpec): string {
+    private static function getDatePickerClassName($formElement, $formSpec): string {
         $datePickerClassName = '';
         if ($formElement[FE_DATE_TIME_PICKER_TYPE] === DATE_TIME_PICKER_QFQ) {
             $datePickerClassName = 'qfq-datepicker';
@@ -230,7 +230,7 @@ class DateTime {
      * @param $formElement
      * @return array
      */
-    private function getDefaultDateFormat(&$formElement): array {
+    private static function getDefaultDateFormat(&$formElement): array {
         $defaultDateFormat = explode(' ', $formElement[FE_DATE_FORMAT], 2);
         $defaultFormat = array();
         if (isset($defaultDateFormat[1])) {
@@ -253,7 +253,7 @@ class DateTime {
      * @param $value
      * @return false|mixed|string
      */
-    private function formatValueForBrowser($feType, $value) {
+    private static function formatValueForBrowser($feType, $value) {
         $dateOldFormat = date_create($value);
         if ($feType === FE_TYPE_DATE) {
             $value = date_format($dateOldFormat, "Y-m-d");
@@ -267,7 +267,7 @@ class DateTime {
      * @param $feType
      * @return string
      */
-    private function getDateTimeBrowserType($feType): string {
+    private static function getDateTimeBrowserType($feType): string {
         if ($feType == FE_TYPE_DATE) {
             $type = 'date';
         } elseif ($feType == FE_TYPE_TIME) {
@@ -283,7 +283,7 @@ class DateTime {
      * @param $feType
      * @return mixed
      */
-    private function getDateTimeFormatQfq($defaultFormat, $feType) {
+    private static function getDateTimeFormatQfq($defaultFormat, $feType): mixed {
         switch ($defaultFormat['date']) {
             case FORMAT_DATE_INTERNATIONAL:
             case FORMAT_DATE_INTERNATIONAL_QFQ:
@@ -309,7 +309,7 @@ class DateTime {
      * @param $feShowSeconds
      * @return mixed
      */
-    private function getTimeFormat($defaultFormat, $feDateTimePickerType, $feShowSeconds) {
+    private static function getTimeFormat($defaultFormat, $feDateTimePickerType, $feShowSeconds) {
         if ($defaultFormat['timeParts'][0] === 'HH' || $defaultFormat['timeParts'][0] === 'hh') {
             $defaultFormat['date'] = $defaultFormat['timeParts'][0] . ':' . $defaultFormat['timeParts'][1];
         } else if ($feDateTimePickerType === DATE_TIME_PICKER_QFQ) {
@@ -328,7 +328,7 @@ class DateTime {
      * @param $enabledDays
      * @return false|string
      */
-    private function getDateTimePickerDisabledDays($enabledDays) {
+    private static function getDateTimePickerDisabledDays($enabledDays) {
         // convert enabled days from datetimepicker user input daysOfWeekEnabled to disabled days
         $enabledDays = explode(',', $enabledDays);
         $disabledDays = '';
@@ -340,7 +340,7 @@ class DateTime {
                     $flagDayPoint = true;
                 }
             }
-            if ($flagDayPoint == false) {
+            if (!$flagDayPoint) {
                 $disabledDays .= $i . ',';
             }
         }
@@ -362,7 +362,7 @@ class DateTime {
      * @return void
      * @throws \CodeException
      */
-    private function setDateTimePickerAttributes($formElement, $defaultDateFormat, $dateTimeKeys, $dateTimeAttributes, &$attribute) {
+    private static function setDateTimePickerAttributes($formElement, $defaultDateFormat, $dateTimeKeys, $dateTimeAttributes, &$attribute) {
         $keyCount = 0;
         foreach ($dateTimeKeys as $key) {
             if (isset($formElement[$key]) && $formElement[$key] != "" && $key != FE_DATE_FORMAT) {
@@ -378,7 +378,7 @@ class DateTime {
      * @param $formElement
      * @return void
      */
-    private function setNoQfqMinMax(&$formElement) {
+    private static function setNoQfqMinMax(&$formElement) {
         if ($formElement[FE_TYPE] == FE_TYPE_DATE) {
             $dateMinMaxFormat = "Y-m-d";
         } else {
@@ -405,7 +405,7 @@ class DateTime {
      * @return string - checked datetime string
      * @throws \UserFormException
      */
-    public static function doDateTime(array &$formElement, $value) {
+    public static function doDateTime(array &$formElement, $value): string {
 
         // check for browser dateTimePickerType and adjust value
         $typeBrowser = false;
diff --git a/extension/Classes/Core/Report/Report.php b/extension/Classes/Core/Report/Report.php
index ac0bfbba5..db99186fc 100644
--- a/extension/Classes/Core/Report/Report.php
+++ b/extension/Classes/Core/Report/Report.php
@@ -349,7 +349,7 @@ class Report {
      * @param string $clause : the sort argument 0 ASC, 1 ASC... according to the number of columns
      * @param bool|true $ascending
      */
-    private function sortIndexArray(array &$ary, $clause, $ascending = true) {
+    private function sortIndexArray(array &$ary, $clause, $ascending = true): void {
 
         $clause = str_ireplace('order by', '', $clause);
         $clause = preg_replace('/\s+/', ' ', $clause);
@@ -369,31 +369,39 @@ class Report {
                 $dirAry[] = $def;
             }
         }
-        $fnBody = '';
+        $fnBody = [];
         for ($i = count($keyAry) - 1; $i >= 0; $i--) {
             $k = $keyAry[$i];
             $t = $dirAry[$i];
             $f = -1 * $t;
-            $aStr = '$a[\'' . $k . '\']';
-            $bStr = '$b[\'' . $k . '\']';
 
-            if (strpos($k, '(') !== false) {
-                $aStr = '$a->' . $k;
-                $bStr = '$b->' . $k;
-            }
+            $fnBody[] = function ($a, $b) use ($k, $t, $f) {
+                if (str_contains($k, '(')) {
+                    $aStr = $a->$k ?? null;
+                    $bStr = $b->$k ?? null;
+                } else {
+                    $aStr = $a[$k] ?? null;
+                    $bStr = $b[$k] ?? null;
+                }
 
-            if ($fnBody == '') {
-                $fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
-                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
-            } else {
-                $fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
-                $fnBody .= "}\n";
-                $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
-            }
+                if ($aStr == $bStr) {
+                    return 0;
+                }
+
+                return ($aStr < $bStr) ? $t : $f;
+            };
         }
 
-        if ($fnBody) {
-            $sortFn = create_function('$a,$b', $fnBody);
+        if (!empty($fnBody)) {
+            $sortFn = function ($a, $b) use ($fnBody) {
+                foreach ($fnBody as $fn) {
+                    $result = $fn($a, $b);
+                    if ($result !== 0) {
+                        return $result;
+                    }
+                }
+                return 0;
+            };
 
             // TODO: at the moment, $sortFn() triggers some E_NOTICE warnings. We stop these here for a short time.
             $errorSet = error_reporting();
-- 
GitLab