Як додати поле «Відділ» і обмежити видимість категорій у WordPress


Іноді потрібно, щоб не всі користувачі сайту бачили однакові категорії.
Наприклад, у вас є два відділи: Гірничий цех і Гараж. Кожен із них має бачити тільки свої категорії.

У WordPress це можна зробити без плагінів — достатньо додати трохи коду.

в адмінці в “Рубриці” (Категорії)

1. Додаємо нові поля в категорії

Код нижче додає в редагування категорії два нових блоки:

  • Кому видна категорія — список користувачів із чекбоксами.

  • Відділ — випадний список із варіантами: “Гірничий цех” і “Гараж”.





Вставте цей код у файл functions.php вашої теми (або дочірньої).

// ===============
// 1. Поля в категорії (Кому видна і Відділ)
// ===============
add_action('category_edit_form_fields', function($term) {
    $users = get_users(['fields' => ['ID', 'display_name']]);
    $allowed = get_term_meta($term->term_id, 'allowed_users', true) ?: [];
    $department = get_term_meta($term->term_id, 'department', true);
    ?>
    <tr class="form-field">
        <th scope="row"><label>Кому видна категорія</label></th>
        <td>
            <?php foreach ($users as $user): ?>
                <label>
                    <input type="checkbox" name="allowed_users[]" value="<?php echo $user->ID; ?>"
                        <?php checked(in_array($user->ID, $allowed)); ?>>
                    <?php echo esc_html($user->display_name); ?>
                </label><br>
            <?php endforeach; ?>
        </td>
    </tr>

    <tr class="form-field">
        <th scope="row"><label for="department">Відділ</label></th>
        <td>
            <select name="department" id="department">
                <option value="">— Не вибрано —</option>
                <option value="гірничий цех" <?php selected($department, 'гірничий цех'); ?>>Гірничий цех</option>
                <option value="гараж" <?php selected($department, 'гараж'); ?>>Гараж</option>
            </select>
            <p class="description">Оберіть відділ, до якого належить категорія.</p>
        </td>
    </tr>
    <?php
});

Після цього в адмінці при редагуванні категорії з’являться два нових поля.

2. Зберігаємо введені дані

Цей код зберігає вибраних користувачів і відділ при оновленні категорії. (файл functions.php).

// ===============
// 2. Зберігаємо дані
// ===============
add_action('edited_category', function($term_id) {
    // користувачі
    if (isset($_POST['allowed_users'])) {
        update_term_meta($term_id, 'allowed_users', array_map('intval', $_POST['allowed_users']));
    } else {
        delete_term_meta($term_id, 'allowed_users');
    }

    // відділ
    if (isset($_POST['department'])) {
        update_term_meta($term_id, 'department', sanitize_text_field($_POST['department']));
    }
});

3. Приховуємо категорії від інших користувачів

Цей код фільтрує список постів:
якщо користувач не має доступу до категорії — записи з неї не відображаються. (файл functions.php).

// ===============
// 3. Фільтр видимості категорій
// ===============
add_action('pre_get_posts', function($query) {
    if (is_admin() || !$query->is_main_query()) return;

    $user_id = get_current_user_id();
    if (!$user_id) return;

    $categories = get_categories(['hide_empty' => false]);
    $allowed = [];

    foreach ($categories as $cat) {
        $allowed_users = get_term_meta($cat->term_id, 'allowed_users', true);
        if (empty($allowed_users) || in_array($user_id, $allowed_users)) {
            $allowed[] = $cat->term_id;
        }
    }

    if ($allowed) {
        $query->set('category__in', $allowed);
    } else {
        $query->set('category__in', [0]);
    }
});

4. Як вивести категорії по відділу

Якщо потрібно відобразити лише категорії певного відділу, додайте функцію (наприклад в sidebar.php, home.php, index.php …):

<?php
function my_thecat($department_filter = '') { 
    $arg_cat = array(
        'orderby'      => 'name',
        'order'        => 'ASC',
        'parent'       => 0,
        'hide_empty'   => 1,
    );

    $categories = get_categories($arg_cat);

    if ($categories) {
        foreach ($categories as $cat) {
            $department = get_term_meta($cat->term_id, 'department', true);
            if ($department_filter && $department != $department_filter) continue;

            echo '<a href="' . get_category_link($cat->term_id) . '" class="list-group-item">' . esc_html($cat->name) . '</a>';
        }
    }
}
?>

Вивести:

<?php
my_thecat('гірничий цех');
my_thecat('гараж');
?>

Результат

  • У кожній категорії в адмінці з’являється поле «Кому видна» та випадний «Відділ».
  • На сайті користувач бачить лише доступні йому категорії.
  • Можна легко вивести категорії конкретного відділу.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *