Snippet PHP: Użyj development() lub WP_User_Query do stworzenia katalogu autorów lub listy pracowników na swojej stronie.
PL

Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query)

5.00 /5 - (28 głosów )
Ostatnio zweryfikowano: 1 marca 2026
Doświadczenie: 5+ lat doświadczenia
Spis treści

W ekosystemie WordPressa to WP_Query zgarnia całą chwałę, ale to WP_User_Query rządzi światem serwisów społecznościowych, intranetów i platform członkowskich.

Niezależnie od tego, czy budujesz prostą stronę “Nasz Zespół” (Team Page), czy skomplikowaną wyszukiwarkę “Znajdź Lekarza” z tysiącami specjalistów, poleganie na wtyczkach typu Ultimate Member do warstwy prezentacji jest często przesadą – i wąskim gardłem wydajnościowym.

W tym poradniku pominiemy interfejsy graficzne i zbudujemy wydajne, bezpieczne zapytania o użytkowników bezpośrednio w PHP. Omówimy granularne filtrowanie, cache’owanie wydajnościowe i krytyczne środki bezpieczeństwa, aby zapobiec wyciekom danych.

1. Development() vs. Wp_User_Query

Tak jak get_posts() jest nakładką na WP_Query, tak development() jest skonfigurowaną nakładką na WP_User_Query.

  • Używaj development() do prostych list (np. “Pokaż mi 5 administratorów”). Zwraca tablicę obiektów WP_User.
  • Używaj WP_User_Query, gdy potrzebujesz zaawansowanych manipulacji SQL, szczegółowej logiki sortowania (‘orderby’) lub inspekcji nagłówków zapytania/wyników bezpośrednio.

W 95% przypadków będziemy używać tablicy argumentów, która ma zastosowanie do obu funkcji.

2. Podstawy: Budowa strony zespołu

Załóżmy, że chcemy wyświetlić siatkę pracowników (Redaktorów i Autorów) posortowaną według ich wyświetlanej nazwy.

$args = [
    'role__in'    => ['editor', 'author'],
    'orderby'     => 'display_name',
    'order'       => 'ASC',
    'number'      => 12, // Limit paginacji
    'paged'       => 1,
];

$user_query = new WP_User_Query($args);
$results    = $user_query->get_results();

if (!empty($results)) {
    echo '<div class="team-grid">';
    foreach ($results as $user) {
        $avatar = get_avatar($user->ID, 128);
        $name   = esc_html($user->display_name);
        $bio    = esc_html(get_user_meta($user->ID, 'description', true));

        echo "<article class='team-member'>
                <figure>{$avatar}</figure>
                <h3>{$name}</h3>
                <p>{$bio}</p>
              </article>";
    }
    echo '</div>';
}

3. Zaawansowane filtrowanie (meta queries)

Tutaj WP_User_Query błyszczy. Wyobraź sobie, że masz katalog programistów i chcesz znaleźć tych, którzy:

  1. Są z “Warszawy”.
  2. Mają profil oznaczony jako “Publiczny”.
  3. Mają “PHP” na liście umiejętności.
$args = [
    'role'       => 'subscriber',
    'meta_query' => [
        'relation' => 'AND',
        [
            'key'     => 'city',
            'value'   => 'Warszawa',
            'compare' => '='
        ],
        [
            'key'     => 'is_public_profile',
            'value'   => '1',
            'compare' => '='
        ],
        [
            'key'     => 'skills',
            'value'   => 'PHP',
            'compare' => 'LIKE' // Wolne, ale skuteczne dla zserializowanych tablic
        ]
    ]
];

[!WARNING] Alert Wydajnościowy: Odpytywanie wp_usermeta jest kosztowne. W przeciwieństwie do wp_posts, tabele użytkowników rzadko są optymalnie indeksowane pod kątem złożonego filtrowania. Dla katalogów >10,000 użytkowników, rozważ przeniesienie indeksu wyszukiwania do Elasticsearch (przez ElasticPress) lub użycie własnej tabeli SQL.

4. Optymalizacja wydajności

Odpytując użytkowników na stronie o dużym ruchu, musisz oszczędnie gospodarować zasobami bazy danych.

A. Ogranicz zwracane pola (fields)

