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