Konvertieren Sie die Ausgabe von nav_menu-Elementen in ein baumartiges mehrdimensionales Array


10

Gibt es eine Möglichkeit, die Navigationsmenüelemente als mehrdimensionales Array anstelle eines flachen Arrays zu erfassen?

Mit einer baumartigen Struktur meine ich etwas, das die Beziehung zwischen untergeordneten und übergeordneten Elementen beibehalten würde (dies ist nur ein Beispiel)…

array(
  array(
    'post_type' => 'page',
    'post_name' => 'Home',
    'children' => array() 
  ),
  array(
    'post_type' => 'page',
    'post_name' => 'About Us',
    'children' => array(
      array(
        'post_type' => 'page',
        'post_name' => 'Our History',
        'children' => array() 
      )
    ) 
  )
)

Es gibt eine wp_get_nav_menu_items()Funktion, die jedoch ein eindimensionales Array mit allen Elementen auf derselben Ebene zurückgibt, was ich nicht möchte. Enthält WordPress eine integrierte Methode, um ein mehrdimensionales Array für meine Menüelemente zu erhalten? Wenn nicht, was ist der beste Weg, um wp_get_nav_menu_items()als baumartige Struktur in Bezug auf die Leistung in ein mehrdimensionales Array zu gelangen ?


3
Dieses eindimensionale Array enthält alle Daten, die Sie zum Erstellen eines Baums benötigen, wenn Sie eine rekursive Funktion verwenden. Suchen Sie für jede der Menüelement-IDs im übergeordneten Objektfeld nach anderen Menüelementen mit übereinstimmender ID. Dies sind die untergeordneten Elemente.
Milo

Ich weiß, dass ich daraus einen Baum machen kann, aber ich habe mich gefragt, ob es in wp bereits eine solche Option gibt.
YemSalat

Was ist Ihr Anwendungsfall? Die WalkerKlasse verarbeitet die Tiefe der sortierten Navigationsmenüelemente automatisch, auch wenn das Array flach ist.
Matt van Andel

1
Ihre Bearbeitung ist falsch. Ich habe den Titel zurück bearbeitet (ein paar Wörter geändert). Die Ausgabe von nav_items ist ein flaches Array, es ist in keiner Weise ein Baum. Mein Anwendungsfall ist: Ich möchte die Navigationselemente als Baum, damit ich sie selbst ausdünnen kann, ohne die kaputten Abstraktionen von WP verwenden zu müssen.
YemSalat

Ich habe die Frage ein wenig geklärt, um klarer zu machen, was ich will.
YemSalat

Antworten:


20

Das Problem , einen Baum aus einem flachen Array zu erstellen, wurde hier mit dieser leicht modifizierten, rekursiven Lösung gelöst:

/**
 * Modification of "Build a tree from a flat array in PHP"
 *
 * Authors: @DSkinner, @ImmortalFirefly and @SteveEdson
 *
 * @link https://stackoverflow.com/a/28429487/2078474
 */
function buildTree( array &$elements, $parentId = 0 )
{
    $branch = array();
    foreach ( $elements as &$element )
    {
        if ( $element->menu_item_parent == $parentId )
        {
            $children = buildTree( $elements, $element->ID );
            if ( $children )
                $element->wpse_children = $children;

            $branch[$element->ID] = $element;
            unset( $element );
        }
    }
    return $branch;
}

Hier haben wir das vorangestellte wpse_childrenAttribut hinzugefügt , um eine Namenskollision zu vermeiden.

Jetzt müssen wir nur noch eine einfache Hilfsfunktion definieren:

/**
 * Transform a navigational menu to it's tree structure
 *
 * @uses  buildTree()
 * @uses  wp_get_nav_menu_items()
 *
 * @param  String     $menud_id 
 * @return Array|null $tree 
 */
function wpse_nav_menu_2_tree( $menu_id )
{
    $items = wp_get_nav_menu_items( $menu_id );
    return  $items ? buildTree( $items, 0 ) : null;
}

Jetzt ist es ganz einfach, ein Navigationsmenü in seine Baumstruktur umzuwandeln:

$tree = wpse_nav_menu_2_tree( 'my_menu' );  // <-- Modify this to your needs!
print_r( $tree );

Für JSON können wir einfach verwenden:

$json = json_encode( $tree );

