Completed
Push — master ( dacaa0...701f1f )
by Vítor
02:08
created

Module::onBootstrap()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
rs 9.6666
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
/**
3
 * ZfDebugModule. Console commands and other utilities for debugging ZF2 apps.
4
 *
5
 * @license http://www.opensource.org/licenses/mit-license.html MIT License
6
 * @copyright 2016 Vítor Brandão <[email protected]>
7
 */
8
9
namespace Noiselabs\ZfDebugModule;
10
11
use Zend\EventManager\EventInterface;
12
use Zend\ModuleManager\Feature\BootstrapListenerInterface;
13
use Zend\ModuleManager\Feature\ConfigProviderInterface;
14
use Zend\ModuleManager\Feature\DependencyIndicatorInterface;
15
use Zend\Mvc\MvcEvent;
16
use Zend\Mvc\Router\RouteInterface;
17
use Zend\Mvc\Router\RouteMatch;
18
use Zend\ServiceManager\ServiceLocatorInterface;
19
use Zend\Stdlib\RequestInterface;
20
21
/**
22
 * ZfDebug Module.
23
 *
24
 * @author Vítor Brandão <[email protected]>
25
 */
26
class Module implements BootstrapListenerInterface, ConfigProviderInterface, DependencyIndicatorInterface
27
{
28
    const DEFAULT_LAYOUT = 'noiselabs/zf-debug-utils/layout';
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function getModuleDependencies()
34
    {
35
        return ['AssetManager'];
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function getConfig()
42
    {
43
        return require __DIR__ . '/Resources/config/module.config.php';
44
    }
45
46
    /**
47
     * Listen to the bootstrap event.
48
     *
49
     * @param EventInterface|MvcEvent $e
50
     *
51
     * @return array
52
     */
53
    public function onBootstrap(EventInterface $e)
54
    {
55
        if (!$e instanceof EventInterface) {
56
            return;
57
        }
58
59
        $currentRouteName = $this->getCurrentRouteName($e->getApplication()->getServiceManager());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\EventManager\EventInterface as the method getApplication() does only exist in the following implementations of said interface: Zend\Mvc\MvcEvent.

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...
60
        $e->getViewModel()->setVariables(['__currentRouteName' => $currentRouteName]);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\EventManager\EventInterface as the method getViewModel() does only exist in the following implementations of said interface: Zend\Mvc\MvcEvent.

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...
61
    }
62
63
    /**
64
     * @param ServiceLocatorInterface $serviceLocator
65
     *
66
     * @return null|string
67
     */
68
    private function getCurrentRouteName(ServiceLocatorInterface $serviceLocator)
69
    {
70
        /** @var RouteInterface $router */
71
        $router = $serviceLocator->get('router');
72
        /** @var RequestInterface $request */
73
        $request = $serviceLocator->get('request');
74
        /** @var RouteMatch|null $matchedRoute */
75
        $matchedRoute = $router->match($request);
76
77
        return ($matchedRoute instanceof RouteMatch) ? $matchedRoute->getMatchedRouteName() : null;
78
    }
79
}
80