Domyślnie WordPress pobiera każdą możliwą daną o użytkowniku (wszystkie metadane). Jeśli potrzebujesz tylko imion i e-maili, powiedz WordPressowi, by był lekki.

$args = [
    'role'   => 'subscriber',
    'number' => 100,
    'fields' => ['ID', 'display_name', 'user_email'], // Zwraca obiekty stdClass, nie WP_User
];

Wynik: Zużycie pamięci RAM spada drastycznie.

B. Policz użytkowników bez ich Ładowania

Jeśli chcesz tylko pokazać “Mamy 500 członków!”, nie ładuj obiektów członków.

$args = [
    'role'   => 'subscriber',
    'fields' => 'ID', // Pobierz tylko ID
];
$query = new WP_User_Query($args);
$count = $query->get_total(); // Używa logiki SQL_CALC_FOUND_ROWS

Lub dla ekstremalnej szybkości (ignorując złożone filtry), użyj count_users():

$count = count_users();
echo "Mamy " . $count['total_users'] . " użytkowników.";

5. Bezpieczeństwo: Zagrożenie “user enumeration”

Domyślnie WordPress jest dość “dziurawy”, jeśli chodzi o dane użytkowników.

  1. Nie ujawniaj Loginów: Nigdy nie wykonuj echo $user->user_login. To połowa klucza potrzebnego do zhakowania konta administratora. Zawsze używaj display_name lub user_nicename.
  2. Ukrywaj E-maile: O ile to nie jest wewnętrzny intranet, nigdy nie wypisuj user_email w kodzie HTML, aby uniknąć botów spamujących.

Blokowanie archiwów autora

Hakerzy często skanują /?author=1, /?author=2, aby odkryć nazwy użytkowników. Jeśli budujesz stronę firmową, gdzie użytkownicy nie potrzebują publicznych archiwów, wyłącz tę trasę.

// Dodaj do functions.php
add_action('template_redirect', function() {
    if (is_author()) {
        wp_redirect(home_url(), 301);
        exit;
    }
});

6. Podsumowanie

Budowanie własnego katalogu użytkowników daje pełną kontrolę nad wydajnością i bezpieczeństwem.

  1. Używaj parametru fields, aby zmniejszyć ślad pamięci.
  2. Cache’uj wyniki używając Transients API, jeśli katalog nie zmienia się co godzinę.
  3. Sanityzuj dane wyjściowe bezlitośnie (zawsze esc_html).
  4. Chroń prywatność, ukrywając loginy i e-maile.

Użytkownicy w WordPressie to encje tak samo jak posty – zacznij ich odpytywać z tą samą precyzją.


7. Paginacja użytkowników

Przy dużych katalogach użytkowników, paginacja jest kluczowa dla wydajności i UX.

Paginacja numeryczna

function wppoland_paginated_users_list( $role = 'subscriber', $per_page = 20 ) {
    $paged = isset( $_GET['paged'] ) ? max( 1, intval( $_GET['paged'] ) ) : 1;

    $args = [
        'role'   => $role,
        'number' => $per_page,
        'paged'  => $paged,
        'fields' => ['ID', 'display_name', 'user_email', 'user_login'],
    ];

    $user_query = new WP_User_Query( $args );
    $users = $user_query->get_results();
    $total_users = $user_query->get_total();
    $total_pages = ceil( $total_users / $per_page );

    // Wyświetl użytkowników
    if ( ! empty( $users ) ) {
        echo '<ul class="users-list">';
        foreach ( $users as $user ) {
            $profile_url = get_author_posts_url( $user->ID );
            echo '<li>';
            echo '<a href="' . esc_url( $profile_url ) . '">';
            echo get_avatar( $user->ID, 48 );
            echo '<span>' . esc_html( $user->display_name ) . '</span>';
            echo '</a>';
            echo '</li>';
        }
        echo '</ul>';
    }

    // Wyświetl paginację
    if ( $total_pages > 1 ) {
        echo '<nav class="pagination">';
        echo paginate_links([
            'base'      => add_query_arg( 'paged', '%#%' ),
            'format'    => '?paged=%#%',
            'current'   => $paged,
            'total'     => $total_pages,
            'prev_text' => '&laquo; Poprzednia',
            'next_text' => 'Następna &raquo;',
        ]);
        echo '</nav>';
    }

    echo '<p class="total-users">Łącznie: ' . $total_users . ' użytkowników</p>';
}

