Passed
Push — master ( 6b35df...b5f91c )
by Andreas
10:55
created

resolver   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Test Coverage

Coverage 80%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 58
c 2
b 0
f 0
dl 0
loc 125
ccs 44
cts 55
cp 0.8
rs 10
wmc 12

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A get_router() 0 9 2
A process_midcom() 0 17 3
B process_component() 0 50 6
1
<?php
2
/**
3
 * @package midcom.routing
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
namespace midcom\routing;
10
11
use Symfony\Component\HttpFoundation\Request;
12
use midcom;
13
use midcom_error_forbidden;
14
use midcom_error_notfound;
15
use midcom_baseclasses_components_viewer;
16
use Symfony\Component\Routing\Router;
17
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
18
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
19
use Symfony\Component\HttpFoundation\Response;
20
21
/**
22
 * @package midcom.routing
23
 */
24
class resolver
25
{
26
    /**
27
     * @var Request
28
     */
29
    private $request;
30
31
    /**
32
     * @var parser
33
     */
34
    private $parser;
35
36
    /**
37
     * @var \midcom_core_context
38
     */
39
    private $context;
40
41 348
    public function __construct(Request $request)
42
    {
43 348
        $this->request = $request;
44 348
        $this->context = $request->attributes->get('context');
45 348
        $this->parser = new parser($this->context);
46
    }
47
48 351
    public static function get_router(string $component, array $request_switch = []) : Router
49
    {
50 351
        $loader = new loader;
51 351
        if (!empty($request_switch)) {
52 123
            return new Router($loader, $request_switch);
53
        }
54 306
        $identifier = str_replace('.', '_', $component);
55 306
        return new Router($loader, $component, [
56 306
            'cache_dir' => midcom::get()->getCacheDir() . '/routing/' . $identifier,
57
        ]);
58
    }
59
60
    /**
61
     * @throws midcom_error_notfound
62
     */
63 348
    public function process_midcom() : bool
64
    {
65 348
        if ($url = $this->parser->find_urlmethod()) {
66
            $router = self::get_router('midcom');
67
            $router->getContext()
68
                ->fromRequest($this->request);
69
70
            try {
71
                $result = $router->match($url);
72
            } catch (ResourceNotFoundException $e) {
73
                throw new midcom_error_notfound('This URL method is unknown.');
74
            }
75
            $this->request->attributes->add($result);
76
77
            return true;
78
        }
79 348
        return false;
80
    }
81
82
    /**
83
     * Basically this method will parse the URL and search for a component that can
84
     * handle the request. If one is found, it will process the request, if not, it
85
     * will report an error, depending on the situation.
86
     *
87
     * Details: The logic will traverse the node tree, and for the last node it will load
88
     * the component that is responsible for it. If the component
89
     * declares to be able to handle the call, its handle function is executed. Depending
90
     * if the handle was successful or not, it will either display an HTTP error page or
91
     * prepares the content handler to display the content later on.
92
     *
93
     * If the parsing process doesn't find any component that declares to be able to
94
     * handle the request, an HTTP 404 - Not Found error is triggered.
95
     *
96
     * @throws midcom_error_forbidden
97
     * @throws midcom_error_notfound
98
     */
99 348
    public function process_component()
100
    {
101 348
        $topic = $this->parser->find_topic();
102 348
        $argv = $this->parser->argv;
103
104
        // Get component interface class
105 348
        $component_interface = midcom::get()->componentloader->get_interface_class($topic->component);
106 348
        $viewer = $component_interface->get_viewer($topic);
107
108 348
        $prefix = $this->context->get_key(MIDCOM_CONTEXT_ANCHORPREFIX);
109
110
        // Check if we need to start up a plugin.
111 348
        if (   count($argv) > 1
112 348
            && $config = plugin::get_config($argv[0], $argv[1])) {
113 87
            $namespace = array_shift($argv);
114 87
            $name = array_shift($argv);
115 87
            $prefix .= $namespace . '/' . $name . '/';
116 87
            debug_add("Loading the plugin {$namespace}/{$name}");
117 87
            $viewer->load_plugin($name, new $config['class'], $config);
118
        }
119
120 348
        $url = '/';
121 348
        if (!empty($argv)) {
122 328
            $url .= implode('/', $argv) . '/';
123
        }
124 348
        $router = $viewer->get_router();
125 348
        $router->getContext()
126 348
            ->fromRequest($this->request)
127 348
            ->setBaseUrl(substr($prefix, 0, -1));
128
129
        try {
130 348
            $result = $router->match($url);
131 13
        } catch (ResourceNotFoundException $e) {
132
            // No match
133 13
            debug_add("Component {$viewer->_component} in {$viewer->_topic->name} declared unable to handle request.", MIDCOM_LOG_INFO);
134 13
            throw new midcom_error_notfound("This page is not available on this server.");
135
        } catch (MethodNotAllowedException $e) {
136
            debug_add("Component {$viewer->_component} in {$viewer->_topic->name} declared unable to handle request (method not allowed).", MIDCOM_LOG_INFO);
137
            throw new midcom_error_forbidden($e->getMessage(), Response::HTTP_METHOD_NOT_ALLOWED);
138
        }
139
140 348
        $result['args'] = array_values(array_filter($result, function($name) {
141 348
            return !str_starts_with($name, '_');
142
        }, ARRAY_FILTER_USE_KEY));
143
144 348
        $result['__viewer'] = $viewer;
145 348
        $result['_controller'] = str_replace('::', '::_handler_', $result['_controller']);
146
147 348
        $this->request->attributes->add($result);
148 348
        $this->context->set_key(MIDCOM_CONTEXT_SHOWCALLBACK, [$viewer, 'show']);
149
    }
150
}