diff --git a/application/applicationcontext.class.inc.php b/application/applicationcontext.class.inc.php index 350619cb1..33ab78e83 100644 --- a/application/applicationcontext.class.inc.php +++ b/application/applicationcontext.class.inc.php @@ -24,6 +24,43 @@ */ require_once(APPROOT."/application/utils.inc.php"); + +/** + * Interface for directing end-users to the relevant application + */ +interface iDBObjectURLMaker +{ + public static function MakeObjectURL($sClass, $iId); +} + +/** + * Direct end-users to the standard iTop application: UI.php + */ +class iTopStandardURLMaker implements iDBObjectURLMaker +{ + public static function MakeObjectURL($sClass, $iId) + { + $sPage = DBObject::ComputeStandardUIPage($sClass); + $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot(); + $sUrl = "{$sAbsoluteUrl}pages/$sPage?operation=details&class=$sClass&id=$iId"; + return $sUrl; + } +} + +/** + * Direct end-users to the standard Portal application + */ +class PortalURLMaker implements iDBObjectURLMaker +{ + public static function MakeObjectURL($sClass, $iId) + { + $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot(); + $sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class=$sClass&id=$iId"; + return $sUrl; + } +} + + /** * Helper class to store and manipulate the parameters that make the application's context * @@ -166,5 +203,72 @@ class ApplicationContext unset($this->aValues[$sParamName]); } } + + static $m_sUrlMakerClass = null; + + /** + * Set the current application url provider + * @param sClass string Class implementing iDBObjectURLMaker + * @return void + */ + public static function SetUrlMakerClass($sClass = 'iTopStandardURLMaker') + { + $sPrevious = self::GetUrlMakerClass(); + + self::$m_sUrlMakerClass = $sClass; + $_SESSION['UrlMakerClass'] = $sClass; + + return $sPrevious; + } + + /** + * Get the current application url provider + * @return string the name of the class + */ + public static function GetUrlMakerClass() + { + if (is_null(self::$m_sUrlMakerClass)) + { + if (isset($_SESSION['UrlMakerClass'])) + { + self::$m_sUrlMakerClass = $_SESSION['UrlMakerClass']; + } + else + { + self::$m_sUrlMakerClass = 'iTopStandardURLMaker'; + } + } + return self::$m_sUrlMakerClass; + } + + /** + * Get the current application url provider + * @return string the name of the class + */ + public static function MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass = null, $bWithNavigationContext = true) + { + $oAppContext = new ApplicationContext(); + + if (is_null($sUrlMakerClass)) + { + $sUrlMakerClass = self::GetUrlMakerClass(); + } + $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey); + if (strlen($sUrl) > 0) + { + if ($bWithNavigationContext) + { + return $sUrl."&".$oAppContext->GetForLink(); + } + else + { + return $sUrl; + } + } + else + { + return ''; + } + } } ?> diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 6f044f6c8..ad45c6724 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -999,8 +999,9 @@ class MenuBlock extends DisplayBlock $sClass = $this->m_oFilter->GetClass(); $oSet = new CMDBObjectSet($this->m_oFilter); $sFilter = $this->m_oFilter->serialize(); + $sFilterDesc = $this->m_oFilter->ToOql(); $aActions = array(); - $sUIPage = cmdbAbstractObject::ComputeUIPage($sClass); + $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass); // 1:n links, populate the target object as a default value when creating a new linked object if (isset($aExtraParams['target_attr'])) { @@ -1032,7 +1033,6 @@ class MenuBlock extends DisplayBlock // Just one object in the set, possible actions are "new / clone / modify and delete" if (!isset($aExtraParams['link_attr'])) { - $sUrl = utils::GetAbsoluteUrl(false); if ($bIsModifyAllowed) { $aActions[] = array ('label' => Dict::S('UI:Menu:Modify'), 'url' => "../pages/$sUIPage?operation=modify&class=$sClass&id=$id&$sContext#"); } if ($bIsModifyAllowed) { $aActions[] = array ('label' => Dict::S('UI:Menu:New'), 'url' => "../pages/$sUIPage?operation=new&class=$sClass&$sContext{$sDefault}"); } if ($bIsDeleteAllowed) { $aActions[] = array ('label' => Dict::S('UI:Menu:Delete'), 'url' => "../pages/$sUIPage?operation=delete&class=$sClass&id=$id&$sContext"); } @@ -1068,7 +1068,8 @@ class MenuBlock extends DisplayBlock } $this->AddMenuSeparator($aActions); // Static menus: Email this page & CSV Export - $aActions[] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=".$oObj->GetName()."&body=".urlencode("$sUrl?operation=details&class=$sClass&id=$id&$sContext")); + $sUrl = ApplicationContext::MakeObjectUrl($sClass, $id); + $aActions[] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=".$oObj->GetName()."&body=".urlencode($sUrl)); $aActions[] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "../pages/$sUIPage?operation=search&filter=$sFilter&format=csv&$sContext"); } else @@ -1112,7 +1113,6 @@ class MenuBlock extends DisplayBlock else { // many objects in the set, possible actions are: new / modify all / delete all - $sUrl = utils::GetAbsoluteUrl(); if ($bIsModifyAllowed) { $aActions[] = array ('label' => Dict::S('UI:Menu:New'), 'url' => "../pages/$sUIPage?operation=new&class=$sClass&$sContext{$sDefault}"); } if ($bIsBulkModifyAllowed) { $aActions[] = array ('label' => Dict::S('UI:Menu:ModifyAll'), 'url' => "../pages/$sUIPage?operation=select_for_modify_all&class=$sClass&filter=$sFilter&sContext"); } if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => Dict::S('UI:Menu:BulkDelete'), 'url' => "../pages/$sUIPage?operation=select_for_deletion&filter=$sFilter&$sContext"); } @@ -1157,7 +1157,8 @@ class MenuBlock extends DisplayBlock } } $this->AddMenuSeparator($aActions); - $aActions[] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=".$oSet->GetFilter()->__DescribeHTML()."&body=".urlencode("$sUrl?operation=search&filter=$sFilter&$sContext")); + $sUrl = utils::GetAbsoluteUrlAppRoot(); + $aActions[] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=$sFilterDesc&body=".urlencode("{$sUrl}pages/$sUIPage?operation=search&filter=$sFilter&$sContext")); $aActions[] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "../pages/$sUIPage?operation=search&filter=$sFilter&format=csv&$sContext"); } $this->AddMenuSeparator($aActions); diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index 16595b027..c33c77bd0 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -39,11 +39,14 @@ class iTopWebPage extends NiceWebPage private $m_sMessage; private $m_sInitScript; - public function __construct($sTitle) - { - parent::__construct($sTitle); - $this->m_sCurrentTabContainer = ''; - $this->m_sCurrentTab = ''; + public function __construct($sTitle) + { + parent::__construct($sTitle); + + ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker'); + + $this->m_sCurrentTabContainer = ''; + $this->m_sCurrentTab = ''; $this->m_aTabs = array(); $this->m_sMenu = ""; $this->m_sMessage = ''; diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index b54d182ae..ed9d40adb 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -223,10 +223,8 @@ EOF { if (self::SecureConnectionRequired() && !self::IsConnectionSecure()) { - // Non secured URL... redirect to a secured one - $sUrl = Utils::GetAbsoluteUrl(true /* query string */, true /* force HTTPS */); - header("Location: $sUrl"); - exit; + // Non secured URL... request for a secure connection + throw new Exception('Secure connection required!'); } $aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes(); diff --git a/application/utils.inc.php b/application/utils.inc.php index a75f238a6..e5b9dc228 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -359,7 +359,7 @@ class utils { // Build an absolute URL to this page on this server/port $sServerName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : ''; - if (MetaModel::GetConfig()->GetSecureConnectionRequired() || MetaModel::GetConfig()->GetHttpsHyperlinks()) + if (MetaModel::GetConfig()->GetSecureConnectionRequired()) { // If a secure connection is required, or if the URL is requested to start with HTTPS // then any URL must start with https ! @@ -413,18 +413,6 @@ class utils return $sUrl; } - /** - * Returns the absolute URL PATH of the current page - * @param $bForceHTTPS bool True to force HTTPS, false otherwise - * @return string The absolute URL to the current page - */ - static public function GetAbsoluteUrlPath($bForceHTTPS = false) - { - $sAbsoluteUrl = self::GetAbsoluteUrl(false, $bForceHTTPS); // False => Don't get the query string - $sAbsoluteUrl = substr($sAbsoluteUrl, 0, 1+strrpos($sAbsoluteUrl, '/')); // remove the current page, keep just the path, up to the last / - return $sAbsoluteUrl; - } - /** * Returns the absolute URL to the server's root path * @param $sCurrentRelativePath string NO MORE USED, kept for backward compatibility only ! @@ -433,7 +421,48 @@ class utils */ static public function GetAbsoluteUrlAppRoot($sCurrentRelativePathUNUSED = '', $bForceHTTPS = false) { - $sAbsoluteUrl = self::GetAbsoluteUrl(false, $bForceHTTPS); // False => Don't get the query string + return MetaModel::GetConfig()->Get('app_root_url'); + } + + static public function GetDefaultUrlAppRoot() + { + // Build an absolute URL to this page on this server/port + $sServerName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : ''; + $sProtocol = (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!="off")) ? 'https' : 'http'; + $iPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80; + if ($sProtocol == 'http') + { + $sPort = ($iPort == 80) ? '' : ':'.$iPort; + } + else + { + $sPort = ($iPort == 443) ? '' : ':'.$iPort; + } + // $_SERVER['REQUEST_URI'] is empty when running on IIS + // Let's use Ivan Tcholakov's fix (found on www.dokeos.com) + if (!empty($_SERVER['REQUEST_URI'])) + { + $sPath = $_SERVER['REQUEST_URI']; + } + else + { + $sPath = $_SERVER['SCRIPT_NAME']; + if (!empty($_SERVER['QUERY_STRING'])) + { + $sPath .= '?'.$_SERVER['QUERY_STRING']; + } + $_SERVER['REQUEST_URI'] = $sPath; + } + $sPath = $_SERVER['REQUEST_URI']; + + // remove all the parameters from the query string + $iQuestionMarkPos = strpos($sPath, '?'); + if ($iQuestionMarkPos !== false) + { + $sPath = substr($sPath, 0, $iQuestionMarkPos); + } + $sAbsoluteUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}"; + $sCurrentScript = realpath($_SERVER['SCRIPT_FILENAME']); $sCurrentScript = str_replace('\\', '/', $sCurrentScript); // canonical path $sAppRoot = str_replace('\\', '/', APPROOT); // canonical path @@ -442,13 +471,13 @@ class utils $sAppRootPos = strpos($sAbsoluteUrl, $sCurrentRelativePath); if ($sAppRootPos !== false) { - $sAbsoluteUrl = substr($sAbsoluteUrl, 0, $sAppRootPos); // remove the current page and path + $sAppRootUrl = substr($sAbsoluteUrl, 0, $sAppRootPos); // remove the current page and path } else { throw new Exception("Failed to determine application root path $sAbsoluteUrl ($sCurrentRelativePath) APPROOT:'$sAppRoot'"); } - return $sAbsoluteUrl; + return $sAppRootUrl; } /** diff --git a/core/action.class.inc.php b/core/action.class.inc.php index 4da8c7d3b..7141aee7e 100644 --- a/core/action.class.inc.php +++ b/core/action.class.inc.php @@ -274,25 +274,33 @@ class ActionEmail extends ActionNotification protected function _DoExecute($oTrigger, $aContextArgs, &$oLog) { - $this->m_iRecipients = 0; - $this->m_aMailErrors = array(); - $bRes = false; // until we do succeed in sending the email - - // Determine recicipients - // - $sTo = $this->FindRecipients('to', $aContextArgs); - $sCC = $this->FindRecipients('cc', $aContextArgs); - $sBCC = $this->FindRecipients('bcc', $aContextArgs); - - $sFrom = $this->Get('from'); - $sReplyTo = $this->Get('reply_to'); - - $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs); - $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs); - - $oObj = $aContextArgs['this->object()']; - $sServerIP = $_SERVER['SERVER_ADDR']; //gethostbyname(gethostname()); - $sReference = 'GetKey().'@'.$sServerIP.'>'; + $sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass(); + try + { + $this->m_iRecipients = 0; + $this->m_aMailErrors = array(); + $bRes = false; // until we do succeed in sending the email + + // Determine recicipients + // + $sTo = $this->FindRecipients('to', $aContextArgs); + $sCC = $this->FindRecipients('cc', $aContextArgs); + $sBCC = $this->FindRecipients('bcc', $aContextArgs); + + $sFrom = $this->Get('from'); + $sReplyTo = $this->Get('reply_to'); + + $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs); + $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs); + + $oObj = $aContextArgs['this->object()']; + $sReference = 'GetKey().'>'; + } + catch(Exception $e) + { + ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker); + throw $e; + } if (!is_null($oLog)) { diff --git a/core/config.class.inc.php b/core/config.class.inc.php index a7e95ca7c..dbd4590f9 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -58,7 +58,6 @@ define ('DEFAULT_MAX_DISPLAY_LIMIT', 15); define ('DEFAULT_STANDARD_RELOAD_INTERVAL', 5*60); define ('DEFAULT_FAST_RELOAD_INTERVAL', 1*60); define ('DEFAULT_SECURE_CONNECTION_REQUIRED', false); -define ('DEFAULT_HTTPS_HYPERLINKS', false); define ('DEFAULT_ALLOWED_LOGIN_TYPES', 'form|basic|external'); define ('DEFAULT_EXT_AUTH_VARIABLE', '$_SERVER[\'REMOTE_USER\']'); define ('DEFAULT_ENCRYPTION_KEY', '@iT0pEncr1pti0n!'); // We'll use a random value, later... @@ -85,6 +84,14 @@ class Config // New way to store the settings ! // protected $m_aSettings = array( + 'app_root_url' => array( + 'type' => 'string', + 'description' => 'Root URL used for navigating within the application, or from an email to the application', + 'default' => '', + 'value' => '', + 'source_of_value' => '', + 'show_in_conf_sample' => true, + ), 'skip_check_to_write' => array( 'type' => 'bool', 'description' => 'Disable data format and integrity checks to boost up data load (insert or update)', @@ -451,13 +458,6 @@ class Config */ protected $m_bSecureConnectionRequired; - /** - * @var boolean Forces iTop to output hyperlinks starting with https:// even - * if the current page is not using https. This can be useful when - * the application runs behind a SSL gateway - */ - protected $m_bHttpsHyperlinks; - /** * @var string Langage code, default if the user language is undefined */ @@ -559,7 +559,6 @@ class Config $this->m_iStandardReloadInterval = DEFAULT_STANDARD_RELOAD_INTERVAL; $this->m_iFastReloadInterval = DEFAULT_FAST_RELOAD_INTERVAL; $this->m_bSecureConnectionRequired = DEFAULT_SECURE_CONNECTION_REQUIRED; - $this->m_bHttpsHyperlinks = DEFAULT_HTTPS_HYPERLINKS; $this->m_sDefaultLanguage = 'EN US'; $this->m_sAllowedLoginTypes = DEFAULT_ALLOWED_LOGIN_TYPES; $this->m_sExtAuthVariable = DEFAULT_EXT_AUTH_VARIABLE; @@ -573,6 +572,18 @@ class Config $this->Load($sConfigFile); $this->Verify(); } + + // Application root url: set a default value, then normalize it + $sAppRootUrl = trim($this->Get('app_root_url')); + if (strlen($sAppRootUrl) == 0) + { + $sAppRootUrl = utils::GetDefaultUrlAppRoot(); + } + if (substr($sAppRootUrl, -1, 1) != '/') + { + $sAppRootUrl .= '/'; + } + $this->Set('app_root_url', $sAppRootUrl); } protected function CheckFile($sPurpose, $sFileName) @@ -681,7 +692,6 @@ class Config $this->m_iStandardReloadInterval = isset($MySettings['standard_reload_interval']) ? trim($MySettings['standard_reload_interval']) : DEFAULT_STANDARD_RELOAD_INTERVAL; $this->m_iFastReloadInterval = isset($MySettings['fast_reload_interval']) ? trim($MySettings['fast_reload_interval']) : DEFAULT_FAST_RELOAD_INTERVAL; $this->m_bSecureConnectionRequired = isset($MySettings['secure_connection_required']) ? (bool) trim($MySettings['secure_connection_required']) : DEFAULT_SECURE_CONNECTION_REQUIRED; - $this->m_bHttpsHyperlinks = isset($MySettings['https_hyperlinks']) ? (bool) trim($MySettings['https_hyperlinks']) : DEFAULT_HTTPS_HYPERLINKS; $this->m_aModuleSettings = isset($MyModuleSettings) ? $MyModuleSettings : array(); @@ -857,11 +867,6 @@ class Config return $this->m_bSecureConnectionRequired; } - public function GetHttpsHyperlinks() - { - return $this->m_bHttpsHyperlinks; - } - public function GetDefaultLanguage() { return $this->m_sDefaultLanguage; @@ -967,11 +972,6 @@ class Config $this->m_bSecureConnectionRequired = $bSecureConnectionRequired; } - public function SetHttpsHyperlinks($bHttpsHyperlinks) - { - $this->m_bHttpsHyperlinks = $bHttpsHyperlinks; - } - public function SetDefaultLanguage($sLanguageCode) { $this->m_sDefaultLanguage = $sLanguageCode; @@ -1037,7 +1037,6 @@ class Config $aSettings['standard_reload_interval'] = $this->m_iStandardReloadInterval; $aSettings['fast_reload_interval'] = $this->m_iFastReloadInterval; $aSettings['secure_connection_required'] = $this->m_bSecureConnectionRequired; - $aSettings['https_hyperlinks'] = $this->m_bHttpsHyperlinks; $aSettings['default_language'] = $this->m_sDefaultLanguage; $aSettings['allowed_login_types'] = $this->m_sAllowedLoginTypes; $aSettings['encryption_key'] = $this->m_sEncryptionKey; @@ -1132,7 +1131,6 @@ class Config fwrite($hFile, "\t'standard_reload_interval' => {$this->m_iStandardReloadInterval},\n"); fwrite($hFile, "\t'fast_reload_interval' => {$this->m_iFastReloadInterval},\n"); fwrite($hFile, "\t'secure_connection_required' => ".($this->m_bSecureConnectionRequired ? 'true' : 'false').",\n"); - fwrite($hFile, "\t'https_hyperlinks' => ".($this->m_bHttpsHyperlinks ? 'true' : 'false').",\n"); fwrite($hFile, "\t'default_language' => '{$this->m_sDefaultLanguage}',\n"); fwrite($hFile, "\t'allowed_login_types' => '{$this->m_sAllowedLoginTypes}',\n"); fwrite($hFile, "\t'encryption_key' => '{$this->m_sEncryptionKey}',\n"); diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 8720da9ba..2bbfa265d 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -528,14 +528,10 @@ abstract class DBObject return $oAtt->GetAsCSV($this->GetOriginal($sAttCode), $sSeparator, $sTextQualifier, $this); } - protected static function MakeHyperLink($sObjClass, $sObjKey, $sLabel = '') + protected static function MakeHyperLink($sObjClass, $sObjKey, $sLabel = '', $sUrlMakerClass = null, $bWithNavigationContext = true) { if ($sObjKey <= 0) return ''.Dict::S('UI:UndefinedObject').''; // Objects built in memory have negative IDs - $oAppContext = new ApplicationContext(); - $sPage = self::ComputeUIPage($sObjClass); - $sAbsoluteUrl = utils::GetAbsoluteUrlPath(); - // Safety net // if (empty($sLabel)) @@ -547,25 +543,23 @@ abstract class DBObject //$sLabel = MetaModel::GetName($sObjClass)." #$sObjKey"; } $sHint = MetaModel::GetName($sObjClass)."::$sObjKey"; - return "GetForLink()."\" title=\"$sHint\">$sLabel"; + $sUrl = ApplicationContext::MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass, $bWithNavigationContext); + if (strlen($sUrl) > 0) + { + return "$sLabel"; + } + else + { + return $sLabel; + } } - public function GetHyperlink() + public function GetHyperlink($sUrlMakerClass = null, $bWithNavigationContext = true) { - if ($this->IsNew()) return ''.Dict::S('UI:UndefinedObject').''; // Objects built in memory have negative IDs - - $oAppContext = new ApplicationContext(); - $sPage = $this->GetUIPage(); - $sAbsoluteUrl = utils::GetAbsoluteUrlPath(); - $sObjClass = get_class($this); - $sObjKey = $this->GetKey(); - - $sLabel = $this->GetName(); - $sHint = MetaModel::GetName($sObjClass)."::$sObjKey"; - return "GetForLink()."\" title=\"$sHint\">$sLabel"; + return self::MakeHyperLink(get_class($this), $this->GetKey(), $this->GetName(), $sUrlMakerClass, $bWithNavigationContext); } - public static function ComputeUIPage($sClass) + public static function ComputeStandardUIPage($sClass) { static $aUIPagesCache = array(); // Cache to store the php page used to display each class of object if (!isset($aUIPagesCache[$sClass])) @@ -1464,10 +1458,8 @@ abstract class DBObject $aScalarArgs[$sArgName] = $this->GetKey(); $aScalarArgs[$sArgName.'->id'] = $this->GetKey(); $aScalarArgs[$sArgName.'->object()'] = $this; - $aScalarArgs[$sArgName.'->hyperlink()'] = $this->GetHyperlink(); - // #@# Prototype for a user portal - to be dehardcoded later - $sToPortal = utils::GetAbsoluteUrlPath().'../portal/index.php?operation=details&id='.$this->GetKey(); - $aScalarArgs[$sArgName.'->hyperlink(portal)'] = ''.$this->GetName().''; + $aScalarArgs[$sArgName.'->hyperlink()'] = $this->GetHyperlink('iTopStandardURLMaker', false); + $aScalarArgs[$sArgName.'->hyperlink(portal)'] = $this->GetHyperlink('PortalURLMaker', false); $aScalarArgs[$sArgName.'->name()'] = $this->GetName(); $sClass = get_class($this); diff --git a/pages/logoff.php b/pages/logoff.php index 078d11668..1125c9f84 100644 --- a/pages/logoff.php +++ b/pages/logoff.php @@ -28,7 +28,7 @@ require_once(APPROOT.'/application/loginwebpage.class.inc.php'); session_name(MetaModel::GetConfig()->Get('session_name')); session_start(); $bPortal = utils::ReadParam('portal', false); -$sUrl = utils::GetAbsoluteUrlAppRoot('pages/logoff.php'); +$sUrl = utils::GetAbsoluteUrlAppRoot(); if ($bPortal) { $sUrl .= 'portal/'; diff --git a/pages/xml.navigator.php b/pages/xml.navigator.php index 38391fb23..c3e500278 100755 --- a/pages/xml.navigator.php +++ b/pages/xml.navigator.php @@ -97,10 +97,8 @@ function GetRelatedObjectsAsXml(DBObject $oObj, $sRelationName, &$oLinks, &$oXml function BuildIconPath($sIconPath) { - $sFullURL = utils::GetAbsoluteURL(false, false); - $iLastSlashPos = strrpos($sFullURL, '/'); - $sFullURLPath = substr($sFullURL, 0, 1 + $iLastSlashPos); - return $sFullURLPath.$sIconPath; + $sFullURL = utils::GetAbsoluteUrlAppRoot(false, false); + return $sFullURL.'pages/'.$sIconPath; } require_once(APPROOT.'/application/startup.inc.php'); diff --git a/synchro/synchrodatasource.class.inc.php b/synchro/synchrodatasource.class.inc.php index a6b121998..2dd667ecf 100644 --- a/synchro/synchrodatasource.class.inc.php +++ b/synchro/synchrodatasource.class.inc.php @@ -817,8 +817,8 @@ EOF if ($iErrors > 0) { $sIssuesOQL = "SELECT SynchroReplica WHERE sync_source_id=".$this->GetKey()." AND status_last_error!=''"; - $sAbsoluteUrl = utils::GetAbsoluteUrlPath(); - $sIssuesURL = "$sAbsoluteUrl../synchro/replica.php?operation=oql&datasource=".$this->GetKey()."&oql=".urlencode($sIssuesOQL); + $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot(); + $sIssuesURL = "{$sAbsoluteUrl}synchro/replica.php?operation=oql&datasource=".$this->GetKey()."&oql=".urlencode($sIssuesOQL); $sSeeIssues = "

"; $sStatistics = "

Statistics

\n"; diff --git a/webservices/export.php b/webservices/export.php index dc3168e4d..ccc01896b 100644 --- a/webservices/export.php +++ b/webservices/export.php @@ -35,6 +35,8 @@ require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); LoginWebPage::DoLogin(); // Check user rights and prompt if needed +ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker'); + $sOperation = utils::ReadParam('operation', 'menu'); $oAppContext = new ApplicationContext(); $iActiveNodeId = utils::ReadParam('menu', -1); @@ -63,8 +65,8 @@ if (!empty($sExpression)) // The HTML output is made for pages located in the /pages/ folder // since this page is in a different folder, let's adjust the HTML 'base' attribute // to make the relative hyperlinks in the page work - $sUrl = utils::GetAbsoluteUrlAppRoot('/webservices/'); - $oP->set_base($sUrl.'/pages/'); + $sUrl = utils::GetAbsoluteUrlAppRoot(); + $oP->set_base($sUrl.'pages/'); $oResultBlock = new DisplayBlock($oFilter, 'list', false, array('menu' => false, 'display_limit' => false, 'zlist' => 'details')); $oResultBlock->Display($oP, 'expresult');