Nieskończone przewijanie (Infinite Scroll)

// AJAX handler dla infinite scroll
add_action( 'wp_ajax_wppoland_load_more_users', 'wppoland_load_more_users' );
add_action( 'wp_ajax_nopriv_wppoland_load_more_users', 'wppoland_load_more_users' );

function wppoland_load_more_users() {
    $page = isset( $_POST['page'] ) ? intval( $_POST['page'] ) : 1;
    $role = isset( $_POST['role'] ) ? sanitize_text_field( $_POST['role'] ) : 'subscriber';

    $args = [
        'role'   => $role,
        'number' => 12,
        'paged'  => $page,
        'fields' => ['ID', 'display_name', 'user_email'],
    ];

    $query = new WP_User_Query( $args );

    if ( $query->get_results() ) {
        foreach ( $query->get_results() as $user ) {
            echo '<div class="user-card">';
            echo get_avatar( $user->ID, 100 );
            echo '<h3>' . esc_html( $user->display_name ) . '</h3>';
            echo '<p>' . esc_html( $user->user_email ) . '</p>';
            echo '</div>';
        }
    }

    wp_die();
}

8. Filtrowanie według niestandardowych ról

WordPress pozwala na tworzenie własnych ról. Oto jak filtrować użytkowników według ról niestandardowych:

// Rejestracja roli niestandardowej
function wppoland_register_custom_roles() {
    add_role(
        'premium_member',
        'Członek Premium',
        [
            'read' => true,
            'edit_posts' => false,
            'delete_posts' => false,
        ]
    );

    add_role(
        'instructor',
        'Instruktor',
        [
            'read' => true,
            'edit_posts' => true,
            'delete_posts' => true,
            'upload_files' => true,
        ]
    );
}
add_action( 'init', 'wppoland_register_custom_roles' );

// Wyświetl wszystkich instruktorów
function wppoland_list_instructors() {
    $args = [
        'role'   => 'instructor',
        'orderby'=> 'display_name',
        'order'  => 'ASC',
    ];

    $query = new WP_User_Query( $args );

    if ( $query->get_results() ) {
        echo '<div class="instructors-grid">';
        foreach ( $query->get_results() as $user ) {
            $specialty = get_user_meta( $user->ID, 'specialty', true );
            echo '<div class="instructor-card">';
            echo get_avatar( $user->ID, 150 );
            echo '<h3>' . esc_html( $user->display_name ) . '</h3>';
            echo '<p class="specialty">Specjalizacja: ' . esc_html( $specialty ) . '</p>';
            echo '<a href="' . esc_url( get_author_posts_url( $user->ID ) ) . '" class="button">Zobacz profil</a>';
            echo '</div>';
        }
        echo '</div>';
    }
}

9. Integracja z WooCommerce (lista klientów)

function wppoland_list_woocommerce_customers() {
    $customers = [];

    // Pobierz użytkowników, którzy złożyli zamówienia
    $args = [
        'role__in' => ['customer', 'subscriber', 'administrator'],
        'number'   => 50,
        'paged'    => isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 1,
    ];

    $query = new WP_User_Query( $args );

    if ( $query->get_results() ) {
        echo '<table class="customers-table">';
        echo '<thead><tr><th>Klient</th><th>Email</th><th>Liczba zamówień</th><th>Suma wydana</th></tr></thead>';
        echo '<tbody>';

        foreach ( $query->get_results() as $user ) {
            // Pobierz dane WooCommerce
            $orders = wc_get_orders([
                'customer' => $user->ID,
                'status'   => ['completed', 'processing'],
                'limit'    => -1,
            ]);

            $order_count = count( $orders );
            $total_spent = 0;

            foreach ( $orders as $order ) {
                $total_spent += $order->get_total();
            }

            echo '<tr>';
            echo '<td>' . esc_html( $user->display_name ) . '</td>';
            echo '<td><a href="mailto:' . esc_attr( $user->user_email ) . '">' . esc_html( $user->user_email ) . '</a></td>';
            echo '<td>' . intval( $order_count ) . '</td>';
            echo '<td>' . wc_price( $total_spent ) . '</td>';
            echo '</tr>';
        }

        echo '</tbody></table>';
    }
}