Für eine etwas andere Version, in der wir die Attribute handverlesen haben, lesen Sie die erste Überarbeitung dieser Antwort hier .

Update: Walker-Klasse

Hier ist eine ziemlich skizzenhafte Idee, wie wir versuchen könnten, uns in den rekursiven Teil der display_element()Methode der abstrakten WalkerKlasse einzuklinken .

$w = new WPSE_Nav_Menu_Tree;
$args = (object) [ 'items_wrap' => '', 'depth' => 0, 'walker' => $w ];
$items = wp_get_nav_menu_items( 'my_menu' );
walk_nav_menu_tree( $items, $args->depth, $args );
print_r( $w->branch );  

Wo WPSE_Nav_Menu_Treeist eine Erweiterung der Walker_Nav_MenuKlasse:

class WPSE_Nav_Menu_Tree extends Walker_Nav_Menu
{
   public $branch = [];

   public function display_element($element, &$children, $max_depth, $depth = 0, $args, &$output )
   {
      if( 0 == $depth )
         $this->branch[$element->ID] = $element;

      if ( isset($children[$element->ID] ) )
         $element->wpse_children = $children[$element->ID];

      parent::display_element($element, $children, $max_depth, $depth, $args, $output);
   }
}

Dies könnte uns einen alternativen Ansatz geben, wenn es funktioniert.


danke, es ist immer interessant und macht Spaß, verschiedene Ansätze zur Problemlösung zu sehen - deine sieht ziemlich cool aus +1. @ialocin
Birgire

1
Das gleiche hier, aber wir wussten bereits, wer gewählt hat :) Möglichkeiten zu erkunden macht Spaß! Der Rest ist oft wie Fließbandarbeit, was ... sagen wir einfach keinen Spaß macht.
Nicolai

Danke, ich hatte gehofft, dass es dafür eine "native" WP-Funktion geben würde. Ich werde etwas länger warten, um zu sehen, ob jemand andere Lösungen veröffentlicht, andernfalls ist dies die gewählte Antwort.
YemSalat

Ich habe die Antwort mit einem anderen Ansatz aktualisiert @YemSalat
birgire

Whoa! Das lässt meine Gedanken wirbeln. Ich habe mich noch nie mit der Walker-Klasse befasst (ich weiß, dass es sie gibt). Ich hatte gehofft, dass es mit ein paar SQL-Abfragen eine performantere Möglichkeit geben würde, aber ich möchte wirklich nicht in die WP-Datenbankstruktur einsteigen. Im Moment würde ich Ihren ersten Ansatz bevorzugen, bei dem er wp_get_nav_menu_itemsrekursiv durchlaufen wird .
YemSalat

3

Kurz gesagt, die folgende Funktion erstellt den Baum von Objekten, indem untergeordnete Elemente in eine neue untergeordnete Eigenschaft innerhalb des übergeordneten Objekts eingefügt werden.

Code:

function wpse170033_nav_menu_object_tree( $nav_menu_items_array ) {
    foreach ( $nav_menu_items_array as $key => $value ) {
        $value->children = array();
        $nav_menu_items_array[ $key ] = $value;
    }

    $nav_menu_levels = array();
    $index = 0;
    if ( ! empty( $nav_menu_items_array ) ) do {
        if ( $index == 0 ) {
            foreach ( $nav_menu_items_array as $key => $obj ) {
                if ( $obj->menu_item_parent == 0 ) {
                    $nav_menu_levels[ $index ][] = $obj;
                    unset( $nav_menu_items_array[ $key ] );
                }
            }
        } else {
            foreach ( $nav_menu_items_array as $key => $obj ) {
                if ( in_array( $obj->menu_item_parent, $last_level_ids ) ) {
                    $nav_menu_levels[ $index ][] = $obj;
                    unset( $nav_menu_items_array[ $key ] );
                }
            }
        }
        $last_level_ids = wp_list_pluck( $nav_menu_levels[ $index ], 'db_id' );
        $index++;
    } while ( ! empty( $nav_menu_items_array ) );

    $nav_menu_levels_reverse = array_reverse( $nav_menu_levels );

    $nav_menu_tree_build = array();
    $index = 0;
    if ( ! empty( $nav_menu_levels_reverse ) ) do {
        if ( count( $nav_menu_levels_reverse ) == 1 ) {
            $nav_menu_tree_build = $nav_menu_levels_reverse;
        }
        $current_level = array_shift( $nav_menu_levels_reverse );
        if ( isset( $nav_menu_levels_reverse[ $index ] ) ) {
            $next_level = $nav_menu_levels_reverse[ $index ];
            foreach ( $next_level as $nkey => $nval ) {
                foreach ( $current_level as $ckey => $cval ) {
                    if ( $nval->db_id == $cval->menu_item_parent ) {
                        $nval->children[] = $cval;
                    }
                }
            }
        }
    } while ( ! empty( $nav_menu_levels_reverse ) );

    $nav_menu_object_tree = $nav_menu_tree_build[ 0 ];
    return $nav_menu_object_tree;
}

