Zend Framework 2: Extrahierung mit Filterung von Daten

Im letzten Beitrag über das Zend Framework 2 ging es um die Hydrierung von Objekten. Dieser Weg funktioniert natürlich auch umgekehrt. Das Extrahieren von Daten funktioniert mit der Hydrierung im Zend Framework 2 genau so einfach, wie das Hydrieren. Anhand des Beispiels aus dem letzten Beitrag möchte ich Euch hier zeigen, wie das Extrahieren von Daten funktioniert.

Das Daten Model

Für das Extrahieren von Daten nehmen wir einfach das Model aus dem letzten Beitrag. Natürlich besitzt unser User Model auch eine Username und eine Passwort Eigenschaft. Für diese zwei neuen Eigenschaften wurden die entsprechenden Getter und Setter Methoden hinzugefügt.

declare(strict_types=1);
namespace Application\Entity;

use Zend\Hydrator\Filter\FilterComposite;
use Zend\Hydrator\Filter\FilterProviderInterface;
use Zend\Hydrator\Filter\GetFilter;
use Zend\Hydrator\Filter\MethodMatchFilter;

class User implements FilterProviderInterface
{
    protected $username;
    protected $password;
    protected $birthday;

    public function getUsername() : string
    {
        return $this->username;
    }

    public function setUsername(string $sUsername) : User
    {
        $this->username = $sUsername;
        return $this;
    }

    public function getPassword() : string
    {
        return $this->password;
    }

    public function setPassword(string $sPassword) : User
    {
        $this->password = $sPassword;
        return $this;
    }

    public function getBirthday() : DateTime 
    {
        return $this->birthday;
    }

    public function setBirthday(DateTime $oBirthday) : User 
    {
        $this->birthday = $oBirthday;
        return $this;
    }

    public function getFilter()
    {
        $oComposite = new FilterComposite();
        $oComposite->addFilter('get', new GetFilter());

        $oExclusionComposite = (new FilterComposite())
            ->addFilter(
                'password', 
                new MethodMatchFilter('getPassword'), 
                FilterComposite::CONDITION_AND
            );

        $oComposite->addFilter(
            'exclude', 
            $oExclusionComposite, 
            FilterComposite::CONDITION_AND
        );

        return $oComposite;
    }
}

Diejenigen, die den letzten Artikel gelesen haben, werden sicherlich gemerkt haben, dass sich bei unserem Model noch weitaus mehr getan hat, als die beiden neuen Eigenschaften Username und Password. Mal angenommen wir benutzen unser Model für eine REST API. Natürlich wollen für diesen Fall kein Password ausliefern. Glücklicherweise bietet das Zend Framework 2 hier von Haus aus ein paar wunderbare Möglichkeiten. Für unser Model nutzen wir das FilterProviderInterface, welches eine getFilter Methode für unser Model erfordert. Diese Methode wird dann bei der Extrahierung der Daten automatisch aufgerufen. In dieser Methode komponieren wir mittels der FilterComposite Klasse unseren Filter und schließen das Passwort für die Extrahierung aus.

Die Hydrator Strategie für Datumswerte

Für die genannte Rest API wollen wir das Datum im ISO8601 Fomat zurückgeben, so dass wir die größtmögliche Kompatibilität mit dem JSON Format erreichen. Die DefaultStrategy Klasse des Zend Framework 2 besitzt eine extract Methode, mit der wir dieses Ziel recht einfach erreichen können. Hierzu erweitern wir unsere DateStrategy Klasse aus dem letzten Beitrag einfach wie folgt. Auch die extract Methode wird voll automatisch aufgerufen, wenn der Hydrator extrahiert wird.

declare(strict_types=1);
namespace Application\Hydrator\Strategy;
class DateTimeStrategy extends DefaultStrategy
{
    public function hydrate($value) : DateTime
    {
        if (!($value instanceof \DateTime)) {
            $value = new \DateTime($value);
        }
 
        return $value;
    }

    public function extract($value) : string
    {
        return $value->format(DateTime::ISO8601);
    }
}

Das komplette Beispiel

Was machen diese Erweiterungen für unsere bereits bekannten Klassen nun wirklich? Folgendes Beispiel veranschaulicht nochmals die Hydrierung aber ach das Extrahieren von unseren Daten.

// Daten aus z.B. einem Formular oder einer Datenbank
$aData = [
    'username' => 'Marcel',
    'password' => 'XXX',
    'birthday' => '1979-12-19',
];
 
// Hydrierung des User Modells mit einem Hydrator und der Strategy
$oUser = (new ClassMethods(false))
    ->addStrategy('birthday', new DateTimeStrategy())
    ->hydrate($aData, new User())
 
// Ausgabe des Geburtstages im Format 19.12.1979
echo $oUser->getBirthday()->format('d.m.Y');

// Extrahierung der Daten für die Rest API
$aResult = (new ClassMethods(false))
    ->addStrategy('birthday', new DateTimeStrategy())
    ->extract($oUser);

// Ergebnis:
// [
//     username => Marcel,
//     birthday => 1979-12-19T00:00:00-00:00
// ]

Zunächst hydrieren wir unser Model mit unseren Daten und erhalten ein UserEntity Objekt. Das Geburtsdatum wird gemäß unserer Strategy ein DateTime Objekt sein. Soweit also alles wie bisher. Neu ist die Extrahierung der Daten. Das FilterProviderInterface sorgt dafür, dass unsere Filter beim Extrahieren automatisch ausgeführt werden. Der eingesetzte Filter sorgt dafür, dass das Passwort bei den extrahierten Daten nicht enthalten ist.

Der denkbare Anwendungsfall

Wie in diesen Beispiel bereits erwähnt, möchte man nicht immer alle Daten eines Models ausliefern. Gerade bei Enterprise Anwendungen, in denen viele kritische Daten enthalten sind, ist es ein Muss bei der Extrahierung der Daten darauf zu achten, was hier heraus gegeben wird. Das Model kann bei der Hydrierung im Zend Framework 2 alle Eigenschaften enthalten. Die Hydrierung erlaubt es uns sehr komfortabel zu bestimmen, welche Typen die Eigenschaften eines Models haben sollen und welche Eigenschaften wir bei der Extrahierung herausgeben.

Bildquelle: Pixabay / CC0 Public Domain Lizenz

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.