Completed
Pull Request — 3.x (#200)
by
unknown
06:29 queued 03:16
created

MessageManagerBackendDispatcher   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 5
Bugs 3 Features 1
Metric Value
wmc 16
c 5
b 3
f 1
lcom 1
cbo 2
dl 0
loc 114
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getBackend() 0 16 4
B __construct() 0 18 5
A getIterator() 0 4 1
A handle() 0 4 1
A initialize() 0 3 1
A getDefaultBackend() 0 14 2
A getStatus() 0 4 1
A cleanup() 0 4 1
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\NotificationBundle\Backend;
13
14
use Sonata\NotificationBundle\Model\MessageInterface;
15
use Sonata\NotificationBundle\Model\MessageManagerInterface;
16
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
use ZendDiagnostics\Result\Success;
18
19
/**
20
 * Producer side of the doctrine backend.
21
 */
22
class MessageManagerBackendDispatcher extends QueueBackendDispatcher
23
{
24
    /**
25
     * @var array
26
     */
27
    protected $dedicatedTypes = array();
28
29
    /**
30
     * @var BackendInterface
31
     */
32
    protected $default;
33
34
    /**
35
     * @param MessageManagerInterface $messageManager Only used in compiler pass
36
     * @param array                   $queues
37
     * @param string                  $defaultQueue
38
     * @param array                   $backends
39
     */
40
    public function __construct(MessageManagerInterface $messageManager, array $queues, $defaultQueue, array $backends)
41
    {
42
        parent::__construct($queues, $defaultQueue, $backends);
43
44
        foreach ($this->queues as $queue) {
45
            if ($queue['default'] === true) {
46
                continue;
47
            }
48
49
            $this->dedicatedTypes = array_merge($this->dedicatedTypes, $queue['types']);
50
        }
51
52
        foreach ($this->backends as $backend) {
53
            if (empty($backend['types'])) {
54
                $this->default = $backend['backend'];
55
            }
56
        }
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function getBackend($type)
63
    {
64
        $default = null;
0 ignored issues
show
Unused Code introduced by
$default is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
65
66
        if (!$type) {
67
            return $this->getDefaultBackend();
68
        }
69
70
        foreach ($this->backends as $backend) {
71
            if (in_array($type, $backend['types'])) {
72
                return $backend['backend'];
73
            }
74
        }
75
76
        return $this->getDefaultBackend();
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function getIterator()
83
    {
84
        throw new \RuntimeException('You need to use a specific doctrine backend supporting the selected queue to run a consumer.');
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function handle(MessageInterface $message, EventDispatcherInterface $dispatcher)
91
    {
92
        throw new \RuntimeException('You need to use a specific doctrine backend supporting the selected queue to run a consumer.');
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function getStatus()
99
    {
100
        return new Success('Channel is running (RabbitMQ) and consumers for all queues available.');
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function cleanup()
107
    {
108
        throw new \RuntimeException('You need to use a specific doctrine backend supporting the selected queue to run a consumer.');
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function initialize()
115
    {
116
    }
117
118
    /**
119
     * @return BackendInterface
120
     */
121
    protected function getDefaultBackend()
122
    {
123
        $types = array();
124
125
        if (!empty($this->dedicatedTypes)) {
126
            $types = array(
127
                'exclude' => $this->dedicatedTypes,
128
            );
129
        }
130
131
        $this->default->setTypes($types);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Sonata\NotificationBundle\Backend\BackendInterface as the method setTypes() does only exist in the following implementations of said interface: Sonata\NotificationBundl...d\MessageManagerBackend.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
132
133
        return $this->default;
134
    }
135
}
136