Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Die DataProvider-Klasse verstehen und anpassen

Die DataProvider-Klasse verstehen und anpassen

~8 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Die DataProvider-Klasse ist die Brücke zwischen der Collection (Kapitel 2) und dem Grid: Sie liefert die Rohdaten, wendet Filter und Sortierung aus dem Request an und gibt am Ende ein Array zurück, das zu JSON serialisiert wird.

Die minimale Implementierung

Für die meisten Grids reicht eine sehr dünne Klasse, die nur die Collection injiziert - die eigentliche Filter-, Sortier- und Paginierungslogik übernimmt die Basisklasse AbstractDataProvider bereits vollständig:

app/code/Mironsoft/Announcement/Ui/DataProvider/Listing/AnnouncementDataProvider.php
<?php

declare(strict_types=1);

namespace Mironsoft\Announcement\Ui\DataProvider\Listing;

use Magento\Framework\Api\Filter;
use Magento\Ui\DataProvider\AbstractDataProvider;
use Mironsoft\Announcement\Model\ResourceModel\Announcement\CollectionFactory;

/**
 * Supplies announcement rows to the admin grid.
 */
class AnnouncementDataProvider extends AbstractDataProvider
{
    /**
     * @param string $name Component name, injected by the UI Component framework.
     * @param string $primaryFieldName Primary key column of the underlying collection.
     * @param string $requestFieldName Request parameter name carrying the current ID.
     * @param CollectionFactory $collectionFactory Factory building the announcement collection.
     * @param array<string, mixed> $meta Additional UI Component meta configuration.
     * @param array<string, mixed> $data Additional UI Component data configuration.
     */
    public function __construct(
        string $name,
        string $primaryFieldName,
        string $requestFieldName,
        CollectionFactory $collectionFactory,
        array $meta = [],
        array $data = [],
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->collection = $collectionFactory->create();
    }
}

Magento erzeugt CollectionFactory automatisch (Factory-Pattern-Konvention: {Collection}Factory), eine eigene Factory-Klasse muss dafür nicht geschrieben werden.

Filter korrekt anwenden: addFieldToFilter()

Sobald eigene Filterlogik nötig ist - zum Beispiel ein Standardfilter, der inaktive Einträge ausblendet, oder eine Anpassung von getData() - gilt in diesem Projekt eine feste PHPStan-Level-5-Pflicht: addFieldToFilter() wird bei einem Integer-Wert immer in der Array-Form ['eq' => $value] aufgerufen, niemals als nackter Skalar.

// Falsch (PHPStan Level 5 schlägt fehl):
$collection->addFieldToFilter('is_active', 1);

// Richtig:
$collection->addFieldToFilter('is_active', ['eq' => 1]);

Der Hintergrund: addFieldToFilter() akzeptiert laut Signatur array|string als zweiten Parameter - ein nackter int-Wert wird zwar von Magento zur Laufzeit toleriert (implizite Typkonvertierung), ist aber laut Typdeklaration nicht zulässig und wird von PHPStan auf Level 5 als Fehler markiert. Die Array-Form ist zudem explizit und lesbarer - eq, neq, gt, lt, in, nin, like stehen als Operatoren zur Verfügung.

getData() überschreiben

Für Grid-weite Zusatzlogik - etwa das Nachladen einer berechneten Spalte, die nicht direkt aus der Tabelle kommt - überschreibt man getData():

/**
 * Returns grid data, augmented with a computed excerpt of the message.
 *
 * @return array<string, mixed>
 */
public function getData(): array
{
    if (isset($this->loadedData)) {
        return $this->loadedData;
    }

    $items = parent::getData();
    foreach ($items['items'] as &$item) {
        $item['excerpt'] = mb_substr((string) $item['message'], 0, 80);
    }

    $this->loadedData = $items;

    return $this->loadedData;
}

Achtung: getData() wird bei jedem Grid-Request neu aufgerufen - ohne Zwischenspeicherung in einer Instanzvariable (wie $this->loadedData oben) läuft teure Zusatzlogik (Datenbankabfragen, Berechnungen) unnötig mehrfach pro Request, weil sowohl das Grid als auch mögliche Export-Aufrufe dieselbe Methode aufrufen.

Wo die eigene Datenlogik hingehört

Der DataProvider selbst ist bewusst dünn gehalten - komplexere Geschäftslogik (etwa "nur Announcements der letzten 30 Tage anzeigen") gehört in ein eigenes, injizierbares Service-Objekt, das der DataProvider im Konstruktor aufruft, statt die Logik direkt in die Klasse zu schreiben. Damit bleibt die DataProvider-Klasse testbar und die Filterlogik wiederverwendbar - zum Beispiel auch von einer CLI-Kommandozeile aus.