diff --git a/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php b/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php index 51b4fd34a..9843aaec2 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php +++ b/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php @@ -79,22 +79,18 @@ if ($_SERVER['APP_DEBUG']) { } } -// If PORTAL_ID is not already defined, we look for it in a parameter -if(!defined('PORTAL_ID')) +if(isset($_ENV['PORTAL_ID'])) { - // Retrieving portal id from request params - $sPortalId = utils::ReadParam('portal_id', '', true); - if ($sPortalId == '') - { - echo "Missing argument 'portal_id'"; - exit; - } - - // Defining portal constants - define('PORTAL_ID', $sPortalId); + // Nothing to do } -else +// Note: Default value is set to "false" to differentiate an empty value from a non given parameter +elseif($sPortalId = utils::ReadParam('portal_id', false, true)) { + + $_ENV['PORTAL_ID'] = $sPortalId; +} +elseif(defined('PORTAL_ID')) { + $_ENV['PORTAL_ID'] = PORTAL_ID; @trigger_error( sprintf( 'Usage of legacy "PORTAL_ID" constant ("%s") is deprecated. You should pass "portal_id" in the URL as GET parameter.', @@ -104,12 +100,16 @@ else ); } -define('PORTAL_CACHE_PATH', utils::GetCachePath() . '/portals/' . PORTAL_ID . '/'); +if(empty($_ENV['PORTAL_ID'])) +{ + echo "Missing argument 'portal_id'"; + exit; +} -// Constants to be used in templates and others -define('COMBODO_CURRENT_ENVIRONMENT', utils::GetCurrentEnvironment()); -define('COMBODO_ABSOLUTE_URL', utils::GetAbsoluteUrlAppRoot()); -define('COMBODO_MODULES_ABSOLUTE_URL', utils::GetAbsoluteUrlModulesRoot()); -define('COMBODO_PORTAL_BASE_ABSOLUTE_URL', utils::GetAbsoluteUrlModulesRoot() . 'itop-portal-base/portal/public/'); -define('COMBODO_PORTAL_BASE_ABSOLUTE_PATH', MODULESROOT . '/itop-portal-base/portal/public/'); -define('COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL', utils::GetAbsoluteUrlModulesRoot() . PORTAL_ID . '/'); \ No newline at end of file +// Env. vars to be used in templates and others +$_ENV['COMBODO_CURRENT_ENVIRONMENT'] = utils::GetCurrentEnvironment(); +$_ENV['COMBODO_ABSOLUTE_URL'] = utils::GetAbsoluteUrlAppRoot(); +$_ENV['COMBODO_MODULES_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot(); +$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot() . 'itop-portal-base/portal/public/'; +$_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'] = MODULESROOT . '/itop-portal-base/portal/public/'; +$_ENV['COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL'] = utils::GetAbsoluteUrlModulesRoot() . $_ENV['PORTAL_ID'] . '/'; \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/config/legacy_silex_compat_layer.php b/datamodels/2.x/itop-portal-base/portal/config/legacy_silex_compat_layer.php index 6668c9a1c..631f1327a 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/legacy_silex_compat_layer.php +++ b/datamodels/2.x/itop-portal-base/portal/config/legacy_silex_compat_layer.php @@ -27,7 +27,7 @@ use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfig // Note: ModuleDesign service is not available yet as this script is processed before service generation, // that's why we have to instantiate it manually. -$oModuleDesign = new ModuleDesign(PORTAL_ID); +$oModuleDesign = new ModuleDesign($_ENV['PORTAL_ID']); // TODO: The following code needs to be refactored to more independent and atomic services. @@ -44,20 +44,20 @@ $oListsCompat = new Lists($oModuleDesign); $oListsCompat->Process($container); // - Generating CSS files -$aImportPaths = array(COMBODO_PORTAL_BASE_ABSOLUTE_PATH.'css/'); +$aImportPaths = array($_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/'); $aPortalConf = $container->getParameter('combodo.portal.instance.conf'); foreach ($aPortalConf['properties']['themes'] as $key => $value) { if (!is_array($value)) { - $aPortalConf['properties']['themes'][$key] = COMBODO_ABSOLUTE_URL.utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value, $aImportPaths); + $aPortalConf['properties']['themes'][$key] = $_ENV['COMBODO_ABSOLUTE_URL'].utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value, $aImportPaths); } else { $aValues = array(); foreach ($value as $sSubValue) { - $aValues[] = COMBODO_ABSOLUTE_URL.utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$sSubValue, $aImportPaths); + $aValues[] = $_ENV['COMBODO_ABSOLUTE_URL'].utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$sSubValue, $aImportPaths); } $aPortalConf['properties']['themes'][$key] = $aValues; } diff --git a/datamodels/2.x/itop-portal-base/portal/config/services.yaml b/datamodels/2.x/itop-portal-base/portal/config/services.yaml index 56e443b13..76438f659 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/services.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/services.yaml @@ -28,14 +28,14 @@ parameters: router.options.generator_base_class: Combodo\iTop\Portal\Routing\UrlGenerator # Used in templates - combodo.current_environment: !php/const COMBODO_CURRENT_ENVIRONMENT - combodo.absolute_url: !php/const COMBODO_ABSOLUTE_URL - combodo.modules.absolute_url: !php/const COMBODO_MODULES_ABSOLUTE_URL + combodo.current_environment: '%env(string:COMBODO_CURRENT_ENVIRONMENT)%' + combodo.absolute_url: '%env(string:COMBODO_ABSOLUTE_URL)%' + combodo.modules.absolute_url: '%env(string:COMBODO_MODULES_ABSOLUTE_URL)%' combodo.modules.absolute_path: !php/const MODULESROOT - combodo.portal.base.absolute_url: !php/const COMBODO_PORTAL_BASE_ABSOLUTE_URL - combodo.portal.base.absolute_path: !php/const COMBODO_PORTAL_BASE_ABSOLUTE_PATH - combodo.portal.instance.absolute_url: !php/const COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL - combodo.portal.instance.id: !php/const PORTAL_ID + combodo.portal.base.absolute_url: '%env(string:COMBODO_PORTAL_BASE_ABSOLUTE_URL)%' + combodo.portal.base.absolute_path: '%env(string:COMBODO_PORTAL_BASE_ABSOLUTE_PATH)%' + combodo.portal.instance.absolute_url: '%env(string:COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL)%' + combodo.portal.instance.id: '%env(string:PORTAL_ID)%' services: # Default configuration for services in *this* file @@ -47,10 +47,10 @@ services: # The best practice is to be explicit about your dependencies anyway. bind: $bDebug: '%kernel.debug%' - $sPortalCachePath: !php/const PORTAL_CACHE_PATH - $sPortalId: !php/const PORTAL_ID + $sPortalCachePath: '%kernel.cache_dir%/' + $sPortalId: '%env(string:PORTAL_ID)%' $aCombodoPortalInstanceConf: '%combodo.portal.instance.conf%' - $sCombodoPortalInstanceAbsoluteUrl: !php/const COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL + $sCombodoPortalInstanceAbsoluteUrl: '%env(string:COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL)%' # Makes classes in src/ available to be used as services # This creates a service per class whose id is the fully-qualified class name diff --git a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php index 9f13dd6cf..bc5225f7e 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php +++ b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php @@ -78,7 +78,7 @@ class Basic extends AbstractConfiguration { $aPortalConf = array( 'properties' => array( - 'id' => PORTAL_ID, + 'id' => $_ENV['PORTAL_ID'], 'name' => 'Page:DefaultTitle', 'logo' => (file_exists(MODULESROOT.'branding/portal-logo.png')) ? utils::GetAbsoluteUrlModulesRoot().'branding/portal-logo.png' : '../images/logo-itop-dark-bg.svg', 'themes' => array( diff --git a/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php b/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php index f0e66a4c3..4553b5093 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php +++ b/datamodels/2.x/itop-portal-base/portal/src/EventListener/UserProvider.php @@ -41,9 +41,9 @@ class UserProvider implements ContainerAwareInterface { /** @var \ModuleDesign */ private $oModuleDesign; - /** - * @var \Symfony\Component\DependencyInjection\ContainerInterface - */ + /** @var string $sPortalId */ + private $sPortalId; + /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ private $container; /** @@ -52,9 +52,10 @@ class UserProvider implements ContainerAwareInterface * @param \ModuleDesign $oModuleDesign * @param \User $oUser */ - public function __construct(ModuleDesign $oModuleDesign) + public function __construct(ModuleDesign $oModuleDesign, $sPortalId) { $this->oModuleDesign = $oModuleDesign; + $this->sPortalId = $sPortalId; } /** @@ -68,7 +69,7 @@ class UserProvider implements ContainerAwareInterface // Note: At this point the Exception handler is not registered, so we can't use $oApp::abort() method, hence the die(). // - Checking user rights and prompt if needed (401 HTTP code returned if XHR request) $iExitMethod = ($oGetResponseEvent->getRequest()->isXmlHttpRequest()) ? LoginWebPage::EXIT_RETURN : LoginWebPage::EXIT_PROMPT; - $iLogonRes = LoginWebPage::DoLoginEx(PORTAL_ID, false, $iExitMethod); + $iLogonRes = LoginWebPage::DoLoginEx($this->sPortalId, false, $iExitMethod); if( ($iExitMethod === LoginWebPage::EXIT_RETURN) && ($iLogonRes != 0) ) { die(Dict::S('Portal:ErrorUserLoggedOut')); @@ -90,6 +91,8 @@ class UserProvider implements ContainerAwareInterface /** * Sets the container. + * + * @param \Symfony\Component\DependencyInjection\ContainerInterface|null $container */ public function setContainer(ContainerInterface $container = null) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Kernel.php b/datamodels/2.x/itop-portal-base/portal/src/Kernel.php index bd766e17b..d2af3f303 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Kernel.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Kernel.php @@ -18,14 +18,14 @@ class Kernel extends BaseKernel public function getCacheDir() { - $cacheDir = PORTAL_ID . '-' . $this->environment; + $cacheDir = $_ENV['PORTAL_ID'] . '-' . $this->environment; return utils::GetCachePath() . "/portals/$cacheDir"; } public function getLogDir() { - $logDir = PORTAL_ID . '-' . $this->environment; + $logDir = $_ENV['PORTAL_ID'] . '-' . $this->environment; return utils::GetLogPath() . "/portals/$logDir"; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/UrlMaker/AbstractPortalUrlMaker.php b/datamodels/2.x/itop-portal-base/portal/src/UrlMaker/AbstractPortalUrlMaker.php new file mode 100644 index 000000000..90028fedd --- /dev/null +++ b/datamodels/2.x/itop-portal-base/portal/src/UrlMaker/AbstractPortalUrlMaker.php @@ -0,0 +1,180 @@ + + * @author Bruno Da Silva + * @since 2.3.0 + */ +abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker +{ + /** @var string PORTAL_ID */ + const PORTAL_ID = ''; + + /** @var \Combodo\iTop\Portal\Kernel[] $aKernels */ + private static $aKernels = array(); + + /** + * Generate an (absolute) URL to an object, either in view or edit mode. + * Returns null if the current user is not allowed to view / edit object. + * + * @param string $sClass The class of the object + * @param int $iId The identifier of the object + * @param string $sMode edit|view + * + * @return string | null + * + * @throws Exception + * @throws CoreException + */ + public static function PrepareObjectURL($sClass, $iId, $sMode) + { + $sPreviousPortalId = (isset($_ENV['PORTAL_ID'])) ? $_ENV['PORTAL_ID'] : ''; + $_ENV['PORTAL_ID'] = static::PORTAL_ID; + + require MODULESROOT . 'itop-portal-base/portal/config/bootstrap.php'; + + $sUrl = self::DoPrepareObjectURL($sClass, $iId, $sMode); + + if(!empty($sPreviousPortalId)) + { + $_ENV['PORTAL_ID'] = $sPreviousPortalId; + } + + return $sUrl; + } + + /** + * @param string $sClass + * @param int $iId + * @param string $sMode + * + * @return string|null + * @throws \CoreException + */ + private static function DoPrepareObjectURL($sClass, $iId, $sMode) + { + $oKernel = self::GetKernelInstance(); + $oContainer = $oKernel->getContainer(); + + /** @var string $sPortalId */ + $sPortalId = $oContainer->getParameter('combodo.portal.instance.id'); + + /** @var \Combodo\iTop\Portal\Routing\UrlGenerator $oUrlGenerator */ + $oUrlGenerator = $oContainer->get('url_generator'); + /** @var \Combodo\iTop\Portal\Helper\SecurityHelper $oSecurityHelper */ + $oSecurityHelper = $oContainer->get('security_helper'); + + // The object is reachable in the specified mode (edit/view) + // + // Note: Scopes only apply when URL check is triggered from the portal GUI. + $sObjectQueryString = null; + switch ($sMode) + { + case 'view': + if (!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId)) + { + $sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId)); + } + break; + + case 'edit': + default: + // Checking if user is allowed to edit object, if not we check if it can at least view it. + if (!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sClass, $iId)) + { + $sObjectQueryString = $oUrlGenerator->generate('p_object_edit', array('sObjectClass' => $sClass, 'sObjectId' => $iId)); + } + elseif (!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId)) + { + $sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId)); + } + break; + } + + $sPortalAbsoluteUrl = utils::GetAbsoluteUrlModulePage('itop-portal-base', 'index.php', array('portal_id' => $sPortalId)); + if ($sObjectQueryString === null) + { + $sUrl = null; + } + elseif (strpos($sPortalAbsoluteUrl, '?') !== false) + { + // Removing generated url query parameters so it can be replaced with those from the absolute url + // Mostly necessary when iTop instance has multiple portals + if (strpos($sObjectQueryString, '?') !== false) + { + $sObjectQueryString = substr($sObjectQueryString, 0, strpos($sObjectQueryString, '?')); + } + + $sUrl = substr($sPortalAbsoluteUrl, 0, strpos($sPortalAbsoluteUrl, '?')).$sObjectQueryString.substr($sPortalAbsoluteUrl, + strpos($sPortalAbsoluteUrl, '?')); + } + else + { + $sUrl = $sPortalAbsoluteUrl.$sObjectQueryString; + } + + return $sUrl; + } + + /** + * Returns the kernel singleton + * + * @return \Combodo\iTop\Portal\Kernel + * @since 2.7.0 + */ + private static function GetKernelInstance() + { + if(!array_key_exists(static::PORTAL_ID, self::$aKernels)) + { + self::$aKernels[static::PORTAL_ID] = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); + self::$aKernels[static::PORTAL_ID]->boot(); + } + + return self::$aKernels[static::PORTAL_ID]; + } + + /** + * @param $sClass + * @param $iId + * + * @return null|string + * + * @throws CoreException + */ + public static function MakeObjectURL($sClass, $iId) + { + return static::PrepareObjectURL($sClass, $iId, 'edit'); + } +} + diff --git a/datamodels/2.x/itop-portal/main.itop-portal.php b/datamodels/2.x/itop-portal/main.itop-portal.php index 4a9c2effe..cb0205552 100644 --- a/datamodels/2.x/itop-portal/main.itop-portal.php +++ b/datamodels/2.x/itop-portal/main.itop-portal.php @@ -1,5 +1,4 @@ * @since 2.3.0 */ -class iTopPortalEditUrlMaker implements iDBObjectURLMaker +class iTopPortalEditUrlMaker extends AbstractPortalUrlMaker { - private static $oKernel; - - /** - * Generate an (absolute) URL to an object, either in view or edit mode. - * Returns null if the current user is not allowed to view / edit object. - * - * @param string $sClass The class of the object - * @param int $iId The identifier of the object - * @param string $sMode edit|view - * - * @return string | null - * - * @throws Exception - * @throws CoreException - */ - public static function PrepareObjectURL($sClass, $iId, $sMode) - { - require_once APPROOT . 'lib/composer-vendor/autoload.php'; - require_once MODULESROOT . 'itop-portal-base/portal/config/bootstrap.php'; - - $oKernel = self::GetKernelInstance(); - $oContainer = $oKernel->getContainer(); - - /** @var string $sPortalId */ - $sPortalId = $oContainer->getParameter('combodo.portal.instance.id'); - - /** @var \Combodo\iTop\Portal\Routing\UrlGenerator $oUrlGenerator */ - $oUrlGenerator = $oContainer->get('url_generator'); - /** @var \Combodo\iTop\Portal\Helper\SecurityHelper $oSecurityHelper */ - $oSecurityHelper = $oContainer->get('security_helper'); - - // The object is reachable in the specified mode (edit/view) - // - // Note: Scopes only apply when URL check is triggered from the portal GUI. - $sObjectQueryString = null; - switch($sMode) - { - case 'view': - if(!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId)) - { - $sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId)); - } - break; - - case 'edit': - default: - // Checking if user is allowed to edit object, if not we check if it can at least view it. - if(!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sClass, $iId)) - { - $sObjectQueryString = $oUrlGenerator->generate('p_object_edit', array('sObjectClass' => $sClass, 'sObjectId' => $iId)); - } - elseif(!ContextTag::Check('GUI:Portal') || $oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $sClass, $iId)) - { - $sObjectQueryString = $oUrlGenerator->generate('p_object_view', array('sObjectClass' => $sClass, 'sObjectId' => $iId)); - } - break; - } - - $sPortalAbsoluteUrl = utils::GetAbsoluteUrlModulePage($sPortalId, 'index.php'); - if($sObjectQueryString === null) - { - $sUrl = null; - } - elseif (strpos($sPortalAbsoluteUrl, '?') !== false) - { - // Removing generated url query parameters so it can be replaced with those from the absolute url - // Mostly necessary when iTop instance has multiple portals - if(strpos($sObjectQueryString, '?') !== false) - { - $sObjectQueryString = substr($sObjectQueryString, 0, strpos($sObjectQueryString, '?')); - } - - $sUrl = substr($sPortalAbsoluteUrl, 0, strpos($sPortalAbsoluteUrl, '?')).$sObjectQueryString.substr($sPortalAbsoluteUrl, strpos($sPortalAbsoluteUrl, '?')); - } - else - { - $sUrl = $sPortalAbsoluteUrl.$sObjectQueryString; - } - - return $sUrl; - } - - /** - * @param $sClass - * @param $iId - * - * @return null|string - * - * @throws CoreException - */ - public static function MakeObjectURL($sClass, $iId) - { - return static::PrepareObjectURL($sClass, $iId, 'edit'); - } - - /** - * Returns the kernel singleton - * - * @return \Combodo\iTop\Portal\Kernel - * @since 2.7.0 - */ - private static function GetKernelInstance() - { - if(self::$oKernel === null) - { - self::$oKernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); - self::$oKernel->boot(); - } - - return self::$oKernel; - } + /** @var string PORTAL_ID */ + const PORTAL_ID = 'itop-portal'; } /** @@ -153,6 +45,9 @@ class iTopPortalEditUrlMaker implements iDBObjectURLMaker */ class iTopPortalViewUrlMaker extends iTopPortalEditUrlMaker { + /** + * @inheritDoc + */ public static function MakeObjectURL($sClass, $iId) { return static::PrepareObjectURL($sClass, $iId, 'view');