/** * Class constructor * * @param JApplicationCms $app JApplicationCms Object * @param JMenu $menu JMenu object * * @since 3.4 */ public function __construct(JApplicationCms $app = null, JMenu $menu = null) { $this->app = $app ? $app : JApplicationCms::getInstance('site'); $this->menu = $menu ? $menu : $this->app->getMenu(); // Add core rules if ($this->app->get('force_ssl') == 2) { $this->attachParseRule(array($this, 'parseCheckSSL'), self::PROCESS_BEFORE); } $this->attachParseRule(array($this, 'parseInit'), self::PROCESS_BEFORE); $this->attachBuildRule(array($this, 'buildInit'), self::PROCESS_BEFORE); $this->attachBuildRule(array($this, 'buildComponentPreprocess'), self::PROCESS_BEFORE); if ($this->app->get('sef')) { if ($this->app->get('sef_suffix')) { $this->attachParseRule(array($this, 'parseFormat'), self::PROCESS_BEFORE); $this->attachBuildRule(array($this, 'buildFormat'), self::PROCESS_AFTER); } $this->attachParseRule(array($this, 'parseSefRoute'), self::PROCESS_DURING); $this->attachBuildRule(array($this, 'buildSefRoute'), self::PROCESS_DURING); $this->attachParseRule(array($this, 'parsePaginationData'), self::PROCESS_AFTER); $this->attachBuildRule(array($this, 'buildPaginationData'), self::PROCESS_AFTER); if ($this->app->get('sef_rewrite')) { $this->attachBuildRule(array($this, 'buildRewrite'), self::PROCESS_AFTER); } } $this->attachParseRule(array($this, 'parseRawRoute'), self::PROCESS_DURING); $this->attachBuildRule(array($this, 'buildBase'), self::PROCESS_AFTER); }
/** * Remember me method to run onAfterInitialise * * @return boolean * * @since 1.5 * @throws InvalidArgumentException */ public function onAfterInitialise() { // No remember me for admin if ($this->app->isAdmin()) { return false; } $user = JFactory::getUser(); $this->app->rememberCookieLifetime = $this->lifetime; $this->app->rememberCookieSecure = $this->secure; $this->app->rememberCookieLength = $this->length; // Check for a cookie if ($user->get('guest') == 1) { // Create the cookie name and data $rememberArray = JUserHelper::getRememberCookieData(); if ($rememberArray !== false) { if (count($rememberArray) != 3) { // Destroy the cookie in the browser. $this->app->input->cookie->set(end($rememberArray), false, time() - 42000, $this->app->get('cookie_path'), $this->app->get('cookie_domain')); JLog::add('Invalid cookie detected.', JLog::WARNING, 'error'); return false; } list($privateKey, $series, $uastring) = $rememberArray; if (!JUserHelper::clearExpiredTokens($this)) { JLog::add('Error in deleting expired cookie tokens.', JLog::WARNING, 'error'); } // Find the matching record if it exists $query = $this->db->getQuery(true)->select($this->db->quoteName(array('user_id', 'token', 'series', 'time', 'invalid')))->from($this->db->quoteName('#__user_keys'))->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series)))->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($uastring))->order($this->db->quoteName('time') . ' DESC'); $results = $this->db->setQuery($query)->loadObjectList(); $countResults = count($results); // We have a user but a cookie that is not in the database, or it is invalid. This is a possible attack, so invalidate everything. if (($countResults === 0 || $results[0]->invalid != 0) && !empty($results[0]->user_id)) { JUserHelper::invalidateCookie($results[0]->user_id, $uastring); JLog::add(JText::sprintf('PLG_SYSTEM_REMEMBER_ERROR_LOG_INVALIDATED_COOKIES', $user->username), JLog::WARNING, 'security'); // Possibly e-mail user and admin here. return false; } // We have a user with one cookie with a valid series and a corresponding record in the database. if ($countResults === 1) { if (substr($results[0]->token, 0, 4) === '$2y$') { if (JCrypt::hasStrongPasswordSupport()) { $match = password_verify($privateKey, $results[0]->token); } } else { if (JCrypt::timingSafeCompare($results[0]->token, $privateKey)) { $match = true; } } if (empty($match)) { JUserHelper::invalidateCookie($results[0]->user_id, $uastring); JLog::add(JText::sprintf('PLG_SYSTEM_REMEMBER_ERROR_LOG_LOGIN_FAILED', $user->username), JLog::WARNING, 'security'); return false; } // Set up the credentials array to pass to onUserAuthenticate $credentials = array('username' => $results[0]->user_id); return $this->app->login($credentials, array('silent' => true, 'lifetime' => $this->lifetime, 'secure' => $this->secure, 'length' => $this->length)); } } } return false; }
/** * This is where we delete any authentication cookie when a user logs out * * @param array $options Array holding options (length, timeToExpiration) * * @return boolean True on success * * @since 3.2 */ public function onUserAfterLogout($options) { // No remember me for admin if ($this->app->isAdmin()) { return false; } $cookieName = 'joomla_remember_me_' . JUserHelper::getShortHashedUserAgent(); $cookieValue = $this->app->input->cookie->get($cookieName); // There are no cookies to delete. if (!$cookieValue) { return true; } $cookieArray = explode('.', $cookieValue); // Filter series since we're going to use it in the query $filter = new JFilterInput(); $series = $filter->clean($cookieArray[1], 'ALNUM'); // Remove the record from the database $query = $this->db->getQuery(true)->delete('#__user_keys')->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series)); try { $this->db->setQuery($query)->execute(); } catch (RuntimeException $e) { // We aren't concerned with errors from this query, carry on } // Destroy the cookie $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain')); return true; }
/** * Set the language cookie * * @param string $lang_code The language code for which we want to set the cookie * * @return void * * @since 3.4.2 */ private function setLanguageCookie($lang_code) { // Get the cookie lifetime we want. $cookie_time = 0; if ($this->params->get('lang_cookie', 1) == 1) { $cookie_time = time() + 365 * 86400; } // Create a cookie. $cookie_domain = $this->app->get('cookie_domain'); $cookie_path = $this->app->get('cookie_path', '/'); $this->app->input->cookie->set(JApplicationHelper::getHash('language'), $lang_code, $cookie_time, $cookie_path, $cookie_domain); }
/** * onAfterRender * * @return void */ public function onAfterRender() { $this->call(array('Article\\CodeInsert', 'insertHeader')); $this->call(array('Asset\\Style', 'register')); if ($this->app->get('caching', 0)) { $this->call(array('System\\Cache', 'cacheEzsetData'), $this); } if ($this->params->get('cacheManagerEnabled', 0) && $this->app->isSite()) { $this->call(array('System\\Cache', 'manage')); } @(include $this->includeEvent(__FUNCTION__)); }
/** * We set the authentication cookie only after login is successfullly finished. * We set a new cookie either for a user with no cookies or one * where the user used a cookie to authenticate. * * @param array options Array holding options * * @return boolean True on success * * @since 3.2 */ public function onUserAfterLogin($options) { // Currently this portion of the method only applies to Cookie based login. if (!isset($options['responseType']) || $options['responseType'] != 'Cookie' && empty($options['remember'])) { return true; } // We get the parameter values differently for cookie and non-cookie logins. $cookieLifetime = empty($options['lifetime']) ? $this->app->rememberCookieLifetime : $options['lifetime']; $length = empty($options['length']) ? $this->app->rememberCookieLength : $options['length']; $secure = empty($options['secure']) ? $this->app->rememberCookieSecure : $options['secure']; // We need the old data to match against the current database $rememberArray = JUserHelper::getRememberCookieData(); $privateKey = JUserHelper::genRandomPassword($length); // We are going to concatenate with . so we need to remove it from the strings. $privateKey = str_replace('.', '', $privateKey); $cryptedKey = JUserHelper::getCryptedPassword($privateKey, '', 'bcrypt', false); $cookieName = JUserHelper::getShortHashedUserAgent(); // Create an identifier and make sure that it is unique. $unique = false; do { // Unique identifier for the device-user $series = JUserHelper::genRandomPassword(20); // We are going to concatenate with . so we need to remove it from the strings. $series = str_replace('.', '', $series); $query = $this->db->getQuery(true)->select($this->db->quoteName('series'))->from($this->db->quoteName('#__user_keys'))->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series))); $results = $this->db->setQuery($query)->loadResult(); if (is_null($results)) { $unique = true; } } while ($unique === false); // If a user logs in with non cookie login and remember me checked we will // delete any invalid entries so that he or she can use remember once again. if ($options['responseType'] !== 'Cookie') { $query = $this->db->getQuery(true)->delete('#__user_keys')->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username)); $this->db->setQuery($query)->execute(); } $cookieValue = $privateKey . '.' . $series . '.' . $cookieName; // Destroy the old cookie. $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path'), $this->app->get('cookie_domain')); // And make a new one. $this->app->input->cookie->set($cookieName, $cookieValue, $cookieLifetime, $this->app->get('cookie_path'), $this->app->get('cookie_domain'), $secure); $query = $this->db->getQuery(true); if (empty($user->cookieLogin) || $options['response'] != 'Coookie') { // For users doing login from Joomla or other systems $query->insert($this->db->quoteName('#__user_keys')); } else { $query->update($this->db->quoteName('#__user_keys'))->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($rememberArray[1])))->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName)); } $query->set($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))->set($this->db->quoteName('time') . ' = ' . $cookieLifetime)->set($this->db->quoteName('token') . ' = ' . $this->db->quote($cryptedKey))->set($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series)))->set($this->db->quoteName('invalid') . ' = 0')->set($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName)); $this->db->setQuery($query)->execute(); return true; }
/** * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. * * @param array $clearGroups The cache groups to clean * @param array $cacheClients The cache clients (site, admin) to clean * * @return void * * @since 3.5 */ private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) { foreach ($clearGroups as $group) { foreach ($cacheClients as $client_id) { try { $options = array('defaultgroup' => $group, 'cachebase' => $client_id ? JPATH_ADMINISTRATOR . '/cache' : $this->app->get('cache_path', JPATH_SITE . '/cache')); $cache = JCache::getInstance('callback', $options); $cache->clean(); } catch (Exception $e) { // Ignore it } } } }
/** * Constructor. * * @param object &$subject The object to observe. * @param array $config An optional associative array of configuration settings. * * @since 1.5 */ public function __construct(&$subject, $config) { parent::__construct($subject, $config); // Log the deprecated API. if ($this->params->get('log-deprecated')) { JLog::addLogger(array('text_file' => 'deprecated.php'), JLog::ALL, array('deprecated')); } // Log everything (except deprecated APIs, these are logged separately with the option above). if ($this->params->get('log-everything')) { JLog::addLogger(array('text_file' => 'everything.php'), JLog::ALL, array('deprecated', 'databasequery'), true); } // Get the application if not done by JPlugin. This may happen during upgrades from Joomla 2.5. if (!$this->app) { $this->app = JFactory::getApplication(); } $this->debugLang = $this->app->get('debug_lang'); // Skip the plugin if debug is off if ($this->debugLang == '0' && $this->app->get('debug') == '0') { return; } // Only if debugging or language debug is enabled. if (JDEBUG || $this->debugLang) { JFactory::getConfig()->set('gzip', 0); ob_start(); ob_implicit_flush(false); } $this->linkFormat = ini_get('xdebug.file_link_format'); if ($this->params->get('logs', 1)) { $priority = 0; foreach ($this->params->get('log_priorities', array()) as $p) { $const = 'JLog::' . strtoupper($p); if (!defined($const)) { continue; } $priority |= constant($const); } // Split into an array at any character other than alphabet, numbers, _, ., or - $categories = array_filter(preg_split('/[^A-Z0-9_\\.-]/i', $this->params->get('log_categories', ''))); $mode = $this->params->get('log_category_mode', 0); JLog::addLogger(array('logger' => 'callback', 'callback' => array($this, 'logger')), $priority, $categories, $mode); } // Prepare disconnect handler for SQL profiling. $db = JFactory::getDbo(); $db->addDisconnectHandler(array($this, 'mysqlDisconnectHandler')); // Log deprecated class aliases foreach (JLoader::getDeprecatedAliases() as $deprecation) { JLog::add(sprintf('%1$s has been aliased to %2$s and the former class name is deprecated. The alias will be removed in %3$s.', $deprecation['old'], $deprecation['new'], $deprecation['version']), JLog::WARNING, 'deprecated'); } }
/** * This is where we delete any authentication cookie when a user logs out * * @param array $options Array holding options (length, timeToExpiration) * * @return boolean True on success * * @since 3.2 */ public function onUserAfterLogout($options) { $rememberArray = JUserHelper::getRememberCookieData(); // There are no cookies to delete. if ($rememberArray === false) { return true; } list($privateKey, $series, $cookieName) = $rememberArray; // Remove the record from the database $query = $this->db->getQuery(true); $query->delete('#__user_keys')->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['username'])); $this->db->setQuery($query)->execute(); // Destroy the cookie $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path'), $this->app->get('cookie_domain')); return true; }
/** * Counts the number of items resulting from a given database query. * * @param JDatabaseQuery $query Query whose results should be counted. * * @throws Exception * @return void */ public function countItems($query) { $cloned = clone $query; $cloned->clear('select')->select('COUNT(*)'); $this->db->setQuery($cloned); $count = $this->db->loadResult(); $offset = isset($this->list['offset']) ? $this->list['offset'] : $this->getState()->get('list.' . $this->prefix . '.offset', 0); $offset = $this->app->input->getInt('limitstart', $offset); $this->getState()->set('list.' . $this->prefix . 'offset', $offset); $defaultLimit = $this->app->get('list_limit'); $limit = isset($this->list['limit']) ? $this->list['limit'] : $this->getState()->get('list.' . $this->prefix . '.limit', $defaultLimit); $this->pagination = new JPagination($count, $offset, $limit, '', $this->app); if ($query instanceof JDatabaseQueryLimitable) { $query->setLimit($limit, $offset); } }
/** * Constructor. * * @param object &$subject The object to observe. * @param array $config An optional associative array of configuration settings. * * @since 1.5 */ public function __construct(&$subject, $config) { parent::__construct($subject, $config); // Log the deprecated API. if ($this->params->get('log-deprecated')) { JLog::addLogger(array('text_file' => 'deprecated.php'), JLog::ALL, array('deprecated')); } // Get the application if not done by JPlugin. This may happen during upgrades from Joomla 2.5. if (!$this->app) { $this->app = JFactory::getApplication(); } $this->debugLang = $this->app->get('debug_lang'); // Skip the plugin if debug is off if ($this->debugLang == '0' && $this->app->get('debug') == '0') { return; } // Only if debugging or language debug is enabled. if (JDEBUG || $this->debugLang) { JFactory::getConfig()->set('gzip', 0); ob_start(); ob_implicit_flush(false); } $this->linkFormat = ini_get('xdebug.file_link_format'); if ($this->params->get('logs', 1)) { $priority = 0; foreach ($this->params->get('log_priorities', array()) as $p) { $const = 'JLog::' . strtoupper($p); if (!defined($const)) { continue; } $priority |= constant($const); } // Split into an array at any character other than alphabet, numbers, _, ., or - $categories = array_filter(preg_split('/[^A-Z0-9_\\.-]/i', $this->params->get('log_categories', ''))); $mode = $this->params->get('log_category_mode', 0); JLog::addLogger(array('logger' => 'callback', 'callback' => array($this, 'logger')), $priority, $categories, $mode); } // Prepare disconnect handler for SQL profiling. $db = JFactory::getDbo(); $db->addDisconnectHandler(array($this, 'mysqlDisconnectHandler')); }
/** * Utility method to act on a user after it has been saved. * * This method sends a registration email to new users created in the backend. * * @param array $user Holds the new user data. * @param boolean $isnew True if a new user is stored. * @param boolean $success True if user was successfully stored in the database. * @param string $msg Message. * * @return void * * @since 1.6 */ public function onUserAfterSave($user, $isnew, $success, $msg) { $mail_to_user = $this->params->get('mail_to_user', 1); if ($isnew) { // TODO: Suck in the frontend registration emails here as well. Job for a rainy day. if ($this->app->isAdmin()) { if ($mail_to_user) { $lang = JFactory::getLanguage(); $defaultLocale = $lang->getTag(); /** * Look for user language. Priority: * 1. User frontend language * 2. User backend language */ $userParams = new JRegistry($user['params']); $userLocale = $userParams->get('language', $userParams->get('admin_language', $defaultLocale)); if ($userLocale != $defaultLocale) { $lang->setLanguage($userLocale); } $lang->load('plg_user_joomla', JPATH_ADMINISTRATOR); // Compute the mail subject. $emailSubject = JText::sprintf('PLG_USER_JOOMLA_NEW_USER_EMAIL_SUBJECT', $user['name'], $config = $this->app->get('sitename')); // Compute the mail body. $emailBody = JText::sprintf('PLG_USER_JOOMLA_NEW_USER_EMAIL_BODY', $user['name'], $this->app->get('sitename'), JUri::root(), $user['username'], $user['password_clear']); // Assemble the email data...the sexy way! $mail = JFactory::getMailer()->setSender(array($this->app->get('mailfrom'), $this->app->get('fromname')))->addRecipient($user['email'])->setSubject($emailSubject)->setBody($emailBody); // Set application language back to default if we changed it if ($userLocale != $defaultLocale) { $lang->setLanguage($defaultLocale); } if (!$mail->Send()) { $this->app->enqueueMessage(JText::_('JERROR_SENDING_EMAIL'), 'warning'); } } } } else { // Existing user - nothing to do...yet. } }
/** * Method to handle any login logic and report back to the subject. * * @param array $user Holds the user data. * @param array $options Array holding options (remember, autoregister, group). * * @return boolean True on success. * * @since 1.5 */ public function onUserLogin($user, $options = array()) { $menu = $this->app->getMenu(); if ($this->app->isSite() && $this->params->get('automatic_change', 1)) { // Load associations. $assoc = JLanguageAssociations::isEnabled(); if ($assoc) { $active = $menu->getActive(); if ($active) { $associations = MenusHelper::getAssociations($active->id); } } $lang_code = $user['language']; if (empty($lang_code)) { $lang_code = $this->default_lang; } if ($lang_code != $this->default_lang) { // Change language. $this->default_lang = $lang_code; // Create a cookie. $cookie_domain = $this->app->get('cookie_domain', ''); $cookie_path = $this->app->get('cookie_path', '/'); setcookie(JApplicationHelper::getHash('language'), $lang_code, $this->getLangCookieTime(), $cookie_path, $cookie_domain); // Change the language code. JFactory::getLanguage()->setLanguage($lang_code); // Change the redirect (language has changed). if (isset($associations[$lang_code]) && $menu->getItem($associations[$lang_code])) { $itemid = $associations[$lang_code]; $this->app->setUserState('users.login.form.return', 'index.php?&Itemid=' . $itemid); } else { JLoader::register('MultilangstatusHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/multilangstatus.php'); $homes = MultilangstatusHelper::getHomepages(); $itemid = isset($homes[$lang_code]) ? $homes[$lang_code]->id : $homes['*']->id; $this->app->setUserState('users.login.form.return', 'index.php?&Itemid=' . $itemid); } } } }
/** * This method should handle any logout logic and report back to the subject * * @param array $user Holds the user data. * @param array $options Array holding options (client, ...). * * @return bool True on success * * @since 1.5 */ public function onUserLogout($user, $options = array()) { $my = JFactory::getUser(); $session = JFactory::getSession(); // Make sure we're a valid user first if ($user['id'] == 0 && !$my->get('tmp_user')) { return true; } $sharedSessions = $this->app->get('shared_session', '0'); // Check to see if we're deleting the current session if ($my->id == $user['id'] && (!$sharedSessions && $options['clientid'] == $this->app->getClientId())) { // Hit the user last visit field $my->setLastVisit(); // Destroy the php session for this user $session->destroy(); } // Enable / Disable Forcing logout all users with same userid $forceLogout = $this->params->get('forceLogout', 1); if ($forceLogout) { $query = $this->db->getQuery(true)->delete($this->db->quoteName('#__session'))->where($this->db->quoteName('userid') . ' = ' . (int) $user['id']); if (!$sharedSessions) { $query->where($this->db->quoteName('client_id') . ' = ' . (int) $options['clientid']); } try { $this->db->setQuery($query)->execute(); } catch (RuntimeException $e) { return false; } } // Delete "user state" cookie used for reverse caching proxies like Varnish, Nginx etc. $cookie_domain = $this->app->get('cookie_domain', ''); $cookie_path = $this->app->get('cookie_path', '/'); if ($this->app->isSite()) { $this->app->input->cookie->set("joomla_user_state", "", time() - 86400, $cookie_path, $cookie_domain, 0); } return true; }
/** * Convert the site URL to fit to the HTTP request. * * @return void */ public function onAfterRender() { if (!$this->app->isSite() || $this->app->get('sef', '0') == '0') { return; } // Replace src links. $base = JUri::base(true) . '/'; $buffer = $this->app->getBody(); // Replace index.php URI by SEF URI. if (strpos($buffer, 'href="index.php?') !== false) { preg_match_all('#href="index.php\\?([^"]+)"#m', $buffer, $matches); foreach ($matches[1] as $urlQueryString) { $buffer = str_replace('href="index.php?' . $urlQueryString . '"', 'href="' . JRoute::_('index.php?' . $urlQueryString) . '"', $buffer); } $this->checkBuffer($buffer); } // Check for all unknown protocals (a protocol must contain at least one alpahnumeric character followed by a ":"). $protocols = '[a-zA-Z0-9\\-]+:'; $attributes = array('href=', 'src=', 'poster='); foreach ($attributes as $attribute) { if (strpos($buffer, $attribute) !== false) { $regex = '#\\s+' . $attribute . '"(?!/|' . $protocols . '|\\#|\')([^"]*)"#m'; $buffer = preg_replace($regex, ' ' . $attribute . '"' . $base . '$1"', $buffer); $this->checkBuffer($buffer); } } // Replace all unknown protocals in javascript window open events. if (strpos($buffer, 'window.open(') !== false) { $regex = '#onclick="window.open\\(\'(?!/|' . $protocols . '|\\#)([^/]+[^\']*?\')#m'; $buffer = preg_replace($regex, 'onclick="window.open(\'' . $base . '$1', $buffer); $this->checkBuffer($buffer); } // Replace all unknown protocols in onmouseover and onmouseout attributes. $attributes = array('onmouseover=', 'onmouseout='); foreach ($attributes as $attribute) { if (strpos($buffer, $attribute) !== false) { $regex = '#' . $attribute . '"this.src=([\']+)(?!/|' . $protocols . '|\\#|\')([^"]+)"#m'; $buffer = preg_replace($regex, $attribute . '"this.src=$1' . $base . '$2"', $buffer); $this->checkBuffer($buffer); } } // Replace all unknown protocols in CSS background image. if (strpos($buffer, 'style=') !== false) { $regex = '#style=\\s*[\'\\"](.*):\\s*url\\s*\\([\'\\"]?(?!/|' . $protocols . '|\\#)([^\\)\'\\"]+)[\'\\"]?\\)#m'; $buffer = preg_replace($regex, 'style="$1: url(\'' . $base . '$2$3\')', $buffer); $this->checkBuffer($buffer); } // Replace all unknown protocols in OBJECT param tag. if (strpos($buffer, '<param') !== false) { // OBJECT <param name="xx", value="yy"> -- fix it only inside the <param> tag. $regex = '#(<param\\s+)name\\s*=\\s*"(movie|src|url)"[^>]\\s*value\\s*=\\s*"(?!/|' . $protocols . '|\\#|\')([^"]*)"#m'; $buffer = preg_replace($regex, '$1name="$2" value="' . $base . '$3"', $buffer); $this->checkBuffer($buffer); // OBJECT <param value="xx", name="yy"> -- fix it only inside the <param> tag. $regex = '#(<param\\s+[^>]*)value\\s*=\\s*"(?!/|' . $protocols . '|\\#|\')([^"]*)"\\s*name\\s*=\\s*"(movie|src|url)"#m'; $buffer = preg_replace($regex, '<param value="' . $base . '$2" name="$3"', $buffer); $this->checkBuffer($buffer); } // Replace all unknown protocols in OBJECT tag. if (strpos($buffer, '<object') !== false) { $regex = '#(<object\\s+[^>]*)data\\s*=\\s*"(?!/|' . $protocols . '|\\#|\')([^"]*)"#m'; $buffer = preg_replace($regex, '$1data="' . $base . '$2"', $buffer); $this->checkBuffer($buffer); } // Use the replaced HTML body. $this->app->setBody($buffer); }
/** * Function to convert a sef route to an internal URI * * @param JUri &$uri The sef URI * * @return string Internal URI * * @since 3.2 * @deprecated 4.0 Attach your logic as rule to the main parse stage */ protected function parseSefRoute(&$uri) { $route = $uri->getPath(); // Remove the suffix if ($this->app->get('sef_suffix')) { if ($suffix = pathinfo($route, PATHINFO_EXTENSION)) { $route = str_replace('.' . $suffix, '', $route); } } // Get the variables from the uri $vars = $uri->getQuery(true); // Handle an empty URL (special case) if (empty($route)) { // If route is empty AND option is set in the query, assume it's non-sef url, and parse apropriately if (isset($vars['option']) || isset($vars['Itemid'])) { return $this->parseRawRoute($uri); } $item = $this->menu->getDefault($this->app->getLanguage()->getTag()); // If user not allowed to see default menu item then avoid notices if (is_object($item)) { // Set the information in the request $vars = $item->query; // Get the itemid $vars['Itemid'] = $item->id; // Set the active menu item $this->menu->setActive($vars['Itemid']); $this->setVars($vars); } return $vars; } // Parse the application route $segments = explode('/', $route); if (count($segments) > 1 && $segments[0] == 'component') { $vars['option'] = 'com_' . $segments[1]; $vars['Itemid'] = null; $route = implode('/', array_slice($segments, 2)); } else { // Get menu items. $items = $this->menu->getMenu(); $found = false; $route_lowercase = JString::strtolower($route); $lang_tag = $this->app->getLanguage()->getTag(); // Iterate through all items and check route matches. foreach ($items as $item) { if ($item->route && JString::strpos($route_lowercase . '/', $item->route . '/') === 0 && $item->type != 'menulink') { // Usual method for non-multilingual site. if (!$this->app->getLanguageFilter()) { // Exact route match. We can break iteration because exact item was found. if ($item->route == $route_lowercase) { $found = $item; break; } // Partial route match. Item with highest level takes priority. if (!$found || $found->level < $item->level) { $found = $item; } } elseif ($item->language == '*' || $item->language == $lang_tag) { // Exact route match. if ($item->route == $route_lowercase) { $found = $item; // Break iteration only if language is matched. if ($item->language == $lang_tag) { break; } } // Partial route match. Item with highest level or same language takes priority. if (!$found || $found->level < $item->level || $item->language == $lang_tag) { $found = $item; } } } } if (!$found) { $found = $this->menu->getDefault($lang_tag); } else { $route = substr($route, strlen($found->route)); if ($route) { $route = substr($route, 1); } } if ($found) { $vars['Itemid'] = $found->id; $vars['option'] = $found->component; } } // Set the active menu item if (isset($vars['Itemid'])) { $this->menu->setActive($vars['Itemid']); } // Set the variables $this->setVars($vars); // Parse the component route if (!empty($route) && isset($this->_vars['option'])) { $segments = explode('/', $route); if (empty($segments[0])) { array_shift($segments); } // Handle component route $component = preg_replace('/[^A-Z0-9_\\.-]/i', '', $this->_vars['option']); if (count($segments)) { $crouter = $this->getComponentRouter($component); $vars = $crouter->parse($segments); $this->setVars($vars); } } else { // Set active menu item if ($item = $this->menu->getActive()) { $vars = $item->query; } } return $vars; }
/** * Convert a prefix__tablename to #__tablename * * @return string table name */ public function getGenericTableName() { $table = $this->getTable(); return str_replace($this->app->get('dbprefix'), '#__', $table->db_table_name); }