Add `LinkHandler::getControllerLink()`
authorMatthias Schmidt <gravatronics@live.com>
Sat, 24 Nov 2018 09:15:19 +0000 (10:15 +0100)
committerMatthias Schmidt <gravatronics@live.com>
Sat, 24 Nov 2018 09:15:19 +0000 (10:15 +0100)
Close #2779

wcfsetup/install/files/lib/system/request/LinkHandler.class.php

index 027a5619456c2801883f8126dd78cc257e4665cd..471c8f96cb94a7d9777aeaeb4f04fc2f7991b7b0 100644 (file)
@@ -18,6 +18,13 @@ use wcf\util\StringUtil;
  * @package    WoltLabSuite\Core\System\Request
  */
 class LinkHandler extends SingletonFactory {
+       /**
+        * regex object to extract controller data from controller class name
+        * @var         Regex
+        * @since       3.2
+        */
+       protected $controllerRegex;
+       
        /**
         * regex object to filter title
         * @var RegEx
@@ -36,12 +43,12 @@ class LinkHandler extends SingletonFactory {
         */
        protected $titleReplace = [];
        
-       
        /**
         * @inheritDoc
         */
        protected function init() {
                $this->titleRegex = new Regex('[^\p{L}\p{N}]+', Regex::UTF_8);
+               $this->controllerRegex = new Regex('^(?P<application>[a-z]+)\\\\(?P<isAcp>acp\\\\)?.+\\\\(?P<controller>[^\\\\]+)(?:Action|Form|Page)$');
                
                if (defined('URL_TITLE_COMPONENT_REPLACEMENT') && URL_TITLE_COMPONENT_REPLACEMENT) {
                        $replacements = explode("\n", StringUtil::unifyNewlines(StringUtil::trim(URL_TITLE_COMPONENT_REPLACEMENT)));
@@ -54,6 +61,36 @@ class LinkHandler extends SingletonFactory {
                }
        }
        
+       /**
+        * Returns in internal link based on the given fully qualified controller
+        * class name.
+        * 
+        * Important: The controller class is not checked if it actually exists.
+        * That check happens during the runtime.
+        * 
+        * @param       string          $controllerClass
+        * @param       array           $parameters
+        * @param       string          $url
+        * @return      string
+        * 
+        * @throws      \InvalidArgumentException       if the passed string is no controller class name
+        * @since       3.2
+        */
+       public function getControllerLink($controllerClass, array $parameters = [], $url = '') {
+               if (!$this->controllerRegex->match($controllerClass)) {
+                       throw new \InvalidArgumentException("Invalid controller '{$controllerClass}' passed.");
+               }
+               
+               $matches = $this->controllerRegex->getMatches();
+               
+               // important: matches cannot overwrite explicitly set parameters
+               $parameters['application'] = $parameters['application'] ?? $matches['application'];
+               $parameters['isACP'] = $parameters['isACP'] ?? $matches['isAcp'];
+               $parameters['forceFrontend'] = $parameters['forceFrontend'] ?? !$matches['isAcp'];
+               
+               return $this->getLink($matches['controller'], $parameters, $url);
+       }
+       
        /**
         * Returns a relative link.
         *