Completed
Push — master ( 06707c...0359c5 )
by Marcus
04:05
created

Router   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 36
lcom 1
cbo 9
dl 0
loc 186
c 3
b 0
f 1
rs 8.8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
F getPage() 0 116 29
B getRoutingoverride() 0 33 6
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: mhaase
5
 * Date: 14.01.16
6
 * Time: 23:04
7
 */
8
9
namespace HaaseIT\HCSF;
10
11
12
use Zend\ServiceManager\ServiceManager;
13
14
class Router
15
{
16
    private $P;
17
18
    /**
19
     * @var string
20
     */
21
    private $sPath;
22
23
    /**
24
     * @var ServiceManager
25
     */
26
    private $serviceManager;
27
28
    /**
29
     * @var \HaaseIT\HCSF\HelperConfig
30
     */
31
    protected $config;
32
33
    /**
34
     * @var \HaaseIT\HCSF\Helper
35
     */
36
    protected $helper;
37
38
    /**
39
     * Router constructor.
40
     * @param ServiceManager $serviceManager
41
     */
42
    public function __construct(ServiceManager $serviceManager)
43
    {
44
        $this->serviceManager = $serviceManager;
45
        $this->config = $serviceManager->get('config');
46
        $this->helper = $serviceManager->get('helper');
47
    }
48
49
    public function getPage()
50
    {
51
        // Maintenance page
52
        if ($this->config->getCore('maintenancemode')) {
53
            try {
54
                $controller = new \HaaseIT\HCSF\Controller\Maintenance($this->serviceManager);
55
                $this->P = $controller->getPage();
56
            } catch (\Exception $e) {
57
                $this->P = $e->getMessage();
58
            }
59
        } else {
60
            $routes = require __DIR__.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'routes.php';
61
            if ($this->config->getCore('enable_sandbox')) {
62
                $routes['literal']['/_misc/sandbox.html'] = 'Sandbox'; // dev sandbox for testing new functionality
63
            }
64
            $aURL = parse_url($this->serviceManager->get('request')->getRequestTarget());
65
            $this->sPath = $aURL['path'];
66
67
            $aPath = explode('/', $this->sPath);
68
            if (!empty($routes['literal'][$this->sPath])) {
69
                $class = '\\HaaseIT\\HCSF\\Controller\\'.$routes[$this->sPath];
70
            } else {
71
                if (!empty($routes['regex'])) {
72
                    foreach ($routes['regex'] as $regex) {
73
                        $result = preg_match('(^' . $regex['regex'] . '$)', $this->sPath, $matches);
74
                        if ($result) {
75
                            $class = $regex['controller'];
76
                            break;
77
                        }
78
                    }
79
                }
80
                if (empty($result) && $aPath[1] === $this->config->getCore('directory_images')) {
81
                    $class = Controller\Glide::class;
82
                }
83
            }
84
85
            if (!empty($class)) {
86
                // Core Page
87
                try {
88
                    /** @var Controller\Base $controller */
89
                    $controller = new $class($this->serviceManager, $aPath, (!empty($matches) ? $matches : false));
90
                    $this->P = $controller->getPage();
91
                } catch (\Exception $e) {
92
                    $this->P = new Page();
93
                    $this->P->setStatus(500);
94
                    // todo: write error message
95
                    //echo $e->getMessage();
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
96
                }
97
            } else {
98
                if ($this->config->getCore('enable_module_shop')) {
99
                    $aRoutingoverride = $this->getRoutingoverride($aPath);
100
                }
101
102
                $this->P = new UserPage($this->serviceManager, $this->sPath);
103
104
                // go and look if the page can be loaded yet
105
                if ($this->P->cb_id === NULL) {
106
                    /*
107
                    If the last part of the path doesn't include a dot (.) and is not empty, apend a slash.
108
                    If there is already a slash at the end, the last part of the path array will be empty.
109
                     */
110
                    if (mb_strpos($aPath[count($aPath) - 1], '.') === false && $aPath[count($aPath) - 1] !== '') {
111
                        $this->sPath .= '/';
112
                    }
113
114
                    if ($this->sPath[strlen($this->sPath) - 1] === '/') {
115
                        $this->sPath .= 'index.html';
116
                    }
117
118
                    $this->P = new UserPage($this->serviceManager, $this->sPath);
119
                }
120
121
                if ($this->P->cb_id === NULL) { // if the page is still not found, unset the page object
122
                    $this->P->setStatus(404);
123
                } else { // if it is found, go on
124
                    // Support for shorturls
125
                    if ($this->P->cb_pagetype === 'shorturl') {
126
                        $this->P->setStatus(302);
127
                        $this->P->setHeader('Location', $this->P->cb_pageconfig);
0 ignored issues
show
Bug introduced by
It seems like $this->P->cb_pageconfig can also be of type array; however, HaaseIT\HCSF\Page::setHeader() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
128
                    }
129
130
                    if (isset($this->P, $aRoutingoverride) && count($aRoutingoverride)) {
131
                        $this->P->cb_pagetype = $aRoutingoverride['cb_pagetype'];
132
                        $this->P->cb_pageconfig->itemno = $aRoutingoverride['itemno'];
133
                    }
134
                }
135
            }
136
137
            if ($this->P->getStatus() === 404) {
138
                $this->P = new CorePage($this->serviceManager);
139
                $this->P->cb_pagetype = 'error';
140
                $this->P->setStatus(404);
141
                $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_page_not_found');
142
            } elseif ($this->P->getStatus() === 500) {
143
                $this->P = new CorePage($this->serviceManager);
144
                $this->P->cb_pagetype = 'error';
145
                $this->P->setStatus(500);
146
                $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_server_error');
147
            } elseif (is_object($this->P) && $this->P->oPayload === null) {// elseif the page has been found but contains no payload...
148
                // no payload is fine if page is one of these
149
                $pagetypesnocontent = [
150
                    'itemoverviewjson',
151
                    'itemoverview',
152
                    'itemoverviewgrpd',
153
                    'itemdetail',
154
                ];
155
                if (!in_array($this->P->cb_pagetype, $pagetypesnocontent, true)) {
156
                    $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_content_not_found');
157
                    $this->P->setStatus(404);
158
                }
159
            } elseif ($this->P->oPayload->cl_lang !== null && $this->P->oPayload->cl_lang !== $this->config->getLang()) { // if the page is available but not in the current language, display info
160
                $this->P->oPayload->cl_html = $this->serviceManager->get('textcats')->T('misc_page_not_available_lang').'<br><br>'.$this->P->oPayload->cl_html;
161
            }
162
        }
163
        return $this->P;
164
    }
165
166
    private function getRoutingoverride($aPath)
167
    {
168
        $aRoutingoverride = [];
169
        // /xxxx/item/0010.html
170
        $aTMP['parts_in_path'] = count($aPath);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$aTMP was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aTMP = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
171
        // if the last dir in path is 'item' and the last part of the path is not empty
172
        if ($aPath[$aTMP['parts_in_path'] - 2] === 'item' && $aPath[$aTMP['parts_in_path'] - 1] !== '') {
173
174
            // explode the filename by .
175
            $aTMP['exploded_request_file'] = explode('.', $aPath[$aTMP['parts_in_path'] - 1]);
176
177
            // if the filename ends in '.html', get the requested itemno
178
            if ($aTMP['exploded_request_file'][count($aTMP['exploded_request_file']) - 1] === 'html') {
179
                // to allow dots in the filename, we have to iterate through all parts of the filename
180
                $aRoutingoverride['itemno'] = '';
181
                for ($i = 0; $i < count($aTMP['exploded_request_file']) - 1; $i++) {
182
                    $aRoutingoverride['itemno'] .= $aTMP['exploded_request_file'][$i].'.';
183
                }
184
                // remove the trailing dot
185
                $aRoutingoverride['itemno'] = \HaaseIT\Toolbox\Tools::cutStringend($aRoutingoverride['itemno'], 1);
186
187
                $aRoutingoverride['cb_pagetype'] = 'itemdetail';
188
189
                // rebuild the path string without the trailing '/item/itemno.html'
190
                $this->sPath = '';
191
                for ($i = 0; $i < $aTMP['parts_in_path'] - 2; $i++) {
192
                    $this->sPath .= $aPath[$i].'/';
193
                }
194
            }
195
        }
196
197
        return $aRoutingoverride;
198
    }
199
}
200