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
|
|
|
} |