@param string $controller
@param string|null $action
@param array|null $params
@param string|null $lang

@return string
510992
public function href(string $controller = null, string $action = null, array $params = null, string $lang = null): string
    {
        return $this->siteHref('', $controller, $action, $params, $lang);
    }
695820
protected function getTemplateFile(string $action = null) : string
    {
        $path = '/controller/' . lcfirst($this->getControllerName()) . '/';

        return $path . ($action ? $action : $this->getActionName());
    }
856727
public function siteHref(string $site, string $controller = null, string $action = null, array $params = null, string $lang = null): string
    {
        if ($controller !== null && strpos($controller, '/') !== false) {
            throw new \InvalidArgumentException('Slash is not allowed in controller name');
        }

        if ($action !== null && strpos($action, '/') !== false) {
            throw new \InvalidArgumentException('Slash is not allowed in action name');
        }

        if ($controller === null) {
            $controller = '';
        }

        if ($site !== '') {
            // we're building link to another server
            $otherSite = Application::getConfig('sites')->get($site);
            if ($otherSite !== null) {
                $url = $otherSite;
            } else {
                Log::warning('Missing sites definition key \'' . $site . '\'; please define it in your sites.php config');
                $url = Application::getDomainWithSchema();
            }
        } else {
            $url = Application::getDomainWithSchema();
        }

        $url .= '/' . $controller;

        if ($action !== null) {
            $url .= '/' . $action;
        }

        if ($params !== null && count($params) > 0) {
            $q = [];
            foreach ($params as $key => $value) {
                if (is_numeric($key)) {
                    $url .= '/' . $value;
                } else {
                    $q[$key] = $value;
                }
            }

            if (sizeof($q) > 0) {
                $url .= '?';
                foreach ($q as $key => $value) {
                    $url .= "{$key}={$value}&";
                }
                $url = substr($url, 0, -1);
            }
        }

        return $url;
    }
416390
private function getControllerActionAnnotations($controller, $action)
    {
        if ($controller instanceof \Closure) {
            return $this->annotation->readFunction($controller);
        }

        return $this->annotation->readMethod($controller, $action . 'Action');
    }
1065220
protected function getActionUrl($action) : string
    {
        $context = Context::getInstance();
        return $context->getUrl($context->getParameter('controller_path') . $action);
    }
116859
public function encodeValidatorRule(Controller $controller = null, JQueryValidator ...$validators) {
		if (method_exists($this, 'getValidateRules')) {
			$this->rules = $this->getValidateRules();
		}
		$url = '';
		if ($controller) {
			$clsName = get_class($controller);
			$url     = App::action($clsName . '::validate') . '/' . str_replace('\\', '.', get_class($this));
		}
		$rules = [];
		$msgs  = [];
		if ($this->rules) {
			foreach ($this->rules as $name => $rs) {
				foreach ($rs as $r) {
					@list($rule, $exp, $msg, $m) = $r;
					$key = $name . ($m ? '[]' : '');
					if ($rule == 'callback') {
						if (!$url) {
							continue;
						}
						$rule = 'remote';
						$exp  = [
							'url' => $url . '/' . $name,
							'rqs' => explode(',', trim(preg_replace('/.+?(\((.*)\))?$/', '\2', $exp)))
						];
					} else {
						switch ($rule) {
							case 'rangelength':
							case 'range':
							case 'rangeWords':
							case 'require_from_group':
								$exp = explode(',', $exp);
								if (count($exp) > 2) {
									$exp = array_slice($exp, 0, 2);
								}
								break;
							default:
								break;
						}
					}
					if ($exp) {
						$rules[ $key ][ $rule ] = $exp;
					} else {
						$rules[ $key ][ $rule ] = true;
					}
					if (!$msg) {
						$msg = _tt($rule . '@validator');
					}
					if (strpos($msg, '%s') !== false) {
						$i   = 0;
						$msg = preg_replace_callback('/%s/', function ($ms) use (&$i) {
							return '{' . ($i++) . '}';
						}, $msg);
					}
					$msgs[ $key ][ $rule ] = $msg;
				}
			}
		}

		$rtn = ['rules' => $rules, 'messages' => $msgs];

		if ($validators) {
			/**@var \wulaphp\validator\JQueryValidator $v */
			foreach ($validators as $v) {
				$v->_encodit = false;
				$vr          = $v->encodeValidatorRule($controller);
				if ($vr) {
					$rtn = array_merge_recursive($rtn, $vr);
				}
			}
		}

		if ($this->_encodit) {
			return json_encode($rtn);
		} else {
			return $rtn;
		}
	}
892373
public function setMvcUrl($controller = null, $action = null, array $params = [])
    {
        $this->mvcUrl = [
            'controller' => trim($controller),
            'action'     => trim($action),
            'params'     => $params
        ];
        return $this;
    }
1202662
public function Link($action = '')
    {
        $link = Controller::join_links(
            Director::baseURL(),
            Config::inst()->get('DocumentationViewer', 'link_base'),
            $this->getLanguage(),
            $action,
            '/'
        );

        return $link;
    }
