From 9f776afed3514e26ffb05b6aebc23c6bf3d2e3af Mon Sep 17 00:00:00 2001 From: Yves Torres Date: Thu, 25 Sep 2025 16:16:48 +0200 Subject: [PATCH 01/12] Refactor getWidget to handle article ID and hash --- redaxo/src/addons/structure/lib/linkmap/var_link.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/redaxo/src/addons/structure/lib/linkmap/var_link.php b/redaxo/src/addons/structure/lib/linkmap/var_link.php index 4d2cb8b40e..e18a29a022 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_link.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_link.php @@ -50,12 +50,16 @@ protected function getOutput() public static function getWidget($id, $name, $value, array $args = []) { $artName = ''; - $art = rex_article::get($value); + [$id, $hash] = array_pad(explode('#', $value ?? '', 2), 2, null); + $art = rex_article::get($id); $category = rex_category::getCurrent() ? rex_category::getCurrent()->getId() : 0; // Aktuelle Kategorie vorauswählen // Falls ein Artikel vorausgewählt ist, dessen Namen anzeigen und beim Öffnen der Linkmap dessen Kategorie anzeigen if ($art instanceof rex_article) { $artName = trim(sprintf('%s [%s]', $art->getName(), $art->getId())); + if($hash) { + $artName .= ' #' . $hash; + } $category = $art->getCategoryId(); } From 9cb967f51953da81d17d9c25b307433a23c69d38 Mon Sep 17 00:00:00 2001 From: Yves Torres Date: Thu, 25 Sep 2025 16:24:14 +0200 Subject: [PATCH 02/12] Refactor linklist processing to handle hashes --- redaxo/src/addons/structure/lib/linkmap/var_linklist.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php index 45640a13a5..ef722177dc 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php @@ -60,8 +60,13 @@ public static function getWidget($id, $name, $value, array $args = []) if ('' == $link) { continue; } - if ($article = rex_article::get((int) $link)) { - $options .= ''; + [$id, $hash] = array_pad(explode('#', $link ?? '', 2), 2, null); + if ($article = rex_article::get((int) $id)) { + $label = trim(sprintf('%s [%s]', $article->getName(), $article->getId())); + if($hash) { + $label .= ' #' . $hash; + } + $options .= ''; } } From 42117162ce8c122d94fbe749ee2a2ffa6e251187 Mon Sep 17 00:00:00 2001 From: Yves Torres Date: Thu, 25 Sep 2025 16:29:56 +0200 Subject: [PATCH 03/12] Increase link column length to 255 characters --- .../structure/plugins/content/install.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/redaxo/src/addons/structure/plugins/content/install.php b/redaxo/src/addons/structure/plugins/content/install.php index 1a79130d17..7066fd0a62 100644 --- a/redaxo/src/addons/structure/plugins/content/install.php +++ b/redaxo/src/addons/structure/plugins/content/install.php @@ -49,16 +49,16 @@ ->ensureColumn(new rex_sql_column('medialist8', 'text', true)) ->ensureColumn(new rex_sql_column('medialist9', 'text', true)) ->ensureColumn(new rex_sql_column('medialist10', 'text', true)) - ->ensureColumn(new rex_sql_column('link1', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link2', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link3', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link4', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link5', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link6', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link7', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link8', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link9', 'varchar(10)', true)) - ->ensureColumn(new rex_sql_column('link10', 'varchar(10)', true)) + ->ensureColumn(new rex_sql_column('link1', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link2', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link3', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link4', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link5', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link6', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link7', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link8', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link9', 'varchar(255)', true)) + ->ensureColumn(new rex_sql_column('link10', 'varchar(255)', true)) ->ensureColumn(new rex_sql_column('linklist1', 'text', true)) ->ensureColumn(new rex_sql_column('linklist2', 'text', true)) ->ensureColumn(new rex_sql_column('linklist3', 'text', true)) From ce6028ae1b52d95b255b31c23a6c69af39337f7b Mon Sep 17 00:00:00 2001 From: ynamite Date: Thu, 25 Sep 2025 16:49:04 +0200 Subject: [PATCH 04/12] fix: formatting --- redaxo/src/addons/structure/lib/linkmap/var_link.php | 4 ++-- redaxo/src/addons/structure/lib/linkmap/var_linklist.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/redaxo/src/addons/structure/lib/linkmap/var_link.php b/redaxo/src/addons/structure/lib/linkmap/var_link.php index e18a29a022..243c258f5f 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_link.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_link.php @@ -57,9 +57,9 @@ public static function getWidget($id, $name, $value, array $args = []) // Falls ein Artikel vorausgewählt ist, dessen Namen anzeigen und beim Öffnen der Linkmap dessen Kategorie anzeigen if ($art instanceof rex_article) { $artName = trim(sprintf('%s [%s]', $art->getName(), $art->getId())); - if($hash) { + if ($hash) { $artName .= ' #' . $hash; - } + } $category = $art->getCategoryId(); } diff --git a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php index ef722177dc..f2fe844f8f 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php @@ -63,9 +63,9 @@ public static function getWidget($id, $name, $value, array $args = []) [$id, $hash] = array_pad(explode('#', $link ?? '', 2), 2, null); if ($article = rex_article::get((int) $id)) { $label = trim(sprintf('%s [%s]', $article->getName(), $article->getId())); - if($hash) { + if ($hash) { $label .= ' #' . $hash; - } + } $options .= ''; } } From c566a4b54309758be0975254c6f3e9ed70f495ab Mon Sep 17 00:00:00 2001 From: ynamite Date: Thu, 25 Sep 2025 16:57:09 +0200 Subject: [PATCH 05/12] fix: psalm and phpstan errors --- redaxo/src/addons/structure/lib/linkmap/var_link.php | 6 +++--- .../addons/structure/lib/linkmap/var_linklist.php | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/redaxo/src/addons/structure/lib/linkmap/var_link.php b/redaxo/src/addons/structure/lib/linkmap/var_link.php index 243c258f5f..86e5f0dda2 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_link.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_link.php @@ -50,15 +50,15 @@ protected function getOutput() public static function getWidget($id, $name, $value, array $args = []) { $artName = ''; - [$id, $hash] = array_pad(explode('#', $value ?? '', 2), 2, null); - $art = rex_article::get($id); + [$id, $hash] = array_pad(explode('#', (string) ($value ?? ''), 2), 2, null); + $art = rex_article::get((int) $id); $category = rex_category::getCurrent() ? rex_category::getCurrent()->getId() : 0; // Aktuelle Kategorie vorauswählen // Falls ein Artikel vorausgewählt ist, dessen Namen anzeigen und beim Öffnen der Linkmap dessen Kategorie anzeigen if ($art instanceof rex_article) { $artName = trim(sprintf('%s [%s]', $art->getName(), $art->getId())); if ($hash) { - $artName .= ' #' . $hash; + $artName .= $hash ? ' #' . $hash : ''; } $category = $art->getCategoryId(); } diff --git a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php index f2fe844f8f..6abcb79e74 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php @@ -60,20 +60,20 @@ public static function getWidget($id, $name, $value, array $args = []) if ('' == $link) { continue; } - [$id, $hash] = array_pad(explode('#', $link ?? '', 2), 2, null); - if ($article = rex_article::get((int) $id)) { + [$id, $hash] = array_pad(explode('#', $link, 2), 2, null); + if (is_int($id) && $article = rex_article::get((int) $id)) { $label = trim(sprintf('%s [%s]', $article->getName(), $article->getId())); if ($hash) { $label .= ' #' . $hash; } - $options .= ''; + $options .= ''; } } $disabled = ' disabled'; $openFunc = ''; $deleteFunc = ''; - $quotedId = "'" . rex_escape($id, 'js') . "'"; + $quotedId = "'" . rex_escape((string) $id, 'js') . "'"; if (rex::requireUser()->getComplexPerm('structure')->hasStructurePerm()) { $disabled = ''; $openFunc = 'openREXLinklist(' . $quotedId . ', \'' . $openParams . '\');'; @@ -87,10 +87,10 @@ public static function getWidget($id, $name, $value, array $args = []) '; $e['moveButtons'] = ' - + - '; + '; $e['functionButtons'] = ' '; From a7f99b663a6de75c16f975a7b3f8088b6a621dc7 Mon Sep 17 00:00:00 2001 From: ynamite Date: Thu, 25 Sep 2025 17:08:52 +0200 Subject: [PATCH 06/12] fix: psalm and phpstan errors (#2 attempt) --- redaxo/src/addons/structure/lib/linkmap/var_link.php | 4 ++-- redaxo/src/addons/structure/lib/linkmap/var_linklist.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redaxo/src/addons/structure/lib/linkmap/var_link.php b/redaxo/src/addons/structure/lib/linkmap/var_link.php index 86e5f0dda2..66eee3ad83 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_link.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_link.php @@ -57,8 +57,8 @@ public static function getWidget($id, $name, $value, array $args = []) // Falls ein Artikel vorausgewählt ist, dessen Namen anzeigen und beim Öffnen der Linkmap dessen Kategorie anzeigen if ($art instanceof rex_article) { $artName = trim(sprintf('%s [%s]', $art->getName(), $art->getId())); - if ($hash) { - $artName .= $hash ? ' #' . $hash : ''; + if (null !== $hash && '' !== $hash) { + $artName .= ' #' . $hash; } $category = $art->getCategoryId(); } diff --git a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php index 6abcb79e74..91f421ce0b 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php @@ -61,12 +61,12 @@ public static function getWidget($id, $name, $value, array $args = []) continue; } [$id, $hash] = array_pad(explode('#', $link, 2), 2, null); - if (is_int($id) && $article = rex_article::get((int) $id)) { + if (null !== $id && '' !== $id && $article = rex_article::get((int) $id)) { $label = trim(sprintf('%s [%s]', $article->getName(), $article->getId())); - if ($hash) { + if (null !== $hash && '' !== $hash) { $label .= ' #' . $hash; } - $options .= ''; + $options .= ''; } } From b7ac6ff46767e3915ebe6b32f5647df4371be47a Mon Sep 17 00:00:00 2001 From: ynamite Date: Thu, 25 Sep 2025 17:32:05 +0200 Subject: [PATCH 07/12] fix: psalm and phpstan errors (3rd attempt) --- redaxo/src/addons/structure/lib/linkmap/var_link.php | 5 +++-- redaxo/src/addons/structure/lib/linkmap/var_linklist.php | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/redaxo/src/addons/structure/lib/linkmap/var_link.php b/redaxo/src/addons/structure/lib/linkmap/var_link.php index 66eee3ad83..0d90743d24 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_link.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_link.php @@ -50,7 +50,7 @@ protected function getOutput() public static function getWidget($id, $name, $value, array $args = []) { $artName = ''; - [$id, $hash] = array_pad(explode('#', (string) ($value ?? ''), 2), 2, null); + [$id, $hash] = array_pad(explode('#', $value, 2), 2, null); $art = rex_article::get((int) $id); $category = rex_category::getCurrent() ? rex_category::getCurrent()->getId() : 0; // Aktuelle Kategorie vorauswählen @@ -75,11 +75,12 @@ public static function getWidget($id, $name, $value, array $args = []) $deleteFunc = ''; if (rex::requireUser()->getComplexPerm('structure')->hasStructurePerm()) { $class = ''; - $escapedId = rex_escape($id, 'js'); + $escapedId = rex_escape($id, 'js') ?? ''; $openFunc = 'openLinkMap(\'REX_LINK_' . $escapedId . '\', \'' . $openParams . '\');'; $deleteFunc = 'deleteREXLink(\'' . $escapedId . '\');'; } + $id = rex_escape((string) $id, 'html_attr') ?? ''; $e = []; $e['field'] = ''; $e['functionButtons'] = ' diff --git a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php index 91f421ce0b..ebb25cd436 100644 --- a/redaxo/src/addons/structure/lib/linkmap/var_linklist.php +++ b/redaxo/src/addons/structure/lib/linkmap/var_linklist.php @@ -80,6 +80,7 @@ public static function getWidget($id, $name, $value, array $args = []) $deleteFunc = 'deleteREXLinklist(' . $quotedId . ');'; } + $id = rex_escape((string) $id, 'html_attr') ?? ''; $e = []; $e['field'] = '