10. Wyszukiwanie użytkowników

function wppoland_user_search_form() {
    ?>
    <form method="get" action="">
        <input type="text" name="user_search" placeholder="Szukaj użytkownika..." value="<?php echo isset( $_GET['user_search'] ) ? esc_attr( $_GET['user_search'] ) : ''; ?>">
        <button type="submit">Szukaj</button>
    </form>
    <?php
}

function wppoland_search_users( $search_term ) {
    $args = [
        'search'         => '*' . sanitize_text_field( $search_term ) . '*',
        'search_columns' => ['user_login', 'user_email', 'display_name'],
        'number'         => 20,
    ];

    $query = new WP_User_Query( $args );

    if ( $query->get_results() ) {
        echo '<ul class="search-results">';
        foreach ( $query->get_results() as $user ) {
            echo '<li>';
            echo get_avatar( $user->ID, 32 );
            echo '<a href="' . esc_url( get_author_posts_url( $user->ID ) ) . '">';
            echo esc_html( $user->display_name );
            echo '</a>';
            echo ' <small>(' . esc_html( $user->user_email ) . ')</small>';
            echo '</li>';
        }
        echo '</ul>';
    } else {
        echo '<p>Nie znaleziono użytkowników.</p>';
    }
}

11. Tworzenie katalogu z filtrami

function wppoland_advanced_user_directory() {
    $role_filter = isset( $_GET['role'] ) ? sanitize_text_field( $_GET['role'] ) : '';
    $city_filter = isset( $_GET['city'] ) ? sanitize_text_field( $_GET['city'] ) : '';
    $search = isset( $_GET['s'] ) ? sanitize_text_field( $_GET['s'] ) : '';

    $args = [
        'number' => 12,
    ];

    if ( $role_filter ) {
        $args['role'] = $role_filter;
    }

    if ( $search ) {
        $args['search'] = '*' . $search . '*';
        $args['search_columns'] = ['display_name', 'user_email'];
    }

    if ( $city_filter ) {
        $args['meta_query'] = [
            [
                'key'   => 'city',
                'value' => $city_filter,
                'compare'=> 'LIKE',
            ]
        ];
    }

    $query = new WP_User_Query( $args );

    // Wyświetl filtry
    echo '<form method="get" class="user-filters">';
    echo '<select name="role"><option value="">Wszystkie role</option>';
    wp_dropdown_roles( $role_filter );
    echo '</select>';
    echo '<input type="text" name="city" placeholder="Miasto" value="' . esc_attr( $city_filter ) . '">';
    echo '<input type="text" name="s" placeholder="Szukaj..." value="' . esc_attr( $search ) . '">';
    echo '<button type="submit">Filtruj</button>';
    echo '</form>';

    // Wyświetl wyniki
    if ( $query->get_results() ) {
        echo '<div class="users-grid">';
        foreach ( $query->get_results() as $user ) {
            $city = get_user_meta( $user->ID, 'city', true );
            echo '<div class="user-card">';
            echo get_avatar( $user->ID, 100 );
            echo '<h3>' . esc_html( $user->display_name ) . '</h3>';
            echo '<p class="role">' . implode( ', ', $user->roles ) . '</p>';
            if ( $city ) {
                echo '<p class="city">📍 ' . esc_html( $city ) . '</p>';
            }
            echo '</div>';
        }
        echo '</div>';
    } else {
        echo '<p>Brak wyników.</p>';
    }
}

12. Cache’owanie wyników

function wppoland_get_cached_users( $role = 'subscriber', $cache_time = HOUR_IN_SECONDS ) {
    $cache_key = 'wppoland_users_' . md5( $role );
    $users = get_transient( $cache_key );

    if ( false === $users ) {
        $args = [
            'role'   => $role,
            'number' => -1,
            'fields' => ['ID', 'display_name', 'user_email'],
        ];

        $query = new WP_User_Query( $args );
        $users = $query->get_results();

        set_transient( $cache_key, $users, $cache_time );
    }

    return $users;
}

