Shuffle and pagination in controller

Hi all,

I have a controller that check for filters and I need the pages to be paginated from a random order. I use infinite scroll. For this reason I used this plugin but nothing happens… Pagination + Shuffle

This is my controller:

<?php 
return function($kirby, $page) {

    $works = page('works')->children()->listed()->shuffleSeed();

    // add the filter filter
    if($filter = Str::split(urldecode(param('filter')))) {
        $works = $works->filterBy('filters', 'in', $filter, ',');
    }
    $works = $works->paginate(2);
    $pagination = $works->pagination();

    $filters = $works->pluck('filters', ',', true);
  
    return compact('works', 'filters', 'filter', 'pagination');
  
};

I use Kirby 3.4.2 (I know, I should upgrade to the new version)

any help^ :upside_down_face:

This description is not very useful. What are you expecting to happen and what is the problem. Also, your infinite scroll probably has a JavaScript part? How are you bringing those bits together?

Thank you and sorry for unclear request :grimacing:

Basically I have to print in the home page all the children pages of a page called “works” (it’s a portfolio of a photographer I’ve done several years ago in WP and now I have to move it to Kirby). Those pages hast to be filtered by categories (and for this task I’m using a controller), paginated in order to load them with an infinite scroll but also appear in random order.
Everything works fine except from the shuffle that of course doesn’t work properly with pagination. I installed the plugin shuffleSeed from Bruno but it doesn’t shuffle the works… what’s wrong with me? I have to say I’m a designer so not an advanced programer :melting_face:

This is the controller I use, where I load the pages, filter, shuffle and paginate them.

<?php 
return function($kirby, $page) {

    $works = page('works')->children()->listed()->shuffleSeed();

    // add the filter filter
    if($filter = Str::split(urldecode(param('filter')))) {
        $works = $works->filterBy('filters', 'in', $filter, ',');
    }
    $works = $works->paginate(2);
    $pagination = $works->pagination();

    $filters = $works->pluck('filters', ',', true);
  
    return compact('works', 'filters', 'filter', 'pagination');
  
};

Here is where I print them in the home page

        <?php foreach($works as $work): ?>
            <?= snippet('work', ['page' => $work]) ?>
        <?php endforeach ?>
        <?php if ($works->pagination()->hasNextPage()): ?>
        <a class="next loading" data-infinte-scroll="<?= $works->pagination()->nextPageURL() ?>" href="<?= $works->pagination()->nextPageURL() ?>">
            ( Waiting )
        </a>
        <?php endif ?>

And this is the plugin I found in the forum

<?php

Kirby::plugin('bruno/shuffleSeed', [
    'pagesMethods' => [
        'shuffleSeed' => function($seed = null) {

            if(is_null($seed)) {
                $seed = s::get('seed');
            
                if(is_null($seed)) {
                  $seed = time();
                  s::set('seed', $seed);
                }
            }

            mt_srand($seed);

            $keys = array_keys($this->data);
            $size = count($keys);

            $order = array_map(function($val) {return mt_rand(); }, range(1, $size));
            array_multisort($order, $keys);

            $collection = clone $this;
            $collection->data = [];

            foreach ($keys as $key) {
                $collection->data[$key] = $this->data[$key];
            }

            return $collection;
        }
    ]
]);
?>

Any idea? :pleading_face:

Hm, not quite sure what you expect. Since the seed is stored in the session, the shuffled order is preserved as long as the session lasts, which makes pagination work.

You should be able to see how the order changes when you delete the session cookie in your browser.

1 Like

Thank you, I tried and deleting the session cookie it works! But how can I implement this in the controller? If I add a $kirby->session()->destroy() at the beginning I get the same problem with pagination…

Why is that important? The session is automatically destroyed when the user closes their browser window, and how likely is it that the user reloads the page multiple times just to see it shuffle?

Maybe delete the seed from the session when the user reaches the last pagination page.

Great idea, it works! I paste the code for everybody else!
Thank you!

<?php 
return function($kirby, $page) {

    $works = page('works')->children()->listed()->shuffleSeed();

    // add the filter filter
    if($filter = Str::split(urldecode(param('filter')))) {
        $works = $works->filterBy('filters', 'in', $filter, ',');
    }
    $works = $works->paginate(2);
    $pagination = $works->pagination();
    $pagination->isLastPage() ? $kirby->session()->destroy() : '';

    $filters = $works->pluck('filters', ',', true);
  
    return compact('works', 'filters', 'filter', 'pagination');
  
};
1 Like

I wouldn’t destroy the session, just remove the seed.

Something like this?

    $pagination->isLastPage() ? $kirby->session()->remove('seed') : '';

Yes, exactly, or using the shortcut s::remove('seed')

Destroying the session might have unwanted side effects.

Amazing! Thank you!