ILIAS  trunk Revision v12.0_alpha-1329-g1094ddb0c33
HandlerService.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
34
39{
41 private array $handlers = [];
42
43 public function __construct(
44 private RequestBuilder $request_builder,
45 private Context $context,
46 private array $handler_instances,
47 private SessionStore $session_store
48 ) {
49 $this->response_factory = new Factory($context);
50 // check handlers
51 foreach ($handler_instances as $handler_instance) {
52 if (!$handler_instance instanceof Handler) {
53 throw new \InvalidArgumentException(
54 'Handler instances must implement the Handler interface'
55 );
56 }
57 }
58 }
59
60 public function initHandler(): void
61 {
62 foreach ($this->handler_instances as $handler) {
63 if (isset($this->handlers[$handler->getNamespace()])) {
64 throw new \LogicException("Namespace-Collision detected: " . $handler->getNamespace());
65 }
66 $this->handlers[$handler->getNamespace()] = $handler;
67 if ($handler instanceof AliasedHandler) {
68 foreach ($handler->getNamespaceAliasses() as $namespace_aliass) {
69 if (isset($this->handlers[$namespace_aliass])) {
70 throw new \LogicException("Namespace-Collision detected: " . $namespace_aliass);
71 }
72 $this->handlers[$namespace_aliass] = $handler;
73 }
74 }
75 }
76 }
77
81 public function performRedirect(URI $base_uri): void
82 {
83 if (empty($this->handlers)) {
84 $this->initHandler();
85 }
86
87 $http = $this->context->http();
88
89 $request = $this->request_builder->buildRequest(
90 $http,
91 $this->context->refinery(),
92 $this->handlers
93 );
94 if (!$request instanceof Request) {
95 throw new \RuntimeException('No request could be built');
96 }
97
98 $handler = $this->handlers[$request->getNamespace()] ?? null;
99 if (!$handler instanceof Handler) {
100 throw new \InvalidArgumentException('No handler found for namespace ' . $request->getNamespace());
101 }
102 $response = $handler->handle($request, $this->context, $this->response_factory);
103
104 if ($response instanceof CannotHandle) {
105 $http->saveResponse(
106 $http->response()->withStatus(404),
107 );
108 $http->sendResponse();
109 $http->close();
110 }
111
112 $uri_builder = new StandardURIBuilder(new StaticURLConfig());
113
114 switch (true) {
115 case $response instanceof MaybeCanHandlerAfterLogin:
116 $target = $uri_builder->buildTarget(
117 $request->getNamespace(),
118 $request->getReferenceId(),
119 $request->getAdditionalParameters()
120 );
121 $full_uri = $base_uri . "/login.php?target=";
122 $full_uri .= str_replace('/', '_', rtrim($target, '/')); // TODO: ILIAS currently need this like this
123 if (!$this->context->isUserLoggedIn()) {
124 $full_uri .= '&cmd=force_login&lang=' . $this->context->getUserLanguage();
125 }
126 $full_uri = $this->appendUnknownParameters($this->context, $full_uri); // Read the comment below
127 break;
128 case $response instanceof CannotReach:
129 $full_uri = $this->buildCannotReachRedirect($base_uri, $request);
130 break;
131 default:
132 // Perform Redirect
133 $uri_path = $response->getURIPath() ?? '';
134 $base_path = $base_uri->getPath() ?? '';
135 if ($base_path !== '' && $base_path !== '/') {
136 $uri_path = str_replace(rtrim($base_path, '/') . '/', '', $uri_path);
137 }
138
139 for ($x = 0; $x < $response->shift(); $x++) {
140 $base_uri = $base_uri->withPath(dirname((string) $base_uri->getPath()));
141 }
142
143 $full_uri = $base_uri . '/' . trim((string) $uri_path, '/');
144 break;
145 }
146
147 $http->saveResponse(
148 $http->response()->withAddedHeader('Location', $full_uri)
149 );
150 $http->sendResponse();
151 $http->close();
152 }
153
166 private function buildCannotReachRedirect(URI $base_uri, Request $request): string
167 {
168 $target_ref_id = $request->getReferenceId()?->toInt() ?? 0;
169 $fallback_ref_id = $target_ref_id > 0
170 ? $this->context->findFirstAccessibleParentRefId($target_ref_id)
171 : null;
172
173 if ($fallback_ref_id !== null) {
174 $this->session_store->set(
175 'pending_goto',
176 'goto.php?target=' . $request->getNamespace() . '_' . $target_ref_id
177 );
178 $this->context->mainTemplate()->setOnScreenMessage(
179 'info',
180 $this->context->lng()->txt('reg_goto_parent_membership_info'),
181 true
182 );
183 return $base_uri . '/ilias.php?baseClass=ilRepositoryGUI&ref_id=' . $fallback_ref_id;
184 }
185
186 $this->context->mainTemplate()->setOnScreenMessage(
187 'failure',
188 $this->context->lng()->txt('permission_denied'),
189 true
190 );
191
192 return $base_uri . '/' . ltrim(\ilUserUtil::getStartingPointAsUrl(), '/');
193 }
194
199 private function appendUnknownParameters(Context $context, string $full_uri): string
200 {
201 if ($context->http()->wrapper()->query()->has('soap_pw')) {
202 return \ilUtil::appendUrlParameterString(
203 $full_uri,
204 'soap_pw=' . $context->http()->wrapper()->query()->retrieve(
205 'soap_pw',
206 $context->refinery()->kindlyTo()->string()
207 )
208 );
209 }
210 if ($context->http()->wrapper()->query()->has('ext_uid')) {
211 return \ilUtil::appendUrlParameterString(
212 $full_uri,
213 'ext_uid=' . $context->http()->wrapper()->query()->retrieve(
214 'ext_uid',
215 $context->refinery()->kindlyTo()->string()
216 )
217 );
218 }
219
220 return $full_uri;
221 }
222}
The scope of this class is split ilias-conform URI's into components.
Definition: URI.php:35
withPath(?string $path=null)
Get URI with modified path.
Definition: URI.php:283
__construct(private RequestBuilder $request_builder, private Context $context, private array $handler_instances, private SessionStore $session_store)
appendUnknownParameters(Context $context, string $full_uri)
buildCannotReachRedirect(URI $base_uri, Request $request)
Builds the redirect target for a {.
Returned by a Handler when it cannot process the given Request at all, e.g.
Returned by a Handler when the target exists but the CURRENT (logged-in) user has no permission to re...
Definition: CannotReach.php:35
Returned when the target is (or might be) reachable after the user logs in.
static getStartingPointAsUrl()
$http
Definition: deliver.php:30
$handler
Definition: oai.php:31
$response
Definition: xapitoken.php:90