// Unieważnij cache przy nowej rejestracji
add_action( 'user_register', 'wppoland_invalidate_users_cache' );
function wppoland_invalidate_users_cache() {
    global $wpdb;
    $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_wppoland_users_%'" );
    $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_timeout_wppoland_users_%'" );
}

13. REST API dla użytkowników

// Rejestracja endpoint REST API
add_action( 'rest_api_init', function() {
    register_rest_route( 'wppoland/v1', '/users', [
        'methods'  => 'GET',
        'callback' => 'wppoland_get_users_api',
        'args'     => [
            'role'   => [
                'default' => 'subscriber',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'limit'  => [
                'default' => 10,
                'sanitize_callback' => 'absint',
            ],
            'offset' => [
                'default' => 0,
                'sanitize_callback' => 'absint',
            ],
        ],
    ]);
});

function wppoland_get_users_api( $request ) {
    $args = [
        'role'   => $request->get_param( 'role' ),
        'number' => $request->get_param( 'limit' ),
        'offset' => $request->get_param( 'offset' ),
        'fields' => ['ID', 'display_name', 'user_email', 'user_login'],
    ];

    $query = new WP_User_Query( $args );

    $users = [];
    foreach ( $query->get_results() as $user ) {
        $users[] = [
            'id'           => $user->ID,
            'name'         => $user->display_name,
            'email'        => $user->user_email,
            'username'     => $user->user_login,
            'avatar_url'   => get_avatar_url( $user->ID ),
            'profile_url'  => get_author_posts_url( $user->ID ),
        ];
    }

    return rest_ensure_response([
        'total' => $query->get_total(),
        'users' => $users,
    ]);
}

14. Shortcode do wyświetlania użytkowników

add_shortcode( 'lista_uzytkownikow', 'wppoland_users_shortcode' );

function wppoland_users_shortcode( $atts ) {
    $atts = shortcode_atts([
        'role'    => 'subscriber',
        'limit'   => 10,
        'columns' => 3,
        'avatar'  => 'yes',
        'bio'     => 'no',
    ], $atts );

    $args = [
        'role'   => $atts['role'],
        'number' => intval( $atts['limit'] ),
        'fields' => ['ID', 'display_name', 'user_email', 'user_login'],
    ];

    $query = new WP_User_Query( $args );

    if ( ! $query->get_results() ) {
        return '<p>Brak użytkowników.</p>';
    }

    $output = '<div class="wppoland-users-shortcode" style="display: grid; grid-template-columns: repeat(' . intval( $atts['columns'] ) . ', 1fr); gap: 20px;">';

    foreach ( $query->get_results() as $user ) {
        $output .= '<div class="user-item" style="text-align: center; padding: 20px; border: 1px solid #eee; border-radius: 8px;">';

        if ( 'yes' === $atts['avatar'] ) {
            $output .= '<div class="user-avatar" style="margin-bottom: 10px;">' . get_avatar( $user->ID, 80 ) . '</div>';
        }

        $output .= '<h4 class="user-name" style="margin: 0 0 5px;">' . esc_html( $user->display_name ) . '</h4>';
        $output .= '<p class="user-role" style="font-size: 0.8em; color: #666;">' . implode( ', ', $user->roles ) . '</p>';

        if ( 'yes' === $atts['bio'] ) {
            $bio = get_user_meta( $user->ID, 'description', true );
            if ( $bio ) {
                $output .= '<p class="user-bio" style="font-size: 0.9em;">' . esc_html( $bio ) . '</p>';
            }
        }

        $output .= '</div>';
    }

    $output .= '</div>';

    return $output;
}

15. Widget użytkowników

class WPPoland_Users_Widget extends WP_Widget {

    public function __construct() {
        parent: ':__construct('
            'wppoland_users_widget',
            'WPPoland: Lista Użytkowników',
            ['description' => 'Wyświetla listę użytkowników z wybraną rolą']
        );
    }

    public function widget( $args, $instance ) {
        echo $args['before_widget'];

        $title = ! empty( $instance['title'] ) ? $instance['title'] : 'Użytkownicy';
        $role = ! empty( $instance['role'] ) ? $instance['role'] : 'subscriber';
        $limit = ! empty( $instance['limit'] ) ? intval( $instance['limit'] ) : 5;

        echo $args['before_title'] . esc_html( $title ) . $args['after_title'];

        $query = new WP_User_Query([
            'role'   => $role,
            'number' => $limit,
            'orderby'=> 'registered',
            'order'  => 'DESC',
        ]);

        if ( $query->get_results() ) {
            echo '<ul class="users-widget-list">';
            foreach ( $query->get_results() as $user ) {
                echo '<li>';
                echo '<a href="' . esc_url( get_author_posts_url( $user->ID ) ) . '">';
                echo get_avatar( $user->ID, 40 );
                echo '<span>' . esc_html( $user->display_name ) . '</span>';
                echo '</a>';
                echo '</li>';
            }
            echo '</ul>';
        }

        echo $args['after_widget'];
    }

    public function form( $instance ) {
        $title = ! empty( $instance['title'] ) ? $instance['title'] : '';
        $role = ! empty( $instance['role'] ) ? $instance['role'] : 'subscriber';
        $limit = ! empty( $instance['limit'] ) ? intval( $instance['limit'] ) : 5;
        ?>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">Tytuł:</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"
                   name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>"
                   type="text" value="<?php echo esc_attr( $title ); ?>">
        </p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'role' ) ); ?>">Rola:</label>
            <select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'role' ) ); ?>"
                    name="<?php echo esc_attr( $this->get_field_name( 'role' ) ); ?>">
                <?php
                global $wp_roles;
                foreach ( $wp_roles->roles as $role_name => $role_info ) {
                    echo '<option value="' . esc_attr( $role_name ) . '"' . selected( $role, $role_name, false ) . '>';
                    echo esc_html( $role_info['name'] );
                    echo '</option>';
                }
                ?>
            </select>
        </p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'limit' ) ); ?>">Liczba użytkowników:</label>
            <input class="tiny-text" id="<?php echo esc_attr( $this->get_field_id( 'limit' ) ); ?>"
                   name="<?php echo esc_attr( $this->get_field_name( 'limit' ) ); ?>"
                   type="number" min="1" max="50" value="<?php echo esc_attr( $limit ); ?>">
        </p>
        <?php
    }

    public function update( $new_instance, $old_instance ) {
        $instance = [];
        $instance['title'] = sanitize_text_field( $new_instance['title'] );
        $instance['role'] = sanitize_text_field( $new_instance['role'] );
        $instance['limit'] = absint( $new_instance['limit'] );
        return $instance;
    }
}

