19 declare(strict_types=1);
53 protected ServerRequestInterface $server_request,
74 $a_base_class = $this->context->getBaseClass() ?? $a_base_class;
77 if (null === $a_base_class) {
78 throw new ilCtrlException(__METHOD__ .
" was not given a baseclass and the request doesn't include one either.");
82 if (!$this->structure->isBaseClass($a_base_class)) {
83 throw new ilCtrlException(
"Provided class '$a_base_class' is not a baseclass");
88 $this->context->setBaseClass($a_base_class);
91 $obj_name = $this->structure->getObjNameByName($a_base_class);
100 $class_name = get_class($a_gui_object);
103 if (!method_exists($a_gui_object,
'executeCommand')) {
104 throw new ilCtrlException(
"$class_name doesn't implement executeCommand().");
107 $this->exec_object = $a_gui_object;
108 $this->
populateCall($class_name, self::CMD_MODE_PROCESS);
115 ->setCmdMode(self::CMD_MODE_PROCESS);
117 $this->subject->notify(ilCtrlEvent::COMMAND_CLASS_FORWARD, $class_name);
119 return $a_gui_object->executeCommand();
125 public function getHTML(
object $a_gui_object, array $a_parameters = null): string
127 $class_name = get_class($a_gui_object);
130 if (!method_exists($a_gui_object,
'getHTML')) {
138 $this->exec_object = $a_gui_object;
141 ->setCmdClass($class_name)
142 ->setCmdMode(self::CMD_MODE_HTML);
144 $html = (null !== $a_parameters) ?
145 $a_gui_object->getHTML($a_parameters) :
146 $a_gui_object->getHTML();
148 $this->structure = $isolatad_structure;
149 $this->context = $isolated_context;
150 $this->exec_object = $isolated_object;
158 public function getCmd(
string $fallback_command = null): ?string
161 if (null !== $this->command && $command === $this->command) {
167 $this->subject->notify(ilCtrlEvent::COMMAND_DETERMINATION, $command);
170 return $command ??
'';
176 public function setCmd(?
string $a_cmd): void
178 if (!empty($a_cmd)) {
179 $this->context->setCmd($a_cmd);
180 $this->command = $a_cmd;
182 $this->context->setCmd(null);
183 $this->command = null;
192 if (null !== ($cmd_class = $this->context->getCmdClass())) {
193 return strtolower($this->structure->getObjNameByName($cmd_class));
204 if (!empty($a_cmd_class)) {
205 $this->context->setCmdClass($a_cmd_class);
207 $this->context->setCmdClass(null);
216 if (null === $a_gui_class && null === $this->exec_object) {
220 if (null === $this->context->getPath()) {
224 $next_cid = $this->context->getPath()->getNextCid(
228 if (null !== $next_cid) {
229 return strtolower($this->structure->getObjNameByCid($next_cid) ??
'');
248 if (!empty($a_parameter)) {
249 if (is_array($a_parameter)) {
250 foreach ($a_parameter as $parameter) {
251 $this->structure->setPermanentParameterByClass($a_class, $parameter);
254 $this->structure->setPermanentParameterByClass($a_class, $a_parameter);
262 public function setParameter(
object $a_gui_obj,
string $a_parameter, $a_value): void
272 $this->structure->setTemporaryParameterByClass($a_class, $a_parameter, $a_value);
288 if (null === $this->structure->getClassCidByName($a_class)) {
289 throw new ilCtrlException(
"Cannot find provided class '$a_class' in the control structure.");
293 $permanent_parameters = $this->structure->getPermanentParametersByClass($a_class);
294 if (null !== $permanent_parameters) {
295 foreach ($permanent_parameters as $parameter) {
300 $temporary_parameters = $this->structure->getTemporaryParametersByClass($a_class);
301 if (null !== $temporary_parameters) {
304 foreach ($temporary_parameters as
$key => $value) {
305 $parameters[
$key] = $value;
328 $this->structure->removeTemporaryParametersByClass($a_class);
336 $this->structure->removeSingleParameterByClass($a_class, $a_parameter);
344 string $a_cmd = null,
345 string $a_anchor = null,
346 bool $is_async =
false,
347 bool $has_xml_style =
false 363 string $a_cmd = null,
364 string $a_anchor = null,
365 bool $is_async =
false,
366 bool $has_xml_style =
false 382 string $a_fallback_cmd = null,
383 string $a_anchor = null,
384 bool $is_async =
false,
385 bool $has_xml_style =
false 401 string $a_fallback_cmd = null,
402 string $a_anchor = null,
403 bool $is_async =
false,
404 bool $has_xml_style =
false 421 string $a_cmd = null,
422 string $a_anchor = null,
423 bool $is_async =
false 438 string $a_cmd = null,
439 string $a_anchor = null,
440 bool $is_async =
false 458 if (defined(
"ILIAS_HTTP_PATH") &&
459 strpos($target_url,
"://") ===
false &&
460 strpos($target_url,
"/") !== 0
462 $target_url = ILIAS_HTTP_PATH .
"/" . $target_url;
467 $target_url = $this->modifyUrlWithPluginHooks($target_url);
474 if (
'application/json' === $this->server_request->getHeaderLine(
'Accept')) {
476 $body = Streams::ofString(
479 'redirect_url' => $target_url,
481 'message' =>
'called redirect after asynchronous file-upload request.',
487 $body = Streams::ofString($exception->getMessage());
498 session_write_close();
501 $this->response_sender->sendResponse(
$response);
503 header(
"Location: $target_url");
504 if (
'application/json' === $this->server_request->getHeaderLine(
'Accept')) {
505 $content = (null !==
$response->getBody()) ?
509 echo json_encode($content, JSON_THROW_ON_ERROR);
512 header(
"Location: $target_url");
513 echo $t->getMessage();
525 if (!empty($obj_type)) {
526 $this->context->setObjId($obj_id);
527 $this->context->setObjType($obj_type);
536 return $this->context->getObjId();
544 return $this->context->getObjType();
560 $path = $this->structure->getRelativePathByName($a_class);
561 if (null ===
$path) {
562 throw new ilCtrlException(
"Class '$a_class' cannot be found in the control structure.");
573 return $this->structure->getObjNameByName($a_class);
581 $path_info = pathinfo($a_class_path);
583 return substr($path_info[
'basename'], 6, -4);
591 $this->context->setTargetScript($a_target_script);
599 return $this->context->isAsync();
605 public function setReturn(
object $a_gui_obj,
string $a_cmd = null): void
615 $this->structure->setReturnTargetByClass(
633 $target_url = $this->appendParameterString(
635 self::PARAM_REDIRECT,
640 if (null !== $a_anchor) {
641 $target_url .=
"#$a_anchor";
660 $path = $this->path_factory->find($this->context, $a_class);
661 if (null !==
$path->getCidPath()) {
662 foreach (
$path->getCidArray() as $cid) {
663 $current_class = $this->structure->getClassNameByCid($cid);
664 $return_target = $this->structure->getReturnTargetByClass($current_class);
665 if (null !== $return_target) {
666 return $return_target;
679 return $this->context->getRedirectSource();
687 throw new ilCtrlException(__METHOD__ .
" is deprecated and must not be used.");
695 $class_cid = $this->structure->getClassCidByName($gui_class);
696 if (null === $class_cid) {
701 $this->context->getPath()->getCidPath() ??
'',
711 if (null === $this->context->getPath()->getCidPath()) {
716 foreach ($this->context->getPath()->getCidArray(SORT_ASC) as $cid) {
717 $class_paths[] = $this->structure->getObjNameByCid($cid);
728 $this->subject->attach($observer, $event);
736 $this->subject->detach($observer, $event);
746 $is_post = (self::CMD_POST === $get_command);
753 $command = ($is_post) ?
754 $post_command ?? $table_command ?? $this->
getQueryParam(self::PARAM_CMD_FALLBACK) :
759 $context_command = $this->context->getCmd();
760 if (null !== $context_command && self::CMD_POST !== $context_command) {
761 $command = $context_command;
764 if (null === $command) {
770 $cmd_class = $this->context->getCmdClass();
771 if (null !== $cmd_class && !$this->
isCmdSecure($is_post, $cmd_class, $command)) {
772 $stored_token = $this->token_repository->getToken();
775 if (null !== $sent_token && $stored_token->verifyWith($sent_token)) {
792 if ($this->get_parameters->has($parameter_name)) {
793 return $this->get_parameters->retrieve(
807 if ($this->post_parameters->has(
'table_top_cmd')) {
808 return $this->post_parameters->retrieve(
810 $this->
refinery->custom()->transformation(
function ($item): ?
string {
811 return is_array($item) ? key($item) : null;
816 if ($this->post_parameters->has(
'select_cmd2')) {
817 return $this->post_parameters->has(
'selected_cmd2')
818 ? $this->post_parameters->retrieve(
'selected_cmd2', $this->
refinery->to()->string())
822 if ($this->post_parameters->has(
'select_cmd')) {
823 return $this->post_parameters->has(
'selected_cmd')
824 ? $this->post_parameters->retrieve(
'selected_cmd', $this->
refinery->to()->string())
837 if ($this->post_parameters->has(self::PARAM_CMD)) {
838 return $this->post_parameters->retrieve(
840 $this->
refinery->custom()->transformation(
841 static function ($value): ?
string {
842 if (!empty($value)) {
843 if (is_array($value)) {
848 return (
string) array_key_first($value);
851 return (
string) $value;
877 string $a_cmd = null,
878 string $a_anchor = null,
879 bool $is_async =
false,
880 bool $is_escaped =
false,
881 bool $is_post =
false 883 if (empty($a_class)) {
884 throw new ilCtrlException(__METHOD__ .
" was provided with an empty class or class-array.");
887 $is_array = is_array($a_class);
889 $path = $this->path_factory->find($this->context, $a_class);
890 if (null !== ($exception =
$path->getException())) {
894 $base_class =
$path->getBaseClass();
895 if (null === $base_class) {
896 throw new ilCtrlException(
"Cannot find a valid baseclass in the cid path '{$path->getCidPath()}'");
899 $target_url = $this->context->getTargetScript();
900 $target_url = $this->appendParameterString(
902 self::PARAM_BASE_CLASS,
903 urlencode($base_class),
907 $cmd_class = ($is_array) ?
908 $a_class[array_key_last($a_class)] :
913 if (null !==
$path->getNextCid($base_class)) {
914 $target_url = $this->appendParameterString(
916 self::PARAM_CID_PATH,
921 $target_url = $this->appendParameterString(
923 self::PARAM_CMD_CLASS,
924 urlencode($cmd_class),
932 $target_url = $this->appendParameterString(
942 if (!empty($a_cmd)) {
943 $target_url = $this->appendParameterString(
945 ($is_post) ? self::PARAM_CMD_FALLBACK : self::PARAM_CMD,
953 foreach (
$path->getCidArray(SORT_ASC) as $cid) {
954 $class_name = $this->structure->getClassNameByCid($cid);
955 if (null === $class_name) {
956 throw new ilCtrlException(
"Classname for cid '$cid' in current path cannot be found.");
968 if (!$this->
isCmdSecure($is_post, $cmd_class, $a_cmd)) {
969 $token = $this->token_repository->getToken();
970 $target_url = $this->appendParameterString(
972 self::PARAM_CSRF_TOKEN,
979 $target_url = $this->appendParameterString(
981 self::PARAM_CMD_MODE,
982 self::CMD_MODE_ASYNC,
987 if (!empty($a_anchor)) {
988 $target_url .=
"#$a_anchor";
1000 private function modifyUrlWithPluginHooks(
string $target_url):
string 1002 $ui_plugins = $this->component_factory->getActivePluginsInSlot(
"uihk");
1003 foreach ($ui_plugins as $plugin_instance) {
1006 $html = $plugin_instance
1007 ->getUIClassInstance()
1009 'Services/Utilities',
1011 [
"html" => $target_url]
1015 $target_url = $plugin_instance
1016 ->getUIClassInstance()
1034 private function isCmdSecure(
bool $is_post,
string $cmd_class,
string $cmd = null): bool
1038 if (null === $cmd) {
1045 $obj_name = $this->structure->getObjNameByName($cmd_class);
1046 if (null === $obj_name) {
1053 if (!is_a($obj_name, ilCtrlSecurityInterface::class,
true)) {
1060 return in_array($cmd, $this->structure->getSafeCommandsByName($cmd_class),
true);
1065 return !in_array($cmd, $this->structure->getUnsafeCommandsByName($cmd_class),
true);
1079 bool $is_escaped =
false 1082 if (!empty($class_parameters)) {
1083 foreach ($class_parameters as
$key => $value) {
1084 $target_url = $this->appendParameterString(
1104 private function appendParameterString(
1106 string $parameter_name,
1108 bool $is_escaped =
false 1112 $value = $this->
refinery->kindlyTo()->string()->transform($value ??
'');
1114 if (
'' === $value) {
1119 $parsed_url = parse_url(str_replace(
'&',
'&', $url));
1121 $query_parameters = $this->query_parser->parseQueriesOfURL($parsed_url[
'query'] ??
'');
1124 $query_parameters[$parameter_name] = $value;
1126 $new_url = $parsed_url[
'path'] ?? $this->context->getTargetScript();
1128 $ampersand = ($is_escaped) ?
'&' :
'&';
1130 foreach ($query_parameters as $parameter => $parameter_value) {
1131 $new_url .= (strpos($new_url,
'?') !==
false) ?
1132 $ampersand .
"$parameter=$parameter_value" :
1133 "?$parameter=$parameter_value";
1146 $obj_name = $this->structure->getObjNameByName($class_name);
1148 $this->stacktrace[] = [
1149 self::PARAM_CMD_CLASS => $obj_name,
1150 self::PARAM_CMD_MODE => $cmd_mode,
1163 return (is_object($object)) ? get_class($object) : $object;
getPostCommand()
Returns the current $_POST command.
getLinkTargetByClass( $a_class, string $a_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
redirectByClass( $a_class, string $a_cmd=null, string $a_anchor=null, bool $is_async=false)
getHTML(object $a_gui_object, array $a_parameters=null)
callBaseClass(string $a_base_class=null)
redirect(object $a_gui_obj, string $a_cmd=null, string $a_anchor=null, bool $is_async=false)
getClassByObject($object)
Helper function that returns the class name of a mixed (object or string) parameter.
getCmd(string $fallback_command=null)
setCmdClass($a_cmd_class)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
insertCtrlCalls($a_parent, $a_child, string $a_comp_prefix)
checkCurrentPathForClass(string $gui_class)
lookupOriginalClassName(string $a_class)
setParameterByClass(string $a_class, string $a_parameter, $a_value)
isCmdSecure(bool $is_post, string $cmd_class, string $cmd=null)
Returns whether a given command is considered safe or not.
clearParameterByClass(string $a_class, string $a_parameter)
setReturnByClass(string $a_class, string $a_cmd=null)
returnToParent(object $a_gui_obj, string $a_anchor=null)
forwardCommand(object $a_gui_object)
event string being used if
Interface ilCtrlTokenRepositoryInterface describes an ilCtrl token.
getClassForClasspath(string $a_class_path)
getParentReturn(object $a_gui_obj)
getNextClass($a_gui_class=null)
getQueryParam(string $parameter_name)
Returns a parameter with the given name from the current GET request.
__construct(protected ilCtrlStructureInterface $structure, protected ilCtrlTokenRepositoryInterface $token_repository, protected ilCtrlPathFactoryInterface $path_factory, protected ilCtrlContextInterface $context, protected ResponseSenderStrategy $response_sender, protected ServerRequestInterface $server_request, protected RequestWrapper $post_parameters, protected RequestWrapper $get_parameters, protected Refinery $refinery, protected ilComponentFactory $component_factory, protected ilCtrlSubject $subject, protected ilCtrlQueryParserInterface $query_parser,)
getFormActionByClass( $a_class, string $a_fallback_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
Interface RequestWrapper.
clearParameters(object $a_gui_obj)
appendParameterStringsByClass(string $class_name, string $target_url, bool $is_escaped=false)
Appends all parameters for a given class to the given URL.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$structure
TOTAL STRUCTURE.
Interface ResponseSenderStrategy.
lookupClassPath(string $a_class)
Interface ilCtrlPathFactoryInterface describes the ilCtrl Path factory.
clearParametersByClass(string $a_class)
getParentReturnByClass(string $a_class)
getLinkTarget(object $a_gui_obj, string $a_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
detachObserver(ilCtrlObserver $observer, ilCtrlEvent $event=ilCtrlEvent::ALL)
getParameterArrayByClass(string $a_class)
setTargetScript(string $a_target_script)
saveParameter(object $a_gui_obj, $a_parameter)
getParameterArray(object $a_gui_obj)
saveParameterByClass(string $a_class, $a_parameter)
setParameter(object $a_gui_obj, string $a_parameter, $a_value)
redirectToURL(string $target_url)
attachObserver(ilCtrlObserver $observer, ilCtrlEvent $event=ilCtrlEvent::ALL)
populateCall(string $class_name, string $cmd_mode)
Helper function that populates a call in the current stacktrace.
getFormAction(object $a_gui_obj, string $a_fallback_cmd=null, string $a_anchor=null, bool $is_async=false, bool $has_xml_style=false)
getTargetUrl( $a_class, string $a_cmd=null, string $a_anchor=null, bool $is_async=false, bool $is_escaped=false, bool $is_post=false)
Helper function that returns a target URL string.
setReturn(object $a_gui_obj, string $a_cmd=null)
setContextObject(int $obj_id, string $obj_type)
Refinery Factory $refinery