Versionen im Vergleich

Schlüssel

  • Diese Zeile wurde hinzugefügt.
  • Diese Zeile wurde entfernt.
  • Formatierung wurde geändert.

...

Die Mapping-Klasse mapEntity hingegen wird genutzt um Doctrine-Entities zu befüllen. Sie nimmt rudimentäre Transformationen an den Daten vor, damit die Integrität des zu befüllenden Entities erhalten bleibt.

...

Der einfachste Anwendungsfall überführt Daten von einem Objekt oder Array in ein anderes Objekt. In folgenden Beispiel wird davon ausgegangen, dass man bspw. ein Datenbank-Entity in ein einfaches Objekt überführen möchte, ohne die Daten zu transformieren oder andere Property-Namen zu nutzen.

Codeblock
languagephp
themeRDark
<?php
  
  namespace brandbox\pluginType\pluginName\lib\request {
    
    use brandbox\admin\plugin;
    use brandbox\pluginType\pluginName;
    
    class vcard extends plugin\lib\requestAbstract {
      
      /**
       * @param pluginName\lib\entity\pluginNamePerson $person
       *
       * @return pluginName\lib\map\vcard
       */
      public function getByEntity($person) { 
        
        return $this
          ->map()
          ->from($person)
          ->to(pluginName\lib\map\vcard::class)
        ;
      }
      
    }
    
  }

?>

Folgende Methoden wurden in diesem Beispiel genutzt:

Methode

Beschreibung

mapBuilderInterface::from($input, $multiple = false)

Legt die Datenquelle fest. Dies kann entweder ein instantiiertes Objekt oder ein Array sein. Wird zusätzlich der Parameter $multiple auf true gesetzt wird als $input ein Array mit Objekten oder Arrays erwartet.

mapBuilderInterface::to($output)

Führt das Mapping auf Basis der festgelegten Informationen durch und gibt das resultierende Objekt, welches über den Parameter $output festgelegt wurde, zurück. Ist der Parameter $multiple im Aufruf von mapBuilderInterface::from($input, $multiple) auf true gesetzt worden, wird ein Array mit den resultierenden Objekten zurückgegeben.

Mapping auf Entities

Muss von einem Array oder Objekt auf ein Datenbank-Entity gemapped werden, so sollte die Mapping-Klasse \brandbox\component\mapping\lib\map\mapEntity genutzt werden. Die wird mithilfe der Methode mapBuilderInterface::withMap($map) festgelegt.

Codeblock
languagephp
themeRDark
<?php
  
  namespace brandbox\pluginType\pluginName\lib\request {
    
    use brandbox\admin\plugin;
    use brandbox\component\mapping;
    use brandbox\pluginType\pluginName;
    
    class vcard extends plugin\lib\requestAbstract {
      
      /**
       * @param pluginName\lib\entity\pluginNamePerson $person
       *
       * @return pluginName\lib\map\vcard
       */
      public function getByEntity($person) { 
        
        return $this
          ->map()
          ->from($person)
		  ->withMap(mapping\lib\map\mapEntity::class)
          ->to(pluginName\lib\map\vcard::class)
        ;
      }
      
    }
    
  }

?>

...

Mit der Mapping-Klasse \brandbox\component\mapping\lib\map\mapEntityAdvanced können nur bestimmte Doctrine-Entity-Properties übertragen werden. Diese lassen sich über eine Black- oder Whitelist einstellen. Sollte Black- bzw. Whitelist erhält man unter anderem durch die Formular-Komponente.

Codeblock
languagephpthemeRDark
<?php
  
  namespace brandbox\pluginType\pluginName\lib\execute {
    
    use brandbox\admin\plugin;

	use brandbox\component\form;
    use brandbox\component\mapping;

    use brandbox\pluginType\pluginName;
    
    class vcard extends plugin\lib\executeAbstract {
      
      /**
       * @param array $params
       *
       * @return void
       */
      public function save($params) { 

		// Ziel-Entity abrufen
		$person = $this
		  ->getRepository(pluginName\lib\entity\person::class)
		  ->getEntity(0)
		;

        // Black- und Whitelist abrufen
		$engine = $this->getAppFactory(form\engine::class);
		$whitelist = $engine->getListedColumnsByEntity($person, '[Formularidentifikator]', $engine::LIST_TYPE_WHITELIST);
		$blacklist = $engine->getListedColumnsByEntity($person, '[Formularidentifikator]', $engine::LIST_TYPE_BLACKLIST);

		// Diese Mapping-Klasse muss vorher initialisiert werden
		$map = mapping\lib\map\mapEntityAdvanced::get($whitelist, $blacklist);
        
		$this
          ->map()
          ->from($params)
		  ->withMap($map)
          ->to($person)
        ;
      }
      
    }
    
  }