493309
public function render($controller = null)
    {
        // Switch current system active module
        $old = $this->system->active($this);

        // If specific controller action should be run
        if (isset($controller)) {
            /**
             * TODO: This would be removed in next major version, here should be
             * passed real controller method for execution.
             */
            $controller = method_exists($this, iModule::OBJ_PREFIX . $controller)
                ? iModule::OBJ_PREFIX . $controller
                : $controller;

            // Define if this is a procedural controller or OOP
            $callback = array($this, $controller);

            // If this controller action is present
            if (method_exists($this, $controller)) {
                // Get passed arguments
                $parameters = func_get_args();
                // Remove first as its a controller action name
                array_shift($parameters);
                // Perform controller action with passed parameters
                call_user_func_array($callback, $parameters);
            } else {
                throw new ControllerActionNotFound($this->id . '#' . $controller);
            }
        }

        // Output view
        echo $this->output();

        // Restore previous active module
        $this->system->active($old);
    }
166099
public function create(array $parameters, $controller = null) {
        $parameters = $this->parseParameters($parameters, $controller);

        $action = new Action(
            $parameters['name'],
            $parameters['pattern'],
            $parameters['uses'],
            $parameters['group']
        );

        $this->setProperties($action, $parameters);

        return $action;
    }
602953
public function buildUrl($controller, $action, array $args = array(), array $get = array())
    {
        $url = $this->buildDestination($controller, $action, $args);
        if (!$this->cleanUrlsEnabled()) {
            $url = $this->entryPoint.$url;
        }
        if ($get) {
            $url .= '?'.http_build_query($get);
        }

        return $url;
    }
607456
protected function findNamespaceInController(&$controller)
    {
        if (strstr($controller, '\\')) {
            $namespace = explode('\\', $controller);
            $controller = end($namespace);
            $namespace = rtrim(join('\\', array_slice($namespace, 0, count($namespace) - 1)), '\\');
        } else {
            $namespace = isset($this->group['_namespace']) ? $this->group['namespace'] : null;
        }

        return $namespace;
    }
970461
private function formatAndInjectExposedAction($controller, $actions)
    {
        $controllerId = explode('\\', get_class($controller));
        $controllerId = str_replace('controller', '', strtolower(array_pop(($controllerId))));
        $this->exposedActions[$controllerId] = array('actions' => array());

        if ($controller instanceof BundleExposedControllerInterface) {
            $this->exposedActions[$controllerId]['label'] = $controller->getLabel();
            $this->exposedActions[$controllerId]['description'] = $controller->getDescription();
            array_unshift($actions, 'indexAction');
            $actions = array_unique($actions);
        }

        foreach ($actions as $action) {
            if (method_exists($controller, $action)) {
                $actionId = str_replace('action', '', strtolower($action));
                $uniqueName = $controllerId.'_'.$actionId;

                $this->exposedActionsCallbacks[$uniqueName] = array($controller, $action);
                $this->exposedActions[$controllerId]['actions'][] = $actionId;
            }
        }
    }
146695
public function handleController(
        $controller, $action = null, array $params = null, $model = null
    ) {

        ! $model || $model = $this->modelFactory->create(null, $model);

        $this->setController(
            $this->controllerFactory->create($params, $controller, $model)
        );

        if (!is_null($action)) {
            $this->setControllerResult(
                $this->executeMethod($this->getController(), $action, $params, $model)
            );
        }
    }
1223110
public function getTranslators($controller, $filename = null)
    {
        $translator = $this->getTranslateAdapter();

        switch ($controller) {
            case 'answers':
                $output['default'] = new \Gems_Model_Translator_TokenAnswerTranslator(
                        $translator->_('Link by token id')
                        );
                $output['resp']    = new \Gems_Model_Translator_RespondentAnswerTranslator(
                        $translator->_('Link by patient id')
                        );
                $output['date']    = new \Gems_Model_Translator_DateAnswerTranslator(
                        $translator->_('Link by patient id and completion date')
                        );
                break;

            case 'calendar':
                $output['default'] = new \Gems_Model_Translator_AppointmentTranslator($translator->_('Direct import'));
                break;

            case 'respondent':
                $output['default'] = new \Gems_Model_Translator_RespondentTranslator($translator->_('Direct import'));
                break;

            case 'staff':
                $output['default'] = new \Gems_Model_Translator_StaffTranslator($translator->_('Direct import'));
                break;

            default:
                $output['default'] = new \Gems_Model_Translator_StraightTranslator($translator->_('Direct import'));
                break;
        }

        foreach ($output as $trs) {
            $this->applySource($trs);
        }

        return $output;
    }
1108179
final public function url($module, $controller = null, $action = null, array $params = array(), $hash = null) {
        $module = ucfirst(Util::hyphenToCamel($module));
        $moduleOptions = engineGet('config', 'modules', $module, false);
        $module = (isset($moduleOptions['alias'])) ? $moduleOptions['alias'] : $module;

        $return = Util::camelToHyphen($module);
        if ($controller)
            $return .= '/' . Util::camelToHyphen($controller);
        if ($action)
            $return .= '/' . Util::camelToHyphen($action);
        if (!empty($params))
            $return .= str_replace('//', '/' . urlencode(' ') . '/', '/' . join('/', $this->encodeParams($params)));
        if ($hash)
            $return .= '#' . $hash;

        return engineGet('serverPath') . $return;
    }
218730
public static function mvcDispatcher($module, $controller, $action, $params)
    {
        $dispatcher = new self;
        $dispatcher->setModule($module);
        $dispatcher->setController($controller);
        $dispatcher->setAction($action);
        $dispatcher->setParams($params);

        // get current application config
        $applicationConfig = Bootstrap::getInstance()->getEnvironment()->getApplicationConfig();

        // build the class name
        $className = '\\' . $applicationConfig->Namespace . '\Modules\\' . $dispatcher->getModule() . '\Controllers\\' . $dispatcher->getController();
        $dispatcher->setClassName($className);

        return $dispatcher;
    }