Completed
Pull Request — 2.x (#659)
by
unknown
11:02
created

RedirectCallback::assembleUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace ZfcUser\Controller;
4
5
use Zend\Mvc\Application;
6
use Zend\Router\RouteInterface;
7
use Zend\Router\Exception;
8
use Zend\Http\PhpEnvironment\Response;
9
use ZfcUser\Options\ModuleOptions;
10
11
/**
12
 * Buils a redirect response based on the current routing and parameters
13
 */
14
class RedirectCallback
15
{
16
17
    /** @var RouteInterface  */
18
    private $router;
19
20
    /** @var Application */
21
    private $application;
22
23
    /** @var ModuleOptions */
24
    private $options;
25
26
    /**
27
     * @param Application $application
28
     * @param RouteInterface $router
29
     * @param ModuleOptions $options
30
     */
31
    public function __construct(Application $application, RouteInterface $router, ModuleOptions $options)
32
    {
33
        $this->router = $router;
34
        $this->application = $application;
35
        $this->options = $options;
36
    }
37
38
    /**
39
     * @return Response
40
     */
41
    public function __invoke()
42
    {
43
        $routeMatch = $this->application->getMvcEvent()->getRouteMatch();
44
        $redirect = $this->getRedirect($routeMatch->getMatchedRouteName(), $this->getRedirectRouteFromRequest());
0 ignored issues
show
Bug introduced by
It seems like $this->getRedirectRouteFromRequest() targeting ZfcUser\Controller\Redir...irectRouteFromRequest() can also be of type string; however, ZfcUser\Controller\RedirectCallback::getRedirect() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
45
46
        $response = $this->application->getResponse();
47
        $response->getHeaders()->addHeaderLine('Location', $redirect);
48
        $response->setStatusCode(302);
49
        return $response;
50
    }
51
52
    /**
53
     * Return the redirect from param.
54
     * First checks GET then POST
55
     * @return string
56
     */
57
    private function getRedirectRouteFromRequest()
58
    {
59
        $request  = $this->application->getRequest();
60
        $redirect = $request->getQuery('redirect');
61
        if ($redirect && ($this->routeExists($redirect) || $this->urlExists($redirect))) {
62
            return urldecode($redirect);
63
        }
64
65
        $redirect = $request->getPost('redirect');
66
        if ($redirect && ($this->routeExists($redirect) || $this->urlExists($redirect))) {
67
            return urldecode($redirect);
68
        }
69
70
        return false;
71
    }
72
73
    /**
74
     * @param $route
75
     * @return bool
76
     */
77
    private function routeExists($route)
78
    {
79
        try {
80
            $this->router->assemble(array(), array('name' => $route));
81
            return true;
82
        } catch (Exception\RuntimeException $e) {
83
            return false;
84
        }
85
    }
86
87
    /**
88
     * @param $route
89
     * @return bool
90
     */
91
    private function urlExists($route)
92
    {
93
        try {
94
            $request = $this->application->getRequest();
95
            $request->setUri($route);
96
            $this->router->match($request);
97
            return true;
98
        } catch (Exception\RuntimeException $e) {
99
            return false;
100
        }
101
    }
102
103
    /**
104
     * Returns the url to redirect to based on current route.
105
     * If $redirect is set and the option to use redirect is set to true, it will return the $redirect url.
106
     *
107
     * @param string $currentRoute
108
     * @param bool $redirect
109
     * @return mixed
110
     */
111
    protected function getRedirect($currentRoute, $redirect = false)
112
    {
113
        $useRedirect = $this->options->getUseRedirectParameterIfPresent();
114
        $routeExists = ($redirect && ($this->routeExists($redirect) || $this->urlExists($redirect)));
115
116
        if (!$useRedirect || !$routeExists) {
117
            $redirect = false;
118
        }
119
120
        switch ($currentRoute) {
121
            case 'zfcuser/register':
122
            case 'zfcuser/login':
123
            case 'zfcuser/authenticate':
124
                $route = ($redirect) ?: $this->options->getLoginRedirectRoute();
125
                return $this->assembleUrl($route);
126
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
127
            case 'zfcuser/logout':
128
                $route = ($redirect) ?: $this->options->getLogoutRedirectRoute();
129
                return $this->assembleUrl($route);
130
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
131
            default:
132
                return $this->router->assemble(array(), array('name' => 'zfcuser'));
133
        }
134
    }
135
136
    /**
137
     * @param $route
138
     * @return bool|mixed
139
     */
140
    protected function assembleUrl($route)
141
    {
142
        try {
143
            return $this->router->assemble(array(), array('name' => $route));
144
        } catch (Exception\RuntimeException $e) {
145
            //This route matches already to an url, so return it of no route by name
146
            return $route;
147
        }
148
    }
149
}
150