QUIQQER issueshttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues2024-03-26T15:59:54Zhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1352QUIQQER Bootstrapping ermöglichen ohne Datenbankverbindung2024-03-26T15:59:54ZJan WennrichQUIQQER Bootstrapping ermöglichen ohne DatenbankverbindungAktuell ist es so, dass wenn man die `bootstrap.php` Datei requiret, zwangsweise eine Datenbankverbindung existieren muss.
Das sorgt dafür, dass bspw. statische Codeanalyse und Unit-Tests sehr viel mehr Zeit benötigen oder gar nicht aus...Aktuell ist es so, dass wenn man die `bootstrap.php` Datei requiret, zwangsweise eine Datenbankverbindung existieren muss.
Das sorgt dafür, dass bspw. statische Codeanalyse und Unit-Tests sehr viel mehr Zeit benötigen oder gar nicht ausgeführt werden können.
Das Verbinden mit der Datenbank passiert wegen folgendem Ablauf:
1. `packages/quiqqer/quiqqer/bootstrap.php`: `require_once lib/header.php`
2. `packages/quiqqer/quiqqer/lib/header.php`: `QUI:load()`
3. `packages/quiqqer/quiqqer/lib/classmap/QUI.php`: `self::getPackageManager()`
4. `packages/quiqqer/quiqqer/lib/classmap/QUI.php`: `new Package/Manager()`
5. `packages/quiqqer/quiqqer/lib/QUI/Package/Manager.php`: `new Events/Manager()`
6. `packages/quiqqer/quiqqer/lib/QUI/Events/Manager.php`: `QUI::getDataBase()`Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1351Funktion des "/var/composer/files" Ordner?2024-03-25T15:16:04ZJan WennrichFunktion des "/var/composer/files" Ordner?Wird der oben genannte Ordner von Composer oder von QUIQQER erstellt?
Wenn ich das richtig sehe enthält der Ordner die Archive diverser Versionen der installierten Pakete.
Somit ist er in etwa genauso groß wie der `/packages` Ordner.
...Wird der oben genannte Ordner von Composer oder von QUIQQER erstellt?
Wenn ich das richtig sehe enthält der Ordner die Archive diverser Versionen der installierten Pakete.
Somit ist er in etwa genauso groß wie der `/packages` Ordner.
Ein `php composer.phar clear-cache` leert den Ordner nicht.
Das liegt vermutlich an dem folgenden Fehler:
```
Cache directory does not exist (cache-vcs-dir):
Cache directory does not exist (cache-repo-dir):
Cache directory does not exist (cache-files-dir):
Cache directory does not exist (cache-dir):
All caches cleared.
```
In der `composer.json` ist folgendes definiert:
```json
"config": {
"cache-dir": "\/var\/www\/vhosts\/xyz\/dev.shop.xyz.de\/var\/composer\/"
}
```
Vielleicht findet er den Ordner wegen der Backslashes dann nicht?
Oder stammt der Ordner gar nicht vom Composer Cache und die Dateien kommen von QUIQQER?
Der Ordner bläht jedes grundlegende QUIQQER System um etwa 100% auf (1 GB statt 500 MB).
Es sollte also geklärt werden, woher der Ordner stammt und welche Funktion er erfüllt.Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1350(Gravierende) Fehler bei/mit Favicons2024-03-22T11:04:23ZJan Wennrich(Gravierende) Fehler bei/mit FaviconsBei einem Kunden sind mir einige (gravierende) Fehler bei den Favicons aufgefallen:
1. [ ] Die `favicon.ico` Datei im root-Verzeichnis wird nie überschrieben
2. [ ] QUIQQER sollte das hochgeladene Bild quadratisch machen (bspw. per Imag...Bei einem Kunden sind mir einige (gravierende) Fehler bei den Favicons aufgefallen:
1. [ ] Die `favicon.ico` Datei im root-Verzeichnis wird nie überschrieben
2. [ ] QUIQQER sollte das hochgeladene Bild quadratisch machen (bspw. per Imagick) oder zumindest darauf hinweisen, dass es quadratisch sein muss
3. [ ] Google schreibt eine [Auflösung von 48px oder einem Vielfachen davon](https://developers.google.com/search/docs/appearance/favicon-in-search?hl=de#guidelines) vor. Es wird nur eine Variante in 48x48px generiert, die anderen Auflösungen sind (für Google) also nutzlos
4. [ ] Wenn das Cache Modul installiert ist, werden die Favicons als `.webp` eingebunden. Dieses Format wird offiziell nicht unterstützt: https://en.wikipedia.org/wiki/Favicon#Image_file_format_support
5. [ ] Als `type` wird immer `image/png` verwendet, obwohl die verlinkte Datei eine `.webp` oder `.jpg` Datei ist
6. [ ] Als `sizes` wird immer `16x16` (oder Vielfache davon) verwendet, obwohl die verlinkte Datei nicht quadratisch ist (bspw. 48x32 px)Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1349"DEV" Modus installiert gefährliche/instabile Abhängigkeiten2024-03-13T08:44:08ZJan Wennrich"DEV" Modus installiert gefährliche/instabile AbhängigkeitenWenn ich mein Test-System in den `DEV`-Modus schalte und ein Update durchführe, werden viele Pakete in "gefährlichen"/instabilen Versionen installiert.
Beispiel:
```
- Upgrading psr/container (2.0.2 => dev-master 7079847)
- Upgrading p...Wenn ich mein Test-System in den `DEV`-Modus schalte und ein Update durchführe, werden viele Pakete in "gefährlichen"/instabilen Versionen installiert.
Beispiel:
```
- Upgrading psr/container (2.0.2 => dev-master 7079847)
- Upgrading psr/http-factory (1.0.2 => dev-master 7037f4b)
- Upgrading psr/http-server-handler (1.0.2 => dev-master 13403d4)
- Upgrading psr/http-server-middleware (1.0.2 => dev-master 459eeb7)
- Upgrading psr/log (3.0.0 => dev-master fe5ea30)
```
Nun sind die Pakete also in "unbekannten" Versionen installiert, die potenziell mein System kaputt machen, da nicht die erwartete API vorhanden ist.
Wieso diese Versionen überhaupt installiert werden können, ist mir unklar. Die Installation von `dev-` Versionen wird nirgendwo explizit erlaubt.
Beispiel:
```
$ ./console composer why psr/container
slim/slim 4.x-dev requires psr/container (^1.0 || ^2.0)
symfony/service-contracts 3.5.x-dev requires psr/container (^1.1|^2.0)
```
------
Meiner Meinung nach ist dieses Verhalten gefährlich und sollte nicht durchgeführt werden.
Ich vermute es liegt daran, dass in der root `composer.json` die `minimum-stability` auf `dev` gesetzt wird.
Als Entwickler (also im DEV Mode), kann ich selbst entscheiden welche Stabilität ich bei welchen Paketen benötige.
Wie instabile Versionen installiert werden können, ist hier dokumentiert: https://dev.quiqqer.com/quiqqer/quiqqer/-/wikis/developer/Paket-in-instabiler-Version-installieren
Wie seht ihr das Installieren von instabilen/gefährlichen Versionen und meinen Änderungsvorschlag, @peat, @mor, @henbug?Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1348"DEV" Modus installiert alle Abhängigkeiten (außer QUIQQER Pakete) als git Re...2024-03-12T11:41:10ZJan Wennrich"DEV" Modus installiert alle Abhängigkeiten (außer QUIQQER Pakete) als git RepositoryWenn der `DEV` Modus in der QUIQQER Config aktiviert ist und ein Update durchgeführt wird, werden ALLE Pakete als git Repository installiert.
Bei meinem kleinen Test-System sind das bereits über 60 Repositories, die geklont werden müss...Wenn der `DEV` Modus in der QUIQQER Config aktiviert ist und ein Update durchgeführt wird, werden ALLE Pakete als git Repository installiert.
Bei meinem kleinen Test-System sind das bereits über 60 Repositories, die geklont werden müssen.
Das sorgt dafür, dass Updates sehr langsam werden und viel RAM verbrauchen.
Ursache für das Installieren der Repositories ist, dass in der root `composer.json` der Wert von `config.preferred-install` auf `source` gesetzt wird. Das weißt Composer an Pakete aus ihrer Source zu klonen (bspw. git).
Hinzu kommt, dass das nicht (richtig) für `quiqqer/*` Pakete funktioniert. Es werden also nur QUIQQER-fremde Pakete als git Repository installiert und QUIQQER Pakete nicht. Als QUIQQER Entwickler hat das für mich keinen Mehrwert.
Ursache hierfür ist, dass der update.quiqqer.com Server die `source` Quelle nur für `dev-`-Versionen zurückgibt für stabile Versionen wird nur die `dist`-Quelle zurückgegeben. Da die meisten Pakete in stabilen Versionen installiert sind, werden sie also nicht als git Repository installiert.
Für Pakete, die von composer.quiqqer.com kommen, funktioniert das hingegen schon, da dort die Quellen stimmen.
<details><summary>Beispiel `quiqqer/quiqqer` auf https://update.quiqqer.com/packages.json</summary>
![grafik](/uploads/d01ba23a7376e578df8545662e910480/grafik.png)
</details>
<details><summary>Beispiel `ramsey/uuid` auf https://composer.quiqqer.com/p2/ramsey/uuid.json: </summary>
![grafik](/uploads/aa3020faf2c9b429c023a8bb16eef01d/grafik.png)
</details>
-----
Meiner Meinung nach sollte das Verhalten wie folgt überarbeitet werden:
1. Auf jeden Fall QUIQQER-fremde Pakete standardmäßig im DEV Mode nie als git Repository installieren. Das würde so funktionieren:
```json
{
"config": {
"preferred-install": {
"quiqqer/*": "source"
}
}
}
```
Quelle: https://getcomposer.org/doc/06-config.md#preferred-install
2. Auf jeden Fall die `source` Quelle von update.quiqqer.com für alle Versionen zurückgeben lassen
3. Eventuell nie alle (QUIQQER) Pakete als git Repository installieren. Es kommt selten vor, dass man wirklich ALLE Pakete als git Repository braucht. Wie man ein einzelnes Paket als git Repository installiert, ist mittlerweile dokumentiert: https://dev.quiqqer.com/quiqqer/quiqqer/-/wikis/developer/Paket-als-git-Repository-installieren
------
Was sagt ihr zu diesen Änderungsvorschlägen, @peat, @mor und @henbug?Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1347Updateserver Typ "path" fehlt2024-03-11T09:49:52ZJan WennrichUpdateserver Typ "path" fehltComposer erlaubt neuerdings (?) das Hinzufügen von Paketen aus Ordnern: https://getcomposer.org/doc/05-repositories.md#path
```json
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-pack...Composer erlaubt neuerdings (?) das Hinzufügen von Paketen aus Ordnern: https://getcomposer.org/doc/05-repositories.md#path
```json
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package"
}
],
"require": {
"my/package": "*"
}
}
```
In der Oberfläche zum Hinzufügen eines Update Servers kann man diesen Typ leider nicht auswählen.
Schreibt man den Wert direkt in die `etc/source.list.ini.php` Config und führt ein Setup aus, dann landet der Eintrag korrekt in der `var/composer/composer.json`.
Es fehlt also vllt. nur der Wert in dem Select in der UI?Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1344Überprüfung und Umstellung der Datenbank-Engine von MyISAM auf InnoDB2024-03-08T09:01:22ZMoritz ScholzÜberprüfung und Umstellung der Datenbank-Engine von MyISAM auf InnoDB
**Beschreibung:**
Eine Überprüfung soll durchgeführt werden, um festzustellen, ob die Umstellung der Standard-Datenbank-Engine von MyISAM auf InnoDB in MySQL/MariaDB sinnvoll und durchführbar ist. In Anbetracht der Vorteile, die InnoD...
**Beschreibung:**
Eine Überprüfung soll durchgeführt werden, um festzustellen, ob die Umstellung der Standard-Datenbank-Engine von MyISAM auf InnoDB in MySQL/MariaDB sinnvoll und durchführbar ist. In Anbetracht der Vorteile, die InnoDB bietet, insbesondere hinsichtlich der Datenintegrität, sowie seiner Rolle als der neue Standard, ist eine Evaluierung für eine mögliche Migration erforderlich.
**Aufgaben:**
1. **Kompatibilitätsprüfung:**
Es muss überprüft werden, ob alle bestehenden Tabellen mit der InnoDB-Engine kompatibel sind und ob eine Migration ohne Probleme möglich ist.
2. **Migrations-Skript:**
Ein Skript für die manuelle Migration von MyISAM zu InnoDB muss erstellt werden. Dieses Skript sollte detaillierte Anweisungen und Hinweise auf mögliche Komplikationen beinhalten.
3. **Anpassung der Standard-Einstellungen:**
Die Standard-Engine-Einstellungen in der Datenbankkonfiguration des QUIQQER-Codes und aller relevanten Module müssen angepasst werden, um InnoDB als Standard zu etablieren.
**Erwartete Ergebnisse:**
- Ein kurzer Bericht über die Machbarkeit der Migration, einschließlich einer Analyse der Kompatibilität und einer Bewertung möglicher Risiken.
- Ein umfassendes Migrations-Skript, das den Wechsel von MyISAM zu InnoDB unterstützt.
- Überarbeitete Konfigurationseinstellungen in der QUIQQER Datenbank KOnfiguration, die InnoDB als die vordefinierte Datenbank-Engine festlegen.2.0 (* *)https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1343Links in Lizenztexte2024-03-06T09:37:04ZMichael DanielczokLinks in Lizenztexte> kannst du da bitte bei gelegenheit links draus amchen ? danke
![image](/uploads/36b9fc9a7a1c3dbdeee92bb51734f594/image.png)> kannst du da bitte bei gelegenheit links draus amchen ? danke
![image](/uploads/36b9fc9a7a1c3dbdeee92bb51734f594/image.png)Michael DanielczokMichael Danielczok2024-03-12https://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1342Fehlende Fehlermeldung im Frontend bei abgelaufenem Nutzeraccount2024-03-05T14:42:43ZMoritz ScholzFehlende Fehlermeldung im Frontend bei abgelaufenem NutzeraccountTicket-Titel: Fehlende Fehlermeldung im Frontend bei abgelaufenem Nutzeraccount
Beschreibung:
Es wurde ein Problem im QUIQQER Backend identifiziert, bei dem keine Fehlermeldung im Frontend angezeigt wird, wenn sich ein Benutzer mit eine...Ticket-Titel: Fehlende Fehlermeldung im Frontend bei abgelaufenem Nutzeraccount
Beschreibung:
Es wurde ein Problem im QUIQQER Backend identifiziert, bei dem keine Fehlermeldung im Frontend angezeigt wird, wenn sich ein Benutzer mit einem abgelaufenen Konto anzumelden versucht. Obwohl der Ajax-Request für den Login eine klare Fehlermeldung zurückliefert, die besagt, dass der Login aufgrund eines abgelaufenen Benutzerkontos fehlgeschlagen ist, wird diese Information nicht an den Nutzer im Frontend weitergeleitet.
Details des Ajax-Response:
Der Ajax-Request für den Login liefert folgende Antwort zurück: `{"ajax_users_login":{"Exception":{"message":"Login fehlgeschlagen. Ihr Benutzerkonto ist abgelaufen. 2024-03-05 00:00:00","code":0,"type":"QUI\\Users\\Exception","attributes":{"reason":"auth_error_login_expired"}}},"message_handler":[],"maintenance":0,"jsCallbacks":[],"vMd5":"3ee640ce0bb771defdbef32774a681a6"}`.
Problem:
Die Fehlermeldung wird nicht im Frontend angezeigt, was zu Verwirrung beim Endbenutzer führt, da dieser nicht über den Grund des fehlgeschlagenen Logins informiert wird.
Aufgaben:
1. Analyse des Problems, um die Ursache zu identifizieren, warum die Fehlermeldung nicht im Frontend dargestellt wird.
2. Implementierung einer Lösung, die sicherstellt, dass die Fehlermeldung aus dem Ajax-Response im Frontend korrekt angezeigt wird.
3. Durchführung von Tests, um zu verifizieren, dass die Fehlermeldung bei abgelaufenen Benutzerkonten nun wie erwartet im Frontend erscheint.
4. Aktualisierung der Dokumentation, falls notwendig, um die Änderungen zu reflektieren.Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1340Integration von PHPStan2024-03-04T07:04:33ZJan WennrichIntegration von PHPStanEs soll diskutiert werden, ob PHPStan in die CI aufgenommen wird, um die Codebase stabiler zu machen.
## Was ist PHPStan?
> PHPStan finds bugs in your code without writing tests.
> PHPStan scans your whole codebase and looks for both ...Es soll diskutiert werden, ob PHPStan in die CI aufgenommen wird, um die Codebase stabiler zu machen.
## Was ist PHPStan?
> PHPStan finds bugs in your code without writing tests.
> PHPStan scans your whole codebase and looks for both obvious & tricky bugs. Even in those rarely executed if statements that certainly aren't covered by tests.
> Thanks to rule levels you don't get overwhelmed with thousands of errors on the first run.
> You can increase PHPStan's capabilities on your code at your own pace. It makes work feel like a game.
> Enjoy new language features before they come to PHP. Do you dream of generics? Array shapes? Checked exceptions? With PHPStan you can use these today by leveraging the power of PHPDocs.
## Was sind Level?
>>>
1. basic checks, unknown classes, unknown functions, unknown methods called on $this, wrong number of arguments passed to those methods and functions, always undefined variables
1. possibly undefined variables, unknown magic methods and properties on classes with __call and __get
1. unknown methods checked on all expressions (not just $this), validating PHPDocs
1. return types, types assigned to properties
1. basic dead code checking - always false instanceof and other type checks, dead else branches, unreachable code after return; etc.
1. checking types of arguments passed to methods and functions
1. report missing typehints
1. report partially wrong union types - if you call a method that only exists on some types in a union type, level 7 starts to report that; other possibly incorrect situations
1. report calling methods and accessing properties on nullable types
1. be strict about the mixed type - the only allowed operation you can do with it is to pass it to another mixed
>>>
Laut diversen Meinungen sollte Level 5 von jedem Projekt erreicht werden (können), um eine grundlegende Stabilität zu bieten.
Jedes Level enthält alle vorherigen Level (also enthält Level 5 auch die Level 0-4)
_Weitere Informationen: https://phpstan.org/user-guide/rule-levels_
## Wie wird PHPStan integriert? (Nutzung der Baseline)
tl;dr: Mit der Baseline werden die Fehler der aktuellen Codebase ignoriert und nur neue Fehler gemeldet
>>>
The usual workflow when introducing PHPStan to the CI pipeline is to get the number of errors reported on level 0 to zero and merge that into the main branch. When the developers feel like it, they can try raising the level by one, go through the list of errors, fix all of them, and enjoy increased strictness from that point on.
>>>
Beim Erhöhen des Level gibt es dann voraussichtlich eine Vielzahl an Fehlern, die nicht auf einmal behoben werden können. Um dieses Problem zu vermeiden, wird die "Baseline" genutzt:
>>>
PHPStan allows you to declare the currently reported list of errors as “the baseline” and cause it not being reported in subsequent runs. It allows you to be interested in violations only in new and changed code.
>>>
## Was ist zu diskutieren?
In den Kommentaren unten zeige ich beispielhaft die Fehler, die von PHPStan in `quiqqer/quiqqer:dev-dev` bei den diversen Levels gemeldet werden.
Auf dieser Basis kann geklärt werden, ob die Integration von PHPStan sinnvoll ist.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1339Version Constraint von symfony/http-foundation präzisieren2024-02-20T14:25:27ZJan WennrichVersion Constraint von symfony/http-foundation präzisierenIn quiqqer/quiqqer#1315 wurde der unbound Version constraint des oben genannten Pakets behoben.
Um keine Schäden zu verursachen wurde eine sehr breite Version Range gewählt.
Das sollte in Zukunft, wenn Tests vorhanden sind, präzisiert ...In quiqqer/quiqqer#1315 wurde der unbound Version constraint des oben genannten Pakets behoben.
Um keine Schäden zu verursachen wurde eine sehr breite Version Range gewählt.
Das sollte in Zukunft, wenn Tests vorhanden sind, präzisiert werden.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1336Workspace Manager: Inkonsistente User Interface/Klasse Verwendung2024-02-20T13:00:21ZJan WennrichWorkspace Manager: Inkonsistente User Interface/Klasse VerwendungDer Workspace Manager akzeptiert zum erstellen von Workspaces (`addWorkspace`) als Benutzer ein `QUI\Interfaces\Users\User`.
Aus meiner Sicht ist das das richtige Verhalten (Liskov Substitution Principle).
Bei den anderen Methoden (bs...Der Workspace Manager akzeptiert zum erstellen von Workspaces (`addWorkspace`) als Benutzer ein `QUI\Interfaces\Users\User`.
Aus meiner Sicht ist das das richtige Verhalten (Liskov Substitution Principle).
Bei den anderen Methoden (bspw. [`getWorkspaceById`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/e3b6b6faf662c02ad49614f544fcff8084b2cdab/lib/QUI/Workspace/Manager.php#L281)) wird hingegen ein `QUI\Users\User` gefordert.
Das erschwert das testen und die Verwendung im allgemeinen.
Es sollte überall das User Interface genutzt werden.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1335Locale: getPartsOfLocaleString liefert unerwartete/falsche Ergebnisse2024-02-02T17:30:28ZJan WennrichLocale: getPartsOfLocaleString liefert unerwartete/falsche ErgebnisseDie Methode [`Locale->getPartsOfLocaleString()`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/312a71f4fdbe9b6fe8b780e7873be39473fb07ec/lib/QUI/Locale.php#L700) liefert unerwartete Ergebnisse, wenn man inkorrekte Locale Strings übergibt (...Die Methode [`Locale->getPartsOfLocaleString()`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/312a71f4fdbe9b6fe8b780e7873be39473fb07ec/lib/QUI/Locale.php#L700) liefert unerwartete Ergebnisse, wenn man inkorrekte Locale Strings übergibt (siehe dazu ggf. auch #1334)
Siehe dazu der nachfolgende Output eines Unit-Tests:
```
There were 3 failures:
1) QUI\LocaleTest::testGetPartsOfLocaleString with data set "3" ('this.is.a.test', null, null)
Failed asserting that 'this.is.a.test' matches expected null.
/opt/homebrew/var/www/quiqqer-cc/packages/quiqqer/quiqqer/tests/unit/QUI/LocaleTest.php:141
2) QUI\LocaleTest::testGetPartsOfLocaleString with data set "4" ('this.is.a.test [quiqqer/quiqqer]', null, null)
Failed asserting that 'this.is.a.test' matches expected null.
/opt/homebrew/var/www/quiqqer-cc/packages/quiqqer/quiqqer/tests/unit/QUI/LocaleTest.php:141
3) QUI\LocaleTest::testGetPartsOfLocaleString with data set "6" ('[ ]', null, null)
Failed asserting that ']' matches expected null.
```
In den Klammern steht ganz links der übergebene Wert und danach dann die von mir erwartete Locale Group und Locale Variable (also immer null).
Die Ausgabe hinter "Failed asserting that" gibt an was die Methode stattdesssen zurückgegeben hat.
Es muss geklärt werden, ob das Verhalten so in Ordnung ist oder ob eine Fehlerbehandlung eingebaut werden sollte.Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1334Locale: isLocaleString liefert falsche Ergebnisse2024-02-02T17:28:28ZJan WennrichLocale: isLocaleString liefert falsche ErgebnisseWenn man [`Locale->isLocaleString()`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/312a71f4fdbe9b6fe8b780e7873be39473fb07ec/lib/QUI/Locale.php#L680) aufruft gibt die Methode teilweise falsche Ergebnisse zurück.
Wenn man die folgenden We...Wenn man [`Locale->isLocaleString()`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/312a71f4fdbe9b6fe8b780e7873be39473fb07ec/lib/QUI/Locale.php#L680) aufruft gibt die Methode teilweise falsche Ergebnisse zurück.
Wenn man die folgenden Werte übergibt, kommt fälschlicherweise `true` zurück:
- `this.is.a.test [quiqqer/quiqqer]`
- `[ ]`
Die Methode prüft nur, ob eckige Klammern und ein Leerzeichen in dem String vorkommen - das ist unzureichend.
Besser wäre ein regulärer Ausdruck der Form:
```regex
\[\w+\/\w+\] [\w\.]+
```
(siehe https://regex101.com/r/3x3m2V/1)Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1333Locale: setTemporaryCurrent & resetCurrent funktioniert nicht korrekt2024-02-02T16:06:52ZJan WennrichLocale: setTemporaryCurrent & resetCurrent funktioniert nicht korrektDie Methode [`setTemporaryCurrent`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/4a1b4877b872545ac3209b4e8ab37559bb65ec0a/lib/QUI/Locale.php) speichert die temporäre Sprache nur, wenn bereits eine temporäre Sprache gesetzt ist.
Das führ...Die Methode [`setTemporaryCurrent`](https://dev.quiqqer.com/quiqqer/quiqqer/blob/4a1b4877b872545ac3209b4e8ab37559bb65ec0a/lib/QUI/Locale.php) speichert die temporäre Sprache nur, wenn bereits eine temporäre Sprache gesetzt ist.
Das führt dazu, dass mit der Methode nie eine temporäre Sprache gesetzt werden kann.
Demenetsprechend funktioniert `resetCurrent` dann auch nicht korrektPatrick MüllerPatrick Müllerhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1330require_once der `/bootstrap.php` entfernen2024-01-30T14:40:42ZJan Wennrichrequire_once der `/bootstrap.php` entfernenDie `packages/quiqqer/quiqqer/quiqqer.php` Datei required die `/bootstrap.php` Datei: https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/master/quiqqer.php#L87.
Also die Datei, die im Webroot liegt.
Die Datei scheint "nur" `ETC_DIR` zu de...Die `packages/quiqqer/quiqqer/quiqqer.php` Datei required die `/bootstrap.php` Datei: https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/master/quiqqer.php#L87.
Also die Datei, die im Webroot liegt.
Die Datei scheint "nur" `ETC_DIR` zu definieren und dann eine weitere Bootstrap Datei von `quiqqer/quiqqer` zu laden.
Das Problem hierbei ist, dass das `require_once` nicht funktioniert, wenn `quiqqer/quiqqer` nicht an dem "normalen" Ort installiert ist (bspw. per Symlink oder ganz ohne QUIQQER-System). Das Problem tritt aktuell bei mir in der CI-Pipeline zum Testen auf.
Kann der Inhalt der `bootstrap.php` Datei mit in die `quiqqer.php` aufgenommen und das Requirement damit entfernt werden?
Im Optimalfall sollte `quiqqer/quiqqer` komplett eigenständig funktionieren können, ohne Abhängigkeiten nach außen kennen zu müssen.Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1329Es werden diversen nicht existierende Methode auf QUI\Package\Manager aufgerufen2024-01-28T21:18:40ZJan WennrichEs werden diversen nicht existierende Methode auf QUI\Package\Manager aufgerufen```
------ -------------------------------------------------------------------------
Line admin/ajax/system/activateLocalServer.php
------ -----------------------------------------------------------...```
------ -------------------------------------------------------------------------
Line admin/ajax/system/activateLocalServer.php
------ -------------------------------------------------------------------------
10 Call to an undefined method QUI\Package\Manager::activateLocalServer().
------ -------------------------------------------------------------------------
------ -------------------------------------------------------------------------
Line admin/ajax/system/readLocalRepository.php
------ -------------------------------------------------------------------------
12 Call to an undefined method QUI\Package\Manager::readLocalRepository().
------ -------------------------------------------------------------------------
------ -------------------------------------------------------------------
Line admin/ajax/system/update/byfile.php
------ -------------------------------------------------------------------
24 Call to an undefined method QUI\Package\Manager::updatePackage().
------ -------------------------------------------------------------------
```
Können die Ajax Methoden einfach komplett entfernt werden?
Ansonsten sollte der Methodenaufruf einfach entfernt werden, sodass die Ajax-Methode nichts machen?Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1328Vielzählige "call to undefined method" bei Media Klassen/Objekten2024-02-27T10:56:02ZJan WennrichVielzählige "call to undefined method" bei Media Klassen/ObjektenPHPStan meldet an einigen Stellen, an denen Media Klassen verwendet werden, dass undefinierte Methoden aufgerufen werden.
<details><summary>Problematisches Beispiel anzeigen</summary>
```php
$ids = $Media->getChildrenIds([
'where' ...PHPStan meldet an einigen Stellen, an denen Media Klassen verwendet werden, dass undefinierte Methoden aufgerufen werden.
<details><summary>Problematisches Beispiel anzeigen</summary>
```php
$ids = $Media->getChildrenIds([
'where' => [
'type' => [
'type' => 'NOT',
'value' => 'folder'
]
]
]);
foreach ($ids as $id) {
try {
$Item = $Media->get($id);
$Item->generateSHA1();
} catch (QUI\Exception $Exception) {
QUI::getMessagesHandler()->addError(
$Exception->getMessage()
);
}
}
```
</details>
In dem Beispiel wird sichergestellt, dass kein `Folder` als Media Item geladen wird. Bei `Folder` Objekten gibt es die Methode nicht.
Allerdings werden auch `Video` Objekte ausgelesen, bei denen die Methode ebenfalls nicht existiert.
Trotz dem `try-catch` führt das dann dazu, dass ein `Call to undefined method`-Error fliegt.
Um Fehler dieser Art zu verhindern könnte geprüft werden, ob die entsprechende Methode in den Objekte existiert.
Das ist allerdings eine wenig elegante Lösung.
Es wäre schöner, wenn entsprechende Interfaces eingeführt würden, die dann von den Klassen implementiert werden.
An den betroffenen Stellen kann dann geprüft werden, ob das Objekt das entsprechende Interface implementiert.
Für das obige Beispiel wäre das Interface `HashableMediaItem` denkbar, dass die Methode `generateSHA1` definiert.
Im Code kann dann folgendes gemacht werden:
<details><summary>Lösungsorientiertes Beispiel anzeigen</summary>
```php
foreach ($ids as $id) {
try {
$Item = $Media->get($id);
} catch (QUI\Exception $Exception) {
QUI::getMessagesHandler()->addError(
$Exception->getMessage()
);
}
if (!$Item typeof HashableMediaItem) {
continue;
}
$Item->generateSHA1();
}
```
</details>
-----
<details><summary>Fehler anzeigen</summary>
```
------ ----------------------------------------------------------------------
Line admin/ajax/media/create/sha1.php
------ ----------------------------------------------------------------------
27 Call to an undefined method QUI\Projects\Media\Item::generateSHA1().
------ ----------------------------------------------------------------------
------ ---------------------------------------------------------------------
Line admin/ajax/media/deleteCache.php
------ ---------------------------------------------------------------------
14 Call to an undefined method QUI\Projects\Media\Item::deleteCache().
------ ---------------------------------------------------------------------
------ -------------------------------------------------------------------
Line admin/ajax/media/details.php
------ -------------------------------------------------------------------
47 Call to an undefined method QUI\Projects\Media\Item::getWidth().
51 Call to an undefined method QUI\Projects\Media\Item::getHeight().
75 Call to an undefined method QUI\Projects\Media\Item::getWidth().
79 Call to an undefined method QUI\Projects\Media\Item::getHeight().
------ -------------------------------------------------------------------
------ ---------------------------------------------------------------------
Line admin/ajax/media/file/save.php
------ ---------------------------------------------------------------------
46 Call to an undefined method QUI\Projects\Media\Item::deleteCache().
------ ---------------------------------------------------------------------
------ ------------------------------------------------------------------------
Line admin/ajax/media/folder/children.php
------ ------------------------------------------------------------------------
35 Call to an undefined method QUI\Projects\Media\Item::getChildrenIds().
76 Call to an undefined method QUI\Projects\Media\Item::getChildrenIds().
------ ------------------------------------------------------------------------
------ ----------------------------------------------------------------------
Line admin/ajax/media/folder/create.php
------ ----------------------------------------------------------------------
28 Call to an undefined method QUI\Projects\Media\Item::createFolder().
------ ----------------------------------------------------------------------
------ -------------------------------------------------------------------
Line admin/ajax/media/folder/download.php
------ -------------------------------------------------------------------
26 Call to an undefined method QUI\Projects\Media\Item::createZIP().
------ -------------------------------------------------------------------
------ --------------------------------------------------------------------
Line admin/ajax/media/folder/firstImage.php
------ --------------------------------------------------------------------
31 Call to an undefined method QUI\Projects\Media\Item::firstImage().
------ --------------------------------------------------------------------
------ -----------------------------------------------------------------
Line admin/ajax/media/folder/getSize.php
------ -----------------------------------------------------------------
26 Call to an undefined method QUI\Projects\Media\Item::getSize().
------ -----------------------------------------------------------------
------ -----------------------------------------------------------------------------
Line admin/ajax/media/folder/recursiveEffects.php
------ -----------------------------------------------------------------------------
27 Call to an undefined method QUI\Projects\Media\Item::setEffectsRecursive().
------ -----------------------------------------------------------------------------
------ ---------------------------------------------------------------------
Line admin/ajax/media/get.php
------ ---------------------------------------------------------------------
25 Call to an undefined method QUI\Projects\Media\Item::getChildren().
------ ---------------------------------------------------------------------
------ --------------------------------------------------------------------
Line admin/ajax/media/getsubfolders.php
------ --------------------------------------------------------------------
30 Call to an undefined method QUI\Projects\Media\Item::getFolders().
36 Call to an undefined method QUI\Projects\Media\Item::getFolders().
------ --------------------------------------------------------------------
------ -------------------------------------------------------------------------
Line admin/ajax/media/url/resized.php
------ -------------------------------------------------------------------------
36 Call to an undefined method QUI\Projects\Media\Item::getSizeCacheUrl().
------ -------------------------------------------------------------------------
------ -----------------------------------------------------------------------------
Line lib/QUI/Projects/Media.php
------ -----------------------------------------------------------------------------
616 Call to an undefined method QUI\Projects\Media\Item::childWithNameExists().
694 Call to an undefined method QUI\Projects\Media\Item::deleteCache().
------ -----------------------------------------------------------------------------
------ -----------------------------------------------------------------------
Line lib/QUI/Projects/Media/Folder.php
------ -----------------------------------------------------------------------
1379 Call to an undefined method QUI\Projects\Media\Item::deleteCache().
1456 Call to an undefined method QUI\Projects\Media\Item::generateMD5().
1457 Call to an undefined method QUI\Projects\Media\Item::generateSHA1().
1471 Call to an undefined method QUI\Projects\Media\Item::getResizeSize().
1474 Call to an undefined method QUI\Projects\Media\Item::resize().
1522 Call to an undefined method QUI\Projects\Media\Item::uploadFolder().
------ -----------------------------------------------------------------------
------ -------------------------------------------------------------------------
Line lib/QUI/Projects/Media/Utils.php
------ -------------------------------------------------------------------------
105 Call to an undefined method QUI\Projects\Media\Item::hasChildren().
106 Call to an undefined method QUI\Projects\Media\Item::hasSubFolders().
128 Call to an undefined method QUI\Projects\Media\Item::hasChildren().
129 Call to an undefined method QUI\Projects\Media\Item::hasSubFolders().
391 Call to an undefined method QUI\Projects\Media\Item::getWidth().
443 Call to an undefined method QUI\Projects\Media\Item::getSizeCacheUrl().
463 Call to an undefined method QUI\Projects\Media\Item::getSizeCacheUrl().
480 Call to an undefined method QUI\Projects\Media\Item::getSizeCacheUrl().
491 Call to an undefined method QUI\Projects\Media\Item::getSizeCacheUrl().
925 Call to an undefined method QUI\Projects\Media\Item::createSizeCache().
931 Call to an undefined method QUI\Projects\Media\Item::createCache().
1405 Call to an undefined method DOMNode::getAttribute().
------ -------------------------------------------------------------------------
```
</details>Jan WennrichJan Wennrichhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1327QUI\UsersGroups\Search: Variables $where(Or) in empty() always exist and are ...2024-03-12T08:45:58ZJan WennrichQUI\UsersGroups\Search: Variables $where(Or) in empty() always exist and are not falsyBetroffene Stellen:
1. https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/UsersGroups/Search.php#L276
2. https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4...Betroffene Stellen:
1. https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/UsersGroups/Search.php#L276
2. https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/UsersGroups/Search.php#L343
3. https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/UsersGroups/Search.php#L469
4. https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/UsersGroups/Search.php#L497
Probleme:
1. Ist niemals `empty`, weil `$searchFields` niemals leer ist (Zeile 256), sodass immer ein Wert in `$whereOr` eingefügt wird (Zeile 267)
2. Ist wegen 1. niemals `empty`
3. Ist niemals `empty`, weil `$searchFields` niemals leer ist (Zeile 449), sodass immer ein Wert in `$whereOr` eingefügt wird (Zeile 460)
4. Ist wegen 3. niemals `empty`
Lösung:
Die `empty`-Checks entfernen oder strikter machen.
Da ich nicht beurteilen kann, welche Lösung sinnvoller ist, erstelle ich dieses Ticket.Henning LeutzHenning Leutzhttps://dev.quiqqer.com/quiqqer/quiqqer/-/issues/1326Tools Update: Variable $lines in empty() always exists and is not falsy.2024-03-12T08:46:21ZJan WennrichTools Update: Variable $lines in empty() always exists and is not falsy.Betroffene Stelle:
https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/System/Console/Tools/Update.php#L554-562
Ruft man `explode` mit `PHP_EOL` auf einem leeren String auf, wird immer ein A...Betroffene Stelle:
https://dev.quiqqer.com/quiqqer/quiqqer/-/blob/a43be21de2c98ce7c534e52cb086d64bef7ac3c4/lib/QUI/System/Console/Tools/Update.php#L554-562
Ruft man `explode` mit `PHP_EOL` auf einem leeren String auf, wird immer ein Array mit dem Element `""` zurückgegeben.
Das Array ist also niemals leer, sodass `empty` immer `true` zurückgibt.
Beispiel: https://3v4l.org/sbJtd
Lösung:
Die `if`-Bedingung kann also entweder entfernt werden, oder sollte strikter gemacht werden.
Da ich nicht beurteilen kann, welche Lösung besser/sinnvoller ist, erstelle ich dieses Ticket.Henning LeutzHenning Leutz