Reputation: 934
Within my application I am sending out notifications to different users, which are assigned to agencies, which are assigned to documents. So whenever a document gets created and an agency is assigned to that document, all the users belonging to that agency should get a notification. The problem: it may happen, that an user is assigned to multiple agencies so whenever the notifications get sent out and all his agencies are assigned to the document, he would get notified multiple times. I'd like to avoid this but I can't figure out how to add only distinct objects to my array collection since it doesn't seem like there's something like the array_unique function.
So far it looks like that:
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0){
$users = $agency->getUseragencies();
foreach ($users as $user){
... notifications are generated
$manager->addNotification($user, $notif);
}
}
}
Any help would be appreciated! oh and background info: Agency is an own entity, as well as User is and they are in a many to many relationship!
edit mapping infos: in entity Agency:
/**
* @ORM\ManyToMany(targetEntity="UserBundle\Entity\User", mappedBy="agencies")
**/
private $useragencies;
in entity User
/**
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Agency", inversedBy="useragencies", cascade={"persist"})
* @ORM\JoinTable(name="user_user_agencies",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="iata8", referencedColumnName="iata8")})
* @var \AppBundle\Entity\Agency
**/
private $agencies;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Notification", mappedBy="user", orphanRemoval=true, cascade={"persist"})
**/
private $notifications;
Upvotes: 3
Views: 5516
Reputation: 64476
I assume your Agency
entity has also bidirectional mapping with Document
entity i guess as ManyToMany
. To get the users whom you want to send the notification which belongs to multiple agencies and an agency can have many documents you can use below DQL to get distinct users by providing the document id if you have any other property to identify the document you can adjust WHERE
clause accordingly
SELECT DISTINCT u
FROM YourBundle:User u
JOIN u.agencies a
JOIN a.documents d
WHERE d.id = :documentid
Using query builder it would be something like
$user = $em->getRepository('YourBundle:User');
$user = $user->createQueryBuilder('u')
->select('u')
->join('u.agencies','a')
->join('a.documents','d')
->where('d.id = :documentid')
->setParameter('documentid', $documentid)
->distinct()
->getQuery();
$users= $user->getResult();
Upvotes: 1
Reputation: 1398
While you cannot use in_array()
on an ArrayCollection
, you'll have to build your own array of unique users.
$users = array();
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0) {
foreach ($agency->getUseragencies()as $user) {
// ... notifications are generated
if(!in_array($user->getId(), $users)) {
$users[] = $user->getId();
}
}
foreach($users as $userId) {
$manager->addNotification($userId, $notif);
}
}
}
or a simpler, lower-cost version:
$sent = array();
foreach($document->getAgencies() as $agency) {
if(count($agency->getUseragencies()) > 0) {
foreach ($agency->getUseragencies()as $user) {
// ... notifications are generated
if(!in_array($user->getId(), $sent)) { // check if user has already been sent the notification
$manager->addNotification($user, $notif); // send the notification
$sent[] = $user->getId(); // add user to the 'sent' list
}
}
}
}
Alternatively, you could save yourself a lot of trouble by writing a custom DQL Query (possibly in your UserRepository
class) to fetch the list of user from database directly. This would remove a lot of complexity in the code by removing the need for a loop altogether.
Upvotes: 1
Reputation: 1
You need to add a condition to handle values already in the array. Try adding something like the condition below.
foreach($user as $user){
if(!in_array($value, $list, true))
Upvotes: 0