Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Knp Paginator Bundle Laravel Package

knplabs/knp-paginator-bundle

View on GitHub
Deep Wiki
Context7

Creating custom subscriber

Let's say we want to paginate a directory content, which might be quite interesting. And when we have such a handy Finder component in symfony, it's easily achievable.

Prepare environment

I will assume we you just installed Symfony demo and you install KnpPaginatorBundle. Follow the installation guide on these repositories, it's very easy to set up.

Create subscriber

Next, let's extend our subscriber. Create a file named src/Subscriber/PaginateDirectorySubscriber.php

<?php

// file: src/Subscriber/PaginateDirectorySubscriber.php
// requires Symfony\Component\Finder\Finder

namespace App\Subscriber;

use Knp\Component\Pager\Event\ItemsEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Finder\Finder;

final class PaginateDirectorySubscriber implements EventSubscriberInterface
{
    public function items(ItemsEvent $event): void
    {
        if (!is_string($event->target) || !is_dir($event->target)) {
            return;
        }
        $finder = new Finder();
        $finder
            ->files()
            ->depth('< 4') // 3 levels
            ->in($event->target)
        ;
        $iterator = $finder->getIterator();
        $files = iterator_to_array($iterator);
        $event->count = count($files);
        $event->items = array_slice($files, $event->getOffset(), $event->getLimit());
        $event->stopPropagation();
    }

    public static function getSubscribedEvents(): array
    {
        return [
            'knp_pager.items' => ['items', 1/* increased priority to override any internal */]
        ];
    }
}

Class above is the simple event subscriber, which listens to knp_pager.items event. Creates a finder and looks in this directory for files. To be more specific it will look for the files in the directory being paginated, max in 3 level depth.

Register subscriber as service

Next we need to tell knp_paginator about our new fancy subscriber which we intend to use in pagination. It is also very simple, add few line to your service config file (usually config/services.xml)

<?xml version="1.0" ?>

<!-- file: config/services.xml -->

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <!-- ... -->
    
        <service id="acme.directory.subscriber" class="App\Subscriber\PaginateDirectorySubscriber">
            <tag name="kernel.event_subscriber" />
        </service>
    </services>
</container>

Controller action

Finally, we are done with configuration, now let's create actual controller action. Modify controller: src/Controller/DemoController.php And add the following action, which paginates the previous directory

<?php

use ...

/**
 * [@Route](https://github.com/Route)("/test", name="_demo_test")
 */
public function test(KnpPaginatorInterface $paginator, Request $request): Response
{
    $pagination = $paginator->paginate(__DIR__.'/../', $request->query->getInt('page', 1), 10);
    
    return $this->render('demo/test.html.twig', ['pagination' => $pagination]);
}

Template

And the last thing is the template, create: templates/demo/test.html.twig

{% extends "layout.html.twig" %}

{% block title "My demo" %}

{% block content %}
    <h1>Demo</h1>

    <table>
        <tr>
            {# sorting of properties based on query components #}
            <th>base name</th>
            <th>path</th>
        </tr>
    
        {# table body #}
        {% for file in pagination %}
            <tr{% if loop.index is odd %} class="color"{% endif %}>
                <td>{{ file.baseName }}</td>
                <td>{{ file.path }}</td>
            </tr>
        {% endfor %}
    </table>
    {# display navigation #}
    <div id="navigation">
        {{ knp_pagination_render(pagination) }}
    </div>
{% endblock %}

Do not forget to reload the cache: php bin/console cache:clear

You should find some files paginated if you open the url: http://baseurl/index.php/demo/test

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
phalcon/cli-options-parser
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
directorytree/privacy-filter-classifier
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata