diff --git a/FriendsOfRedaxo/addon/UsageCheck/Addon.php b/FriendsOfRedaxo/addon/UsageCheck/Addon.php index af4906e..32cbada 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Addon.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Addon.php @@ -10,6 +10,7 @@ use FriendsOfRedaxo\addon\UsageCheck\Exception\CloneException; use rex_addon; +use rex_addon_interface; /** * Description of Addon @@ -20,7 +21,7 @@ final class Addon { /** * Addon - * @var \rex_addon + * @var rex_addon_interface */ private $addon; diff --git a/FriendsOfRedaxo/addon/UsageCheck/Config.php b/FriendsOfRedaxo/addon/UsageCheck/Config.php index b14908a..6d32446 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Config.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Config.php @@ -21,35 +21,11 @@ class Config /** * (Absolutes) Basis Verzeichnis holen * @return string - */ - public static function getBaseDir() - { - return realpath(__DIR__.'/../../../'); - } - - /** - * Test, ob das Vendor-Verzeichnis gelöscht wurde. - * - * Performance-Probleme durch den rex_autoloader verhindern. - * Dieser versucht alle Dateien zu analysieren. - * - * @throws Exception * @codeCoverageIgnore */ - public static function checkVendorDir() + public static function getBaseDir() { - if (!isset($_SERVER['argv'])) { - $vendorDir = self::getBaseDir().'/vendor'; - if (file_exists($vendorDir) && is_dir($vendorDir)) { - throw new Exception('Please delete '.realpath($vendorDir)); - } - -// $nodeDir = self::getBaseDir().'/node_modules'; -// if(file_exists($nodeDir) && is_dir($nodeDir)){ -// throw new \Exception('Please delete '.realpath($nodeDir)); -// } - } - return true; + return (string) realpath(__DIR__.'/../../../'); } /** diff --git a/FriendsOfRedaxo/addon/UsageCheck/Error.php b/FriendsOfRedaxo/addon/UsageCheck/Error.php index 3256605..e2c147f 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Error.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Error.php @@ -21,6 +21,7 @@ * einem einfachen foreach durlaufen werden können. * * @author akrys + * @implements Iterator */ class Error implements Iterator { @@ -79,7 +80,7 @@ public function next(): void public function current(): string { if (!$this->valid()) { - return false; + return ''; } return $this->errors[$this->index]; } @@ -162,7 +163,7 @@ final public function __clone() /** * Fehlerausgabe - * @param array $messages + * @param array $messages */ public static function getMessageOutputFragment(array $messages): rex_fragment { diff --git a/FriendsOfRedaxo/addon/UsageCheck/Exception/InvalidParameterException.php b/FriendsOfRedaxo/addon/UsageCheck/Exception/InvalidParameterException.php new file mode 100644 index 0000000..2bfc496 --- /dev/null +++ b/FriendsOfRedaxo/addon/UsageCheck/Exception/InvalidParameterException.php @@ -0,0 +1,26 @@ +filename; + } +} diff --git a/FriendsOfRedaxo/addon/UsageCheck/Lib/BaseModule.php b/FriendsOfRedaxo/addon/UsageCheck/Lib/BaseModule.php index 65fa1ad..6c8a787 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Lib/BaseModule.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Lib/BaseModule.php @@ -23,7 +23,7 @@ abstract class BaseModule extends RexBase /** * Tabellenfelder - * @var array + * @var array */ protected array $tableFields = []; @@ -31,14 +31,20 @@ abstract class BaseModule extends RexBase * Anzeigemodus umstellen * @param boolean $bln */ - public function showAll(bool $bln) + public function showAll(bool $bln): void { $this->showAll = $bln; } + /** + * Rechte prüfen + * @return bool + */ + abstract public function hasPerm(): bool; + /** * Daten holen - * @return array + * @return array */ abstract public function get(): array; @@ -52,7 +58,7 @@ abstract protected function getSQL(int $datail_id = null): string; /** * Details holen * @param int $item_id - * @return array + * @return array */ abstract public function getDetails(int $item_id): array; } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Lib/FileSize.php b/FriendsOfRedaxo/addon/UsageCheck/Lib/FileSize.php index 5009ea8..539bef0 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Lib/FileSize.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Lib/FileSize.php @@ -17,16 +17,16 @@ class FileSize { /** * Dateigröße, die analysiert werden soll. - * @var int + * @var int|float */ - private int $size; + private int|float $size; /** * Konstruktor * - * @param int $size + * @param int|float $size */ - public function __construct(int $size) + public function __construct(int|float $size) { $this->size = $size; } @@ -79,10 +79,10 @@ public function getSizeOut(): string * * Dabei zählen, wie oft man sie verkleinern konnte. Daraus ergibt sich die Einheit. * - * @param int $size - * @return array Indezes: index, size + * @param int|float $size + * @return array Indezes: index, size */ - private function getSizeReadable(int $size): array + private function getSizeReadable(int|float $size): array { $return = [ 'index' => 0, @@ -91,7 +91,7 @@ private function getSizeReadable(int $size): array $return['index'] = 0; - while ($return['size'] > 1024 && $return['index'] <= 6) { + while ($return['size'] >= 1024 && $return['index'] <= 6) { $return['index']++; $return['size'] /= 1024; } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Lib/PictureYFrom.php b/FriendsOfRedaxo/addon/UsageCheck/Lib/PictureYFrom.php index d231f18..02cab56 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Lib/PictureYFrom.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Lib/PictureYFrom.php @@ -25,7 +25,9 @@ class PictureYFrom extends RexBase * SQL Partsfür YForm generieren. * * @param int $detail_id - * @return array + * @return array + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ public function getYFormTableSQLParts(int $detail_id = null): array { @@ -65,7 +67,7 @@ public function getYFormTableSQLParts(int $detail_id = null): array $return['additionalJoins'] .= ' OR '; } - $return['additionalJoins'] .= $this->getJoinCondition($field, $tableName); + $return['additionalJoins'] .= $this->getJoinCondition($field, (string) $tableName); } $return['tableFields'][$tableName] = $fields; @@ -78,8 +80,7 @@ public function getYFormTableSQLParts(int $detail_id = null): array /** * YFormTables holen * - * @return array - * @param array &$return + * @return array> */ public function getYFormSQL(): array { @@ -139,7 +140,7 @@ public function getYFormSQL(): array * zu können. * * @param string $yformFieldTable - * @param array $dbs + * @param array $dbs * @returns boolean * @SuppressWarnings(PHPMD.StaticAccess) */ @@ -152,9 +153,10 @@ private function hasMultiple(string $yformFieldTable, ?array $dbs = null): bool } $where = []; + $params = []; foreach ($dbs as $db) { if (isset($db['name']) && $db['name'] != '') { - $where[] .= "(TABLE_NAME=? and TABLE_SCHEMA=? and COLUMN_NAME='multiple')"; + $where[] = "(TABLE_NAME=? and TABLE_SCHEMA=? and COLUMN_NAME='multiple')"; $params[] = $yformFieldTable; $params[] = $db['name']; } @@ -180,7 +182,7 @@ private function hasMultiple(string $yformFieldTable, ?array $dbs = null): bool * Das dürfte an der Anpassung zu YForm 2 liegen, da dort in be_media nun mehrere Dateien angegeben werden dürfen. * Die Prüfung auf $field['multiple'] ist dann eine ebene zu tief. * - * @param array $field + * @param array $field * @param string $tableName * @return string */ diff --git a/FriendsOfRedaxo/addon/UsageCheck/Lib/RexBase.php b/FriendsOfRedaxo/addon/UsageCheck/Lib/RexBase.php index 673b1a4..ef7788c 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Lib/RexBase.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Lib/RexBase.php @@ -9,6 +9,7 @@ namespace FriendsOfRedaxo\addon\UsageCheck\Lib; use Exception; +use FriendsOfRedaxo\addon\UsageCheck\Exception\InvalidParameterException; use rex; use rex_sql; @@ -21,9 +22,9 @@ class RexBase { /** * rexSQL instanz - * @var rex_sql + * @var ?rex_sql */ - private rex_sql $rexSql; + private ?rex_sql $rexSql; /** * rex Instanz @@ -69,9 +70,13 @@ public function setRexSql(rex_sql $sql): self * lt. phpmd sollte man nicht statisch drauf zugreifen * @param string $table * @return string + * @throws InvalidParameterException */ protected function getTable(string $table): string { + if ($table === '') { + throw new InvalidParameterException('Paramer $table should not be empty'); + } if (!$this->rex) { $this->rex = new rex; } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Medium.php b/FriendsOfRedaxo/addon/UsageCheck/Medium.php index 9e10337..ee571e3 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Medium.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Medium.php @@ -24,7 +24,7 @@ class Medium /** * Holt ein Medium-Objekt mit Prüfung der Rechte * - * @param array $item Idezes: category_id, filename + * @param array $item Idezes: category_id, filename * @return rex_media * @throws FunctionNotCallableException * @SuppressWarnings(PHPMD.StaticAccess) @@ -32,8 +32,11 @@ class Medium public static function get(array $item): rex_media { $user = rex::getUser(); - $complexPerm = $user->getComplexPerm('media'); - if (!$user->isAdmin() && + /** + * @var \rex_media_perm $complexPerm + */ + $complexPerm = $user?->getComplexPerm('media'); + if (!$user?->isAdmin() && !(is_object($complexPerm) && $complexPerm->hasCategoryPerm($item['category_id']))) { //keine Rechte am Medium @@ -43,6 +46,9 @@ public static function get(array $item): rex_media //Das Medium wird später gebraucht. /* @var $medium rex_media */ $medium = rex_media::get($item['filename']); + if (!$medium) { + throw new Exception\MediaNotFoundException('Medium '.$item['filename'].' not found'); + } return $medium; } @@ -50,7 +56,7 @@ public static function get(array $item): rex_media * Überprüfen, ob eine Datei existiert. * * @global type $REX - * @param array $item + * @param array $item * @return boolean * @SuppressWarnings(PHPMD.StaticAccess) */ diff --git a/FriendsOfRedaxo/addon/UsageCheck/Modules/Actions.php b/FriendsOfRedaxo/addon/UsageCheck/Modules/Actions.php index eecdee7..d481bd2 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Modules/Actions.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Modules/Actions.php @@ -29,14 +29,14 @@ class Actions extends BaseModule /** * Nicht genutze Module holen * - * @return array + * @return array * * @todo bei Instanzen mit vielen Slices testen. Die Query * riecht nach Performance-Problemen -> Using join buffer (Block Nested Loop) */ public function get(): array { - if (!Permission::getInstance()->check(Perm::PERM_MODUL)) { + if (!$this->hasPerm()) { return []; } @@ -48,12 +48,12 @@ public function get(): array /** * Details zu einem Eintrag holen * @param int $item_id - * @return array + * @return array */ public function getDetails(int $item_id): array { - if (!Permission::getInstance()->check(Perm::PERM_MODUL)) { - return false; + if (!$this->hasPerm()) { + return []; } $result = []; @@ -77,6 +77,8 @@ public function getDetails(int $item_id): array * SQL generieren * @param int $detail_id * @return string + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ protected function getSQL(int $detail_id = null): string { @@ -92,7 +94,7 @@ protected function getSQL(int $detail_id = null): string ,ma.module_id as usagecheck_ma_module, m.name as usage_check_m_name SQL; - $whereArray[] = 'a.id='.$rexSQL->escape($detail_id); + $whereArray[] = 'a.id='.$rexSQL->escape((string) $detail_id); $groupBy = 'group by a.id,ma.module_id'; } else { $where = ''; @@ -129,4 +131,13 @@ protected function getSQL(int $detail_id = null): string return $sql; } + + /** + * Rechte prüfen + * @return bool + */ + public function hasPerm(): bool + { + return Permission::getInstance()->check(Perm::PERM_MODUL); + } } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Modules/Modules.php b/FriendsOfRedaxo/addon/UsageCheck/Modules/Modules.php index 8d22608..4247a33 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Modules/Modules.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Modules/Modules.php @@ -29,14 +29,14 @@ class Modules extends BaseModule /** * Nicht genutze Module holen * - * @return array + * @return array * * @todo bei Instanzen mit vielen Slices testen. Die Query * riecht nach Performance-Problemen -> Using join buffer (Block Nested Loop) */ public function get(): array { - if (!Permission::getInstance()->check(Perm::PERM_STRUCTURE)) { + if (!$this->hasPerm()) { //Permission::PERM_MODUL return []; } @@ -50,11 +50,11 @@ public function get(): array /** * Details zu einem Eintrag holen * @param int $item_id - * @return array + * @return array */ public function getDetails(int $item_id): array { - if (!Permission::getInstance()->check(Perm::PERM_STRUCTURE)) { + if (!$this->hasPerm()) { //Permission::PERM_MODUL return []; } @@ -74,14 +74,13 @@ public function getDetails(int $item_id): array 'fields' => $this->tableFields, ]; } -// -///////////////////// Tmplementation aus RexV5 ///////////////////// -// /** * SQL generieren * @param int $detail_id * @return string + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ protected function getSQL(int $detail_id = null): string { @@ -92,7 +91,7 @@ protected function getSQL(int $detail_id = null): string $rexSQL = rex_sql::factory(); if ($detail_id) { - $whereArray[] = 'm.id='.$rexSQL->escape($detail_id); + $whereArray[] = 'm.id='.$rexSQL->escape((string) $detail_id); $groupBy = ''; $additionalFields = <<showAll) { - $whereArray[] .= 's.id is null'; + $whereArray[] = 's.id is null'; } $additionalFields = ', group_concat(s.id) as slice_data'; @@ -139,4 +138,13 @@ protected function getSQL(int $detail_id = null): string SQL; return $sql; } + + /** + * Rechte prüfen + * @return bool + */ + public function hasPerm(): bool + { + return Permission::getInstance()->check(Perm::PERM_STRUCTURE); + } } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Modules/Pictures.php b/FriendsOfRedaxo/addon/UsageCheck/Modules/Pictures.php index fdcc2a0..d8b2242 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Modules/Pictures.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Modules/Pictures.php @@ -26,6 +26,7 @@ * Description of Pictures * * @author akrys + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Pictures extends BaseModule { @@ -52,7 +53,7 @@ class Pictures extends BaseModule * * @param int $id */ - public function setCategory(int $id) + public function setCategory(int $id): void { $this->catId = $id; } @@ -60,21 +61,21 @@ public function setCategory(int $id) /** * Nicht genutze Bilder holen * - * @return array + * @retur array * * @todo bei Instanzen mit vielen Dateien im Medienpool testen. Die Query * riecht nach Performance-Problemen -> Using join buffer (Block Nested Loop) */ public function get(): array { - if (!Permission::getInstance()->check(Perm::PERM_MEDIA)) { - return false; + if (!$this->hasPerm()) { + return []; } $rexSQL = $this->getRexSql(); if (!isset($this->yform)) { - $this->yform = new PictureYFrom($this); + $this->yform = new PictureYFrom(); $this->yform->setRexSql($rexSQL); } @@ -85,17 +86,19 @@ public function get(): array /** * Details zu einem Eintrag holen * @param int $item_id - * @return array + * @return array + * @SuppressWarnings(CyclomaticComplexity) + * @SuppressWarnings(NPathComplexity) */ public function getDetails(int $item_id): array { - if (!Permission::getInstance()->check(Perm::PERM_MEDIA)) { - return false; + if (!$this->hasPerm()) { + return []; } $rexSQL = $this->getRexSql(); if (!isset($this->yform)) { - $this->yform = new PictureYFrom($this); + $this->yform = new PictureYFrom(); $this->yform->setRexSql($rexSQL); } @@ -108,11 +111,13 @@ public function getDetails(int $item_id): array } if (isset($articleData['usagecheck_metaArtIDs']) && (int) $articleData['usagecheck_metaArtIDs'] > 0) { - $result['art_meta'][$articleData['usagecheck_art_id'].'_'.$articleData['usagecheck_art_clang']] = $articleData; + $index = $articleData['usagecheck_art_id'].'_'.$articleData['usagecheck_art_clang']; + $result['art_meta'][$index] = $articleData; } if (isset($articleData['usagecheck_metaCatIDs']) && (int) $articleData['usagecheck_metaCatIDs'] > 0) { - $result['cat_meta'][$articleData['usagecheck_cat_id'].'_'.$articleData['usagecheck_cat_clang']] = $articleData; + $index = $articleData['usagecheck_cat_id'].'_'.$articleData['usagecheck_cat_clang']; + $result['cat_meta'][$index] = $articleData; } if (isset($articleData['usagecheck_metaMedIDs']) && (int) $articleData['usagecheck_metaMedIDs'] > 0) { @@ -123,7 +128,8 @@ public function getDetails(int $item_id): array if (!isset($articleData['usagecheck_'.$table.'_id'])) { continue; } - $result['yform'][$table][$field[0]['table_out']][$articleData['usagecheck_'.$table.'_id']] = $articleData; + $index = $articleData['usagecheck_'.$table.'_id']; + $result['yform'][$table][$field[0]['table_out']][$index] = $articleData; } } return [ @@ -132,34 +138,37 @@ public function getDetails(int $item_id): array 'fields' => $this->tableFields, ]; } -// -///////////////////// Tmplementation aus RexV5 ///////////////////// -// /** * Spezifisches SQL für redaxo 5 * @param int $detail_id * @return string + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function getSQL(int $detail_id = null): string { - $sqlPartsYForm = $this->yform->getYFormTableSQLParts($detail_id); + $sqlPartsYForm = $this->yform?->getYFormTableSQLParts($detail_id); $sqlPartsMeta = $this->getMetaTableSQLParts($detail_id); $havingClauses = []; $additionalSelect = ''; $additionalJoins = ''; + $additionalGroupBy = ''; $this->tableFields = []; - $havingClauses = array_merge($havingClauses, $sqlPartsYForm['havingClauses']); - $additionalSelect .= $sqlPartsYForm['additionalSelect']; - $additionalJoins .= $sqlPartsYForm['additionalJoins']; - $this->tableFields = array_merge($this->tableFields, $sqlPartsYForm['tableFields']); + $havingClauses = array_merge($havingClauses, $sqlPartsYForm['havingClauses'] ?? []); + $additionalSelect .= $sqlPartsYForm['additionalSelect'] ?? ''; + $additionalJoins .= $sqlPartsYForm['additionalJoins'] ?? ''; + $this->tableFields = array_merge($this->tableFields, $sqlPartsYForm['tableFields'] ?? []); - $havingClauses = array_merge($havingClauses, $sqlPartsMeta['havingClauses']); + $havingClauses = array_merge($havingClauses, $sqlPartsMeta['havingClauses'] ?? []); $additionalSelect .= $sqlPartsMeta['additionalSelect']; $additionalJoins .= $sqlPartsMeta['additionalJoins']; - $this->tableFields = array_merge($this->tableFields, $sqlPartsMeta['tableFields']); + $this->tableFields = array_merge($this->tableFields, $sqlPartsMeta['tableFields'] ?? []); + + $additionalGroupBy .= $sqlPartsMeta['groupBy']; $mediaTable = $this->getTable('media'); $articleSliceTable = $this->getTable('article_slice'); @@ -224,22 +233,28 @@ protected function getSQL(int $detail_id = null): string if (!isset($detail_id)) { if (!$this->showAll) { $where[] = 's.id is null '; - $havingClauses[] = ' ifnull(usagecheck_metaCatIDs, 0) = 0 and ifnull(usagecheck_metaArtIDs, 0) = 0 and ifnull(usagecheck_metaMedIDs, 0) = 0'; + $havingClauses[] = ' ifnull(usagecheck_metaCatIDs, 0) = 0 and '. + 'ifnull(usagecheck_metaArtIDs, 0) = 0 and '. + 'ifnull(usagecheck_metaMedIDs, 0) = 0'; } if ($this->catId) { - $where[] = "category_id=".$this->getRexSql()->escape($this->catId)." "; + $where[] = "f.category_id=".$this->getRexSql()->escape((string) $this->catId)." "; } if ($where) { $sql .= 'where '.implode(' and ', $where); } - $sql .= 'group by f.filename, f.id,rex_article_art_meta.id,rex_article_cat_meta.id '; - if (!$this->showAll && isset($havingClauses) && count($havingClauses) > 0) { + $sql .= 'group by f.filename, f.id '; + if ($additionalGroupBy) { + $sql .= ','.$additionalGroupBy.' '; + } + + if (!$this->showAll && count($havingClauses) > 0) { $sql .= 'having '.implode(' and ', $havingClauses).''; } } else { - $sql .= 'where f.id = '.$this->getRexSql()->escape($detail_id); + $sql .= 'where f.id = '.$this->getRexSql()->escape((string) $detail_id); } return $sql; } @@ -282,7 +297,7 @@ private function addGroupFields(?int $detail_id, string $additionalSelect): stri * * @param string $name * - * @return array Indezes field, table + * @return array Indezes field, table */ private function getTableNames(string $name): array { @@ -307,7 +322,7 @@ private function getTableNames(string $name): array * SQL Parts für die Metadaten innerhalb von Redaxo5 generieren * * @param int $detail_id - * @return array + * @return array * @SuppressWarnings(PHPMD.ElseExpression) */ private function getMetaTableSQLParts(int $detail_id = null): array @@ -317,6 +332,7 @@ private function getMetaTableSQLParts(int $detail_id = null): array 'additionalJoins' => '', 'tableFields' => [], 'havingClauses' => [], + 'groupBy' => '', ]; $joinArtMeta = ''; @@ -362,11 +378,13 @@ private function getMetaTableSQLParts(int $detail_id = null): array * * Komplexitätsvermeidung von getMetaTableSQLParts * - * @param array &$return + * @param array &$return * @param string $joinArtMeta * @param int $detail_id + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ - private function addArtSelectAndJoinStatements(array &$return, string $joinArtMeta, ?int $detail_id = null) + private function addArtSelectAndJoinStatements(array &$return, string $joinArtMeta, ?int $detail_id = null): void { $selectMetaNull = ',0 as usagecheck_metaArtIDs '.PHP_EOL; if (!$detail_id) { @@ -384,6 +402,8 @@ private function addArtSelectAndJoinStatements(array &$return, string $joinArtMe if ($joinArtMeta != '') { $return['additionalJoins'] .= 'LEFT join rex_article as rex_article_art_meta on '. '(rex_article_art_meta.id is not null and ('.$joinArtMeta.'))'.PHP_EOL; + + $return['groupBy'] .= 'rex_article_art_meta.id,rex_article_cat_meta.id'; } } @@ -392,11 +412,13 @@ private function addArtSelectAndJoinStatements(array &$return, string $joinArtMe * * Komplexitätsvermeidung von getMetaTableSQLParts * - * @param array &$return + * @param array &$return * @param string $joinCatMeta * @param int $detail_id + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ - private function addCatSelectAndJoinStatements(array &$return, string $joinCatMeta, int $detail_id = null) + private function addCatSelectAndJoinStatements(array &$return, string $joinCatMeta, int $detail_id = null): void { $selectMetaNull = ',0 as usagecheck_metaCatIDs '.PHP_EOL; if (!$detail_id) { @@ -424,11 +446,13 @@ private function addCatSelectAndJoinStatements(array &$return, string $joinCatMe * * Komplexitätsvermeidung von getMetaTableSQLParts * - * @param array &$return + * @param array &$return * @param string $joinMedMeta * @param int $detail_id + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ - private function addMedSelectAndJoinStatements(array &$return, string $joinMedMeta, int $detail_id = null) + private function addMedSelectAndJoinStatements(array &$return, string $joinMedMeta, int $detail_id = null): void { $selectMetaNull = ',0 as usagecheck_metaMedIDs '.PHP_EOL; if (!$detail_id) { @@ -451,7 +475,7 @@ private function addMedSelectAndJoinStatements(array &$return, string $joinMedMe /** * Meta-Bildfelder ermitteln. - * @return array + * @return array> */ private function getMetaNames(): array { @@ -474,9 +498,13 @@ private function getMetaNames(): array /** * Anzeige Benutzt/Nicht benutzt erstellen - * @param array $item - * @param array $fields + * @param array $item + * @param array $fields * @return string + * @SuppressWarnings(CyclomaticComplexity) + * @SuppressWarnings(NPathComplexity) + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ public static function showUsedInfo(array $item, array $fields): string { @@ -487,11 +515,10 @@ public static function showUsedInfo(array $item, array $fields): string $used = true; } - $table = ''; foreach ($fields as $tablename => $field) { - if ($item[$tablename] !== null) { + unset($field); //phpmd: unused variable $field + if (isset($item[$tablename])) { $used = true; - $table = $tablename; break; } @@ -554,4 +581,13 @@ public static function showUsedInfo(array $item, array $fields): string } return $return; } + + /** + * Rechte prüfen + * @return bool + */ + public function hasPerm():bool + { + return Permission::getInstance()->check(Perm::PERM_MEDIA); + } } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Modules/Templates.php b/FriendsOfRedaxo/addon/UsageCheck/Modules/Templates.php index bd16d77..3cc5228 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Modules/Templates.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Modules/Templates.php @@ -38,7 +38,7 @@ class Templates extends BaseModule * Anzeigemodus "inaktive zeigen" umstellen * @param boolean $bln */ - public function showInactive(bool $bln) + public function showInactive(bool $bln): void { $this->showInactive = $bln; } @@ -46,7 +46,7 @@ public function showInactive(bool $bln) /** * Nicht genutze Module holen * - * @return array + * @return array * * @todo bei Instanzen mit vielen Slices testen. Die Query * riecht nach Performance-Problemen -> Using join buffer (Block Nested Loop) @@ -56,13 +56,13 @@ public function get(): array { $showInactive = $this->showInactive; - if (!Permission::getInstance()->check(Perm::PERM_STRUCTURE)) { + if (!$this->hasPerm()) { //Permission::PERM_TEMPLATE - return false; + return []; } $user = rex::getUser(); - if (!$user->isAdmin() && $showInactive === true) { + if (!$user?->isAdmin() && $showInactive === true) { $showInactive = false; } @@ -86,24 +86,28 @@ public function get(): array /** * Details zu einem Eintrag holen * @param int $item_id - * @return array + * @return array */ public function getDetails(int $item_id): array { - if (!Permission::getInstance()->check(Perm::PERM_STRUCTURE)) { + if (!$this->hasPerm()) { //Permission::PERM_TEMPLATE - return false; + return []; } + $result = []; + $result = []; $rexSQL = $this->getRexSql(); $sql = $this->getSQL($item_id); $res = $rexSQL->getArray($sql); foreach ($res as $articleData) { if (isset($articleData['usagecheck_article_a_id']) && (int) $articleData['usagecheck_article_a_id'] > 0) { - $result['articles'][$articleData['usagecheck_article_a_id'].'_'.$articleData['usagecheck_article_a_clang_id']] = $articleData; + $index = $articleData['usagecheck_article_a_id'].'_'.$articleData['usagecheck_article_a_clang_id']; + $result['articles'][$index] = $articleData; } - if (isset($articleData['usagecheck_template_t2_id']) && (int) $articleData['usagecheck_template_t2_id'] > 0) { + if (isset($articleData['usagecheck_template_t2_id']) && + (int) $articleData['usagecheck_template_t2_id'] > 0) { $result['templates'][$articleData['usagecheck_template_t2_id']] = $articleData; } } @@ -155,6 +159,8 @@ private function addParamStatementKeywords(string &$where, string &$having): voi * SQL für Redaxo 5 * @param int $detail_id * @return string + * @SuppressWarnings(PHPMD.ElseExpression) + * -> zu tief verschachtelt.... vllt. Funktionsauslagerung? */ protected function getSQL(int $detail_id = null): string { @@ -186,7 +192,7 @@ protected function getSQL(int $detail_id = null): string t2.name as usagecheck_template_t2_name SQL; $groupBy = 'group by a.template_id,t.id,a.id'; - $where .= 'where t.id='.$rexSQL->escape($detail_id); + $where .= 'where t.id='.$rexSQL->escape((string) $detail_id); $groupBy = 'group by a.template_id,t.id,a.id'; } else { $additionalFields = <<check(Perm::PERM_STRUCTURE); + } } diff --git a/FriendsOfRedaxo/addon/UsageCheck/Permission.php b/FriendsOfRedaxo/addon/UsageCheck/Permission.php index 803e369..7f0640c 100644 --- a/FriendsOfRedaxo/addon/UsageCheck/Permission.php +++ b/FriendsOfRedaxo/addon/UsageCheck/Permission.php @@ -19,6 +19,7 @@ */ class Permission { + /** * Prüft die Rechte für den aktuellen User. * @@ -26,49 +27,53 @@ class Permission * Die Rechteverwaltung ist zu nah am RedaxoCore, um das auf die Schnelle simulieren zu können. * @codeCoverageIgnore * - * @param string $perm eine der PERM-Konstanten + * @param Perm $perm eine der PERM-Konstanten * @return boolean * @SuppressWarnings(PHPMD.StaticAccess) */ public function check(Perm $perm): bool { $user = rex::getUser(); - $complexPerm = $user->getComplexPerm($perm->value); + $complexPerm = $user?->getComplexPerm($perm->value); + + $class = ''; + if ($complexPerm !== null) { + $class = get_class($complexPerm); + } $hasSpecialPerm = true; - switch (get_class($complexPerm)) { + switch ($class) { case 'rex_media_perm': - /* @var $complexPerm rex_media_perm */ + /** @var rex_media_perm $complexPerm */ $hasSpecialPerm = $complexPerm->hasMediaPerm(); break; case 'rex_structure_perm': - /* @var $complexPerm rex_structure_perm */ + /** @var rex_structure_perm $complexPerm */ $hasSpecialPerm = $complexPerm->hasStructurePerm(); break; case 'rex_module_perm': - /* @var $complexPerm rex_module_perm */ + /** @var rex_module_perm $complexPerm */ $hasSpecialPerm = $complexPerm->hasAll(); break; default: - throw new Exception('"'.get_class($complexPerm).'": unknown permission class'); - break; + throw new Exception('"'.$class.'": unknown permission class'); } - return $user->isAdmin() || $user->hasPerm($perm) || $hasSpecialPerm; + return $user?->isAdmin() || $user?->hasPerm($perm->value) || $hasSpecialPerm; /* || (isset($complexPerm) && $complexPerm->hasAll()) */ } // /** * Instance - * @var Error + * @var Permission */ private static $instance = null; /** * create Singleton Instance - * @return Error + * @return Permission */ - public static function getInstance() + public static function getInstance(): Permission { if (self::$instance == null) { self::$instance = new self(); diff --git a/boot.php b/boot.php index 1c70a9d..e8dd29a 100644 --- a/boot.php +++ b/boot.php @@ -5,24 +5,13 @@ */ require_once __DIR__.'/FriendsOfRedaxo/addon/UsageCheck/Config.php'; -/* - * Sichergehen, dass der rex_autoloader nicht Stundenlang die PHPUnit-Klassen analysiert. - * - * sollte nur bei Aufrufen vom Webserver passieren. Auf der Console (z.B. während PHPUnit läuft) braucht man das - * Verzeichnis. - */ -try { - \FriendsOfRedaxo\addon\UsageCheck\Config::checkVendorDir(); -} catch (\Exception $e) { - if (\rex::isBackend()) { - print $e->getMessage(); - } - die(); -} - +/** @phpstan-ignore-next-line */ spl_autoload_register(['FriendsOfRedaxo\\addon\\UsageCheck\\Config', 'autoload'], true, true); -rex_fragment::addDirectory(realpath(__DIR__)); +$dir = realpath(__DIR__); +if ($dir !== false) { + rex_fragment::addDirectory($dir); +} if (rex::isBackend()) { /** @var \rex_addon $this */ diff --git a/fragments/modules/details/module.php b/fragments/modules/details/module.php index 4fba5b2..3f1e3d0 100644 --- a/fragments/modules/details/module.php +++ b/fragments/modules/details/module.php @@ -5,7 +5,7 @@ return; } $user = rex::getUser(); -$structurePerm = $user->getComplexPerm('structure'); +$structurePerm = $user?->getComplexPerm('structure'); ?>
@@ -23,7 +23,7 @@
    isAdmin()) { + if ($user?->isAdmin()) { $url = 'index.php?page=modules/modules&function=edit&module_id='.$this->data['first']['id']; $index = 'akrys_usagecheck_module_linktext_edit_code'; $linkText = rex_i18n::rawMsg($index); @@ -48,7 +48,9 @@ $categoryID = $item['usagecheck_a_parent_id']; $articleName = $item['usagecheck_a_name']; - + /** + * @var rex_structure_perm $structurePerm + */ $hasPerm = $structurePerm->hasCategoryPerm($articleID); if ($hasPerm) { diff --git a/fragments/modules/details/picture.php b/fragments/modules/details/picture.php index 99e2ba2..c358d0b 100644 --- a/fragments/modules/details/picture.php +++ b/fragments/modules/details/picture.php @@ -2,6 +2,7 @@ use FriendsOfRedaxo\addon\UsageCheck\Lib\FileSize; use FriendsOfRedaxo\addon\UsageCheck\Modules\Pictures; + if (count($this->errors) > 0) { $fragment = new rex_fragment(['msg' => $this->errors]); echo $fragment->parse('msg/error_box.php'); @@ -9,8 +10,8 @@ } $user = rex::getUser(); -$mediaPerm = $user->getComplexPerm('media'); -$structurePerm = $user->getComplexPerm('structure'); +$mediaPerm = $user?->getComplexPerm('media'); +$structurePerm = $user?->getComplexPerm('structure'); $media = rex_media::get($this->data['first']['filename']); ?> @@ -44,6 +45,9 @@ $clang = $item['usagecheck_s_clang_id']; $ctype = $item['usagecheck_s_ctype_id']; + /** + * @var rex_structure_perm $structurePerm + */ $hasPerm = $structurePerm->hasCategoryPerm($articleID); if ($hasPerm) { $linkText = $linkTextRaw; @@ -69,6 +73,9 @@ $articleName = $item['usagecheck_art_name']; $clang = $item['usagecheck_art_clang']; + /** + * @var rex_structure_perm $structurePerm + */ $hasPerm = $structurePerm->hasCategoryPerm($articleID); $href = 'index.php?'. 'page=content/metainfo&'. @@ -99,8 +106,10 @@ $clang = $item['usagecheck_cat_clang']; $parentID = $item['usagecheck_cat_parent_id']; + /** + * @var rex_structure_perm $structurePerm + */ $hasPerm = $structurePerm->hasCategoryPerm($articleID); - if ($hasPerm) { $linkText = $linkTextRaw; $linkText = str_replace('$articleID$', $articleID, $linkText); @@ -125,7 +134,10 @@ $fileCatID = $item['usagecheck_med_cat_id']; $filename = $item['usagecheck_med_filename']; - $hasPerm = $mediaPerm->hasMediaPerm($fileID); + /** + * @var rex_media_perm $mediaPerm + */ + $hasPerm = $mediaPerm->hasMediaPerm(); if ($hasPerm) { $linkText = $linkTextRaw; $linkText = str_replace('$filename$', $filename, $linkText); @@ -146,8 +158,8 @@ foreach ($entries as $id => $item) { $id = $item['usagecheck_'.$table.'_id']; - $hasPerm = rex::getUser()->isAdmin() || ( - rex::getUser()->hasPerm('yform[]') && + $hasPerm = rex::getUser()?->isAdmin() || ( + rex::getUser()?->hasPerm('yform[]') && rex::getUser()->hasPerm('yform[table:'.$table.']') ); @@ -160,9 +172,6 @@ 'table_name='.$table.'&'. 'data_id='.$id.'&'. 'func=edit'; - if ($href == '') { - continue; - } ?>
  1. @@ -263,7 +272,7 @@ - 100 ? ' class="longcontent"' : '' ?> data-length=""> + 100 ? ' class="longcontent"' : '' ?> data-length=""> getComplexPerm('structure'); +$structurePerm = $user?->getComplexPerm('structure'); ?>
    @@ -27,11 +27,13 @@ $articleName = $item['usagecheck_article_a_name']; $clang = $item['usagecheck_article_a_clang_id']; - if ($startpage == 1) { $articleReID = $articleID; } + /** + * @var rex_structure_perm $structurePerm + */ $hasPerm = $structurePerm->hasCategoryPerm($articleID); if ($hasPerm) { $href = 'index.php?page=structure&article_id='.$articleID. @@ -50,7 +52,7 @@ //Templates, die in Templates verwendert werden, betrifft //nur die Coder, und das wären Admins - $hasPerm = $user->isAdmin(); + $hasPerm = $user?->isAdmin(); if ($hasPerm) { if (isset($this->data['result']['templates'])) { $index = 'akrys_usagecheck_template_linktext_edit_template'; diff --git a/fragments/modules/modules.php b/fragments/modules/modules.php index a20d90f..8b7a435 100644 --- a/fragments/modules/modules.php +++ b/fragments/modules/modules.php @@ -1,6 +1,7 @@ @@ -15,7 +16,11 @@ items as $item) { - if (!$user->isAdmin() && !$user->getComplexPerm('modules')->hasPerm($item['id'])) { + /** + * @var rex_module_perm $perm + */ + $perm = $user?->getComplexPerm('modules'); + if (!$user?->isAdmin() && !$perm->hasPerm($item['id'])) { continue; } ?> @@ -46,7 +51,7 @@ isAdmin()) { + if ($user?->isAdmin()) { $url = 'index.php?page=modules/modules&function=edit&module_id='.$item['id']; $index = 'akrys_usagecheck_module_linktext_edit_code'; $linkText = rex_i18n::rawMsg($index); diff --git a/fragments/modules/pictures.php b/fragments/modules/pictures.php index 75d8e10..311cc56 100644 --- a/fragments/modules/pictures.php +++ b/fragments/modules/pictures.php @@ -5,8 +5,8 @@ use FriendsOfRedaxo\addon\UsageCheck\Modules\Pictures; $user = rex::getUser(); -$mediaPerm = $user->getComplexPerm('media'); -$structurePerm = $user->getComplexPerm('structure'); +$mediaPerm = $user?->getComplexPerm('media'); +$structurePerm = $user?->getComplexPerm('structure'); ?> @@ -76,7 +76,7 @@
    getSizeOut($item).')'; + echo $item['filename'].' ('.$fileSize->getSizeOut().')'; ?>
    diff --git a/fragments/modules/templates.php b/fragments/modules/templates.php index 2095cdd..f084a33 100644 --- a/fragments/modules/templates.php +++ b/fragments/modules/templates.php @@ -55,7 +55,7 @@ isAdmin()) { + if ($user?->isAdmin()) { $url = 'index.php?page=templates&function=edit&template_id='.$item['id']; $fragmet = new rex_fragment([ diff --git a/install.php b/install.php index 73165ba..da5a0e0 100644 --- a/install.php +++ b/install.php @@ -5,28 +5,5 @@ */ require_once __DIR__.'/FriendsOfRedaxo/addon/UsageCheck/Config.php'; -$error = ''; -/* - * Sichergehen, dass der rex_autoloader nicht Stundenlang die PHPUnit-Klassen analysiert. - * - * sollte nur bei Aufrufen vom Webserver passieren. Auf der Console (z.B. während PHPUnit läuft) braucht man das - * Verzeichnis. - */ -try { - \FriendsOfRedaxo\addon\UsageCheck\Config::checkVendorDir(); -} catch (\Exception $e) { - if (\rex::isBackend()) { - print $e->getMessage(); - } - die(); -} - +/** @phpstan-ignore-next-line */ spl_autoload_register(['FriendsOfRedaxo\\addon\\UsageCheck\\Config', 'autoload'], true, true); - - - -if ($error) { - $this->setProperty('installmsg', $error); -} else { - $this->setProperty('install', true); -} diff --git a/package.yml b/package.yml index b73cf25..71248c2 100644 --- a/package.yml +++ b/package.yml @@ -1,5 +1,5 @@ package: usage_check -version: '3.0.1' +version: '3.1' author: Axel Krysztofiak supportpage: https://github.com/akrys/redaxo-usage_check #load: early diff --git a/pages/_action.php b/pages/_action.php index 21e4ae6..b5842c2 100644 --- a/pages/_action.php +++ b/pages/_action.php @@ -9,6 +9,10 @@ use FriendsOfRedaxo\addon\UsageCheck\Config; use FriendsOfRedaxo\addon\UsageCheck\Modules\Actions; +if(!isset($subpage)) { + throw new \Exception("this file should not be called directly."); +} + $title = new rex_fragment(); $title->setVar('name', Addon::getInstance()->getName()); $title->setVar('supage_title', rex_i18n::rawMsg('akrys_usagecheck_action_subpagetitle')); @@ -34,10 +38,10 @@ $items = $actions->get(); -if ($items === false) { +if (empty($items)) { $msg = rex_i18n::rawMsg('akrys_usagecheck_no_rights'); $fragment = new rex_fragment([ - 'text' => $index, + 'text' => $msg, ]); $fragment = new rex_fragment([ 'text' => $fragment->parse('fragments/msg/tagged_msg.php'), diff --git a/pages/_changelog.php b/pages/_changelog.php index 8f9b740..50a9496 100644 --- a/pages/_changelog.php +++ b/pages/_changelog.php @@ -18,19 +18,21 @@ die(); } -$language = rex::getUser()->getLanguage(); +$language = rex::getUser()?->getLanguage(); if ($language == '') { $language = rex::getProperty('lang'); } -if (stristr($language, 'de_')) { +if (stristr((string) $language, 'de_')) { $dir = glob(__DIR__.'/release_notes/de/*_*.php'); } else { $dir = glob(__DIR__.'/release_notes/en/*_*.php'); } +if (!$dir) { + $dir = []; +} rsort($dir); - $fragment = new rex_fragment([ 'dir' => $dir, ]); diff --git a/pages/_index.php b/pages/_index.php deleted file mode 100644 index fb13dde..0000000 --- a/pages/_index.php +++ /dev/null @@ -1,35 +0,0 @@ -count() > 0) { - $text = ''; - foreach (\FriendsOfRedaxo\addon\UsageCheck\Error::getInstance() as $error) { - $fragment = new \rex_fragment([ - 'text' => $error, - ]); - $text .= $fragment->parse('fragments/msg/tagged_msg.php'); - - echo RedaxoCall::getAPI()->getErrorMsg($text, false); - } -} - -$subpage = rex_be_controller::getCurrentPagePart(2, 'overview'); - -// echo rex_view::title(rex_i18n::msg('backup_title')); -// var_dump(rex_be_controller::getCurrentPageObject()->getSubPath()); -// include rex_be_controller::getCurrentPageObject()->getSubPath(); - -$contentFile = __DIR__.'/_'.$subpage.'.php'; - -if (file_exists($contentFile)) { - include $contentFile; -} else { - $msg = RedaxoCall::getAPI()->getI18N('akrys_usagecheck_error_content_file_not_found').':
    '.$contentFile; - echo RedaxoCall::getAPI()->getErrorMsg($msg, true); -} diff --git a/pages/_module.php b/pages/_module.php index 5ab4994..95dd9ea 100644 --- a/pages/_module.php +++ b/pages/_module.php @@ -7,6 +7,10 @@ use FriendsOfRedaxo\addon\UsageCheck\Config; use FriendsOfRedaxo\addon\UsageCheck\Modules\Modules; +if(!isset($subpage)) { + throw new \Exception("this file should not be called directly."); +} + $modules = new Modules(); $modules->setRexSql(rex_sql::factory()); @@ -28,12 +32,12 @@ $title->setVar('version', Addon::getInstance()->getVersion()); echo rex_view::title($title->parse('fragments/title.php')); -$items = $modules->get($showAll); +$items = $modules->get(); -if ($items === false) { +if (empty($items)) { $msg = rex_i18n::rawMsg('akrys_usagecheck_no_rights'); $fragment = new rex_fragment([ - 'text' => $index, + 'text' => $msg, ]); $fragment = new rex_fragment([ 'text' => $fragment->parse('fragments/msg/tagged_msg.php'), diff --git a/pages/_picture.php b/pages/_picture.php index 19ff77d..88a8909 100644 --- a/pages/_picture.php +++ b/pages/_picture.php @@ -7,6 +7,10 @@ use FriendsOfRedaxo\addon\UsageCheck\Config; use FriendsOfRedaxo\addon\UsageCheck\Modules\Pictures; +if(!isset($subpage)) { + throw new \Exception("this file should not be called directly."); +} + $pictures = new Pictures(); $pictures->setRexSql(rex_sql::factory()); @@ -36,10 +40,10 @@ $items = $pictures->get(); -if ($items === false) { +if (empty($items)) { $msg = rex_i18n::rawMsg('akrys_usagecheck_no_rights'); $fragment = new rex_fragment([ - 'text' => $index, + 'text' => $msg, ]); $fragment = new rex_fragment([ 'text' => $fragment->parse('fragments/msg/tagged_msg.php'), diff --git a/pages/_template.php b/pages/_template.php index 2ecaedf..a2808a7 100644 --- a/pages/_template.php +++ b/pages/_template.php @@ -7,6 +7,10 @@ use FriendsOfRedaxo\addon\UsageCheck\Config; use FriendsOfRedaxo\addon\UsageCheck\Modules\Templates; +if(!isset($subpage)) { + throw new \Exception("this file should not be called directly."); +} + switch (rex_get('showall', 'string', "")) { case 'true': $showAll = true; @@ -45,10 +49,10 @@ } $items = $templates->get(); -if ($items === false) { +if (empty($items)) { $msg = rex_i18n::rawMsg('akrys_usagecheck_no_rights'); $fragment = new rex_fragment([ - 'text' => $index, + 'text' => $msg, ]); $fragment = new rex_fragment([ 'text' => $fragment->parse('fragments/msg/tagged_msg.php'), diff --git a/pages/index.php b/pages/index.php index e59c35a..7de37ed 100644 --- a/pages/index.php +++ b/pages/index.php @@ -9,11 +9,11 @@ * Grundlegendes Frontend */ $locale = null; - $language = rex::getUser()->getLanguage(); + $language = rex::getUser()?->getLanguage(); if ($language == '') { $language = rex::getProperty('lang'); } - if (!stristr($language, 'de_') && !stristr($language, 'en_')) { + if (!stristr((string) $language, 'de_') && !stristr((string) $language, 'en_')) { $locale = rex_i18n::getLocale(); rex_i18n::setLocale('en_gb'); } diff --git a/pages/release_notes/de/2024-04-27_3.1.php b/pages/release_notes/de/2024-04-27_3.1.php new file mode 100644 index 0000000..d9091d4 --- /dev/null +++ b/pages/release_notes/de/2024-04-27_3.1.php @@ -0,0 +1,5 @@ +
      +
    • Code-Qualität-Prüfung via PHPStan, PHPMD, PHPCS
    • +
    • Bugfix: SQL-Fehler, wenn es keine Bilder in den Artikel-Mata-Daten gibt.
    • +
    • Fehlerhafte Rechte-Prüfung in Modulen korrigiert.
    • +
    diff --git a/pages/release_notes/en/2024-04-27_3.1.php b/pages/release_notes/en/2024-04-27_3.1.php new file mode 100644 index 0000000..7366ae5 --- /dev/null +++ b/pages/release_notes/en/2024-04-27_3.1.php @@ -0,0 +1,5 @@ +
      +
    • code quality check via PHPStan, PHPMD, PHPCS
    • +
    • Bugfix: SQL error, if there are no pictures in article meta data.
    • +
    • Bugfix: rights checking in modules.
    • +