Verwendungszweck:

$nav_menu_items = wp_get_nav_menu_items( 'main-menu' );
wpse170033_nav_menu_object_tree( $nav_menu_items );

Ausgabe:

Array
(
 [0] => WP_Post Object
  (
   [ID] => 51
   [post_author] => 1
   [post_date] => 2015-06-26 21:13:23
   [post_date_gmt] => 2015-06-26 19:13:23
   [post_content] => 
   [post_title] => 
   [post_excerpt] => 
   [post_status] => publish
   [comment_status] => open
   [ping_status] => open
   [post_password] => 
   [post_name] => 51
   [to_ping] => 
   [pinged] => 
   [post_modified] => 2015-07-29 20:55:10
   [post_modified_gmt] => 2015-07-29 18:55:10
   [post_content_filtered] => 
   [post_parent] => 0
   [guid] => http://example.com/?p=51
   [menu_order] => 1
   [post_type] => nav_menu_item
   [post_mime_type] => 
   [comment_count] => 0
   [filter] => raw
   [db_id] => 51
   [menu_item_parent] => 0
   [object_id] => 2
   [object] => page
   [type] => post_type
   [type_label] => Page
   [url] => http://example.com/example-page/
   [title] => Example-Page-1
   [target] => 
   [attr_title] => 
   [description] => 
   [classes] => Array
    (
     [0] => 
    )
   [xfn] => 
   [children] => Array
    (
     [0] => WP_Post Object
      (
       [ID] => 80
       [post_author] => 1
       [post_date] => 2015-06-27 14:03:31
       [post_date_gmt] => 2015-06-27 12:03:31
       [post_content] => 
       [post_title] => 
       [post_excerpt] => 
       [post_status] => publish
       [comment_status] => open
       [ping_status] => open
       [post_password] => 
       [post_name] => 80
       [to_ping] => 
       [pinged] => 
       [post_modified] => 2015-07-29 20:55:10
       [post_modified_gmt] => 2015-07-29 18:55:10
       [post_content_filtered] => 
       [post_parent] => 2
       [guid] => http://example.com/?p=80
       [menu_order] => 2
       [post_type] => nav_menu_item
       [post_mime_type] => 
       [comment_count] => 0
       [filter] => raw
       [db_id] => 80
       [menu_item_parent] => 51
       [object_id] => 69
       [object] => page
       [type] => post_type
       [type_label] => Page
       [url] => http://example.com/example-page/subpage-1/
       [title] => Subpage-1
       [target] => 
       [attr_title] => 
       [description] => 
       [classes] => Array
        (
         [0] => 
        )
       [xfn] => 
       [children] => Array
        (
        )
      )
    )
  )
 [1] => WP_Post Object
  (
   [ID] => 49
   [post_author] => 1
   [post_date] => 2015-06-26 21:13:23
   [post_date_gmt] => 2015-06-26 19:13:23
   [post_content] => 
   [post_title] => 
   [post_excerpt] => 
   [post_status] => publish
   [comment_status] => open
   [ping_status] => open
   [post_password] => 
   [post_name] => 49
   [to_ping] => 
   [pinged] => 
   [post_modified] => 2015-07-29 20:55:10
   [post_modified_gmt] => 2015-07-29 18:55:10
   [post_content_filtered] => 
   [post_parent] => 0
   [guid] => http://example.com/?p=49
   [menu_order] => 3
   [post_type] => nav_menu_item
   [post_mime_type] => 
   [comment_count] => 0
   [filter] => raw
   [db_id] => 49
   [menu_item_parent] => 0
   [object_id] => 41
   [object] => page
   [type] => post_type
   [type_label] => Page
   [url] => http://example.com/example-page-2/
   [title] => Example-Page-2
   [target] => 
   [attr_title] => 
   [description] => 
   [classes] => Array
    (
     [0] => 
    )
   [xfn] => 
   [children] => Array
    (
    )
  )
 [2] => WP_Post Object
  (
   [ID] => 48
   [post_author] => 1
   [post_date] => 2015-06-26 21:13:23
   [post_date_gmt] => 2015-06-26 19:13:23
   [post_content] => 
   [post_title] => 
   [post_excerpt] => 
   [post_status] => publish
   [comment_status] => open
   [ping_status] => open
   [post_password] => 
   [post_name] => 48
   [to_ping] => 
   [pinged] => 
   [post_modified] => 2015-07-29 20:55:10
   [post_modified_gmt] => 2015-07-29 18:55:10
   [post_content_filtered] => 
   [post_parent] => 0
   [guid] => http://example.com/?p=48
   [menu_order] => 4
   [post_type] => nav_menu_item
   [post_mime_type] => 
   [comment_count] => 0
   [filter] => raw
   [db_id] => 48
   [menu_item_parent] => 0
   [object_id] => 42
   [object] => page
   [type] => post_type
   [type_label] => Page
   [url] => http://example.com/example-page-3/
   [title] => Example-Page-3
   [target] => 
   [attr_title] => 
   [description] => 
   [classes] => Array
    (
     [0] => 
    )
   [xfn] => 
   [children] => Array
    (
     [0] => WP_Post Object
      (
       [ID] => 79
       [post_author] => 1
       [post_date] => 2015-06-27 14:03:31
       [post_date_gmt] => 2015-06-27 12:03:31
       [post_content] => 
       [post_title] => 
       [post_excerpt] => 
       [post_status] => publish
       [comment_status] => open
       [ping_status] => open
       [post_password] => 
       [post_name] => 79
       [to_ping] => 
       [pinged] => 
       [post_modified] => 2015-07-29 20:55:10
       [post_modified_gmt] => 2015-07-29 18:55:10
       [post_content_filtered] => 
       [post_parent] => 42
       [guid] => http://example.com/?p=79
       [menu_order] => 5
       [post_type] => nav_menu_item
       [post_mime_type] => 
       [comment_count] => 0
       [filter] => raw
       [db_id] => 79
       [menu_item_parent] => 48
       [object_id] => 70
       [object] => page
       [type] => post_type
       [type_label] => Page
       [url] => http://example.com/example-page-3/subpage-2/
       [title] => Subpage-2
       [target] => 
       [attr_title] => 
       [description] => 
       [classes] => Array
        (
         [0] => 
        )
       [xfn] => 
       [children] => Array
        (
         [0] => WP_Post Object
          (
           [ID] => 78
           [post_author] => 1
           [post_date] => 2015-06-27 14:03:31
           [post_date_gmt] => 2015-06-27 12:03:31
           [post_content] => 
           [post_title] => 
           [post_excerpt] => 
           [post_status] => publish
           [comment_status] => open
           [ping_status] => open
           [post_password] => 
           [post_name] => 78
           [to_ping] => 
           [pinged] => 
           [post_modified] => 2015-07-29 20:55:10
           [post_modified_gmt] => 2015-07-29 18:55:10
           [post_content_filtered] => 
           [post_parent] => 70
           [guid] => http://example.com/?p=78
           [menu_order] => 6
           [post_type] => nav_menu_item
           [post_mime_type] => 
           [comment_count] => 0
           [filter] => raw
           [db_id] => 78
           [menu_item_parent] => 79
           [object_id] => 76
           [object] => page
           [type] => post_type
           [type_label] => Page
           [url] => http://example.com/example-page-3/subpage-2/subpage-3/
           [title] => Subpage-3
           [target] => 
           [attr_title] => 
           [description] => 
           [classes] => Array
            (
             [0] => 
            )
           [xfn] => 
           [children] => Array
            (
             [0] => WP_Post Object
              (
               [ID] => 87
               [post_author] => 1
               [post_date] => 2015-06-27 15:27:08
               [post_date_gmt] => 2015-06-27 13:27:08
               [post_content] => 
               [post_title] => 
               [post_excerpt] => 
               [post_status] => publish
               [comment_status] => open
               [ping_status] => open
               [post_password] => 
               [post_name] => 87
               [to_ping] => 
               [pinged] => 
               [post_modified] => 2015-07-29 20:55:10
               [post_modified_gmt] => 2015-07-29 18:55:10
               [post_content_filtered] => 
               [post_parent] => 76
               [guid] => http://example.com/?p=87
               [menu_order] => 7
               [post_type] => nav_menu_item
               [post_mime_type] => 
               [comment_count] => 0
               [filter] => raw
               [db_id] => 87
               [menu_item_parent] => 78
               [object_id] => 85
               [object] => page
               [type] => post_type
               [type_label] => Page
               [url] => http://example.com/example-page-3/subpage-2/subpage-3/subpage-4/
               [title] => Subpage-4
               [target] => 
               [attr_title] => 
               [description] => 
               [classes] => Array
                (
                 [0] => 
                )
               [xfn] => 
               [children] => Array
                (
                 [0] => WP_Post Object
                  (
                   [ID] => 366
                   [post_author] => 1
                   [post_date] => 2015-07-29 20:52:46
                   [post_date_gmt] => 2015-07-29 18:52:46
                   [post_content] => 
                   [post_title] => 
                   [post_excerpt] => 
                   [post_status] => publish
                   [comment_status] => open
                   [ping_status] => open
                   [post_password] => 
                   [post_name] => 366
                   [to_ping] => 
                   [pinged] => 
                   [post_modified] => 2015-07-29 20:55:10
                   [post_modified_gmt] => 2015-07-29 18:55:10
                   [post_content_filtered] => 
                   [post_parent] => 85
                   [guid] => http://example.com/?p=366
                   [menu_order] => 8
                   [post_type] => nav_menu_item
                   [post_mime_type] => 
                   [comment_count] => 0
                   [filter] => raw
                   [db_id] => 366
                   [menu_item_parent] => 87
                   [object_id] => 112
                   [object] => page
                   [type] => post_type
                   [type_label] => Page
                   [url] => http://example.com/example-page-3/subpage-2/subpage-3/subpage-4/subpage-5/
                   [title] => Subpage-5
                   [target] => 
                   [attr_title] => 
                   [description] => 
                   [classes] => Array
                    (
                     [0] => 
                    )
                   [xfn] => 
                   [children] => Array
                    (
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  )
)

Eine baumartige Struktur in WordPress ist kein mehrdimensionales Array. Es ist ein Array von Objekten mit Informationen zur Abstammung.
Matt van Andel

Versuchte ungefähr 10 verschiedene Lösungen für dieses Problem. Vielen Dank für diese großartige Lösung, die eine schöne WP-Objektstruktur aufweist. Dies muss tatsächlich akzeptiert werden!
Johan Pretorius

@ JohanPretorius Danke und mein Vergnügen. Nun, die Leute suchen nach verschiedenen Dingen. Ich gehe davon aus, dass das OP die andere Antwort hilfreicher fand. Es ist alles gut.
Nicolai

1

Geänderte Version der akzeptierten Antwort, bei der die menu_orderEigenschaft der Menüelemente berücksichtigt wird , um die richtige Reihenfolge des ursprünglichen flachen Arrays beizubehalten. menu_orderwird automatisch von WordPress eingestellt, sodass Sie nicht nach etwas suchen müssen:

function buildTree(array &$flatNav, $parentId = 0) {
    $branch = [];

    foreach ($flatNav as &$navItem) {
      if($navItem->menu_item_parent == $parentId) {
        $children = buildTree($flatNav, $navItem->ID);
        if($children) {
          $navItem->children = $children;
        }

        $branch[$navItem->menu_order] = $navItem;
        unset($navItem);
      }
    }

    return $branch;
}

Verwendungszweck:

// get navs
$locations = get_nav_menu_locations();

// get menu items by menu name
$flatMainNav = wp_get_nav_menu_items($locations['main']);
$mainNav = buildTree($flatMainNav);

-2

Es kann hier ein Missverständnis über WordPress-Navigationsmenüelemente als baumartige Strukturen geben.

Baumartige Strukturen in WordPress SIND KEINE MULTIDIMENSIONALEN ARRAYS!

Beachten Sie, dass das zurückgegebene Menüelementarray zwar flach ist, aber dennoch eine baumartige Struktur aufweist, da jedes Element Informationen zu seiner Abstammung enthält (der übergeordnete Wert ist entweder 0, wenn das Element kein übergeordnetes Element hat - oder die ID des übergeordneten Elements, wenn dies der Fall ist tut).

Wenn Sie ein solches Array an die WalkerKlasse übergeben, durchläuft es die Ergebnisse und erstellt zwei Arrays - eines mit Elementen der obersten Ebene und eines mit untergeordneten Elementen im Format, $parent_id => array()in dem das Array Menüelemente enthält, die direkte untergeordnete Elemente dieses Elements sind.

Der Walker durchläuft dann das Elementarray der obersten Ebene, verarbeitet dieses Element und überprüft dann das untergeordnete Array, um festzustellen, ob für das aktuelle Element untergeordnete Elemente vorhanden sind, und verarbeitet jedes Element auf dieselbe Weise rekursiv.

Wenn Sie wissen möchten, wie eine baumartige WordPress-Struktur in ein mehrdimensionales Array konvertiert wird, ist dies eine völlig andere Frage (und technisch gesehen keine WordPress-Frage). Die von zurückgegebenen Informationen wp_get_nav_menu_items() sind jedoch baumartig ... und Sie können sie unverändert verwenden Walker, um damit umzugehen.

Wenn Sie den genauen Code sehen möchten, den die Walker-Klasse von WordPress ausführt , um das Array zu durchlaufen , sehen Sie sich Walker-> walk () in WordPress Trac in den Zeilen 213-258 an . Sie können diesen Code unverändert verwenden, um ein mehrdimensionales Array zu erstellen, wenn Sie danach suchen.

Wanderer

WordPress wurde entwickelt, um die WalkerKlasse zum Verarbeiten ihrer baumartigen Strukturen zu verwenden. Wenn Sie einfach ein Menü rendern oder wirklich nur die endgültige Ausgabe benötigen, sollten Sie die Verwendung wp_nav_menu()Ihres Menüs in Betracht ziehen.

Beispiel:

wp_nav_menu(array(
    'menu' => 6, // your menu id, name, or slug
    'echo' => true, // set this to false if you want a string back instead
    'walker' => new Your_Walker(),
));

Sie würden die Walker-Klasse (z. B. Your_Walker()) erweitern, um die gewünschte Ausgabe zu erhalten. Ein Beispiel finden Sie in diesem Eintrag im Codex .


2
In Option A $sorted_menu_itemsist es immer noch ein "flaches" Array und die Ausgabe von Option B ist eine Zeichenfolge.
Birgire

Ich denke, es gibt ein Missverständnis darüber, wie WordPress "baumartige Strukturen" definiert. wp_get_nav_menu_items()Gibt eine baumartige Struktur zurück, dh ein Array, in dem jedes Element Elterndaten enthält. Diese Strukturen sollen mit einer WalkerKlasse gerendert werden . Wenn der Anwendungsfall hier lediglich das Konvertieren eines "flachen" Arrays in ein mehrdimensionales Array basierend auf Abstammungsdaten (z. B. 'post_parent' => 123) umfasst, bezieht sich diese Frage technisch nicht auf WordPress und sollte in den Stapelüberlauf verschoben werden.
Matt van Andel

1
Schau, es ist mir egal, was WordPress "baumartige Strukturen" definiert (ich glaube nicht, dass dieses Urteil überhaupt Sinn macht). Alles, was mich interessiert, ist ein mehrdimensionales Array, mit dem ich selbst Sachen machen kann.
YemSalat

Sie werden das NICHT als Standard-WordPress-Verhalten erhalten. Wie bereits erwähnt, verfügen Sie über alle Informationen, die Sie benötigen, um das gewünschte Array neu zu strukturieren, und ich habe Sie mit bestimmten Bereichen in WordPress Core verknüpft, um sie als Referenz zu verwenden. Dies ist nicht wirklich eine WordPress-Frage, sondern eine PHP-Frage. Sie können entweder die Walker-Klasse unverändert verwenden oder die relevanten Zeilen von Walker :: walk () wie angegeben kopieren, um Ihr Array zu erstellen.
Matt van Andel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.