php - Is it possible to use array_walk() to append terms to an array of posts?

admin2025-06-04  1

I'm creating a masonry post grid of animals. I plan to filter the the visible posts by toggling classes. The classes would in turn would be the post's.

I'm using an MVC theme and would like to get all my data within the Controller, and not have to do multiple queries within the theme loop.

I'm thinking something this:

<?php

namespace App\Controllers;

use Sober\Controller\Controller;

class PageOurAnimals extends Controller
{
    protected $acf = true;

    public function animals() {
        $args = [
            'posts_per_page' => -1,
            'post_type' => 'portfolio',
            'post_status' => 'publish',
            'order_by' => 'date',
            'order' => 'DESC',
        ];

        return array_map(function($post) {
            $post->terms = [];

           // Maps terms to posts (doesn't work)
            array_map(function($term) {
                if (isset($term)) {
                    array_push($post->terms, $term->slug);
                }
            }, wp_get_post_terms($post->ID, 'category'));

        }, get_posts($args));
    }
}

.

 {-- Blade Template --}
    @foreach($animals as $i => $animal)
            <div class="cell {{ implode(' ', $animal->terms }}">
                <div class="animal animated rollin">
                    <figure class="zoom zoom__container animal__figure">
                        {!!
                            get_the_post_thumbnail($animal->ID, 'medium', [
                                'title' => $animal->post_title,
                                'class' => 'zoom__image'
                            ])
                        !!}
                        <div class="animal__overlay"></div>
                    </figure>
                    <div class="animal__caption">
                        <span class="animal__name">
                            {{ $animal->post_title }}
                        </span>
                    </div>
                </div>
            </div>
        @endforeach

Edit: I looked up the documentation and found array_map doesn't modify the original array, and what I actually want is array_walk().

I've updated the the code to what is below, but it is still returning an empty array.

    $posts = get_posts($args);
    array_walk($posts, function(&$post, $index) {
        $terms = wp_get_post_terms($post->ID, 'category');

        if (isset($terms)) {
            $post->terms = [];

            array_walk($terms, function(&$term, $term_index) {
                // die(print_r($term));
                if (isset($term->slug)) {
                    array_push($post->terms, $term->slug);
                }
            });
        }
    });

    return $posts;

I'm creating a masonry post grid of animals. I plan to filter the the visible posts by toggling classes. The classes would in turn would be the post's.

I'm using an MVC theme and would like to get all my data within the Controller, and not have to do multiple queries within the theme loop.

I'm thinking something this:

<?php

namespace App\Controllers;

use Sober\Controller\Controller;

class PageOurAnimals extends Controller
{
    protected $acf = true;

    public function animals() {
        $args = [
            'posts_per_page' => -1,
            'post_type' => 'portfolio',
            'post_status' => 'publish',
            'order_by' => 'date',
            'order' => 'DESC',
        ];

        return array_map(function($post) {
            $post->terms = [];

           // Maps terms to posts (doesn't work)
            array_map(function($term) {
                if (isset($term)) {
                    array_push($post->terms, $term->slug);
                }
            }, wp_get_post_terms($post->ID, 'category'));

        }, get_posts($args));
    }
}

.

 {-- Blade Template --}
    @foreach($animals as $i => $animal)
            <div class="cell {{ implode(' ', $animal->terms }}">
                <div class="animal animated rollin">
                    <figure class="zoom zoom__container animal__figure">
                        {!!
                            get_the_post_thumbnail($animal->ID, 'medium', [
                                'title' => $animal->post_title,
                                'class' => 'zoom__image'
                            ])
                        !!}
                        <div class="animal__overlay"></div>
                    </figure>
                    <div class="animal__caption">
                        <span class="animal__name">
                            {{ $animal->post_title }}
                        </span>
                    </div>
                </div>
            </div>
        @endforeach

Edit: I looked up the documentation and found array_map doesn't modify the original array, and what I actually want is array_walk().

I've updated the the code to what is below, but it is still returning an empty array.

    $posts = get_posts($args);
    array_walk($posts, function(&$post, $index) {
        $terms = wp_get_post_terms($post->ID, 'category');

        if (isset($terms)) {
            $post->terms = [];

            array_walk($terms, function(&$term, $term_index) {
                // die(print_r($term));
                if (isset($term->slug)) {
                    array_push($post->terms, $term->slug);
                }
            });
        }
    });

    return $posts;
Share Improve this question edited Jan 11, 2019 at 18:02 Dan asked Jan 11, 2019 at 17:31 DanDan 1491 silver badge15 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I guess you have a problem with variable scopes in here.

        array_walk($terms, function(&$term, $term_index) {
            // die(print_r($term));
            if (isset($term->slug)) {
                array_push($post->terms, $term->slug);
            }
        });

In this part of your code, you use anonymous function and inside of it you use $post variable. But it is a different variable than the one from few lines back - you're in different function now.

But you can simplify that code a lot:

$posts = get_posts($args);
array_walk($posts, function(&$post, $index) {
    $terms = wp_get_post_terms($post->ID, 'category');

    if ( ! empty($terms) && ! is_wp_error($terms) ) {
        $post->terms = [];

        foreach ($terms as $term) {
            $post->terms[] = $term->slug;
        }
    }
});

return $posts;

And even easier, if you know some "magic" WP functions like wp_list_pluck

$posts = get_posts($args);
array_walk($posts, function(&$post, $index) {
    $terms = wp_get_post_terms($post->ID, 'category');
    $post->terms = []; // Prevents error on blade template's implode()

    if ( ! empty($terms) && ! is_wp_error($terms) ) {
        $post->terms = wp_list_pluck( $terms, 'slug' );
    }
});

return $posts;

PS. You have some errors in your $args too.

    $args = [
        'posts_per_page' => -1,
        'post_type' => 'portfolio',
        'post_status' => 'publish',
        'order_by' => 'date',
        'order' => 'DESC',
    ];

It should be orderby instead of oder_by.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749020213a315676.html

最新回复(0)