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