`ɔɔ ʔʔʔ@˔˔̔@z`z@z``̔̔ ͔Ы@Ы@͔͔@ΔΔ  ϔ`ϔ@|@` @`p@ஔP p@ஔP }0  * object. If the argument is a JInput object that object will become the * application's input object, otherwise a default input object is created. * @param ?Registry $config An optional argument to provide dependency injection for the application's config * object. If the argument is a Registry object that object will become the * application's config object, otherwise a default config object is created. * @param ?WebClient $client An optional argument to provide dependency injection for the application's client * object. If the argument is a WebClient object that object will become the * application's client object, otherwise a default client object is created. * @param ?Container $container Dependency injection container. * * @since 3.2 */ public function __construct(?Input $input = null, ?Registry $config = null, ?WebClient $client = null, ?Container $container = null) { $container = $container ?: new Container(); $this->setContainer($container); parent::__construct($input, $config, $client); // If JDEBUG is defined, load the profiler instance if (\defined('JDEBUG') && JDEBUG) { $this->profiler = Profiler::getInstance('Application'); } // Enable sessions by default. if ($this->config->get('session') === null) { $this->config->set('session', true); } // Set the session default name. if ($this->config->get('session_name') === null) { $this->config->set('session_name', $this->getName()); } } /** * Checks the user session. * * If the session record doesn't exist, initialise it. * If session is new, create session variables * * @return void * * @since 3.2 * @throws \RuntimeException */ public function checkSession() { $this->getContainer()->get(MetadataManager::class)->createOrUpdateRecord($this->getSession(), $this->getIdentity()); } /** * Enqueue a system message. * * @param string $msg The message to enqueue. * @param string $type The message type. Default is message. * * @return void * * @since 3.2 */ public function enqueueMessage($msg, $type = self::MSG_INFO) { // Don't add empty messages. if ($msg === null || trim($msg) === '') { return; } $inputFilter = InputFilter::getInstance( [], [], InputFilter::ONLY_BLOCK_DEFINED_TAGS, InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES ); // Build the message array and apply the HTML InputFilter with the default blacklist to the message $message = [ 'message' => $inputFilter->clean($msg, 'html'), 'type' => $inputFilter->clean(strtolower($type), 'cmd'), ]; // For empty queue, if messages exists in the session, enqueue them first. $messages = $this->getMessageQueue(); if (!\in_array($message, $this->messageQueue)) { // Enqueue the message. $this->messageQueue[] = $message; } } /** * Ensure several core system input variables are not arrays. * * @return void * * @since 3.9 */ private function sanityCheckSystemVariables() { $input = $this->input; // Get invalid input variables $invalidInputVariables = array_filter( ['option', 'view', 'format', 'lang', 'Itemid', 'template', 'templateStyle', 'task'], function ($systemVariable) use ($input) { return $input->exists($systemVariable) && \is_array($input->getRaw($systemVariable)); } ); // Unset invalid system variables foreach ($invalidInputVariables as $systemVariable) { $input->set($systemVariable, null); } // Stop when there are invalid variables if ($invalidInputVariables) { throw new \RuntimeException('Invalid input, aborting application.'); } } /** * Execute the application. * * @return void * * @since 3.2 */ public function execute() { try { $this->sanityCheckSystemVariables(); $this->setupLogging(); $this->createExtensionNamespaceMap(); // Perform application routines. $this->doExecute(); // If we have an application document object, render it. if ($this->document instanceof \Joomla\CMS\Document\Document) { // Render the application output. $this->render(); } // If gzip compression is enabled in configuration and the server is compliant, compress the output. if ($this->get('gzip') && !\ini_get('zlib.output_compression') && \ini_get('output_handler') !== 'ob_gzhandler') { $this->compress(); // Trigger the onAfterCompress event. $this->dispatchEvent( 'onAfterCompress', new AfterCompressEvent('onAfterCompress', ['subject' => $this]) ); } } catch (\Throwable $throwable) { $event = new ErrorEvent( 'onError', [ 'subject' => $throwable, 'application' => $this, ] ); // Trigger the onError event. $this->dispatchEvent('onError', $event); ExceptionHandler::handleException($event->getError()); } // Trigger the onBeforeRespond event. $this->dispatchEvent( 'onBeforeRespond', new BeforeRespondEvent('onBeforeRespond', ['subject' => $this]) ); // Send the application response. $this->respond(); // Trigger the onAfterRespond event. $this->dispatchEvent( 'onAfterRespond', new AfterRespondEvent('onAfterRespond', ['subject' => $this]) ); } /** * Check if the user is required to reset their password. * * If the user is required to reset their password will be redirected to the page that manage the password reset. * * @param string $option The option that manage the password reset * @param string $view The view that manage the password reset * @param string $layout The layout of the view that manage the password reset * @param string $tasks Permitted tasks * * @return void * * @throws \Exception * @deprecated 5.2.3 will be removed in 7.0 * Use $this->checkUserRequiresReset() instead. */ protected function checkUserRequireReset($option, $view, $layout, $tasks) { $name = $this->getName(); $urls = []; if ($this->get($name . '_reset_password_override', 0)) { $tasks = $this->get($name . '_reset_password_tasks', ''); } // Check task if (!empty($tasks)) { $tasks = explode(',', $tasks); foreach ($tasks as $task) { [$option, $t] = explode('/', $task); $urls[] = ['option' => $option, 'task' => $t]; } } $this->checkUserRequiresReset($option, $view, $layout, $urls); } /** * Check if the user is required to reset their password. * * If the user is required to reset their password will be redirected to the page that manage the password reset. * * @param string $option The option that manage the password reset * @param string $view The view that manage the password reset * @param string $layout The layout of the view that manage the password reset * @param array $urls Multi-dimensional array of permitted urls. Ex: [['option' => 'com_users', 'view' => 'profile'],...] * * @return void * * @throws \Exception */ protected function checkUserRequiresReset($option, $view, $layout, $urls = []) { if ($this->getIdentity()->requireReset) { $redirect = false; /* * By default user profile edit page is used. * That page allows you to change more than just the password and might not be the desired behavior. * This allows a developer to override the page that manage the password reset. * (can be configured using the file: configuration.php, or if extended, through the global configuration form) */ $name = $this->getName(); if ($this->get($name . '_reset_password_override', 0)) { $option = $this->get($name . '_reset_password_option', ''); $view = $this->get($name . '_reset_password_view', ''); $layout = $this->get($name . '_reset_password_layout', ''); $urls = $this->get($name . '_reset_password_urls', $urls); } // If the current URL matches an entry in $urls, we do not redirect if (\count($urls)) { $found = false; foreach ($urls as $url) { $found2 = false; foreach ($url as $key => $value) { if ($this->input->getCmd($key) !== $value) { $found2 = false; break; } $found2 = true; } if ($found2) { $found = true; break; } } if (!$found) { $redirect = true; } } else { if ( $this->input->getCmd('option', '') !== $option || $this->input->getCmd('view', '') !== $view || $this->input->getCmd('layout', '') !== $layout ) { // Requested a different option/view/layout $redirect = true; } } if ($redirect) { // Redirect to the profile edit page $this->enqueueMessage(Text::_('JGLOBAL_PASSWORD_RESET_REQUIRED'), 'notice'); $url = Route::_('index.php?option=' . $option . '&view=' . $view . '&layout=' . $layout, false); // In the administrator we need a different URL if (strtolower($name) === 'administrator') { $user = Factory::getApplication()->getIdentity(); $url = Route::_('index.php?option=' . $option . '&task=' . $view . '.' . $layout . '&id=' . $user->id, false); } $this->redirect($url); } } } /** * Gets a configuration value. * * @param string $varname The name of the value to get. * @param string $default Default value to return * * @return mixed The user state. * * @since 3.2 * * @deprecated 3.2 will be removed in 6.0 * Use get() instead * Example: Factory::getApplication()->get($varname, $default); */ public function getCfg($varname, $default = null) { try { Log::add( \sprintf('%s() is deprecated and will be removed in 6.0. Use Factory->getApplication()->get() instead.', __METHOD__), Log::WARNING, 'deprecated' ); } catch (\RuntimeException $exception) { // Informational log only } return $this->get($varname, $default); } /** * Gets the client id of the current running application. * * @return integer A client identifier. * * @since 3.2 */ public function getClientId() { return $this->clientId; } /** * Returns a reference to the global CmsApplication object, only creating it if it doesn't already exist. * * This method must be invoked as: $web = CmsApplication::getInstance(); * * @param string $name The name (optional) of the CmsApplication class to instantiate. * @param string $prefix The class name prefix of the object. * @param ?Container $container An optional dependency injection container to inject into the application. * * @return CmsApplication * * @since 3.2 * @throws \RuntimeException * @deprecated 4.0 will be removed in 6.0 * Use the application service from the DI container instead * Example: Factory::getContainer()->get($name); */ public static function getInstance($name = null, $prefix = '\JApplication', ?Container $container = null) { if (empty(static::$instances[$name])) { // Create a CmsApplication object. $classname = $prefix . ucfirst($name); if (!$container) { $container = Factory::getContainer(); } if ($container->has($classname)) { static::$instances[$name] = $container->get($classname); } elseif (class_exists($classname)) { // @todo This creates an implicit hard requirement on the ApplicationCms constructor static::$instances[$name] = new $classname(null, null, null, $container); } else { throw new \RuntimeException(Text::sprintf('JLIB_APPLICATION_ERROR_APPLICATION_LOAD', $name), 500); } static::$instances[$name]->loadIdentity(Factory::getUser()); } return static::$instances[$name]; } /** * Returns the application \JMenu object. * * @param string $name The name of the application/client. * @param array $options An optional associative array of configuration settings. * * @return AbstractMenu * * @since 3.2 */ public function getMenu($name = null, $options = []) { if (!isset($name)) { $name = $this->getName(); } // Inject this application object into the \JMenu tree if one isn't already specified if (!isset($options['app'])) { $options['app'] = $this; } if (\array_key_exists($name, $this->menus)) { return $this->menus[$name]; } if ($this->menuFactory === null) { @trigger_error('Menu factory must be set in 5.0', E_USER_DEPRECATED); $this->menuFactory = $this->getContainer()->get(MenuFactoryInterface::class); } $this->menus[$name] = $this->menuFactory->createMenu($name, $options); // Make sure the abstract menu has the instance too, is needed for BC and will be removed with version 5 AbstractMenu::$instances[$name] = $this->menus[$name]; return $this->menus[$name]; } /** * Get the system message queue. * * @param boolean $clear Clear the messages currently attached to the application object * * @return array The system message queue. * * @since 3.2 */ public function getMessageQueue($clear = false) { // For empty queue, if messages exists in the session, enqueue them. if (!\count($this->messageQueue)) { $sessionQueue = $this->getSession()->get('application.queue', []); if ($sessionQueue) { $this->messageQueue = $sessionQueue; $this->getSession()->set('application.queue', []); } } $messageQueue = $this->messageQueue; if ($clear) { $this->messageQueue = []; } return $messageQueue; } /** * Gets the name of the current running application. * * @return string The name of the application. * * @since 3.2 */ public function getName() { return $this->name; } /** * Returns the application Pathway object. * * @return Pathway * * @since 3.2 */ public function getPathway() { if (!$this->pathway) { $resourceName = ucfirst($this->getName()) . 'Pathway'; if (!$this->getContainer()->has($resourceName)) { throw new \RuntimeException( Text::sprintf('JLIB_APPLICATION_ERROR_PATHWAY_LOAD', $this->getName()), 500 ); } $this->pathway = $this->getContainer()->get($resourceName); } return $this->pathway; } /** * Returns the application Router object. * * @param string $name The name of the application. * @param array $options An optional associative array of configuration settings. * * @return Router * * @since 3.2 * * @deprecated 4.3 will be removed in 6.0 * Inject the router or load it from the dependency injection container * Example: Factory::getContainer()->get($name); */ public static function getRouter($name = null, array $options = []) { $app = Factory::getApplication(); if (!isset($name)) { $name = $app->getName(); } $options['mode'] = $app->get('sef'); return Router::getInstance($name, $options); } /** * Gets the name of the current template. * * @param boolean $params An optional associative array of configuration settings * * @return string|\stdClass The name of the template if the params argument is false. The template object if the params argument is true. * * @since 3.2 */ public function getTemplate($params = false) { if ($params) { $template = new \stdClass(); $template->template = 'system'; $template->params = new Registry(); $template->inheritable = 0; $template->parent = ''; return $template; } return 'system'; } /** * Gets a user state. * * @param string $key The path of the state. * @param mixed $default Optional default value, returned if the internal value is null. * * @return mixed The user state or null. * * @since 3.2 */ public function getUserState($key, $default = null) { $registry = $this->getSession()->get('registry'); if ($registry !== null) { return $registry->get($key, $default); } return $default; } /** * Gets the value of a user state variable. * * @param string $key The key of the user state variable. * @param string $request The name of the variable passed in a request. * @param string $default The default value for the variable if not found. Optional. * @param string $type Filter for the variable. Optional. * @see \Joomla\CMS\Filter\InputFilter::clean() for valid values. * * @return mixed The request user state. * * @since 3.2 */ public function getUserStateFromRequest($key, $request, $default = null, $type = 'none') { $cur_state = $this->getUserState($key, $default); $new_state = $this->input->get($request, null, $type); if ($new_state === null) { return $cur_state; } // Save the new value only if it was set in this request. $this->setUserState($key, $new_state); return $new_state; } /** * Initialise the application. * * @param array $options An optional associative array of configuration settings. * * @return void * * @since 3.2 */ protected function initialiseApp($options = []) { // Check that we were given a language in the array (since by default may be blank). if (isset($options['language'])) { $this->set('language', $options['language']); } // Build our language object $lang = $this->getContainer()->get(LanguageFactoryInterface::class)->createLanguage($this->get('language'), $this->get('debug_lang')); // Load the language to the API $this->loadLanguage($lang); // Register the language object with Factory Factory::$language = $this->getLanguage(); // Load the library language files $this->loadLibraryLanguage(); // Set user specific editor. $user = Factory::getUser(); $editor = $user->getParam('editor', $this->get('editor')); if (!PluginHelper::isEnabled('editors', $editor)) { $editor = $this->get('editor'); if (!PluginHelper::isEnabled('editors', $editor)) { $editor = 'none'; } } $this->set('editor', $editor); // Load the behaviour plugins PluginHelper::importPlugin('behaviour', null, true, $this->getDispatcher()); // Trigger the onAfterInitialise event. PluginHelper::importPlugin('system', null, true, $this->getDispatcher()); $this->dispatchEvent( 'onAfterInitialise', new AfterInitialiseEvent('onAfterInitialise', ['subject' => $this]) ); } /** * Checks if HTTPS is forced in the client configuration. * * @param integer $clientId An optional client id (defaults to current application client). * * @return boolean True if is forced for the client, false otherwise. * * @since 3.7.3 */ public function isHttpsForced($clientId = null) { $clientId = (int) ($clientId !== null ? $clientId : $this->getClientId()); $forceSsl = (int) $this->get('force_ssl'); if ($clientId === 0 && $forceSsl === 2) { return true; } if ($clientId === 1 && $forceSsl >= 1) { return true; } return false; } /** * Check the client interface by name. * * @param string $identifier String identifier for the application interface * * @return boolean True if this application is of the given type client interface. * * @since 3.7.0 */ public function isClient($identifier) { return $this->getName() === $identifier; } /** * Load the library language files for the application * * @return void * * @since 3.6.3 */ protected function loadLibraryLanguage() { $this->getLanguage()->load('lib_joomla', JPATH_ADMINISTRATOR); } /** * Login authentication function. * * Username and encoded password are passed the onUserLogin event which * is responsible for the user validation. A successful validation updates * the current session record with the user's details. * * Username and encoded password are sent as credentials (along with other * possibilities) to each observer (authentication plugin) for user * validation. Successful validation will update the current session with * the user details. * * @param array $credentials Array('username' => string, 'password' => string) * @param array $options Array('remember' => boolean) * * @return boolean|\Exception True on success, false if failed or silent handling is configured, or a \Exception object on authentication error. * * @since 3.2 */ public function login($credentials, $options = []) { // Get the global Authentication object. $authenticate = Authentication::getInstance($this->authenticationPluginType); $response = $authenticate->authenticate($credentials, $options); $dispatcher = $this->getDispatcher(); // Import the user plugin group. PluginHelper::importPlugin('user', null, true, $dispatcher); if ($response->status === Authentication::STATUS_SUCCESS) { /* * Validate that the user should be able to login (different to being authenticated). * This permits authentication plugins blocking the user. */ $authorisations = $authenticate->authorise($response, $options); $denied_states = Authentication::STATUS_EXPIRED | Authentication::STATUS_DENIED; foreach ($authorisations as $authorisation) { if ((int) $authorisation->status & $denied_states) { // Trigger onUserAuthorisationFailure Event. $dispatcher->dispatch('onUserAuthorisationFailure', new AuthorisationFailureEvent('onUserAuthorisationFailure', [ 'subject' => (array) $authorisation, 'options' => $options, ])); // If silent is set, just return false. if (isset($options['silent']) && $options['silent']) { return false; } // Return the error. switch ($authorisation->status) { case Authentication::STATUS_EXPIRED: $this->enqueueMessage(Text::_('JLIB_LOGIN_EXPIRED'), 'error'); return false; case Authentication::STATUS_DENIED: $this->enqueueMessage(Text::_('JLIB_LOGIN_DENIED'), 'error'); return false; default: $this->enqueueMessage(Text::_('JLIB_LOGIN_AUTHORISATION'), 'error'); return false; } } } // OK, the credentials are authenticated and user is authorised. Let's fire the onLogin event. $loginEvent = new LoginEvent('onUserLogin', ['subject' => (array) $response, 'options' => $options]); $dispatcher->dispatch('onUserLogin', $loginEvent); $results = $loginEvent['result'] ?? []; /* * If any of the user plugins did not successfully complete the login routine * then the whole method fails. * * Any errors raised should be done in the plugin as this provides the ability * to provide much more information about why the routine may have failed. */ $user = Factory::getUser(); if ($response->type === 'Cookie') { $user->set('cookieLogin', true); } if (\in_array(false, $results, true) == false) { $options['user'] = $user; $options['responseType'] = $response->type; // The user is successfully logged in. Run the after login events $dispatcher->dispatch('onUserAfterLogin', new AfterLoginEvent('onUserAfterLogin', [ 'options' => $options, 'subject' => (array) $response, ])); return true; } } // Trigger onUserLoginFailure Event. $dispatcher->dispatch('onUserLoginFailure', new LoginFailureEvent('onUserLoginFailure', [ 'subject' => (array) $response, 'options' => $options, ])); // If silent is set, just return false. if (isset($options['silent']) && $options['silent']) { return false; } // If status is success, any error will have been raised by the user plugin if ($response->status !== Authentication::STATUS_SUCCESS) { $this->getLogger()->warning($response->error_message, ['category' => 'jerror']); } return false; } /** * Logout authentication function. * * Passed the current user information to the onUserLogout event and reverts the current * session record back to 'anonymous' parameters. * If any of the authentication plugins did not successfully complete * the logout routine then the whole method fails. Any errors raised * should be done in the plugin as this provides the ability to give * much more information about why the routine may have failed. * * @param integer $userid The user to load - Can be an integer or string - If string, it is converted to ID automatically * @param array $options Array('clientid' => array of client id's) * * @return boolean True on success * * @since 3.2 */ public function logout($userid = null, $options = []) { // Get a user object from the Application. $user = Factory::getUser($userid); $dispatcher = $this->getDispatcher(); // Build the credentials array. $parameters = [ 'username' => $user->username, 'id' => $user->id, ]; // Set clientid in the options array if it hasn't been set already and shared sessions are not enabled. if (!$this->get('shared_session', '0') && !isset($options['clientid'])) { $options['clientid'] = $this->getClientId(); } // Import the user plugin group. PluginHelper::importPlugin('user', null, true, $dispatcher); // OK, the credentials are built. Lets fire the onLogout event. $logoutEvent = new LogoutEvent('onUserLogout', ['subject' => $parameters, 'options' => $options]); $dispatcher->dispatch('onUserLogout', $logoutEvent); $results = $logoutEvent['result'] ?? []; // Check if any of the plugins failed. If none did, success. if (!\in_array(false, $results, true)) { $options['username'] = $user->username; $dispatcher->dispatch('onUserAfterLogout', new AfterLogoutEvent('onUserAfterLogout', [ 'options' => $options, 'subject' => $parameters, ])); return true; } // Trigger onUserLogoutFailure Event. $dispatcher->dispatch('onUserLogoutFailure', new LogoutFailureEvent('onUserLogoutFailure', [ 'subject' => $parameters, 'options' => $options, ])); return false; } /** * Redirect to another URL. * * If the headers have not been sent the redirect will be accomplished using a "301 Moved Permanently" * or "303 See Other" code in the header pointing to the new location. If the headers have already been * sent this will be accomplished using a JavaScript statement. * * @param string $url The URL to redirect to. Can only be http/https URL * @param integer $status The HTTP 1.1 status code to be provided. 303 is assumed by default. * * @return void * * @since 3.2 */ public function redirect($url, $status = 303) { // Persist messages if they exist. if (\count($this->messageQueue)) { $this->getSession()->set('application.queue', $this->messageQueue); } // Hand over processing to the parent now parent::redirect($url, $status); } /** * Rendering is the process of pushing the document buffers into the template * placeholders, retrieving data from the document and pushing it into * the application response buffer. * * @return void * * @since 3.2 */ protected function render() { // Setup the document options. $this->docOptions['template'] = $this->get('theme'); $this->docOptions['file'] = $this->get('themeFile', 'index.php'); $this->docOptions['params'] = $this->get('themeParams'); $this->docOptions['csp_nonce'] = $this->get('csp_nonce'); $this->docOptions['templateInherits'] = $this->get('themeInherits'); if ($this->get('themes.base')) { $this->docOptions['directory'] = $this->get('themes.base'); } else { // Fall back to constants. $this->docOptions['directory'] = \defined('JPATH_THEMES') ? JPATH_THEMES : (\defined('JPATH_BASE') ? JPATH_BASE : __DIR__) . '/themes'; } // Parse the document. $this->document->parse($this->docOptions); // Trigger the onBeforeRender event. PluginHelper::importPlugin('system', null, true, $this->getDispatcher()); $this->dispatchEvent( 'onBeforeRender', new BeforeRenderEvent('onBeforeRender', ['subject' => $this]) ); $caching = false; if ($this->isClient('site') && $this->get('caching') && $this->get('caching', 2) == 2 && !$this->getIdentity()->id) { $caching = true; } // Render the document. $data = $this->document->render($caching, $this->docOptions); // Set the application output data. $this->setBody($data); // Trigger the onAfterRender event. $this->dispatchEvent( 'onAfterRender', new AfterRenderEvent('onAfterRender', ['subject' => $this]) ); // Mark afterRender in the profiler. JDEBUG ? $this->profiler->mark('afterRender') : null; } /** * Route the application. * * Routing is the process of examining the request environment to determine which * component should receive the request. The component optional parameters * are then set in the request object to be processed when the application is being * dispatched. * * @return void * * @since 3.2 * * @deprecated 4.0 will be removed in 6.0 * Implement the route functionality in the extending class, this here will be removed without replacement */ protected function route() { // Get the full request URI. $uri = clone Uri::getInstance(); $router = static::getRouter(); $result = $router->parse($uri, true); $active = $this->getMenu()->getActive(); if ( $active !== null && $active->type === 'alias' && $active->getParams()->get('alias_redirect') && \in_array($this->input->getMethod(), ['GET', 'HEAD'], true) ) { $item = $this->getMenu()->getItem($active->getParams()->get('aliasoptions')); if ($item !== null) { $oldUri = clone Uri::getInstance(); if ($oldUri->getVar('Itemid') == $active->id) { $oldUri->setVar('Itemid', $item->id); } $base = Uri::base(true); $oldPath = StringHelper::strtolower(substr($oldUri->getPath(), \strlen($base) + 1)); $activePathPrefix = StringHelper::strtolower($active->route); $position = strpos($oldPath, $activePathPrefix); if ($position !== false) { $oldUri->setPath($base . '/' . substr_replace($oldPath, $item->route, $position, \strlen($activePathPrefix))); $this->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true); $this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true); $this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate', false); $this->sendHeaders(); $this->redirect((string) $oldUri, 301); } } } foreach ($result as $key => $value) { $this->input->def($key, $value); } // Trigger the onAfterRoute event. PluginHelper::importPlugin('system', null, true, $this->getDispatcher()); $this->dispatchEvent( 'onAfterRoute', new AfterRouteEvent('onAfterRoute', ['subject' => $this]) ); } /** * Sets the value of a user state variable. * * @param string $key The path of the state. * @param mixed $value The value of the variable. * * @return mixed The previous state, if one existed. Null otherwise. * * @since 3.2 */ public function setUserState($key, $value) { $session = $this->getSession(); $registry = $session->get('registry'); if ($registry !== null) { return $registry->set($key, $value); } return null; } /** * Sends all headers prior to returning the string * * @param boolean $compress If true, compress the data * * @return string * * @since 3.2 */ public function toString($compress = false) { // Don't compress something if the server is going to do it anyway. Waste of time. if ($compress && !\ini_get('zlib.output_compression') && \ini_get('output_handler') !== 'ob_gzhandler') { $this->compress(); } if ($this->allowCache() === false) { $this->setHeader('Cache-Control', 'no-cache', false); } $this->sendHeaders(); return $this->getBody(); } /** * Method to determine a hash for anti-spoofing variable names * * @param boolean $forceNew If true, force a new token to be created * * @return string Hashed var name * * @since 4.0.0 */ public function getFormToken($forceNew = false) { /** @var Session $session */ $session = $this->getSession(); return $session::getFormToken($forceNew); } /** * Checks for a form token in the request. * * Use in conjunction with getFormToken. * * @param string $method The request method in which to look for the token key. * * @return boolean True if found and valid, false otherwise. * * @since 4.0.0 */ public function checkToken($method = 'post') { /** @var Session $session */ $session = $this->getSession(); return $session::checkToken($method); } /** * Flag if the application instance is a CLI or web based application. * * Helper function, you should use the native PHP functions to detect if it is a CLI application. * * @return boolean * * @since 4.0.0 * * @deprecated 4.0 will be removed in 6.0 * Will be removed without replacements */ public function isCli() { return false; } /** * No longer used * * @return boolean * * @since 4.0.0 * * @throws \Exception * * @deprecated 4.2 will be removed in 6.0 * Will be removed without replacements */ protected function isTwoFactorAuthenticationRequired(): bool { return false; } /** * No longer used * * @return boolean * * @since 4.0.0 * * @throws \Exception * * @deprecated 4.2 will be removed in 6.0 * Will be removed without replacements */ private function hasUserConfiguredTwoFactorAuthentication(): bool { return false; } /** * Setup logging functionality. * * @return void * * @since 4.0.0 */ private function setupLogging(): void { // Add InMemory logger that will collect all log entries to allow to display them later by extensions if ($this->get('debug')) { Log::addLogger(['logger' => 'inmemory']); } // Log the deprecated API. if ($this->get('log_deprecated')) { Log::addLogger(['text_file' => 'deprecated.php'], Log::ALL, ['deprecated']); } // We only log errors unless Site Debug is enabled $logLevels = Log::ERROR | Log::CRITICAL | Log::ALERT | Log::EMERGENCY; if ($this->get('debug')) { $logLevels = Log::ALL; } Log::addLogger(['text_file' => 'joomla_core_errors.php'], $logLevels, ['system']); // Log everything (except deprecated APIs, these are logged separately with the option above). if ($this->get('log_everything')) { Log::addLogger(['text_file' => 'everything.php'], Log::ALL, ['deprecated', 'deprecation-notes', 'databasequery'], true); } if ($this->get('log_categories')) { $priority = 0; foreach ($this->get('log_priorities', ['all']) as $p) { $const = '\\Joomla\\CMS\\Log\\Log::' . strtoupper($p); if (\defined($const)) { $priority |= \constant($const); } } // Split into an array at any character other than alphabet, numbers, _, ., or - $categories = preg_split('/[^\w.-]+/', $this->get('log_categories', ''), -1, PREG_SPLIT_NO_EMPTY); $mode = (bool) $this->get('log_category_mode', false); if (!$categories) { return; } Log::addLogger(['text_file' => 'custom-logging.php'], $priority, $categories, $mode); } } /** * Sets the internal menu factory. * * @param MenuFactoryInterface $menuFactory The menu factory * * @return void * * @since 4.2.0 */ public function setMenuFactory(MenuFactoryInterface $menuFactory): void { $this->menuFactory = $menuFactory; } } Attempted to load class "CMSApplication" from namespace "Joomla\CMS\Application". Did you forget a "use" statement for another namespace? (500 Whoops, looks like something went wrong.)

ClassNotFoundError

HTTP 500 Whoops, looks like something went wrong.

Attempted to load class "CMSApplication" from namespace "Joomla\CMS\Application".
Did you forget a "use" statement for another namespace?

Exception

Symfony\Component\ErrorHandler\Error\ ClassNotFoundError

  1. /**
  2.  * Joomla! Site Application class
  3.  *
  4.  * @since  3.2
  5.  */
  6. final class SiteApplication extends CMSApplication
  7. {
  8.     use CacheControllerFactoryAwareTrait;
  9.     use MultiFactorAuthenticationHandler;
  10.     /**
  1.          *
  2.          * @param  string $file
  3.          * @return void
  4.          */
  5.         self::$includeFile \Closure::bind(static function($file) {
  6.             include $file;
  7.         }, nullnull);
  8.     }
  9. }
  1.      */
  2.     public function loadClass($class)
  3.     {
  4.         if ($file $this->findFile($class)) {
  5.             $includeFile self::$includeFile;
  6.             $includeFile($file);
  7.             return true;
  8.         }
  9.         return null;
ClassLoader->loadClass('Joomla\\CMS\\Application\\SiteApplication') in /datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/src/Autoload/ClassLoader.php (line 59)
  1.      *
  2.      * @since   3.4
  3.      */
  4.     public function loadClass($class)
  5.     {
  6.         if ($result $this->loader->loadClass($class)) {
  7.             \JLoader::applyAliasFor($class);
  8.         }
  9.         return $result;
  10.     }
ClassLoader->loadClass('Joomla\\CMS\\Application\\SiteApplication') in /datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/src/Service/Provider/Application.php (line 101)
  1.         $container->alias(SiteApplication::class, 'JApplicationSite')
  2.             ->share(
  3.                 'JApplicationSite',
  4.                 function (Container $container) {
  5.                     $app = new SiteApplication($container->get(CMSInput::class), $container->get('config'), null$container);
  6.                     $app->setDispatcher($container->get(DispatcherInterface::class));
  7.                     $app->setLogger($container->get(LoggerInterface::class));
  8.                     $app->setSession($container->get(SessionInterface::class));
  9.                     $app->setUserFactory($container->get(UserFactoryInterface::class));
  10.                     $app->setCacheControllerFactory($container->get(CacheControllerFactoryInterface::class));
  1.     {
  2.         $callable $this->factory;
  3.         if ($this->isShared()) {
  4.             if ($this->instance === null) {
  5.                 $this->instance $callable($this->container);
  6.             }
  7.             return $this->instance;
  8.         }
  1.             }
  2.             throw new KeyNotFoundException(sprintf("Resource '%s' has not been registered with the container."$resourceName));
  3.         }
  4.         return $this->resources[$key]->getInstance();
  5.     }
  6.     /**
  7.      * Check if specified resource exists.
  8.      *
Container->get('Joomla\\CMS\\Application\\SiteApplication') in /datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/includes/app.php (line 52)
  1.     ->alias(\Joomla\CMS\Session\Session::class, 'session.web.site')
  2.     ->alias(\Joomla\Session\Session::class, 'session.web.site')
  3.     ->alias(\Joomla\Session\SessionInterface::class, 'session.web.site');
  4. // Instantiate the application.
  5. $app $container->get(\Joomla\CMS\Application\SiteApplication::class);
  6. // Set the application as global app
  7. \Joomla\CMS\Factory::$application $app;
  8. // Execute the application.
require_once('/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/includes/app.php') in /datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/index.php (line 32)
  1.  * define() is used rather than "const" to not error for PHP 5.2 and lower
  2.  */
  3. define('_JEXEC'1);
  4. // Run the application - All executable code should be triggered through this file
  5. require_once dirname(__FILE__) . '/includes/app.php';

Stack Trace

ClassNotFoundError
Symfony\Component\ErrorHandler\Error\ClassNotFoundError:
Attempted to load class "CMSApplication" from namespace "Joomla\CMS\Application".
Did you forget a "use" statement for another namespace?

  at /datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/src/Application/SiteApplication.php:42
  at include()
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/vendor/composer/ClassLoader.php:576)
  at Composer\Autoload\{closure}('/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/vendor/composer/../../../libraries/src/Application/SiteApplication.php')
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/vendor/composer/ClassLoader.php:427)
  at Composer\Autoload\ClassLoader->loadClass('Joomla\\CMS\\Application\\SiteApplication')
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/src/Autoload/ClassLoader.php:59)
  at Joomla\CMS\Autoload\ClassLoader->loadClass('Joomla\\CMS\\Application\\SiteApplication')
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/src/Service/Provider/Application.php:101)
  at Joomla\CMS\Service\Provider\Application->Joomla\CMS\Service\Provider\{closure}(object(Container))
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/vendor/joomla/di/src/ContainerResource.php:166)
  at Joomla\DI\ContainerResource->getInstance()
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/libraries/vendor/joomla/di/src/Container.php:95)
  at Joomla\DI\Container->get('Joomla\\CMS\\Application\\SiteApplication')
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/includes/app.php:52)
  at require_once('/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/includes/app.php')
     (/datas/yulpa173848/sites/test2025.samclap-ufolep.fr/htdocs/index.php:32)