e variable's namespace e.g. the component name. Default: 'default' * * @return mixed */ public function getSessionVar(string $name, $default = null, $namespace = 'default') { // CLI if ($this->isCli() && !class_exists('FOFApplicationCLI')) { return static::$fakeSession->get("$namespace.$name", $default); } // Joomla 3 if (version_compare(JVERSION, '3.9999.9999', 'le')) { return $this->container->session->get($name, $default, $namespace); } // Joomla 4 if (empty($namespace)) { return $this->container->session->get($name, $default); } $registry = $this->container->session->get('registry'); if (is_null($registry)) { $registry = new Registry(); $this->container->session->set('registry', $registry); } return $registry->get($namespace . '.' . $name, $default); } /** * Unset a variable from the user session * * @param string $name The name of the variable to unset * @param string $namespace (optional) The variable's namespace e.g. the component name. Default: 'default' * * @return void */ public function unsetSessionVar(string $name, string $namespace = 'default'): void { $this->setSessionVar($name, null, $namespace); } /** * Return the session token. Two types of tokens can be returned: * * Session token ($formToken == false): Used for anti-spam protection of forms. This is specific to a session * object. * * Form token ($formToken == true): A secure hash of the user ID with the session token. Both the session and the * user are fetched from the application container. * * @param bool $formToken Should I return a form token? * @param bool $forceNew Should I force the creation of a new token? * * @return mixed */ public function getToken(bool $formToken = false, bool $forceNew = false): string { // For CLI apps we implement our own fake token system if ($this->isCli()) { $token = $this->getSessionVar('session.token'); // Create a token if (is_null($token) || $forceNew) { $token = UserHelper::genRandomPassword(32); $this->setSessionVar('session.token', $token); } if (!$formToken) { return $token; } $user = $this->getUser(); return ApplicationHelper::getHash($user->id . $token); } // Web application, go through the regular Joomla! API. if ($formToken) { return Session::getFormToken($forceNew); } return $this->container->session->getToken($forceNew); } /** @inheritDoc */ public function addScriptOptions($key, $value, $merge = true) { /** @var HtmlDocument $document */ $document = $this->getDocument(); if (!method_exists($document, 'addScriptOptions')) { return; } $document->addScriptOptions($key, $value, $merge); } /** @inheritDoc */ public function getScriptOptions($key = null) { /** @var HtmlDocument $document */ $document = $this->getDocument(); if (!method_exists($document, 'getScriptOptions')) { return []; } return $document->getScriptOptions($key); } /** * Main function to detect if we're running in a CLI environment, if we're admin or if it's an API application * * @return array isCLI and isAdmin. It's not an associative array, so we can use list(). */ protected function isCliAdminApi(): array { if (is_null(static::$isCLI) && is_null(static::$isAdmin)) { static::$isCLI = false; static::$isAdmin = false; static::$isApi = false; try { if (is_null(JoomlaFactory::$application)) { static::$isCLI = true; static::$isAdmin = false; return [static::$isCLI, static::$isAdmin, static::$isApi]; } $app = JoomlaFactory::getApplication(); static::$isCLI = $app instanceof Exception || $app instanceof CliApplication; if (class_exists('Joomla\CMS\Application\CliApplication')) { static::$isCLI = static::$isCLI || $app instanceof JApplicationCli; } if (class_exists('Joomla\CMS\Application\ConsoleApplication')) { static::$isCLI = static::$isCLI || ($app instanceof ConsoleApplication); } } catch (Exception $e) { static::$isCLI = true; } if (static::$isCLI) { return [static::$isCLI, static::$isAdmin, static::$isApi]; } try { $app = JoomlaFactory::getApplication(); } catch (Exception $e) { return [static::$isCLI, static::$isAdmin, static::$isApi]; } if (method_exists($app, 'isAdmin')) { static::$isAdmin = $app->isAdmin(); } elseif (method_exists($app, 'isClient')) { static::$isAdmin = $app->isClient('administrator'); static::$isApi = $app->isClient('api'); } } return [static::$isCLI, static::$isAdmin, static::$isApi]; } /** * Gets a reference to the cache object, loading it from the disk if * needed. * * @param bool $force Should I forcibly reload the registry? * * @return Registry */ private function &getCacheObject(bool $force = false): Registry { // Check if we have to load the cache file or we are forced to do that if (is_null($this->_cache) || $force) { // Try to get data from Joomla!'s cache $cache = JoomlaFactory::getCache('fof', ''); $this->_cache = $cache->get('cache', 'fof'); $isRegistry = is_object($this->_cache); if ($isRegistry) { $isRegistry = $this->_cache instanceof Registry; } if (!$isRegistry) { // Create a new Registry object $this->_cache = new Registry(); } } return $this->_cache; } /** * Save the cache object back to disk * * @return bool True on success */ private function saveCache(): bool { // Get the Registry object of our cached data $registry = $this->getCacheObject(); $cache = JoomlaFactory::getCache('fof', ''); return $cache->store($registry, 'cache', 'fof'); } /** * Joomla! 3.7 has a broken System - Page Cache plugin. When this plugin is enabled it FORCES the caching of all * pages as soon as Joomla! starts loading, before the plugin has a chance to request to not be cached. Event worse, * in case of a redirection, it doesn't try to remove the cache lock. This means that the next request will be * treated as though the result of the page should be cached. Since there is NO cache content for the page Joomla! * returns an empty response with a 200 OK header. This will, of course, get in the way of every single attempt to * perform a redirection in the frontend of the site. * * @return void */ private function bugfixJoomlaCachePlugin(): void { // Only do something when the System - Cache plugin is activated if (!class_exists('PlgSystemCache')) { return; } // Forcibly uncache the current request $options = [ 'defaultgroup' => 'page', 'browsercache' => false, 'caching' => false, ]; $cache_key = Uri::getInstance()->toString(); Cache::getInstance('page', $options)->cache->remove($cache_key, 'page'); } }