solved Paged list of filtered users

TiG
TiG
@tig
3 months ago
184 posts
I am trying to display a paged list of users which includes only active, non-blocked, and good emails (per Kickbox). I can filter in the db query with 'user_active = 1' but if I try to include the other conditions (e.g. 'user_blocked != 1') the resulting join fails since the key 'user_blocked' is sporadic.

I have attempted to use a db_search_items_listener to perform the remaining filters but unfortunately this is triggered after the count is determined. Thus when I filter out the bad users (violating the count), the content runs out before the paging logic thinks it should.

I need a way to filter the content before the paging metadata is determined.

Looks to me as though there is no way to filter content in a paged display unless the filtering is done upfront in the db query itself. Is there a way to do this?


--
TiG

updated by @tig: 04/22/24 07:06:21AM
michael
@michael
3 months ago
7,695 posts
Yeah it would. That 'user_blocked != 1' is only going to be there on blocked users not all users. To avoid having to add it to all users and set it to 0 so that the search works, the first way I would look to do it is get all the users back in not paginated format using a while(true){} structure to get chunks of users at a time if you expected there to be a ton of results.

That would get the full unpaginated data set to work with then use a foreach loop to filter out the matching blocked !=1 users until you've got it down to just the user set you want then construct the pagination manually.

I'll try to find an example. back soon.
michael
@michael
3 months ago
7,695 posts
get all the users using a while, add in caching or sleep if you like:
function get_tigs_users(){
    $iid  = 0;
    $_tmp = array();
    while (true) {
        $_sp = array(
            'search'          => array(
                "_item_id > {$iid}"
            ),
            'order_by'        => array('_item_id' => 'asc'),
            'return_keys'     => array('user_name', 'user_whatever', 'user_group'),
            'skip_all_checks' => true,
            'limit'           => 500
        );
        $_sp = jrCore_db_search_items('jrUser', $_sp);
        if ($_sp && is_array($_sp) && !empty($_sp['_items']) && count($_sp['_items']) > 0) {
            foreach ($_sp['_items'] as $u) {

                $iid = $u['_item_id'];

                // Exclude admin and master users
                if (empty($u['user_group']) || $u['user_group'] != 'user') {
                    continue;
                }

                // Exclude empty users
                if (isset($u['user_blocked']) && $u['user_blocked'] == 1) {
                    continue;
                }
                $_tmp[] = $u;
            }
        }
        else {
            break;
        }
    }
    return $_tmp;
}
michael
@michael
3 months ago
7,695 posts
Then the table pager goes something like this:

$_users = get_tigs_users();
$pagebreak = jrCore_get_pager_rows();
$page = 1;
if (isset($_post['p']) && jrCore_checktype($_post['p'], 'number_nz')) {
    $page = (int) $_post['p'];
}
$tcn  = count($_users);
$_usr = array_slice($_users, (($page - 1) * $pagebreak), $pagebreak, true);

$dat = array();
$dat[1]['title'] = 'User name';
jrCore_page_table_header($dat);

foreach ($_usr as $_us) {
    $dat             = array();
    $dat[1]['title'] = $_us['user_name'];
    // how ever many cols here.....
    
    jrCore_page_table_row($dat);
}
$tpg = ceil($tcn / $pagebreak);
$_pg = array(
    'info' => array(
        'this_page'   => $page,
        'prev_page'   => ($page > 1) ? ($page - 1) : 0,
        'next_page'   => ($tpg > $page) ? ($page + 1) : 0,
        'total_pages' => $tpg
    )
);
jrCore_page_table_pager($_pg);

updated by @michael: 01/17/24 01:36:11AM
TiG
TiG
@tig
3 months ago
184 posts
Michael

Much obliged. Basically, filter offline to get the count and then use that to establish a proper pager.

Thanks for the confirmation and a solution.

TiG


--
TiG

Tags