function wppoland_register_users_widget() {
    register_widget( 'WPPoland_Users_Widget' );
}
add_action( 'widgets_init', 'wppoland_register_users_widget' );

16. FAQ - Najczęściej zadawane pytania

Jak wyświetlić tylko użytkowników z konkretną rolą?

$args = [
    'role' => 'administrator', // lub inna rola
];
$users = get_users( $args );

Jak ukryć użytkowników bez avatarów?

$args = [
    'role'   => 'subscriber',
    'number' => 20,
];
$query = new WP_User_Query( $args );

foreach ( $query->get_results() as $user ) {
    if ( get_avatar_url( $user->ID ) ) {
        // Wyświetl użytkownika
    }
}

Jak sortować użytkowników według daty rejestracji?

$args = [
    'role'   => 'subscriber',
    'orderby'=> 'registered',
    'order'  => 'DESC', // najnowsi pierwszy
];

Jak wykluczyć użytkowników z listy?

$args = [
    'role__not_in' => ['administrator', 'editor'],
    'exclude'      => [1, 2, 3], // ID do wykluczenia
];

Jak pobrać tylko liczbę użytkowników?

$args = [
    'role'   => 'subscriber',
    'fields' => 'ID',
];
$query = new WP_User_Query( $args );
$count = $query->get_total();

Jak wyświetlić użytkowników online?

function wppoland_get_online_users() {
    $transient_key = 'wppoland_online_users';
    $online_users = get_transient( $transient_key );

    if ( false === $online_users ) {
        $ten_minutes_ago = time() - 600;
        $users = get_users([
            'fields' => ['ID', 'display_name'],
        ]);

        $online = [];
        foreach ( $users as $user ) {
            $last_active = get_user_meta( $user->ID, 'last_activity', true );
            if ( $last_active && $last_active > $ten_minutes_ago ) {
                $online[] = $user;
            }
        }

        $online_users = $online;
        set_transient( $transient_key, $online_users, 300 );
    }

    return $online_users;
}

