Completed
Push — master ( 38e793...194a5f )
by dan
01:59
created

DatabaseNotificationManager.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace IrishDan\NotificationBundle;
4
5
use IrishDan\NotificationBundle\Notification\DatabaseNotificationInterface;
6
use IrishDan\NotificationBundle\Notification\NotifiableInterface;
7
use Symfony\Bridge\Doctrine\ManagerRegistry;
8
use Symfony\Component\PropertyAccess\PropertyAccess;
9
10
/**
11
 * Class DatabaseNotificationManager
12
 *
13
 * @package IrishDan\NotificationBundle
14
 */
15
class DatabaseNotificationManager
16
{
17
    /**
18
     * @var array
19
     */
20
    protected $databaseConfiguration;
21
    /**
22
     * @var ManagerRegistry
23
     */
24
    protected $managerRegistry;
25
    /**
26
     * @var PropertyAccess
27
     */
28
    protected $propertyAccessor;
29
30
    /**
31
     * DatabaseNotificationManager constructor.
32
     *
33
     * @param ManagerRegistry $managerRegistry
34
     * @param array           $databaseConfiguration
35
     */
36
    public function __construct(ManagerRegistry $managerRegistry, array $databaseConfiguration = [])
37
    {
38
        $this->managerRegistry = $managerRegistry;
39
        $this->databaseConfiguration = $databaseConfiguration;
40
    }
41
42
    protected function getEntityManager()
43
    {
44
        $entity = $this->notificationEntityName();
45
        if ($entity) {
46
            return $this->managerRegistry->getManagerForClass($entity);
47
        }
48
49
        return false;
50
    }
51
52
    /**
53
     * @param array $data
54
     * @return bool
55
     */
56
    public function createDatabaseNotification(array $data)
57
    {
58
        if ($this->propertyAccessor === null) {
59
            $this->propertyAccessor = PropertyAccess::createPropertyAccessor();
0 ignored issues
show
Documentation Bug introduced by
It seems like \Symfony\Component\Prope...reatePropertyAccessor() of type object<Symfony\Component...ccess\PropertyAccessor> is incompatible with the declared type object<Symfony\Component...yAccess\PropertyAccess> of property $propertyAccessor.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
60
        }
61
62
        $entityManager = $this->getEntityManager();
63
        if ($entityManager) {
64
            $entity = $this->notificationEntityName();
65
            $class = $entityManager->getRepository($entity)->getClassName();
66
            $databaseNotification = new $class();
67
68
            // Transfer values from message to databaseNotification.
69
            $properties = ['notifiable', 'uuid', 'type', 'body', 'title'];
70
            foreach ($properties as $property) {
71
                $value = $this->propertyAccessor->getValue($data, '[' . $property . ']');
0 ignored issues
show
The method getValue does only exist in Symfony\Component\PropertyAccess\PropertyAccessor, but not in Symfony\Component\PropertyAccess\PropertyAccess.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
72
                $this->propertyAccessor->setValue($databaseNotification, $property, $value);
0 ignored issues
show
The method setValue does only exist in Symfony\Component\PropertyAccess\PropertyAccessor, but not in Symfony\Component\PropertyAccess\PropertyAccess.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
73
            }
74
75
            // Save the notification to the database
76
            $entityManager->persist($databaseNotification);
77
            $entityManager->flush();
78
79
            return $databaseNotification;
80
        }
81
82
        return false;
83
    }
84
85
    /**
86
     * @param DatabaseNotificationInterface $notification
87
     * @param null                          $now
88
     * @param bool                          $flush
89
     */
90
    public function setReadAtDate(DatabaseNotificationInterface $notification, $now = null, $flush = true)
91
    {
92
        if (empty($now)) {
93
            $now = new \DateTime();
94
        }
95
96
        $notification->setReadAt($now);
97
98
        $entityManager = $this->getEntityManager();
99
        $entityManager->persist($notification);
100
        if ($flush) {
101
            $entityManager->flush();
102
        }
103
    }
104
105
    /**
106
     * @param NotifiableInterface $notifiable
107
     * @param null                $now
108
     */
109
    public function setUsersNotificationsAsRead(NotifiableInterface $notifiable, $now = null)
110
    {
111
        $entity = $this->notificationEntityName();
112
        if (!empty($entity)) {
113
            $options = [
114
                'notifiable' => $notifiable,
115
                'readAt' => null,
116
            ];
117
118
            $entityManager = $this->getEntityManager();
119
            $usersNotifications = $entityManager->getRepository($entity)->findBy($options);
120
121
            if (!empty($usersNotifications)) {
122
                foreach ($usersNotifications as $notification) {
123
                    $this->setReadAtDate($notification, null, false);
124
                }
125
            }
126
            $entityManager->flush();
127
        }
128
    }
129
130
    public function getUsersUnreadNotifications(DatabaseNotifiableInterface $user)
131
    {
132
        $entityManager = $this->getEntityManager();
133
        if ($entityManager) {
134
            $entity = $this->notificationEntityName();
135
            $notifications = $entityManager->getRepository($entity)->getUnreadNotifications($user);
136
137
            return $notifications;
138
        }
139
140
        return [];
141
    }
142
143
    /**
144
     * @param NotifiableInterface $user
145
     * @param string              $status
146
     * @return int
147
     */
148
    public function getUsersNotificationCount(NotifiableInterface $user, $status = '')
149
    {
150
        $entityManager = $this->getEntityManager();
151
        if ($entityManager) {
152
            $entity = $this->notificationEntityName();
153
            $count = $entityManager->getRepository($entity)->getNotificationsCount($user, $status);
154
155
            return $count;
156
        }
157
158
        return 0;
159
    }
160
161
    /**
162
     * @return bool|mixed
163
     */
164
    protected function notificationEntityName()
165
    {
166
        $config = $this->databaseConfiguration;
167
        if (!empty($config['entity'])) {
168
            return $config['entity'];
169
        }
170
171
        return false;
172
    }
173
}
174