Apply PSR-12 code style (#3886)
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / application / ApplicationHandler.class.php
index 6cf776ee1a03da1de4b250cd16067dfdadc052f9..8d8e2f12e3c7aeed155b72e9ba37bda8616a78d2 100644 (file)
 <?php
+
 namespace wcf\system\application;
+
 use wcf\data\application\Application;
 use wcf\data\application\ApplicationAction;
 use wcf\data\application\ApplicationList;
 use wcf\data\package\Package;
 use wcf\data\package\PackageList;
 use wcf\system\cache\builder\ApplicationCacheBuilder;
+use wcf\system\Regex;
 use wcf\system\request\RequestHandler;
 use wcf\system\request\RouteHandler;
-use wcf\system\Regex;
 use wcf\system\SingletonFactory;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
 
 /**
  * Handles multi-application environments.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\System\Application
+ *
+ * @author  Alexander Ebert
+ * @copyright   2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Application
  */
-class ApplicationHandler extends SingletonFactory {
-       /**
-        * application cache
-        * @var mixed[][]
-        */
-       protected $cache;
-       
-       /**
-        * true for multi-domain setups
-        * @var bool
-        */
-       protected $isMultiDomain;
-       
-       /**
-        * list of page URLs
-        * @var string[]
-        */
-       protected $pageURLs = [];
-       
-       /**
-        * Initializes cache.
-        */
-       protected function init() {
-               $this->cache = ApplicationCacheBuilder::getInstance()->getData();
-       }
-       
-       /**
-        * Returns an application based upon it's abbreviation. Will return the
-        * primary application if the abbreviation is `wcf` or `null` if no such
-        * application exists.
-        * 
-        * @param       string          $abbreviation   package abbreviation, e.g. `wbb` for `com.woltlab.wbb`
-        * @return      Application|null
-        */
-       public function getApplication($abbreviation) {
-               if (isset($this->cache['abbreviation'][$abbreviation])) {
-                       $packageID = $this->cache['abbreviation'][$abbreviation];
-                       
-                       if (isset($this->cache['application'][$packageID])) {
-                               return $this->cache['application'][$packageID];
-                       }
-               }
-               
-               return null;
-       }
-       
-       /**
-        * Returns an application delivered by the package with the given id or `null`
-        * if no such application exists.
-        * 
-        * @param       int                     $packageID      package id
-        * @return      Application|null        application object
-        * @since       3.0
-        */
-       public function getApplicationByID($packageID) {
-               // work-around for update from 2.1 (out-dated cache)
-               if ($packageID == 1 && !isset($this->cache['application'][1])) {
-                       $this->cache['application'][1] = new Application(1);
-               }
-               if (isset($this->cache['application'][$packageID])) {
-                       return $this->cache['application'][$packageID];
-               }
-               
-               return null;
-       }
-       
-       /**
-        * Returns pseudo-application representing WCF used for special cases,
-        * e.g. cross-domain files requestable through the webserver.
-        * 
-        * @return      Application
-        * @deprecated  3.0 please use `getApplication()` instead
-        */
-       public function getWCF() {
-               return $this->getApplicationByID(1);
-       }
-       
-       /**
-        * Returns the currently active application.
-        * 
-        * @return      Application
-        */
-       public function getActiveApplication() {
-               // work-around during WCFSetup
-               if (!PACKAGE_ID) {
-                       $host = str_replace(RouteHandler::getProtocol(), '', RouteHandler::getHost());
-                       $documentRoot = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator(realpath($_SERVER['DOCUMENT_ROOT'])));
-                       
-                       // always use the core directory
-                       if (empty($_POST['directories']) || empty($_POST['directories']['wcf'])) {
-                               // within ACP
-                               $_POST['directories'] = ['wcf' => $documentRoot . FileUtil::removeLeadingSlash(RouteHandler::getPath(['acp']))];
-                       }
-                       
-                       $path = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator(FileUtil::getRelativePath($documentRoot, $_POST['directories']['wcf']))));
-                       
-                       return new Application(null, [
-                               'domainName' => $host,
-                               'domainPath' => $path,
-                               'cookieDomain' => $host,
-                       ]);
-               }
-               
-               $request = RequestHandler::getInstance()->getActiveRequest();
-               if ($request !== null) {
-                       $abbreviation = substr($request->getClassName(), 0, mb_strpos($request->getClassName(), '\\'));
-                       
-                       return $this->getApplication($abbreviation);
-               }
-               
-               if (isset($this->cache['application'][PACKAGE_ID])) {
-                       return $this->cache['application'][PACKAGE_ID];
-               }
-               
-               return $this->getWCF();
-       }
-       
-       /**
-        * Returns a list of dependent applications.
-        * 
-        * @return      Application[]
-        */
-       public function getDependentApplications() {
-               $applications = $this->getApplications();
-               foreach ($applications as $key => $application) {
-                       if ($application->packageID == $this->getActiveApplication()->packageID) {
-                               unset($applications[$key]);
-                               break;
-                       }
-               }
-               
-               return $applications;
-       }
-       
-       /**
-        * Returns a list of all active applications.
-        * 
-        * @return      Application[]
-        */
-       public function getApplications() {
-               return $this->cache['application'];
-       }
-       
-       /**
-        * Returns abbreviation for a given package id or `null` if application is unknown.
-        * 
-        * @param       int             $packageID      unique package id
-        * @return      string|null
-        */
-       public function getAbbreviation($packageID) {
-               foreach ($this->cache['abbreviation'] as $abbreviation => $applicationID) {
-                       if ($packageID == $applicationID) {
-                               return $abbreviation;
-                       }
-               }
-               
-               return null;
-       }
-       
-       /**
-        * Returns the list of application abbreviations.
-        * 
-        * @return      string[]
-        * @since       3.1
-        */
-       public function getAbbreviations() {
-               return array_keys($this->cache['abbreviation']);
-       }
-       
-       /**
-        * Returns true if given $url is an internal URL.
-        * 
-        * @param       string          $url
-        * @return      bool
-        */
-       public function isInternalURL($url) {
-               $protocolRegex = new Regex('^https(?=://)');
-               if (empty($this->pageURLs)) {
-                       foreach ($this->getApplications() as $application) {
-                               $this->pageURLs[] = preg_replace('~/$~', '', $protocolRegex->replace(RouteHandler::getProtocol() . $application->domainName, 'http'));
-                       }
-                       $this->pageURLs = array_unique($this->pageURLs);
-               }
-               
-               foreach ($this->pageURLs as $pageURL) {
-                       if (stripos($protocolRegex->replace($url, 'http'), $pageURL) === 0) {
-                               return true;
-                       }
-               }
-               
-               // relative urls contain no protocol, including implied
-               if (!preg_match('~^([a-zA-Z0-9]+)?://~', $url)) {
-                       return true;
-               }
-               
-               return false;
-       }
-       
-       /**
-        * Returns true if this is a multi-domain setup.
-        * 
-        * @return      bool
-        * @since       3.1
-        */
-       public function isMultiDomainSetup() {
-               if ($this->isMultiDomain === null) {
-                       $this->isMultiDomain = false;
-                       
-                       $domainName = $this->getApplicationByID(1)->domainName;
-                       foreach ($this->getApplications() as $application) {
-                               if ($application->domainName !== $domainName) {
-                                       $this->isMultiDomain = true;
-                                       break;
-                               }
-                       }
-               }
-               
-               return $this->isMultiDomain;
-       }
-       
-       /**
-        * @since 5.2
-        */
-       public function rebuildActiveApplication() {
-               /** @var AbstractApplication $application */
-               foreach ($this->cache['application'] as $application) {
-                       if ($application->getPackage()->package === 'com.woltlab.wcf') {
-                               continue;
-                       }
-                       
-                       $appObject = WCF::getApplicationObject($application);
-                       if ($appObject instanceof AbstractApplication) {
-                               $appObject->rebuildActiveApplication();
-                       }
-               }
-       }
-       
-       /**
-        * Rebuilds cookie domain/path for all applications.
-        */
-       public static function rebuild() {
-               $applicationList = new ApplicationList();
-               $applicationList->readObjects();
-               
-               $applicationAction = new ApplicationAction($applicationList->getObjects(), 'rebuild');
-               $applicationAction->executeAction();
-       }
-       
-       /**
-        * Replaces `app1_` in the given string with the correct installation number:
-        * `app{WCF_N_}`.
-        * 
-        * This method can either be used for database table names directly or for
-        * queries, for example.
-        * 
-        * @param       string          $string         string to be processed
-        * @param       bool            $skipCache      if `true`, no caches will be used and relevant application packages will be read from database directly
-        * @return      string                          processed string
-        * @since       5.2
-        */
-       public static function insertRealDatabaseTableNames($string, $skipCache = false) {
-               if ($skipCache) {
-                       $packageList = new PackageList();
-                       $packageList->getConditionBuilder()->add('package.isApplication = ?', [1]);
-                       $packageList->readObjects();
-                       
-                       foreach ($packageList as $package) {
-                               $abbreviation = Package::getAbbreviation($package->package);
-                               
-                               $string = str_replace($abbreviation . '1_', $abbreviation . WCF_N . '_', $string);
-                       }
-               }
-               else {
-                       foreach (static::getInstance()->getAbbreviations() as $abbreviation) {
-                               $string = str_replace($abbreviation . '1_', $abbreviation . WCF_N . '_', $string);
-                       }
-               }
-               
-               return $string;
-       }
+class ApplicationHandler extends SingletonFactory
+{
+    /**
+     * application cache
+     * @var mixed[][]
+     */
+    protected $cache;
+
+    /**
+     * true for multi-domain setups
+     * @var bool
+     */
+    protected $isMultiDomain;
+
+    /**
+     * list of page URLs
+     * @var string[]
+     */
+    protected $pageURLs = [];
+
+    /**
+     * Initializes cache.
+     */
+    protected function init()
+    {
+        $this->cache = ApplicationCacheBuilder::getInstance()->getData();
+    }
+
+    /**
+     * Returns an application based upon it's abbreviation. Will return the
+     * primary application if the abbreviation is `wcf` or `null` if no such
+     * application exists.
+     *
+     * @param string $abbreviation package abbreviation, e.g. `wbb` for `com.woltlab.wbb`
+     * @return  Application|null
+     */
+    public function getApplication($abbreviation)
+    {
+        if (isset($this->cache['abbreviation'][$abbreviation])) {
+            $packageID = $this->cache['abbreviation'][$abbreviation];
+
+            if (isset($this->cache['application'][$packageID])) {
+                return $this->cache['application'][$packageID];
+            }
+        }
+    }
+
+    /**
+     * Returns an application delivered by the package with the given id or `null`
+     * if no such application exists.
+     *
+     * @param int $packageID package id
+     * @return  Application|null    application object
+     * @since   3.0
+     */
+    public function getApplicationByID($packageID)
+    {
+        // work-around for update from 2.1 (out-dated cache)
+        if ($packageID == 1 && !isset($this->cache['application'][1])) {
+            $this->cache['application'][1] = new Application(1);
+        }
+        if (isset($this->cache['application'][$packageID])) {
+            return $this->cache['application'][$packageID];
+        }
+    }
+
+    /**
+     * Returns pseudo-application representing WCF used for special cases,
+     * e.g. cross-domain files requestable through the webserver.
+     *
+     * @return  Application
+     * @deprecated  3.0 please use `getApplication()` instead
+     */
+    public function getWCF()
+    {
+        return $this->getApplicationByID(1);
+    }
+
+    /**
+     * Returns the currently active application.
+     *
+     * @return  Application
+     */
+    public function getActiveApplication()
+    {
+        // work-around during WCFSetup
+        if (!PACKAGE_ID) {
+            $host = \str_replace(RouteHandler::getProtocol(), '', RouteHandler::getHost());
+            $documentRoot = FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator(\realpath($_SERVER['DOCUMENT_ROOT'])));
+
+            // always use the core directory
+            if (empty($_POST['directories']) || empty($_POST['directories']['wcf'])) {
+                // within ACP
+                $_POST['directories'] = ['wcf' => $documentRoot . FileUtil::removeLeadingSlash(RouteHandler::getPath(['acp']))];
+            }
+
+            $path = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash(FileUtil::unifyDirSeparator(FileUtil::getRelativePath(
+                $documentRoot,
+                $_POST['directories']['wcf']
+            ))));
+
+            return new Application(null, [
+                'domainName' => $host,
+                'domainPath' => $path,
+                'cookieDomain' => $host,
+            ]);
+        }
+
+        $request = RequestHandler::getInstance()->getActiveRequest();
+        if ($request !== null) {
+            $abbreviation = \substr($request->getClassName(), 0, \mb_strpos($request->getClassName(), '\\'));
+
+            return $this->getApplication($abbreviation);
+        }
+
+        if (isset($this->cache['application'][PACKAGE_ID])) {
+            return $this->cache['application'][PACKAGE_ID];
+        }
+
+        return $this->getWCF();
+    }
+
+    /**
+     * Returns a list of dependent applications.
+     *
+     * @return  Application[]
+     */
+    public function getDependentApplications()
+    {
+        $applications = $this->getApplications();
+        foreach ($applications as $key => $application) {
+            if ($application->packageID == $this->getActiveApplication()->packageID) {
+                unset($applications[$key]);
+                break;
+            }
+        }
+
+        return $applications;
+    }
+
+    /**
+     * Returns a list of all active applications.
+     *
+     * @return  Application[]
+     */
+    public function getApplications()
+    {
+        return $this->cache['application'];
+    }
+
+    /**
+     * Returns abbreviation for a given package id or `null` if application is unknown.
+     *
+     * @param int $packageID unique package id
+     * @return  string|null
+     */
+    public function getAbbreviation($packageID)
+    {
+        foreach ($this->cache['abbreviation'] as $abbreviation => $applicationID) {
+            if ($packageID == $applicationID) {
+                return $abbreviation;
+            }
+        }
+    }
+
+    /**
+     * Returns the list of application abbreviations.
+     *
+     * @return      string[]
+     * @since       3.1
+     */
+    public function getAbbreviations()
+    {
+        return \array_keys($this->cache['abbreviation']);
+    }
+
+    /**
+     * Returns true if given $url is an internal URL.
+     *
+     * @param string $url
+     * @return  bool
+     */
+    public function isInternalURL($url)
+    {
+        $protocolRegex = new Regex('^https(?=://)');
+        if (empty($this->pageURLs)) {
+            foreach ($this->getApplications() as $application) {
+                $this->pageURLs[] = \preg_replace(
+                    '~/$~',
+                    '',
+                    $protocolRegex->replace(RouteHandler::getProtocol() . $application->domainName, 'http')
+                );
+            }
+            $this->pageURLs = \array_unique($this->pageURLs);
+        }
+
+        foreach ($this->pageURLs as $pageURL) {
+            if (\stripos($protocolRegex->replace($url, 'http'), $pageURL) === 0) {
+                return true;
+            }
+        }
+
+        // relative urls contain no protocol, including implied
+        if (!\preg_match('~^([a-zA-Z0-9]+)?://~', $url)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if this is a multi-domain setup.
+     *
+     * @return      bool
+     * @since       3.1
+     */
+    public function isMultiDomainSetup()
+    {
+        if ($this->isMultiDomain === null) {
+            $this->isMultiDomain = false;
+
+            $domainName = $this->getApplicationByID(1)->domainName;
+            foreach ($this->getApplications() as $application) {
+                if ($application->domainName !== $domainName) {
+                    $this->isMultiDomain = true;
+                    break;
+                }
+            }
+        }
+
+        return $this->isMultiDomain;
+    }
+
+    /**
+     * @since 5.2
+     */
+    public function rebuildActiveApplication()
+    {
+        /** @var AbstractApplication $application */
+        foreach ($this->cache['application'] as $application) {
+            if ($application->getPackage()->package === 'com.woltlab.wcf') {
+                continue;
+            }
+
+            $appObject = WCF::getApplicationObject($application);
+            if ($appObject instanceof AbstractApplication) {
+                $appObject->rebuildActiveApplication();
+            }
+        }
+    }
+
+    /**
+     * Rebuilds cookie domain/path for all applications.
+     */
+    public static function rebuild()
+    {
+        $applicationList = new ApplicationList();
+        $applicationList->readObjects();
+
+        $applicationAction = new ApplicationAction($applicationList->getObjects(), 'rebuild');
+        $applicationAction->executeAction();
+    }
+
+    /**
+     * Replaces `app1_` in the given string with the correct installation number:
+     * `app{WCF_N_}`.
+     *
+     * This method can either be used for database table names directly or for
+     * queries, for example.
+     *
+     * @param string $string string to be processed
+     * @param bool $skipCache if `true`, no caches will be used and relevant application packages will be read from database directly
+     * @return  string              processed string
+     * @since   5.2
+     */
+    public static function insertRealDatabaseTableNames($string, $skipCache = false)
+    {
+        if ($skipCache) {
+            $packageList = new PackageList();
+            $packageList->getConditionBuilder()->add('package.isApplication = ?', [1]);
+            $packageList->readObjects();
+
+            foreach ($packageList as $package) {
+                $abbreviation = Package::getAbbreviation($package->package);
+
+                $string = \str_replace($abbreviation . '1_', $abbreviation . WCF_N . '_', $string);
+            }
+        } else {
+            foreach (static::getInstance()->getAbbreviations() as $abbreviation) {
+                $string = \str_replace($abbreviation . '1_', $abbreviation . WCF_N . '_', $string);
+            }
+        }
+
+        return $string;
+    }
 }