// Aktualizuj last_activity przy każdej wizycie
add_action( 'wp_footer', function() {
    if ( is_user_logged_in() ) {
        update_user_meta( get_current_user_id(), 'last_activity', time() );
    }
});

Jak dodać własne pola do profilu użytkownika?

// Dodaj pola do formularza profilu
add_action( 'show_user_profile', 'wppoland_extra_profile_fields' );
add_action( 'edit_user_profile', 'wppoland_extra_profile_fields' );

function wppoland_extra_profile_fields( $user ) {
    ?>
    <h3>Dodatkowe informacje</h3>
    <table class="form-table">
        <tr>
            <th><label for="city">Miasto</label></th>
            <td>
                <input type="text" name="city" id="city" value="<?php echo esc_attr( get_user_meta( $user->ID, 'city', true ) ); ?>" class="regular-text">
            </td>
        </tr>
        <tr>
            <th><label for="phone">Telefon</label></th>
            <td>
                <input type="text" name="phone" id="phone" value="<?php echo esc_attr( get_user_meta( $user->ID, 'phone', true ) ); ?>" class="regular-text">
            </td>
        </tr>
    </table>
    <?php
}

// Zapisz pola
add_action( 'personal_options_update', 'wppoland_save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'wppoland_save_extra_profile_fields' );

function wppoland_save_extra_profile_fields( $user_id ) {
    if ( ! current_user_can( 'edit_user', $user_id ) ) {
        return false;
    }

    update_user_meta( $user_id, 'city', sanitize_text_field( $_POST['city'] ) );
    update_user_meta( $user_id, 'phone', sanitize_text_field( $_POST['phone'] ) );
}

Podsumowanie

ZadanieFunkcja/MetodaPrzykład
Podstawowa listaget_users()get_users(['role' => 'author'])
Zaawansowane filtryWP_User_Querynew WP_User_Query(['meta_query' => [...]])
Paginacjapaginate_links()Z WP_User_Query->get_total()
WyszukiwanieParametr search['search' => '*tekst*']
Cacheset_transient()Cache’owanie wyników
REST APIregister_rest_route()Endpoint /wp-json/wppoland/v1/users
Shortcodeadd_shortcode()[lista_uzytkownikow role="editor"]
WidgetWP_WidgetRejestracja własnego widgetu

Kluczowe zasady:

  1. Używaj fields dla oszczędności pamięci
  2. Cache’uj wyniki dla dużych katalogów
  3. Chroń prywatność - nie ujawniaj loginów i emaili publicznie
  4. Paginate wyniki dla lepszej wydajności
  5. Sanityzuj wszystkie dane wyjściowe (esc_html, esc_url)

Słowa kluczowe: WP_User_Query, get_users, lista użytkowników WordPress, katalog użytkowników, role użytkowników, filtrowanie użytkowników, paginacja użytkowników, shortcode użytkowników, widget użytkowników, cache użytkowników, REST API użytkownicy, bezpieczeństwo użytkowników, user enumeration, WooCommerce klienci, niestandardowe role.

FAQ do artykułu

Często zadawane pytania

Najważniejsze odpowiedzi, które pomagają wdrożyć temat w praktyce.

SEO-ready GEO-ready AEO-ready 3 Q&A
Czym jest Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query)?
Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query) to kluczowy element zarządzania witryną WordPress, który pomaga poprawić jej wydajność, bezpieczeństwo i doświadczenie użytkownika.
Jak wdrożyć Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query)?
Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query) polega na konfiguracji różnych ustawień i wdrażaniu najlepszych praktyk w celu optymalizacji Twojej strony WordPress.
Dlaczego Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query) jest ważne?
Jak wyświetlić listę użytkowników w WordPress? (Wp_User_Query) jest to kluczowa sprawa, ponieważ ma bezpośredni wpływ na rankingi strony w wyszukiwarkach, prędkość ładowania i ogólny sukces witryny.

Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.

Porozmawiajmy

Polecane artykuły