?>

...

In alle Mapping-Vorgänge kann auf verschiedenste Weise eingegriffen werden. Die folgenden Methoden stehen hierfür zur Verfügung und können vor dem Aufruf von mapBuilderInterface::to($output) eingesetzt werden.

Methode

Beschreibung

mapBuilderInterface::withMap($map, $withSource = false)

Setzt die Mapping-Klasse für den aktuellen Mapping-Vorgang. Hier kann entweder ein Klassenname oder ein instantiiertes Objekt angegeben werden. Mapping-Klassen müssen das o.g. mapInterface implementieren und generische oder spezifische Mapping-Methoden bereitstellen.

$withSource kann verwendet werden um in der Mapping-Methode nicht die Property rein gereicht zu bekommen sondern das gesamte Quellobjekt.

mapBuilderInterface::withPropertyMap($target, $source)

Zwischen Quelle und Ziel können sich die Property-Namen unterscheiden, obwohl die gleichen Daten enthalten sein sollen. Hierfür kann diese Methode genutzt werden. Der Parameter $target gibt den Property-Namen im Zielobjekt an und der Parameter $source den Property-Namen im Quellobjekt.

Beispiel
Codeblock
languagephp
themeRDarktitleBeispielcollapsetrue
<?php
  
  namespace brandbox\pluginType\pluginName\lib\request {
    
    use brandbox\admin\plugin;
    use brandbox\pluginType\pluginName;
    
    class vcard extends plugin\lib\requestAbstract {
      
      /**
       * @param pluginName\lib\entity\pluginNamePerson $person
       *
       * @return pluginName\lib\map\vcard
       */
      public function getByEntity($person) { 
        
        return $this
          ->map()
          ->from($person)
		  ->withPropertyMap('vcardPersonID', 'id')
          ->to(pluginName\lib\map\vcard::class)
        ;
      }
      
    }
    
  }

?>


mapBuilderInterface::withStaticMap($target, $value)

Mithilfe dieser Methode können statische Werte in bestimmte Properties im Zielobjekt eingefügt werden. Hierbei wird das eigentliche Mapping umgangen und der angegebene Wert genutzt.

mapBuilderInterface::withCallableMap($target, $callable, $source = null)

Mithilfe dieser Methode kann für eine bestimmte Property Code außerhalb der Mapping-Klasse aufgerufen werden. Auch kann hier, wie bei mapBuilderInterface::withPropertyMap($target, $source) der Property-Name im Quell- und Zielobjekt gemapped werden.

Beispiel
Codeblock
languagephp
themeRDarktitleBeispielcollapse
true
<?php
  
  namespace brandbox\pluginType\pluginName\lib\request {
    
    use brandbox\admin\plugin;
    use brandbox\pluginType\pluginName;
    
    class vcard extends plugin\lib\requestAbstract {
      
      /**
       * @param pluginName\lib\entity\pluginNamePerson $person
       *
       * @return pluginName\lib\map\vcard
       */
      public function getByEntity($person) { 
        
        return $this
          ->map()
          ->from($person)
		  ->withCallableMap('homepage', [$this, 'callableMapHomepage'], 'id')
          ->to(pluginName\lib\map\vcard::class)
        ;
      }

      /**
       * @param int $id
       *
       * @return string
       */
      public function callableMapHomepage($id) {
        
        return '/person?id='.$id;
      }

   }
    
  }

?>


Eigene Mapping-Klassen nutzen

Sollten die bereitgestellten Mapping-Klassen und die Zusatzfunktionen nicht ausreichend sein oder wird ein bestimmtes Mapping-Verhalten mehrfach benötigt, kann es sinnvoll sein eine eigene Mapping-Klasse zu definieren. In den meisten Fällen kann als Grundlage einer eigenen Mapping-Klasse von \brandbox\component\mapping\lib\map\mapGeneric oder \brandbox\component\mapping\lib\map\mapAbstract abgeleitet werden. Zwingend notwendig ist jedoch die Implementation des Interface \brandbox\component\mapping\lib\map\mapInterface. Die eigene Mapping-Klasse kann in einem Mapping-Vorgang mithilfe der Methode mapBuilderInterface::withMap($map) gesetzt werden.

Codeblock
languagephpthemeRDark
<?php

  namespace brandbox\pluginType\pluginName\lib\map {

    use brandbox\component\mapping;

    /**
     * @author Dominik Hisler <hisler@konmedia.com>
     */
    class myCustomMap extends mapping\lib\map\mapGeneric {

      /**
       * @param string $value
       *
       * @return string
       */
      public function getSomeTargetPropertyName($value) {

        return 'someTransformation'.$value;
      }

    }

  }

?>

...