Symfony:获取朋友的帖子

Symfony: Get Posts of Friends

我想知道是否有人可以为我指明正确的方向,让我知道如何让用户的所有朋友的帖子合并某种新闻流

我有一个简单的用户实体 $user->getPosts() 和 $用户->getFriends() return 适当的 posts/user 对象通过学说中的相应关系设置。这些工作正常,但我如何将我所有朋友的所有帖子编译成一个 ArrayCollection 帖子?

我能想到的唯一方法是遍历所有朋友,获取帖子,将它们合并到一个数组中,然后进行一些排序...但这听起来有点complicated/imperformant

我不认为 $user->getFriends()->getPosts() 是不可能的,而且我如何正确地对帖子进行排序以获取最新的帖子?我也想知道性能问题。给定一个用户有很多朋友,从数据库中检索的数据会相当多。有效征服它的最佳方法是什么?或者因为 symphony 的延迟加载我根本不担心这个?

感谢您的帮助!

这是用户实体

AppBundle\Entity\User:
type: entity
repositoryClass: AppBundle\Entity\UserRepository
table: user
indexes:
    id:
        columns:
            - id
uniqueConstraints:
    username:
        columns:
            - username
    handle:
        columns:
            - handle
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: true
        id: true
        generator:
            strategy: IDENTITY
fields:
    username:
        type: string
        nullable: false
        length: 30
        options:
            fixed: false
    password:
        type: string
        nullable: false
        length: 60
        options:
            fixed: false
    email:
        type: string
        nullable: false
        length: 60
        options:
            fixed: false
oneToMany:
    images:
        targetEntity: Image
        mappedBy: user
    posts:
        targetEntity: Post
        mappedBy: user
    postcomments:
        targetEntity: Postcomment
        mappedBy: user
oneToOne:
    sedcard:
        targetEntity: Sedcard
        mappedBy: user
    portfolio:
        targetEntity: Portfolio
        mappedBy: user
manyToMany:
    myFriends:
        targetEntity: User
        joinTable:
            name: friend
        joinColumns:
            user_source:
                referencedColumnName: id
        inverseJoinColumns:
            user_target:
                referencedColumnName: id
        inversedBy: friendsWithMe
    friendsWithMe:
        targetEntity: User
        mappedBy: myFriends                    
lifecycleCallbacks: {  }

这是 Post 实体

AppBundle\Entity\Post:
type: entity
table: post
indexes:
    user_id:
        columns:
            - user_id
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: true
        id: true
        generator:
            strategy: IDENTITY
fields:
    userId:
        type: integer
        nullable: false
        options:
            unsigned: true
        column: user_id
    body:
        type: text
        nullable: false
        length: 65535
        options:
            fixed: false
    type:
        type: boolean
        nullable: false
    created:
        type: datetime
        nullable: false
    active:
        type: boolean
        nullable: false
oneToMany:
    postcomments:
        targetEntity: Postcomment
        mappedBy: post
manyToOne:
    user:
        targetEntity: User
        inversedBy: posts
        joinColumn:
            name: user_id
            referencedColumnName: id
lifecycleCallbacks: {  }

对于这项工作,您不想再使用 $user->getPosts() 函数,因为这将给出此用户之前 posted 的 post 的列表。您想要的是一个包含 "Post" 个实体的数组,但只是来自所有 "Post" 个实体的选定组,而不是所有实体。为此,您需要使用高级 DQL 查询。在您的用户实体旁边开始使用存储库。然后在您的存储库中编写一个自定义函数,该函数仅检索用户他的朋友的 posts。

读这个:

Querying for Objects with DQL

Custom Repository Classes

DQL and joins

只有当您post您的相关实体时,我们才能进一步帮助您

<?php

namespace AppBundle\Repository;

/**
 * PostRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class PostRepository extends \Doctrine\ORM\EntityRepository
{
    public function findAllPostsOfFriends($userId)
    {
        return $this->getEntityManager()
            ->createQuery(
                'SELECT p, u FROM AppBundle:Post p ' .
                'JOIN p.user u ' .
                'JOIN u.friendsWithMe f ' . 
                'WHERE f.id=:userId'
            )->setParameter('userId', $userId)
            ->getResult();
    }
}

解释:

start to select all posts: (we want to select p and u (posts and authors) 进入内存当我们还想显示作者的一些信息时,避免对屏幕上显示的每个 post 进行额外的查询。您可以在调试栏上计算 doctrine 进行的查询。(删除 ,u 并查看结果) )

SELECT p, u FROM AppBundle:Post p

然后从 posts

加入 authors 的完整用户实体
JOIN p.user u

接下来加入与作者为好友的所有用户的用户实体

JOIN u.friendsWithMe f

最后但同样重要的是,只筛选一个朋友(我自己)和所有作者

WHERE f.id=:userId

控制器:

public function indexAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    // give the user.id as parameter from who you want to see the posts of all his friends
    $posts = $em->getRepository('AppBundle:Post')->findAllPostsOfFriends(2); 

    return $this->render('default/index.html.twig', array(
        'posts' => $posts
    ));
}

模板:

{% extends 'base.html.twig' %}

{% block body %}
    <ul>
        {% for post in posts %}
            <li>{{ post.body }} <strong>Author: {{ post.user.username }}</strong></li>
        {% endfor %}
    </ul>
{% endblock %}