1. YoureCom
    1. Über mich
  2. Lösungen
    1. Tipprunde
    2. Aufgaben & Support
    3. Mitglieder-Netzwerk
    4. Online-Shop
    5. Alle Lösungen & Preise
  3. Für Admins
    1. Plugins
    2. ByteMon
    3. ByteMon: Community verwalten
    4. ByteMon: Portalidentität
    5. Individuelle Entwicklung
    6. WSC 6.3 Alpha
    7. GitHub
  4. Neuigkeiten
    1. Kurzmeldungen
  5. Support
  6. Mein Konto
  7. Lösungen testen
  • Anmelden
  • Registrieren
  • Warenkorb 0
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Aufgaben
  • Produkte
  • Pulse-Beiträge
  • Erweiterte Suche
  1. YoureCom – Software für Vereine, Teams & Communities
  2. Repository-Liste
  3. de.yourecom.wcf.api.mpdf

YoureCom Standard automatisch aktualisiert (verwaltete Dateien aus _dev/standard)

  • Marcel Beckers
  • -13 Löschungen
  • +41 Hinzufügungen
  • 54 Gesamt
  • 2 Dateien
  • 22. Oktober 2026 um 08:31
  • tests/lint/check-architecture.php
    <pre>@@ -35,9 +35,11 @@
    * isAccessible() only checks `userID > 0`, it has to check access to the parent object
    * - link-application: `{link controller='X'}` in templates/ of an application without `application=` for a controller
    * (Page/Form/Action) of the plugin itself, it resolves against wcf
    - * - sql-concat: `->query()`/`->prepare()` with a string built by concatenation (literal `.` $var or a variable that
    - * was built with `.=`), instead of `->prepareStatement()` with bound parameters. Same risk as classic
    - * SQL injection regardless of where the value comes from (Marcel 21.10.2026, Sitzung). `query()` on a
    + * - sql-concat: `->query()`/`->prepare()`/`->prepareStatement()`/`->prepareUnmanaged()` with a string built by
    + * concatenation (literal `.` $var or a variable that was built with `.=`) instead of a literal SQL
    + * string with `?` placeholders bound through execute(). Same risk as classic SQL injection regardless
    + * of where the value comes from (Marcel 21.10.2026, Sitzung). Use `prepare()`: prepareStatement() is
    + * deprecated in 6.2 and, like prepareUnmanaged(), does not resolve `app1_` table names. `query()` on a
    * DOMXPath variable is XPath, not SQL, and is skipped
    *
    * Rules that need the types of PHPStan are PHPStan rules (tests/phpstan): getPermission() compared with true/false
    @@ -113,25 +115,25 @@
    $report($relative, 'endpoint-validate-action', 'RPC endpoint calls validateAction(), call the check directly (e.g. validateDelete()) or check in the endpoint/command');
    }
    - // ->query()/->prepare() (not the parameter-bound ->prepareStatement() wrapper) with a string built by
    - // concatenation: same risk as classic SQL injection, whether or not the value comes from user input
    + // SQL built by concatenation instead of `?` placeholders: same risk as classic SQL injection, whether or not the
    + // value comes from user input
    \preg_match_all('~\$(\w+)\s*(?:\.=|=\s*(?:\$\1\s*)?\.)~', $source, $concatMatches);
    $concatenatedVars = \array_unique($concatMatches[1]);
    // DOMXPath::query() takes an XPath expression, not SQL
    \preg_match_all('~\bDOMXPath\s+\$(\w+)|\$(\w+)\s*=\s*new\s+\\\\?DOMXPath\b~', $source, $xpathMatches);
    $xpathVars = \array_filter([...$xpathMatches[1], ...$xpathMatches[2]]);
    - \preg_match_all('~(?:\$(\w+))?->(query|prepare)\s*\(\s*([^)]*)~', $source, $sqlCalls, \PREG_SET_ORDER);
    + \preg_match_all('~(?:\$(\w+))?->(query|prepare|prepareStatement|prepareUnmanaged)\s*\(\s*([^)]*)~', $source, $sqlCalls, \PREG_SET_ORDER);
    foreach ($sqlCalls as $call) {
    [, $receiver, $method, $argument] = $call;
    if ($method === 'query' && \in_array($receiver, $xpathVars, true)) {
    continue;
    }
    if (\str_contains($argument, '.')) {
    - $report($relative, 'sql-concat', "->{$method}() with inline string concatenation, use ->prepareStatement() with bound parameters");
    + $report($relative, 'sql-concat', "->{$method}() with inline string concatenation, use ->prepare() with a literal SQL string and ? placeholders");
    continue;
    }
    if (\preg_match('~^\$(\w+)~', \trim($argument), $variable) && \in_array($variable[1], $concatenatedVars, true)) {
    - $report($relative, 'sql-concat', "->{$method}(\${$variable[1]}) where \${$variable[1]} is built by concatenation, use ->prepareStatement() with bound parameters");
    + $report($relative, 'sql-concat', "->{$method}(\${$variable[1]}) where \${$variable[1]} is built by concatenation, use ->prepare() with a literal SQL string and ? placeholders");
    }
    }
  • tests/lint/check-comments.php
    <pre>@@ -37,13 +37,29 @@
    $messages["{$file}|{$rule}"] ??= "{$file}: [{$rule}] {$message}";
    };
    -/** Strips comment delimiters and asterisks, returns the descriptive lines (without PHPStan/TSDoc tags). */
    +/**
    + * Strips comment delimiters and asterisks, returns the descriptive lines: without PHPStan/TSDoc tags and the lines that
    + * continue a tag up to the next empty line (e.g. a multi-line array shape of @return), like OverrideOrDocblockRule.
    + */
    $descriptive = static function (string $text): array {
    - $lines = \preg_split('~\R~', $text) ?: [];
    - $lines = \array_map(static fn (string $line): string => \trim($line, " \t*/"), $lines);
    - $lines = \array_values(\array_filter($lines, static fn (string $line): bool => $line !== ''));
    + $descriptive = [];
    + $inTag = false;
    + foreach (\preg_split('~\R~', $text) ?: [] as $line) {
    + $line = \trim($line, " \t*/");
    + if ($line === '') {
    + $inTag = false;
    + continue;
    + }
    + if (\preg_match('~^\{?@[a-zA-Z]~', $line)) {
    + $inTag = true;
    + continue;
    + }
    + if (!$inTag) {
    + $descriptive[] = $line;
    + }
    + }
    - return \array_values(\array_filter($lines, static fn (string $line): bool => !\preg_match('~^@[a-zA-Z]~', $line)));
    + return $descriptive;
    };
    /** Returns null if the descriptive text of a comment is at most one line. */
    @@ -165,7 +181,17 @@
    while (\is_array($tokens[$k] ?? null) && $tokens[$k][0] === \T_WHITESPACE) {
    $k++;
    }
    + if (($tokens[$k] ?? null) === '&') {
    + $k++;
    + while (\is_array($tokens[$k] ?? null) && $tokens[$k][0] === \T_WHITESPACE) {
    + $k++;
    + }
    + }
    $name = \is_array($tokens[$k] ?? null) ? $tokens[$k][1] : '';
    + // a closure has no name and cannot carry a docblock
    + if ($name === '') {
    + continue;
    + }
    $onlyInheritDoc = $comment !== null && \str_contains($comment, '@inheritDoc') && $descriptive($comment) === [];
    // with #[\Override] the PHPStan rule yourecom.method.inheritDoc forbids the @inheritDoc docblock
    if (\str_starts_with($name, '__') && !$hasOverride) {

Bereit, deine Community smarter zu machen?

Ob fertiges Produkt oder individuelle Softwarelösung – überzeuge dich selbst.

Jetzt kaufen Demo testen

Direkter Support vom Entwickler

Zuletzt erledigte Aufgaben

  1. Overlay beim Verschieben eines Themas Clan Verwaltung Clan Verwaltung: Foren

    Marcel Beckers Erledigt am 23. Oktober 2026 um 22:10
  2. Feature-Wunsch: Einführung von Tippgemeinschaften / Team-Wertung (Team-Tippen) Wettbewerbe Basissystem Wettbewerbe: Tippspiel

    villain Erledigt am 22. Oktober 2026 um 08:15
  3. Verschiebung zwischen Clanforen/WSB Clan Verwaltung Clan Verwaltung: Foren

    Marcel Beckers Erledigt am 22. Oktober 2026 um 00:12
  4. Massenbearbeitung von Clans Clan Verwaltung

    Marcel Beckers Erledigt am 22. Oktober 2026 um 00:10
  5. Synchronisation zwischen Clan und Benutzergruppe erweitern Clan Verwaltung

    Marcel Beckers Erledigt am 21. Oktober 2026 um 23:59
  6. Überarbeitung der eigenen Events Clan Verwaltung

    Marcel Beckers Erledigt am 21. Oktober 2026 um 23:40
Arbeitsplatz
YoureCom – Software für Vereine, Teams & Communities

YoureCom – Software für Vereine, Teams & Communities. Seit 2004.

Fertig eingerichtete Lösungen für Verein, Team und Community, dazu Erweiterungen für die WoltLab Suite. Aus Wuppertal, für Kunden weltweit.

Lösungen

  • Tipprunde
  • Aufgaben & Support
  • Mitglieder-Netzwerk
  • Online-Shop
  • Alle Lösungen & Preise

Für Administratoren

  • Plugins
  • Clan Verwaltung
  • Wettbewerbe
  • MultiHunter
  • ByteMon
  • Individuelle Entwicklung

YoureCom

  • Über mich
  • Shop
  • Kontakt
  • Neuigkeiten
  • GitHub

Cloud-Verträge

  • AGB Cloud
  • AVV Cloud
  • Rechtswidrige Inhalte melden
  • Datenwechsel

Rechtliches

  • Datenschutzerklärung
  • Impressum
  • AGB
  • Vertrag widerrufen
  • Abonnements kündigen
  • Widerrufsbelehrung
© 2026 YoureCom · Marcel Beckers