манипулирование почтовым порядком в объекте Timber $ context ['posts'] - PullRequest
0 голосов
/ 08 февраля 2019

Я стараюсь, чтобы первые две записи в моем {{posts}} объекте имели миниатюры, в то время как остальные посты продолжают упорядочиваться по последней опубликованной первой.Я пытаюсь создать фильтр следующим образом:

Определение фильтра в PHP:

function posts_with_thumbs_first_filter( $posts, $num_top_posts = 2 ){

    // find first posts with thumbnails in them to decide what posts need to be reordered to first position in the array
    $first_posts_with_thumbs = array();
    foreach ($posts as $key => $post) {
        if ($post->thumbnail) {
            $first_posts_with_thumbs[] = $key;
            if (count($first_posts_with_thumbs) == $num_top_posts) { break; }
        }
    }

    ...manipulate order of posts here...

    return $posts;
}

Использование фильтра в Twig:

{% for post in posts|posts_with_thumbs_first %}
    ...regular post output here, only with posts now reordered...
{% endfor %}

Но этопохоже, что манипулировать порядком записей сложно, потому что это не стандартный массив, это объект Timber \ PostQuery с частными итераторами и методами внутри, которые контролируют данные записей.Я не могу использовать функции массива PHP, такие как array_slice, array_splice и т. Д., Поскольку posts - это не массив, а объект.

Есть ли надежный способ манипулировать порядком записей?

1 Ответ

0 голосов
/ 09 февраля 2019

Вот один из способов сделать это: преобразовать объект posts в массив, чтобы разрешить использование PHP-функций манипулирования массивом.

function posts_with_thumbs_first_filter( $posts, $num_top_posts = 2 ){
    $posts = (array) $posts; // convert posts object to array to use PHP's array manipulating functions
    $first_posts_with_thumbs = array();
    foreach ($posts as $key => $post) {
        if ($post->thumbnail) {
            $first_posts_with_thumbs[] = $key;
            if (count($first_posts_with_thumbs) === $num_top_posts) { break; }
        }
    }
    $posts_to_move_to_top = array();
    for ($i = count($first_posts_with_thumbs) - 1; $i >= 0; $i--){
        $posts[$first_posts_with_thumbs[$i]]->moved = true;
        $posts_to_move_to_top[] = array_splice($posts, ($first_posts_with_thumbs[$i]), 1); // extract post from posts array
    }
    foreach ($posts_to_move_to_top as $post) { // put back into posts at beginning
        array_unshift($posts, $post[0]);
    }
    return $posts;
}
...