feat(wiki): Beitragsliste für Betriebsrat-Nutzer auf zugängliche Kategorien filtern

BR-Nutzer (r-wiki-br ohne r-wiki) sehen in der Beitragsliste und im
Kategorie-Dropdown nur Beiträge und Kategorien, die ihren freigegebenen
Kategorien (betriebsrat_editable=1 + alle Nachfahren per BFS) zugeordnet sind.

Der Filter wird server-seitig in post_listform.php berechnet und als Parameter
an den Ajax-Endpunkt übergeben, da get_permission_state() im Ajax-Kontext
nicht verfügbar ist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 10:07:48 +02:00
parent 5da7916651
commit 60eea92f11
4 changed files with 152 additions and 27 deletions

View File

@@ -186,29 +186,44 @@ $_kcBrOnly = !is_wiki_redakteur() && is_wiki_betriebsrat();
* gefiltert, sodass in den Bereichen (Abteilung, Mandant, Rolle) entweder kein Eintrag vorliegt
* oder der Eintrag mit den erlaubten Werten übereinstimmt.
*/
// Für Betriebsrat: nur Beiträge zeigen, die mindestens einer freigegebenen Kategorie zugeordnet sind
$brCategoryFilter = '';
if ($_kcBrOnly) {
$brCatIds = get_all_betriebsrat_accessible_category_ids();
if (empty($brCatIds)) {
$brCategoryFilter = 'AND 1=0'; // kein Zugriff
} else {
$brCatIdList = implode(',', $brCatIds);
$brCategoryFilter = "AND EXISTS (
SELECT 1 FROM knowledgecenter_category_post kcp_br
WHERE kcp_br.post_id = kp.id AND kcp_br.category_id IN ($brCatIdList)
)";
}
}
$sqlPosts = "
SELECT
kp.id,
kp.modified_at,
pv.title,
pv.image,
SELECT
kp.id,
kp.modified_at,
pv.title,
pv.image,
pv.link,
pv.link_label,
pv.version_number
FROM
FROM
knowledgecenter_category_post AS kcp
JOIN
JOIN
knowledgecenter_posts AS kp ON kcp.post_id = kp.id
LEFT JOIN
knowledgecenter_post_versions AS pv ON kp.id = pv.post_id
AND pv.language_id = $languageId
LEFT JOIN
knowledgecenter_post_versions AS pv ON kp.id = pv.post_id
AND pv.language_id = $languageId
AND pv.state = 1
AND (pv.valid_from IS NULL OR pv.valid_from <= NOW())
AND (pv.valid_until IS NULL OR pv.valid_until >= NOW())
AND pv.version_number = (
SELECT MAX(v2.version_number)
SELECT MAX(v2.version_number)
FROM knowledgecenter_post_versions AS v2
WHERE v2.post_id = kp.id
WHERE v2.post_id = kp.id
AND v2.language_id = $languageId
AND v2.state = 1
AND (v2.valid_from IS NULL OR v2.valid_from <= NOW())
@@ -232,9 +247,10 @@ $_kcBrOnly = !is_wiki_redakteur() && is_wiki_betriebsrat();
AND ( pr.role_id IS NULL OR pr.role_id IN ($allowedRoles) )
AND ( pe.einricht_id IS NULL OR pe.einricht_id IN ($allowedEinrichts) )
AND ( pfb.fachbereich_id IS NULL OR pfb.fachbereich_id IN ($allowedFachbereiche) )
GROUP BY
$brCategoryFilter
GROUP BY
kp.id
ORDER BY
ORDER BY
$orderBy $orderDir
";

View File

@@ -3,14 +3,32 @@
// Redirect-URL für den Zurück-Button bzw. Navigation
$redirectURL = isset($_GET['redirectURL']) ? $_GET['redirectURL'] : '?action=Category';
// Kategorien für das Dropdown holen (state = 1)
$catsQuery = "
SELECT c.id, t.title
FROM knowledgecenter_categories_update AS c
LEFT JOIN knowledgecenter_category_translations AS t
ON t.category_id = c.id AND t.language_id = $languageId
ORDER BY t.title ASC
";
// Kategorien für das Dropdown holen
$_isBrOnly = !is_wiki_redakteur() && is_wiki_betriebsrat();
if ($_isBrOnly) {
$_brCatIds = get_all_betriebsrat_accessible_category_ids();
if (empty($_brCatIds)) {
$catsQuery = "SELECT NULL LIMIT 0";
} else {
$_brCatIdList = implode(',', $_brCatIds);
$catsQuery = "
SELECT c.id, t.title
FROM knowledgecenter_categories_update AS c
LEFT JOIN knowledgecenter_category_translations AS t
ON t.category_id = c.id AND t.language_id = $languageId
WHERE c.id IN ($_brCatIdList)
ORDER BY t.title ASC
";
}
} else {
$catsQuery = "
SELECT c.id, t.title
FROM knowledgecenter_categories_update AS c
LEFT JOIN knowledgecenter_category_translations AS t
ON t.category_id = c.id AND t.language_id = $languageId
ORDER BY t.title ASC
";
}
$catsResult = mysqli_query($GLOBALS['mysql_con'], $catsQuery);
$allCategories = [];
while ($r = mysqli_fetch_assoc($catsResult)) {
@@ -44,9 +62,14 @@ while ($r = mysqli_fetch_assoc($catsResult)) {
</div>
<?php
$_brCategoryIds = $_isBrOnly ? ($_brCatIds ?? []) : null;
$_brCategoryIdsJson = json_encode($_brCategoryIds);
?>
<script>
var myRedirectURL = window.location.href;
var debounceTimer;
var brCategoryIds = <?= $_brCategoryIdsJson ?>;
function loadPostList() {
var searchQuery = $('#searchQuery').val();
@@ -61,7 +84,8 @@ while ($r = mysqli_fetch_assoc($catsResult)) {
language_id: '<?= $languageId ?>',
redirectURL: myRedirectURL,
query: searchQuery,
category_id: categoryId // hier mitgeben
category_id: categoryId,
br_category_ids: brCategoryIds !== null ? JSON.stringify(brCategoryIds) : null
},
dataType: 'json',
beforeSend: function () { $('#overlayLoader').show(); },