Completed
Push — master ( c18000...efec97 )
by Anton
12s
created

Bootstrap::forbidden()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 6.8088

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 8
nop 1
dl 0
loc 25
rs 8.439
c 0
b 0
f 0
ccs 7
cts 12
cp 0.5833
crap 6.8088
1
<?php
2
/**
3
 * @copyright Bluz PHP Team
4
 * @link https://github.com/bluzphp/skeleton
5
 */
6
7
/**
8
 * @namespace
9
 */
10
namespace Application;
11
12
use Bluz\Application\Application;
13
use Bluz\Application\Exception\ForbiddenException;
14
use Bluz\Auth\AuthException;
15
use Bluz\Proxy\Auth as AuthProxy;
16
use Bluz\Proxy\Layout;
17
use Bluz\Proxy\Logger;
18
use Bluz\Proxy\Messages;
19
use Bluz\Proxy\Request;
20
use Bluz\Proxy\Response;
21
use Bluz\Proxy\Router;
22
use Bluz\Proxy\Session;
23
use Bluz\Proxy\Translator;
24
25
/**
26
 * Bootstrap
27
 *
28
 * @category Application
29
 * @package  Bootstrap
30
 *
31
 * @author   Anton Shevchuk
32
 * @created  20.07.11 17:38
33
 */
34
class Bootstrap extends Application
35
{
36
    /**
37
     * {@inheritdoc}
38
     *
39
     * @param string $module
40
     * @param string $controller
41
     * @param array $params
42
     * @return void
43
     */
44 37
    protected function preDispatch($module, $controller, $params = array())
0 ignored issues
show
Coding Style introduced by
preDispatch uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
45
    {
46
        // example of setup default title
47 37
        Layout::title("Bluz Skeleton");
48
49
        // apply "remember me" function
50 37
        if (!AuthProxy::getIdentity()) {
51 11
            if ($token = Request::getHeader('Bluz-Token')) {
52
                Auth\Table::getInstance()->authenticateToken($token);
53 11
            } elseif (!empty($_COOKIE['rToken']) && !empty($_COOKIE['rId'])) {
54
                // try to login
55
                try {
56
                    Auth\Table::getInstance()->authenticateCookie($_COOKIE['rId'], $_COOKIE['rToken']);
57
                } catch (AuthException $e) {
58
                    $this->getResponse()->setCookie('rId', '', 1, '/');
59
                    $this->getResponse()->setCookie('rToken', '', 1, '/');
60
                }
61
            }
62
        }
63
64 37
        parent::preDispatch($module, $controller, $params);
65 37
    }
66
67
    /**
68
     * {@inheritdoc}
69
     *
70
     * @param string $module
71
     * @param string $controller
72
     * @param array $params
73
     * @return void
74
     */
75 31
    protected function postDispatch($module, $controller, $params = array())
76
    {
77 31
        parent::postDispatch($module, $controller, $params);
78 31
    }
79
80
    /**
81
     * Denied access
82
     * @param ForbiddenException $exception
83
     * @return \Bluz\Controller\Controller|null
84
     */
85 2
    public function forbidden(ForbiddenException $exception)
86
    {
87 2
        if (AuthProxy::getIdentity()) {
88 2
            $message = Translator::translate("You don't have permissions to access this page");
0 ignored issues
show
Bug introduced by
The call to translate() misses a required argument $...$text.

This check looks for function calls that miss required arguments.

Loading history...
89
        } else {
90
            $message = Translator::translate("You don't have permissions, please sign in");
0 ignored issues
show
Bug introduced by
The call to translate() misses a required argument $...$text.

This check looks for function calls that miss required arguments.

Loading history...
91
        }
92
93
        // for AJAX and API calls (over JSON)
94 2
        $jsonOrApi = Request::isXmlHttpRequest()
95 2
            || (Request::getAccept([Request::TYPE_HTML, Request::TYPE_JSON]) == Request::TYPE_JSON);
96
97
        // for guest, for requests
98 2
        if (!AuthProxy::getIdentity() && !$jsonOrApi) {
99
            // save URL to session and redirect make sense if presentation is null
100
            Session::set('rollback', Request::getUri()->__toString());
101
            // add error notice
102
            Messages::addError($message);
0 ignored issues
show
Bug introduced by
The call to addError() misses a required argument $...$text.

This check looks for function calls that miss required arguments.

Loading history...
103
            // redirect to Sign In page
104
            $url = Router::getUrl('users', 'signin');
105
            return $this->redirect($url);
106
        } else {
107 2
            return $this->error(new ForbiddenException($message, 403, $exception));
108
        }
109
    }
110
111
    /**
112
     * Render with debug headers
113
     * @return void
114
     */
115
    public function render()
0 ignored issues
show
Coding Style introduced by
render uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
116
    {
117
        Logger::info('app:render');
118
119
        if ($this->debugFlag && !headers_sent()) {
120
            $debugString = sprintf(
121
                "%fsec; %skb",
122
                microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'],
123
                ceil((memory_get_usage()/1024))
124
            );
125
            $debugString .= '; '. Request::getModule() .'/'. Request::getController();
126
127
            Response::setHeader('Bluz-Debug', $debugString);
128
129
            if ($info = Logger::get('info')) {
130
                Response::setHeader('Bluz-Bar', json_encode($info));
131
            } else {
132
                Response::setHeader('Bluz-Bar', '{"!":"Logger is disabled"}');
133
            }
134
        }
135
136
        parent::render();
137
    }
138
139
    /**
140
     * Finish it
141
     * @return void
142
     */
143 View Code Duplication
    public function end()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
    {
145
        if ($messages = Logger::get('error')) {
146
            foreach ($messages as $message) {
147
                errorLog(new \ErrorException($message, 0, E_USER_ERROR));
148
            }
149
        }
150
    }
151
}
152