diff --git a/datamodels/2.x/itop-portal-base/index.php b/datamodels/2.x/itop-portal-base/index.php index 1a7b397f2..587d80b75 100644 --- a/datamodels/2.x/itop-portal-base/index.php +++ b/datamodels/2.x/itop-portal-base/index.php @@ -1,21 +1,24 @@ +/** + * Copyright (C) 2013-2019 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * + * + */ /** * Executes a portal without having a dedicated module. @@ -23,15 +26,15 @@ */ // Load current environment -if (file_exists(__DIR__ . '/../../approot.inc.php')) +if (file_exists(__DIR__.'/../../approot.inc.php')) { - require_once __DIR__ . '/../../approot.inc.php'; // When in env-xxxx folder + require_once __DIR__.'/../../approot.inc.php'; // When in env-xxxx folder } else { - require_once __DIR__ . '/../../../approot.inc.php'; // When in datamodels/x.x folder + require_once __DIR__.'/../../../approot.inc.php'; // When in datamodels/x.x folder } -require_once APPROOT . 'application/startup.inc.php'; +require_once APPROOT.'application/startup.inc.php'; // Load frontal -require_once MODULESROOT . 'itop-portal-base/portal/public/index.php'; +require_once MODULESROOT.'itop-portal-base/portal/public/index.php'; diff --git a/datamodels/2.x/itop-portal-base/portal/bin/console b/datamodels/2.x/itop-portal-base/portal/bin/console index 970d8646c..89be1fbf8 100644 --- a/datamodels/2.x/itop-portal-base/portal/bin/console +++ b/datamodels/2.x/itop-portal-base/portal/bin/console @@ -5,33 +5,35 @@ use Combodo\iTop\Portal\Kernel; use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArgvInput; -if (false === in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) { - echo 'Warning: The console should be invoked via the CLI version of PHP, not the '.\PHP_SAPI.' SAPI'.\PHP_EOL; +if (false === in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) +{ + echo 'Warning: The console should be invoked via the CLI version of PHP, not the '.\PHP_SAPI.' SAPI'.\PHP_EOL; } set_time_limit(0); -if(!defined('APPROOT')) +if (!defined('APPROOT')) { - if (file_exists(__DIR__ . '/../../../../approot.inc.php')) + if (file_exists(__DIR__.'/../../../../approot.inc.php')) { - require_once __DIR__ . '/../../../../approot.inc.php'; // When in env-xxxx folder + require_once __DIR__.'/../../../../approot.inc.php'; // When in env-xxxx folder } else { - require_once __DIR__ . '/../../../../../approot.inc.php'; // When in datamodels/x.x folder + require_once __DIR__.'/../../../../../approot.inc.php'; // When in datamodels/x.x folder } } -require_once APPROOT . 'lib/composer-vendor/autoload.php'; +require_once APPROOT.'lib/composer-vendor/autoload.php'; -if (!class_exists(Application::class)) { - throw new RuntimeException('You need to add "symfony/framework-bundle" as a Composer dependency.'); +if (!class_exists(Application::class)) +{ + throw new RuntimeException('You need to add "symfony/framework-bundle" as a Composer dependency.'); } // Remove --portal_id from CLI params to avoid SF CLI conflicts // Note: The parameter is needed when calling the bin/console to determine which portal to select $aCleanedArgv = $_SERVER['argv']; -foreach($aCleanedArgv as $iArg => $sArg) +foreach ($aCleanedArgv as $iArg => $sArg) { if (preg_match('/^--portal_id=(.*)$/', $sArg, $aMatches)) { @@ -40,17 +42,20 @@ foreach($aCleanedArgv as $iArg => $sArg) } } -$input = new ArgvInput($aCleanedArgv); -if (null !== $env = $input->getParameterOption(['--env', '-e'], null, true)) { - putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env); +$oInput = new ArgvInput($aCleanedArgv); +if (null !== $sEnv = $oInput->getParameterOption(['--env', '-e'], null, true)) +{ + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $sEnv); } -if ($input->hasParameterOption('--no-debug', true)) { - putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); +if ($oInput->hasParameterOption('--no-debug', true)) +{ + putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); } -require_once MODULESROOT . 'itop-portal-base/portal/config/bootstrap.php'; +require_once MODULESROOT.'itop-portal-base/portal/config/bootstrap.php'; -$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); -$application = new Application($kernel); -$application->run($input); +$oKernel = new Kernel($_SERVER['APP_ENV'], (bool)$_SERVER['APP_DEBUG']); +$oApplication = new Application($oKernel); +/** @noinspection PhpUnhandledExceptionInspection */ +$oApplication->run($oInput); 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 59cbc7761..932c1c61f 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php +++ b/datamodels/2.x/itop-portal-base/portal/config/bootstrap.php @@ -1,63 +1,101 @@ =1.2) -if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) { - $_ENV += $env; -} elseif (!class_exists(Dotenv::class)) { - throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); -} else { - $path = dirname(__DIR__).'/.env'; - $dotenv = new Dotenv(false); +if (is_array($sEnv = @include dirname(__DIR__).'/.env.local.php')) +{ + $_ENV += $sEnv; +} +elseif (!class_exists(Dotenv::class)) +{ + throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); +} +else +{ + $sPath = dirname(__DIR__).'/.env'; + $oDotenv = new Dotenv(false); - // load all the .env files - if (method_exists($dotenv, 'loadEnv')) { - $dotenv->loadEnv($path); - } else { - // fallback code in case your Dotenv component is not 4.2 or higher (when loadEnv() was added) + // load all the .env files + if (method_exists($oDotenv, 'loadEnv')) + { + $oDotenv->loadEnv($sPath); + } + else + { + // fallback code in case your Dotenv component is not 4.2 or higher (when loadEnv() was added) - if (file_exists($path) || !file_exists($p = "$path.dist")) { - $dotenv->load($path); - } else { - $dotenv->load($p); - } + if (file_exists($sPath) || !file_exists($sPathDist = "$sPath.dist")) + { + $oDotenv->load($sPath); + } + else + { + $oDotenv->load($sPathDist); + } - if (null === $env = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null))) { - $dotenv->populate(array('APP_ENV' => $env = 'prod')); - } + if (null === $sEnv = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null))) + { + $oDotenv->populate(array('APP_ENV' => $sEnv = 'prod')); + } - if ('test' !== $env && file_exists($p = "$path.local")) { - $dotenv->load($p); - $env = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : $env); - } + if ('test' !== $sEnv && file_exists($sPathDist = "$sPath.local")) + { + $oDotenv->load($sPathDist); + $sEnv = isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : $sEnv); + } - if (file_exists($p = "$path.$env")) { - $dotenv->load($p); - } + if (file_exists($sPathDist = "$sPath.$sEnv")) + { + $oDotenv->load($sPathDist); + } - if (file_exists($p = "$path.$env.local")) { - $dotenv->load($p); - } - } + if (file_exists($sPathDist = "$sPath.$sEnv.local")) + { + $oDotenv->load($sPathDist); + } + } } // Set debug mode only when necessary @@ -69,27 +107,30 @@ if (utils::ReadParam('debug', 'false') === 'true') $_SERVER += $_ENV; $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = (isset($_SERVER['APP_ENV']) ? $_SERVER['APP_ENV'] : (isset($_ENV['APP_ENV']) ? $_ENV['APP_ENV'] : null)) ?: 'prod'; $_SERVER['APP_DEBUG'] = isset($_SERVER['APP_DEBUG']) ? $_SERVER['APP_DEBUG'] : (isset($_ENV['APP_DEBUG']) ? $_ENV['APP_DEBUG'] : ('prod' !== $_SERVER['APP_ENV'])); -$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; +$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int)$_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], + FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; -if ($_SERVER['APP_DEBUG']) { +if ($_SERVER['APP_DEBUG']) +{ umask(0000); - if (class_exists(Debug::class)) { + if (class_exists(Debug::class)) + { Debug::enable(); } } -if(isset($_ENV['PORTAL_ID'])) +if (isset($_ENV['PORTAL_ID'])) { // Nothing to do } // 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)) +elseif ($sPortalId = utils::ReadParam('portal_id', false, true)) { $_ENV['PORTAL_ID'] = $sPortalId; } -elseif(defined('PORTAL_ID')) +elseif (defined('PORTAL_ID')) { $_ENV['PORTAL_ID'] = PORTAL_ID; @trigger_error( @@ -101,7 +142,7 @@ elseif(defined('PORTAL_ID')) ); } -if(empty($_ENV['PORTAL_ID'])) +if (empty($_ENV['PORTAL_ID'])) { echo "Missing argument 'portal_id'"; exit; @@ -110,7 +151,7 @@ if(empty($_ENV['PORTAL_ID'])) // 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 +$_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/bundles.php b/datamodels/2.x/itop-portal-base/portal/config/bundles.php index 433d8356a..1d7360452 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/bundles.php +++ b/datamodels/2.x/itop-portal-base/portal/config/bundles.php @@ -1,7 +1,26 @@ ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true], + Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true], ]; 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 631f1327a..ad97be2cc 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 @@ -20,52 +20,60 @@ * */ +// Disable PhpUnhandledExceptionInspection as the exception handling is made by the file including this one +/** @noinspection PhpUnhandledExceptionInspection */ + // Loading file use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration\Basic; use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration\Forms; use Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration\Lists; -// Note: ModuleDesign service is not available yet as this script is processed before service generation, +// Note: ModuleDesign service is not available yet as this script is processed before services generation, // that's why we have to instantiate it manually. $oModuleDesign = new ModuleDesign($_ENV['PORTAL_ID']); // TODO: The following code needs to be refactored to more independent and atomic services. +// Load portal conf. such as properties, themes, templates, ... // Append into %combodo.portal.instance.conf% $oBasicCompat = new Basic($oModuleDesign); $oBasicCompat->Process($container); +// Load portal forms definition // Append into %combodo.portal.instance.conf% $oFormsCompat = new Forms($oModuleDesign); $oFormsCompat->Process($container); +// Load portal lists definition // Append into %combodo.portal.instance.conf% $oListsCompat = new Lists($oModuleDesign); $oListsCompat->Process($container); -// - Generating CSS files +// Generating CSS files $aImportPaths = array($_ENV['COMBODO_PORTAL_BASE_ABSOLUTE_PATH'].'css/'); $aPortalConf = $container->getParameter('combodo.portal.instance.conf'); -foreach ($aPortalConf['properties']['themes'] as $key => $value) +foreach ($aPortalConf['properties']['themes'] as $sKey => $value) { if (!is_array($value)) { - $aPortalConf['properties']['themes'][$key] = $_ENV['COMBODO_ABSOLUTE_URL'].utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value, $aImportPaths); + $aPortalConf['properties']['themes'][$sKey] = $_ENV['COMBODO_ABSOLUTE_URL'].utils::GetCSSFromSASS('env-'.utils::GetCurrentEnvironment().'/'.$value, + $aImportPaths); } else { $aValues = array(); foreach ($value as $sSubValue) { - $aValues[] = $_ENV['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; + $aPortalConf['properties']['themes'][$sKey] = $aValues; } } $container->setParameter('combodo.portal.instance.conf', $aPortalConf); //TODO: The following needs to be refactored -//session messages +// Session messages $aAllMessages = array(); if ((array_key_exists('obj_messages', $_SESSION)) && (!empty($_SESSION['obj_messages']))) { diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/cache.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/cache.yaml index 93e620efa..37e916327 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/cache.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/cache.yaml @@ -1,19 +1,19 @@ framework: - cache: - # Put the unique name of your app here: the prefix seed - # is used to compute stable namespaces for cache keys. - #prefix_seed: your_vendor_name/app_name + cache: + # Put the unique name of your app here: the prefix seed + # is used to compute stable namespaces for cache keys. + #prefix_seed: your_vendor_name/app_name - # The app cache caches to the filesystem by default. - # Other options include: + # The app cache caches to the filesystem by default. + # Other options include: - # Redis - #app: cache.adapter.redis - #default_redis_provider: redis://localhost + # Redis + #app: cache.adapter.redis + #default_redis_provider: redis://localhost - # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) - #app: cache.adapter.apcu + # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) + #app: cache.adapter.apcu - # Namespaced pools use the above "app" backend by default - #pools: - #my.dedicated.cache: ~ + # Namespaced pools use the above "app" backend by default + #pools: + #my.dedicated.cache: ~ diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/dev/routing.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/dev/routing.yaml index 4116679a2..a3d2503d5 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/dev/routing.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/dev/routing.yaml @@ -1,3 +1,3 @@ framework: - router: - strict_requirements: true + router: + strict_requirements: true diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/framework.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/framework.yaml index 60f24ae25..27b6842c7 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/framework.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/framework.yaml @@ -1,15 +1,15 @@ framework: - secret: '%env(APP_SECRET)%' - #default_locale: en - #csrf_protection: true - #http_method_override: true + secret: '%env(APP_SECRET)%' + #default_locale: en + #csrf_protection: true + #http_method_override: true - # Enables session support. Note that the session will ONLY be started if you read or write from it. - # Remove or comment this section to explicitly disable session support. - session: - handler_id: ~ + # Enables session support. Note that the session will ONLY be started if you read or write from it. + # Remove or comment this section to explicitly disable session support. + session: + handler_id: ~ - #esi: true - #fragments: true - php_errors: - log: true + #esi: true + #fragments: true + php_errors: + log: true diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/routing.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/routing.yaml index 368bc7f49..17ae54822 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/routing.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/routing.yaml @@ -1,3 +1,3 @@ framework: - router: - strict_requirements: ~ + router: + strict_requirements: ~ diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/test/framework.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/test/framework.yaml index d051c8400..d153e0d23 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/test/framework.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/test/framework.yaml @@ -1,4 +1,4 @@ framework: - test: true - session: - storage_id: session.storage.mock_file + test: true + session: + storage_id: session.storage.mock_file diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/test/routing.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/test/routing.yaml index 4116679a2..a3d2503d5 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/test/routing.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/test/routing.yaml @@ -1,3 +1,3 @@ framework: - router: - strict_requirements: true + router: + strict_requirements: true diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/test/web_profiler.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/test/web_profiler.yaml index fd7ff5a35..976923b4b 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/test/web_profiler.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/test/web_profiler.yaml @@ -3,4 +3,4 @@ web_profiler: intercept_redirects: false framework: - profiler: { collect: false } \ No newline at end of file + profiler: { collect: falseS } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/config/packages/twig.yaml b/datamodels/2.x/itop-portal-base/portal/config/packages/twig.yaml index c5d5a94c3..e4a98b501 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/packages/twig.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/packages/twig.yaml @@ -1,4 +1,4 @@ twig: - default_path: '%combodo.modules.absolute_path%' - debug: '%kernel.debug%' - strict_variables: '%kernel.debug%' + default_path: '%combodo.modules.absolute_path%' + debug: '%kernel.debug%' + strict_variables: '%kernel.debug%' diff --git a/datamodels/2.x/itop-portal-base/portal/config/routes/dev/twig.yaml b/datamodels/2.x/itop-portal-base/portal/config/routes/dev/twig.yaml index f4ee83960..93c0e4cf8 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/routes/dev/twig.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/routes/dev/twig.yaml @@ -1,3 +1,3 @@ _errors: - resource: '@TwigBundle/Resources/config/routing/errors.xml' - prefix: /_error + resource: '@TwigBundle/Resources/config/routing/errors.xml' + prefix: /_error diff --git a/datamodels/2.x/itop-portal-base/portal/config/routes/extensions_extra_routes.php b/datamodels/2.x/itop-portal-base/portal/config/routes/extensions_extra_routes.php index d72d9e241..3c00375ae 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/routes/extensions_extra_routes.php +++ b/datamodels/2.x/itop-portal-base/portal/config/routes/extensions_extra_routes.php @@ -1,34 +1,47 @@ add( - $route['bind'], - new Route( - $route['pattern'], - array_merge( - ['_controller' => $route['callback']], - $route['values'] - ), - $route['asserts'] - ) - ); + $oRouteCollection->add( + $aRoute['bind'], + new Route( + $aRoute['pattern'], + array_merge( + ['_controller' => $aRoute['callback']], + $aRoute['values'] + ), + $aRoute['asserts'] + ) + ); } -return $routes; \ No newline at end of file +return $oRouteCollection; \ No newline at end of file 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 76438f659..5becb1794 100644 --- a/datamodels/2.x/itop-portal-base/portal/config/services.yaml +++ b/datamodels/2.x/itop-portal-base/portal/config/services.yaml @@ -19,115 +19,115 @@ # Files in the packages/ subdirectory configure your dependencies. imports: - - { resource: "legacy_silex_compat_layer.php" } + - { resource: "legacy_silex_compat_layer.php" } # Put parameters here that don't need to change on each machine where the app is deployed # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: - # Replace default url generator service - router.options.generator_base_class: Combodo\iTop\Portal\Routing\UrlGenerator + # Replace default url generator service + router.options.generator_base_class: Combodo\iTop\Portal\Routing\UrlGenerator - # Used in templates - 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: '%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)%' + # Used in templates + 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: '%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 - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - public: false # Allows optimizing the container by removing unused services; this also means - # fetching services directly from the container via $container->get() won't work. - # The best practice is to be explicit about your dependencies anyway. - bind: - $bDebug: '%kernel.debug%' - $sPortalCachePath: '%kernel.cache_dir%/' - $sPortalId: '%env(string:PORTAL_ID)%' - $aCombodoPortalInstanceConf: '%combodo.portal.instance.conf%' - $sCombodoPortalInstanceAbsoluteUrl: '%env(string:COMBODO_PORTAL_INSTANCE_ABSOLUTE_URL)%' + # Default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + public: false # Allows optimizing the container by removing unused services; this also means + # fetching services directly from the container via $container->get() won't work. + # The best practice is to be explicit about your dependencies anyway. + bind: + $bDebug: '%kernel.debug%' + $sPortalCachePath: '%kernel.cache_dir%/' + $sPortalId: '%env(string:PORTAL_ID)%' + $aCombodoPortalInstanceConf: '%combodo.portal.instance.conf%' + $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 - Combodo\iTop\Portal\: - resource: '../src/*' - exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + # Makes classes in src/ available to be used as services + # This creates a service per class whose id is the fully-qualified class name + Combodo\iTop\Portal\: + resource: '../src/*' + exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' - # Controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class - Combodo\iTop\Portal\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] + # Controllers are imported separately to make sure services can be injected + # as action arguments even if you don't extend any base controller class + Combodo\iTop\Portal\Controller\: + resource: '../src/Controller' + tags: ['controller.service_arguments'] - # Tag services without defining them (see https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags) - _instanceof: - Combodo\iTop\Portal\EventListener\UserProvider: - tags: [{ name: 'kernel.event_listener', event: 'kernel.request' }] - calls: - - [setContainer, ['@service_container']] - Combodo\iTop\Portal\EventListener\ApplicationContextSetUrlMakerClass: - tags: [{ name: 'kernel.event_listener', event: 'kernel.request' }] + # Tag services without defining them (see https://symfony.com/doc/current/service_container/tags.html#autoconfiguring-tags) + _instanceof: + Combodo\iTop\Portal\EventListener\UserProvider: + tags: [{ name: 'kernel.event_listener', event: 'kernel.request' }] + calls: + - [setContainer, ['@service_container']] + Combodo\iTop\Portal\EventListener\ApplicationContextSetUrlMakerClass: + tags: [{ name: 'kernel.event_listener', event: 'kernel.request' }] - # Add more service definitions when explicit configuration is needed - # Please note that last definitions always *replace* previous ones + # Add more service definitions when explicit configuration is needed + # Please note that last definitions always *replace* previous ones - # Legacy code as a service: since it is not in the auto-wiring path, it needs to be explicitly declared - ModuleDesign: - public: true - class: ModuleDesign - arguments: - - '%combodo.portal.instance.id%' + # Legacy code as a service: since it is not in the auto-wiring path, it needs to be explicitly declared + ModuleDesign: + public: true + class: ModuleDesign + arguments: + - '%combodo.portal.instance.id%' - # Decoration - # - Compatibility layer with Silex\Application which was used almost everywhere in the portal's templates - Combodo\iTop\Portal\Twig\AppVariable: - decorates: twig.app_variable - arguments: - - '@Combodo\iTop\Portal\Twig\AppVariable.inner' - - '@service_container' + # Decoration + # - Compatibility layer with Silex\Application which was used almost everywhere in the portal's templates + Combodo\iTop\Portal\Twig\AppVariable: + decorates: twig.app_variable + arguments: + - '@Combodo\iTop\Portal\Twig\AppVariable.inner' + - '@service_container' - # Standard services - combodo.current_contact.photo_url: - public: true - class: Combodo\iTop\Portal\VariableAccessor\CombodoCurrentContactPhotoUrl - arguments: ['@combodo.current_user'] - # Note: This service is initialized with a UserLocal object as it needs a class that can be instantiated. - # Anyway, it will be replaced with the real class by UserProvider in onKernelRequestEvent. - # Note: Services relying on this one should use \User in their signature and not \UserLocal. - combodo.current_user: - public: true - class: UserLocal + # Standard services + combodo.current_contact.photo_url: + public: true + class: Combodo\iTop\Portal\VariableAccessor\CombodoCurrentContactPhotoUrl + arguments: ['@combodo.current_user'] + # Note: This service is initialized with a UserLocal object as it needs a class that can be instantiated. + # Anyway, it will be replaced with the real class by UserProvider in onKernelRequestEvent. + # Note: Services relying on this one should use \User in their signature and not \UserLocal. + combodo.current_user: + public: true + class: UserLocal - # Aliases - brick_collection: - alias: Combodo\iTop\Portal\Brick\BrickCollection - public: true - request_manipulator: - alias: Combodo\iTop\Portal\Helper\RequestManipulatorHelper - public: true - scope_validator: - alias: Combodo\iTop\Portal\Helper\ScopeValidatorHelper - public: true - security_helper: - alias: Combodo\iTop\Portal\Helper\SecurityHelper - public: true - context_manipulator: - alias: Combodo\iTop\Portal\Helper\ContextManipulatorHelper - public: true - lifecycle_validator: - alias: Combodo\iTop\Portal\Helper\LifecycleValidatorHelper - public: true - url_generator: - alias: router - public: true - object_form_handler: - alias: Combodo\iTop\Portal\Helper\ObjectFormHandlerHelper - public: true - browse_brick: - alias: Combodo\iTop\Portal\Helper\BrowseBrickHelper - public: true \ No newline at end of file + # Aliases + brick_collection: + alias: Combodo\iTop\Portal\Brick\BrickCollection + public: true + request_manipulator: + alias: Combodo\iTop\Portal\Helper\RequestManipulatorHelper + public: true + scope_validator: + alias: Combodo\iTop\Portal\Helper\ScopeValidatorHelper + public: true + security_helper: + alias: Combodo\iTop\Portal\Helper\SecurityHelper + public: true + context_manipulator: + alias: Combodo\iTop\Portal\Helper\ContextManipulatorHelper + public: true + lifecycle_validator: + alias: Combodo\iTop\Portal\Helper\LifecycleValidatorHelper + public: true + url_generator: + alias: router + public: true + object_form_handler: + alias: Combodo\iTop\Portal\Helper\ObjectFormHandlerHelper + public: true + browse_brick: + alias: Combodo\iTop\Portal\Helper\BrowseBrickHelper + public: true \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/public/index.php b/datamodels/2.x/itop-portal-base/portal/public/index.php index 508f83ff7..ad2c16904 100644 --- a/datamodels/2.x/itop-portal-base/portal/public/index.php +++ b/datamodels/2.x/itop-portal-base/portal/public/index.php @@ -1,22 +1,44 @@ handle($request); -$response->send(); -$kernel->terminate($request, $response); +$oKernel = new Kernel($_SERVER['APP_ENV'], (bool)$_SERVER['APP_DEBUG']); +$oRequest = Request::createFromGlobals(); +/** @noinspection PhpUnhandledExceptionInspection */ +$oResponse = $oKernel->handle($oRequest); +$oResponse->send(); +$oKernel->terminate($oRequest, $oResponse); diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/AbstractBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/AbstractBrick.php index f583c7855..d252df8d0 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/AbstractBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/AbstractBrick.php @@ -1,26 +1,29 @@ +/** + * Copyright (C) 2013-2019 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * + * + */ namespace Combodo\iTop\Portal\Brick; -require_once APPROOT . '/core/moduledesign.class.inc.php'; -require_once APPROOT . '/setup/compiler.class.inc.php'; +require_once APPROOT.'/core/moduledesign.class.inc.php'; +require_once APPROOT.'/setup/compiler.class.inc.php'; use DOMFormatException; use ModuleDesign; @@ -28,40 +31,68 @@ use Combodo\iTop\DesignElement; /** * Description of AbstractBrick - * - * Bricks are used mostly in the portal for now, not the console. - * This class defines common functionnalities for the extended classes. + * + * Bricks are used mostly in the portal for now, not the console. + * This class defines common functionalities for the extended classes. * * @author Guillaume Lajarige + * @since 2.3.0 */ abstract class AbstractBrick { + /** @var string ENUM_DATA_LOADING_LAZY */ const ENUM_DATA_LOADING_LAZY = 'lazy'; + /** @var string ENUM_DATA_LOADING_FULL */ const ENUM_DATA_LOADING_FULL = 'full'; + /** @var string ENUM_DATA_LOADING_AUTO */ const ENUM_DATA_LOADING_AUTO = 'auto'; + + /** @var bool DEFAULT_MANDATORY */ const DEFAULT_MANDATORY = true; + /** @var bool DEFAULT_ACTIVE */ const DEFAULT_ACTIVE = true; + /** @var bool DEFAULT_VISIBLE */ const DEFAULT_VISIBLE = true; + /** @var float DEFAULT_RANK */ const DEFAULT_RANK = 1.0; + /** @var string|null DEFAULT_PAGE_TEMPLATE_PATH */ const DEFAULT_PAGE_TEMPLATE_PATH = null; + /** @var string DEFAULT_TITLE */ const DEFAULT_TITLE = ''; + /** @var string|null DEFAULT_DESCRIPTION */ const DEFAULT_DESCRIPTION = null; + /** @var string DEFAULT_DATA_LOADING */ const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_AUTO; + /** @var string DEFAULT_ALLOWED_PROFILES_OQL */ const DEFAULT_ALLOWED_PROFILES_OQL = ''; + /** @var string DEFAULT_DENIED_PROFILES_OQL */ const DEFAULT_DENIED_PROFILES_OQL = ''; + /** @var string $sId */ protected $sId; + /** @var bool $bMandatory */ protected $bMandatory; + /** @var bool $bActive */ protected $bActive; + /** @var bool $bVisible */ protected $bVisible; + /** @var float $fRank */ protected $fRank; + /** @var string|null $sPageTemplatePath */ protected $sPageTemplatePath; + /** @var string $sTitle */ protected $sTitle; + /** @var string|null $sDescription */ protected $sDescription; + /** @var string $sDataLoading */ protected $sDataLoading; + /** @var array $aAllowedProfiles */ protected $aAllowedProfiles; + /** @var array $aDeniedProfiles */ protected $aDeniedProfiles; + /** @var string $sAllowedProfilesOql */ protected $sAllowedProfilesOql; + /** @var string $sDeniedProfilesOql */ protected $sDeniedProfilesOql; /** @@ -77,7 +108,7 @@ abstract class AbstractBrick /** * Default attributes values of AbstractBrick are specified in the definition, not the constructor. */ - function __construct() + public function __construct() { $this->bMandatory = static::DEFAULT_MANDATORY; $this->bActive = static::DEFAULT_ACTIVE; @@ -253,8 +284,8 @@ abstract class AbstractBrick * Sets if the brick is visible * * @param boolean $bVisible - * - * @return \Combodo\iTop\Portal\Brick\AbstractBrick + * + * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function SetVisible($bVisible) { @@ -344,12 +375,13 @@ abstract class AbstractBrick * Sets the allowed profiles for the brick * * @param array $aAllowedProfiles - * - * @return \Combodo\iTop\Portal\Brick\AbstractBrick + * + * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function SetAllowedProfiles($aAllowedProfiles) { $this->aAllowedProfiles = $aAllowedProfiles; + return $this; } @@ -357,8 +389,8 @@ abstract class AbstractBrick * Sets the denied profiles for the brick * * @param array $aDeniedProfiles - * - * @return \Combodo\iTop\Portal\Brick\AbstractBrick + * + * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function SetDeniedProfiles($aDeniedProfiles) { @@ -382,7 +414,7 @@ abstract class AbstractBrick /** * Sets the denied profiles oql query for the brick * - * @param array $sDeniedProfilesOql + * @param string $sDeniedProfilesOql * * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ @@ -396,12 +428,13 @@ abstract class AbstractBrick * Adds $sProfile to the list of allowed profiles for that brick * * @param string $sProfile - * + * * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function AddAllowedProfile($sProfile) { $this->aAllowedProfiles[] = $sProfile; + return $this; } @@ -409,7 +442,7 @@ abstract class AbstractBrick * Removes $sProfile from the list of allowed profiles * * @param string $sProfile - * + * * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function RemoveAllowedProfile($sProfile) @@ -418,6 +451,7 @@ abstract class AbstractBrick { unset($this->aAllowedProfiles[$sProfile]); } + return $this; } @@ -435,12 +469,13 @@ abstract class AbstractBrick * Adds $sProfile to the list of denied profiles for that brick * * @param string $sProfile - * + * * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function AddDeniedProfile($sProfile) { $this->aDeniedProfiles[] = $sProfile; + return $this; } @@ -448,7 +483,7 @@ abstract class AbstractBrick * Removes $sProfile from the list of denied profiles * * @param string $sProfile - * + * * @return \Combodo\iTop\Portal\Brick\AbstractBrick */ public function RemoveDeniedProfile($sProfile) @@ -457,6 +492,7 @@ abstract class AbstractBrick { unset($this->aDeniedProfiles[$sProfile]); } + return $this; } @@ -477,7 +513,7 @@ abstract class AbstractBrick * Priority is deny/allow * * @param string $sProfile - * + * * @return boolean */ public function IsGrantedForProfile($sProfile) @@ -492,7 +528,7 @@ abstract class AbstractBrick * Priority is deny/allow * * @param array $aProfiles - * + * * @return boolean */ public function IsGrantedForProfiles($aProfiles) @@ -543,9 +579,9 @@ abstract class AbstractBrick * This is used to set all the brick attributes at once. * * @param \Combodo\iTop\DesignElement $oMDElement - * - * @return \Combodo\iTop\Portal\Brick\AbstractBrick - * + * + * @return \Combodo\iTop\Portal\Brick\AbstractBrick + * * @throws \DOMFormatException */ public function LoadFromXml(DesignElement $oMDElement) @@ -558,28 +594,31 @@ abstract class AbstractBrick $this->SetId($oMDElement->getAttribute('id')); // Checking others elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) { case 'mandatory': - $this->SetMandatory(($oBrickSubNode->GetText() === 'no') ? false : true ); + $this->SetMandatory(($oBrickSubNode->GetText() === 'no') ? false : true); break; case 'active': - $this->SetActive(($oBrickSubNode->GetText() === 'false') ? false : true ); + $this->SetActive(($oBrickSubNode->GetText() === 'false') ? false : true); break; case 'rank': $oOptionalNode = $oBrickSubNode->GetOptionalElement('default'); if ($oOptionalNode !== null) { - $this->SetRank((float) $oOptionalNode->GetText(static::DEFAULT_RANK)); + $this->SetRank((float)$oOptionalNode->GetText(static::DEFAULT_RANK)); } break; case 'templates': - $oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id=' . ModuleDesign::XPathQuote('page') . ']'); + $oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id='.ModuleDesign::XPathQuote('page').']'); if ($oTemplateNodeList->length > 0) { - $this->SetPageTemplatePath($oTemplateNodeList->item(0)->GetText(static::DEFAULT_PAGE_TEMPLATE_PATH)); + /** @var \Combodo\iTop\DesignElement $oTemplateNode */ + $oTemplateNode = $oTemplateNodeList->item(0); + $this->SetPageTemplatePath($oTemplateNode->GetText(static::DEFAULT_PAGE_TEMPLATE_PATH)); } break; case 'title': @@ -596,11 +635,13 @@ abstract class AbstractBrick $this->SetDataLoading($oBrickSubNode->GetText(static::DEFAULT_DATA_LOADING)); break; case 'security': + /** @var \Combodo\iTop\DesignElement $oSecurityNode */ foreach ($oBrickSubNode->childNodes as $oSecurityNode) { if ($oSecurityNode->nodeType === XML_TEXT_NODE && $oSecurityNode->GetText() === '') { - throw new DOMFormatException('Brick security node "' . $oSecurityNode->nodeName . '" must contain an OQL query, it cannot be empty', null, null, $oMDElement); + throw new DOMFormatException('Brick security node "'.$oSecurityNode->nodeName.'" must contain an OQL query, it cannot be empty', + null, null, $oMDElement); } switch ($oSecurityNode->nodeName) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/AggregatePageBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/AggregatePageBrick.php index b379f19d5..1aa801cee 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/AggregatePageBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/AggregatePageBrick.php @@ -1,35 +1,49 @@ -// +/** + * Copyright (C) 2013-2019 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * + * + */ namespace Combodo\iTop\Portal\Brick; use Combodo\iTop\DesignElement; use Dict; +use DOMFormatException; +/** + * Class AggregatePageBrick + * + * @package Combodo\iTop\Portal\Brick + * @since 2.5.0 + * @author Eric Espie + * @author Guillaume Lajarige + * @author Pierre Goiffon + */ class AggregatePageBrick extends PortalBrick { + // Overloaded constants const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-dashboard'; const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-dashboard fa-2x'; const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/aggregate-page/layout.html.twig'; - static $sRouteName = 'p_aggregatepage_brick'; + // Overloaded variables + public static $sRouteName = 'p_aggregatepage_brick'; /** * @var string[] list of bricks to use, ordered by rank (key=id, value=rank) @@ -50,23 +64,25 @@ class AggregatePageBrick extends PortalBrick * @param \Combodo\iTop\DesignElement $oMDElement * * @return \Combodo\iTop\Portal\Brick\AggregatePageBrick - * + * * @throws \DOMFormatException */ public function LoadFromXml(DesignElement $oMDElement) { parent::LoadFromXml($oMDElement); + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) { case 'aggregate_page_bricks': + /** @var \Combodo\iTop\DesignElement $oAggregatePageBrickNode */ foreach ($oBrickSubNode->GetNodes('./aggregate_page_brick') as $oAggregatePageBrickNode) { if (!$oAggregatePageBrickNode->hasAttribute('id')) { - throw new \DOMFormatException('AggregatePageBrick : must have an id attribute', null, + throw new DOMFormatException('AggregatePageBrick : must have an id attribute', null, null, $oAggregatePageBrickNode); } $sBrickName = $oAggregatePageBrickNode->getAttribute('id'); diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickCollection.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickCollection.php index 0ec05ecf0..8dab6a648 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickCollection.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickCollection.php @@ -31,24 +31,24 @@ use Combodo\iTop\Portal\Helper\ApplicationHelper; * Class BrickCollection * * @package Combodo\iTop\Portal\Brick - * @author Bruno Da Silva - * @author Guillaume Lajarige - * @since 2.7.0 + * @author Bruno Da Silva + * @author Guillaume Lajarige + * @since 2.7.0 */ class BrickCollection { - /** @var \ModuleDesign */ + /** @var \ModuleDesign $oModuleDesign */ private $oModuleDesign; - /** @var array|null $aAllowedBricks Lazily computed */ - private $aAllowedBricks; - /** @var int $iDisplayedInHome Lazily computed */ - private $iDisplayedInHome; - /** @var int $iDisplayedInNavigationMenu Lazily computed */ - private $iDisplayedInNavigationMenu; - /** @var array $aHomeOrdering */ - private $aHomeOrdering; - /** @var array $aNavigationMenuOrdering */ - private $aNavigationMenuOrdering; + /** @var array|null $aAllowedBricks Lazily computed */ + private $aAllowedBricks; + /** @var int $iDisplayedInHome Lazily computed */ + private $iDisplayedInHome; + /** @var int $iDisplayedInNavigationMenu Lazily computed */ + private $iDisplayedInNavigationMenu; + /** @var array $aHomeOrdering */ + private $aHomeOrdering; + /** @var array $aNavigationMenuOrdering */ + private $aNavigationMenuOrdering; /** * BrickCollection constructor. @@ -58,16 +58,16 @@ class BrickCollection * @throws \Exception */ public function __construct(ModuleDesign $oModuleDesign) - { - $this->oModuleDesign = $oModuleDesign; - $this->aAllowedBricks = null; - $this->iDisplayedInHome = 0; - $this->iDisplayedInNavigationMenu = 0; - $this->aHomeOrdering = array(); - $this->aNavigationMenuOrdering = array(); + { + $this->oModuleDesign = $oModuleDesign; + $this->aAllowedBricks = null; + $this->iDisplayedInHome = 0; + $this->iDisplayedInNavigationMenu = 0; + $this->aHomeOrdering = array(); + $this->aNavigationMenuOrdering = array(); - $this->Load(); - } + $this->Load(); + } /** * @param $method @@ -78,32 +78,32 @@ class BrickCollection * @throws \Exception */ public function __call($method, $arguments) - { - // Made for cleaner/easier access from twig (eg. app['brick_collection'].bricks) - switch($method) - { - case 'bricks': - return $this->GetBricks(); - break; - case 'home_ordering': - return $this->GetHomeOrdering(); - break; - case 'navigation_menu_ordering': - return $this->GetNavigationMenuOrdering(); - break; - default: - throw new PropertyNotFoundException("The property '$method' do not exists in BricksCollection"); - } - } + { + // Made for cleaner/easier access from twig (eg. app['brick_collection'].bricks) + switch ($method) + { + case 'bricks': + return $this->GetBricks(); + break; + case 'home_ordering': + return $this->GetHomeOrdering(); + break; + case 'navigation_menu_ordering': + return $this->GetNavigationMenuOrdering(); + break; + default: + throw new PropertyNotFoundException("The property '$method' do not exists in BricksCollection"); + } + } /** * @return \Combodo\iTop\Portal\Brick\PortalBrick[]|null * @throws \Exception */ - public function GetBricks() - { - return $this->aAllowedBricks; - } + public function GetBricks() + { + return $this->aAllowedBricks; + } public function GetHomeOrdering() { @@ -122,93 +122,95 @@ class BrickCollection * @throws \Combodo\iTop\Portal\Brick\BrickNotFoundException * @throws \Exception */ - public function GetBrickById($sId) - { - foreach ($this->GetBricks() as $oBrick) { - if ($oBrick->GetId() === $sId) - { - return $oBrick; - } - } + public function GetBrickById($sId) + { + foreach ($this->GetBricks() as $oBrick) + { + if ($oBrick->GetId() === $sId) + { + return $oBrick; + } + } - throw new BrickNotFoundException('Brick with id = "'.$sId.'" was not found among loaded bricks.'); - } + throw new BrickNotFoundException('Brick with id = "'.$sId.'" was not found among loaded bricks.'); + } /** * @throws \Exception */ private function Load() - { - $aRawBrickList = $this->GetRawBrickList(); + { + $aRawBrickList = $this->GetRawBrickList(); - foreach ($aRawBrickList as $oBrick) { - ApplicationHelper::LoadBrickSecurity($oBrick); + foreach ($aRawBrickList as $oBrick) + { + ApplicationHelper::LoadBrickSecurity($oBrick); - if ($oBrick->GetActive() && $oBrick->IsGrantedForProfiles(UserRights::ListProfiles())) - { - $this->aAllowedBricks[] = $oBrick; - if ($oBrick->GetVisibleHome()) - { - $this->iDisplayedInHome++; - } - if ($oBrick->GetVisibleNavigationMenu()) - { - $this->iDisplayedInNavigationMenu++; - } - } - } + if ($oBrick->GetActive() && $oBrick->IsGrantedForProfiles(UserRights::ListProfiles())) + { + $this->aAllowedBricks[] = $oBrick; + if ($oBrick->GetVisibleHome()) + { + $this->iDisplayedInHome++; + } + if ($oBrick->GetVisibleNavigationMenu()) + { + $this->iDisplayedInNavigationMenu++; + } + } + } - // - Sorting bricks by rank - // - Home - $this->aHomeOrdering = $this->aAllowedBricks; - usort($this->aHomeOrdering, function (PortalBrick $a, PortalBrick $b) { - return $a->GetRankHome() > $b->GetRankHome(); - }); - // - Navigation menu - $this->aNavigationMenuOrdering = $this->aAllowedBricks; - usort($this->aNavigationMenuOrdering, function (PortalBrick $a, PortalBrick $b) { - return $a->GetRankNavigationMenu() > $b->GetRankNavigationMenu(); - }); - } + // - Sorting bricks by rank + // - Home + $this->aHomeOrdering = $this->aAllowedBricks; + usort($this->aHomeOrdering, function (PortalBrick $a, PortalBrick $b) { + return $a->GetRankHome() > $b->GetRankHome(); + }); + // - Navigation menu + $this->aNavigationMenuOrdering = $this->aAllowedBricks; + usort($this->aNavigationMenuOrdering, function (PortalBrick $a, PortalBrick $b) { + return $a->GetRankNavigationMenu() > $b->GetRankNavigationMenu(); + }); + } /** * @return array * @throws \Exception */ private function GetRawBrickList() - { - $aBricks = array(); - /** @var \Combodo\iTop\DesignElement $oBrickNode */ - foreach ($this->oModuleDesign->GetNodes('/module_design/bricks/brick') as $oBrickNode) - { - $sBrickClass = $oBrickNode->getAttribute('xsi:type'); - try - { - if (class_exists($sBrickClass)) - { - /** @var \Combodo\iTop\Portal\Brick\PortalBrick $oBrick */ - $oBrick = new $sBrickClass(); - $oBrick->LoadFromXml($oBrickNode); + { + $aBricks = array(); + /** @var \Combodo\iTop\DesignElement $oBrickNode */ + foreach ($this->oModuleDesign->GetNodes('/module_design/bricks/brick') as $oBrickNode) + { + $sBrickClass = $oBrickNode->getAttribute('xsi:type'); + try + { + if (class_exists($sBrickClass)) + { + /** @var \Combodo\iTop\Portal\Brick\PortalBrick $oBrick */ + $oBrick = new $sBrickClass(); + $oBrick->LoadFromXml($oBrickNode); - $aBricks[] = $oBrick; - } - else - { - throw new DOMFormatException('Unknown brick class "'.$sBrickClass.'" from xsi:type attribute', null, - null, $oBrickNode); - } - } - catch (DOMFormatException $e) - { - throw new Exception('Could not create brick ('.$sBrickClass.') from XML because of a DOM problem : '.$e->getMessage()); - } - catch (Exception $e) - { - throw new Exception('Could not create brick ('.$sBrickClass.') from XML : '.$oBrickNode->Dump().' '.$e->getMessage()); - } - } + $aBricks[] = $oBrick; + } + else + { + throw new DOMFormatException('Unknown brick class "'.$sBrickClass.'" from xsi:type attribute', null, + null, $oBrickNode); + } + } + catch (DOMFormatException $e) + { + throw new Exception('Could not create brick ('.$sBrickClass.') from XML because of a DOM problem : '.$e->getMessage()); + } + catch (Exception $e) + { + throw new Exception('Could not create brick ('.$sBrickClass.') from XML : '.$oBrickNode->Dump().' '.$e->getMessage()); + } + } - return $aBricks; - } + return $aBricks; + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickNotFoundException.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickNotFoundException.php index c0bfb0234..e76df7d24 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickNotFoundException.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/BrickNotFoundException.php @@ -1,8 +1,22 @@ */ class BrickNotFoundException extends Exception { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/BrowseBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/BrowseBrick.php index 0605bb59b..b28fc77fd 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/BrowseBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/BrowseBrick.php @@ -27,49 +27,79 @@ use Combodo\iTop\DesignElement; /** * Description of BrowseBrick - * + * + * @package Combodo\iTop\Portal\Brick + * @since 2.3.0 * @author Guillaume Lajarige */ class BrowseBrick extends PortalBrick { + /** @var string ENUM_BROWSE_MODE_LIST */ const ENUM_BROWSE_MODE_LIST = 'list'; - const ENUM_BROWSE_MODE_TREE = 'tree'; - const ENUM_BROWSE_MODE_MOSAIC = 'mosaic'; + /** @var string ENUM_BROWSE_MODE_TREE */ + const ENUM_BROWSE_MODE_TREE = 'tree'; + /** @var string ENUM_BROWSE_MODE_MOSAIC */ + const ENUM_BROWSE_MODE_MOSAIC = 'mosaic'; + /** @var string ENUM_ACTION_VIEW */ const ENUM_ACTION_VIEW = 'view'; + /** @var string ENUM_ACTION_EDIT */ const ENUM_ACTION_EDIT = 'edit'; + /** @var string ENUM_ACTION_DRILLDOWN */ const ENUM_ACTION_DRILLDOWN = 'drilldown'; - + /** @var string ENUM_ACTION_CREATE_FROM_THIS */ const ENUM_ACTION_CREATE_FROM_THIS = 'create_from_this'; + + /** @var string ENUM_ACTION_ICON_CLASS_VIEW */ const ENUM_ACTION_ICON_CLASS_VIEW = 'glyphicon glyphicon-list-alt'; + /** @var string ENUM_ACTION_ICON_CLASS_EDIT */ const ENUM_ACTION_ICON_CLASS_EDIT = 'glyphicon glyphicon-pencil'; + /** @var string ENUM_ACTION_ICON_CLASS_DRILLDOWN */ const ENUM_ACTION_ICON_CLASS_DRILLDOWN = 'glyphicon glyphicon-menu-down'; + /** @var string ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS */ const ENUM_ACTION_ICON_CLASS_CREATE_FROM_THIS = 'glyphicon glyphicon-edit'; + /** @var string ENUM_FACTORY_TYPE_METHOD */ const ENUM_FACTORY_TYPE_METHOD = 'method'; + /** @var string ENUM_FACTORY_TYPE_CLASS */ const ENUM_FACTORY_TYPE_CLASS = 'class'; + // Overloaded constants const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-map'; - const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-map fa-2x'; - const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_FULL; + const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-map fa-2x'; + const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_FULL; + + /** @var string DEFAULT_LEVEL_NAME_ATT */ const DEFAULT_LEVEL_NAME_ATT = 'name'; + /** @var string DEFAULT_BROWSE_MODE */ const DEFAULT_BROWSE_MODE = self::ENUM_BROWSE_MODE_LIST; + /** @var string DEFAULT_ACTION */ const DEFAULT_ACTION = self::ENUM_ACTION_DRILLDOWN; + /** @var string DEFAULT_ACTION_OPENING_TARGET */ const DEFAULT_ACTION_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL; + /** @var int DEFAULT_LIST_LENGTH */ const DEFAULT_LIST_LENGTH = 20; - static $aBrowseModes = array( - self::ENUM_BROWSE_MODE_LIST, - self::ENUM_BROWSE_MODE_TREE, - self::ENUM_BROWSE_MODE_MOSAIC - ); + // Overloaded variables + public static $sRouteName = 'p_browse_brick'; - static $sRouteName = 'p_browse_brick'; + /** @var array $aBrowseModes */ + public static $aBrowseModes = array( + self::ENUM_BROWSE_MODE_LIST, + self::ENUM_BROWSE_MODE_TREE, + self::ENUM_BROWSE_MODE_MOSAIC, + ); + /** @var array $aLevels */ protected $aLevels; + /** @var array $aAvailablesBrowseModes */ protected $aAvailablesBrowseModes; + /** @var string $sDefaultBrowseMode */ protected $sDefaultBrowseMode; + /** + * BrowseBrick constructor. + */ public function __construct() { parent::__construct(); @@ -90,7 +120,7 @@ class BrowseBrick extends PortalBrick } /** - * Returns the brick availables browse modes + * Returns the brick available browse modes * * @return array */ @@ -109,42 +139,45 @@ class BrowseBrick extends PortalBrick return $this->sDefaultBrowseMode; } - /** - * Sets the levels of the brick - * - * @param array $aLevels - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick - */ + /** + * Sets the levels of the brick + * + * @param array $aLevels + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick + */ public function SetLevels($aLevels) { $this->aLevels = $aLevels; + return $this; } /** - * Sets the availables browse modes of the brick + * Sets the available browse modes of the brick * * @param array $aAvailablesBrowseModes - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick */ public function SetAvailablesBrowseModes($aAvailablesBrowseModes) { $this->aAvailablesBrowseModes = $aAvailablesBrowseModes; + return $this; } /** - * Sets the adefault browse mode of the brick + * Sets the default browse mode of the brick * * @param string $sDefaultBrowseMode - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick */ public function SetDefaultBrowseMode($sDefaultBrowseMode) { $this->sDefaultBrowseMode = $sDefaultBrowseMode; + return $this; } @@ -162,12 +195,13 @@ class BrowseBrick extends PortalBrick * Adds $aLevel to the list of levels for that brick * * @param array $aLevel - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick */ public function AddLevel($aLevel) { $this->aLevels[] = $aLevel; + return $this; } @@ -175,8 +209,8 @@ class BrowseBrick extends PortalBrick * Removes $aLevel from the list of levels browse modes * * @param string $sLevel - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick */ public function RemoveLevels($sLevel) { @@ -184,6 +218,7 @@ class BrowseBrick extends PortalBrick { unset($this->aLevels[$sLevel]); } + return $this; } @@ -191,13 +226,14 @@ class BrowseBrick extends PortalBrick * Adds $sModeId to the list of availables browse modes for that brick * * @param string $sModeId - * @param array $aData Hash array containing 'template' => TEMPLATE_PATH - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * @param array $aData Hash array containing 'template' => TEMPLATE_PATH + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick */ public function AddAvailableBrowseMode($sModeId, $aData = array()) { $this->aAvailablesBrowseModes[$sModeId] = $aData; + return $this; } @@ -205,8 +241,8 @@ class BrowseBrick extends PortalBrick * Removes $sModeId from the list of availables browse modes * * @param string $sModeId - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick */ public function RemoveAvailableBrowseMode($sModeId) { @@ -214,6 +250,7 @@ class BrowseBrick extends PortalBrick { unset($this->aAvailablesBrowseModes[$sModeId]); } + return $this; } @@ -222,9 +259,9 @@ class BrowseBrick extends PortalBrick * This is used to set all the brick attributes at once. * * @param \Combodo\iTop\DesignElement $oMDElement - * - * @return \Combodo\iTop\Portal\Brick\BrowseBrick - * + * + * @return \Combodo\iTop\Portal\Brick\BrowseBrick + * * @throws \DOMFormatException */ public function LoadFromXml(DesignElement $oMDElement) @@ -232,11 +269,13 @@ class BrowseBrick extends PortalBrick parent::LoadFromXml($oMDElement); // Checking specific elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) { case 'levels': + /** @var \Combodo\iTop\DesignElement $oLevelNode */ foreach ($oBrickSubNode->childNodes as $oLevelNode) { if ($oLevelNode->nodeName === 'level') @@ -246,16 +285,19 @@ class BrowseBrick extends PortalBrick } break; case 'browse_modes': + /** @var \Combodo\iTop\DesignElement $oBrowseModeNode */ foreach ($oBrickSubNode->childNodes as $oBrowseModeNode) { switch ($oBrowseModeNode->nodeName) { case 'availables': + /** @var \Combodo\iTop\DesignElement $oModeNode */ foreach ($oBrowseModeNode->childNodes as $oModeNode) { if (!$oModeNode->hasAttribute('id')) { - throw new DOMFormatException('BrowseBrick : Browse mode must have a unique ID attribute', null, null, $oModeNode); + throw new DOMFormatException('BrowseBrick : Browse mode must have a unique ID attribute', null, + null, $oModeNode); } $sModeId = $oModeNode->getAttribute('id'); @@ -269,7 +311,7 @@ class BrowseBrick extends PortalBrick } else { - $sTemplatePath = 'itop-portal-base/portal/templates/bricks/browse/mode_' . $sModeId . '.html.twig'; + $sTemplatePath = 'itop-portal-base/portal/templates/bricks/browse/mode_'.$sModeId.'.html.twig'; } $aModeData['template'] = $sTemplatePath; @@ -290,10 +332,11 @@ class BrowseBrick extends PortalBrick { throw new DOMFormatException('BrowseBrick : Must have at least one browse mode', null, null, $oMDElement); } - // Checking that default browse mode in among the availables + // Checking that default browse mode in among the available if (!in_array($this->sDefaultBrowseMode, array_keys($this->aAvailablesBrowseModes))) { - throw new DOMFormatException('BrowseBrick : Default browse mode "' . $this->sDefaultBrowseMode . '" must be one of the available browse modes (' . implode(', ', $this->aAvailablesBrowseModes) . ')', null, null, $oMDElement); + throw new DOMFormatException('BrowseBrick : Default browse mode "'.$this->sDefaultBrowseMode.'" must be one of the available browse modes ('.implode(', ', + $this->aAvailablesBrowseModes).')', null, null, $oMDElement); } // Checking that the brick has at least a level if (count($this->GetLevels()) === 0) @@ -305,12 +348,12 @@ class BrowseBrick extends PortalBrick } /** - * Parses the ModuleDesignElement to recursivly load levels + * Parses the ModuleDesignElement to recursively load levels * * @param \Combodo\iTop\DesignElement $oMDElement - * + * * @return array - * + * * @throws \DOMFormatException */ protected function LoadLevelFromXml(DesignElement $oMDElement) @@ -318,12 +361,12 @@ class BrowseBrick extends PortalBrick $aLevel = array( 'parent_att' => null, 'tooltip_att' => null, - 'description_att' => null, - 'image_att' => null, + 'description_att' => null, + 'image_att' => null, 'title' => null, 'name_att' => static::DEFAULT_LEVEL_NAME_ATT, 'fields' => array(), - 'actions' => array('default' => array('type' => static::DEFAULT_ACTION, 'rules' => array())) + 'actions' => array('default' => array('type' => static::DEFAULT_ACTION, 'rules' => array())), ); // Getting level ID @@ -333,9 +376,11 @@ class BrowseBrick extends PortalBrick } else { - throw new DOMFormatException('BrowseBrick : level tag without "id" attribute. It must have one and it must not be empty', null, null, $oMDElement); + throw new DOMFormatException('BrowseBrick : level tag without "id" attribute. It must have one and it must not be empty', null, + null, $oMDElement); } // Getting level properties + /** @var \Combodo\iTop\DesignElement $oLevelPropertyNode */ foreach ($oMDElement->childNodes as $oLevelPropertyNode) { switch ($oLevelPropertyNode->nodeName) @@ -344,17 +389,19 @@ class BrowseBrick extends PortalBrick $sClass = $oLevelPropertyNode->GetText(); if ($sClass === '') { - throw new DOMFormatException('BrowseBrick : class tag is empty. Must contain Classname', null, null, $oLevelPropertyNode); + throw new DOMFormatException('BrowseBrick : class tag is empty. Must contain Classname', null, null, + $oLevelPropertyNode); } - $aLevel['oql'] = 'SELECT ' . $sClass; + $aLevel['oql'] = 'SELECT '.$sClass; break; case 'oql': $sOql = $oLevelPropertyNode->GetText(); if ($sOql === '') { - throw new DOMFormatException('BrowseBrick : oql tag is empty. Must contain OQL statement', null, null, $oLevelPropertyNode); + throw new DOMFormatException('BrowseBrick : oql tag is empty. Must contain OQL statement', null, null, + $oLevelPropertyNode); } $aLevel['oql'] = $sOql; @@ -362,8 +409,8 @@ class BrowseBrick extends PortalBrick case 'parent_att': case 'tooltip_att': - case 'description_att': - case 'image_att': + case 'description_att': + case 'image_att': case 'title': $aLevel[$oLevelPropertyNode->nodeName] = $oLevelPropertyNode->GetText(null); break; @@ -378,6 +425,7 @@ class BrowseBrick extends PortalBrick if ($oLevelPropertyNode->hasChildNodes()) { $aLevel[$sTagName] = array(); + /** @var \Combodo\iTop\DesignElement $oFieldNode */ foreach ($oLevelPropertyNode->childNodes as $oFieldNode) { if ($oFieldNode->hasAttribute('id') && $oFieldNode->getAttribute('id') !== '') @@ -386,7 +434,8 @@ class BrowseBrick extends PortalBrick } else { - throw new DOMFormatException('BrowseBrick : ' . $sTagName . '/* tag must have an "id" attribute and it must not be empty', null, null, $oFieldNode); + throw new DOMFormatException('BrowseBrick : '.$sTagName.'/* tag must have an "id" attribute and it must not be empty', + null, null, $oFieldNode); } $oFieldSubNode = $oFieldNode->GetOptionalElement('hidden'); @@ -404,13 +453,14 @@ class BrowseBrick extends PortalBrick if ($oLevelPropertyNode->hasChildNodes()) { $aLevel[$sTagName] = array(); + /** @var \Combodo\iTop\DesignElement $oActionNode */ foreach ($oLevelPropertyNode->childNodes as $oActionNode) { if ($oActionNode->hasAttribute('id') && $oActionNode->getAttribute('id') !== '') { $aTmpAction = array( 'type' => null, - 'rules' => array() + 'rules' => array(), ); // Action type @@ -422,14 +472,14 @@ class BrowseBrick extends PortalBrick { $aTmpAction['factory'] = array( 'type' => static::ENUM_FACTORY_TYPE_METHOD, - 'value' => $oActionNode->GetOptionalElement('factory_method')->GetText() + 'value' => $oActionNode->GetOptionalElement('factory_method')->GetText(), ); } else { $aTmpAction['factory'] = array( 'type' => static::ENUM_FACTORY_TYPE_CLASS, - 'value' => $oActionNode->GetUniqueElement('class')->GetText() + 'value' => $oActionNode->GetUniqueElement('class')->GetText(), ); } } @@ -446,21 +496,23 @@ class BrowseBrick extends PortalBrick $aTmpAction['icon_class'] = $oActionIconClassNode->GetText(); } // Action opening target - $oActionOpeningTargetNode = $oActionNode->GetOptionalElement('opening_target'); - if($oActionOpeningTargetNode !== null) - { - $aTmpAction['opening_target'] = $oActionOpeningTargetNode->GetText(static::DEFAULT_ACTION_OPENING_TARGET); - } - else - { - $aTmpAction['opening_target'] = static::DEFAULT_ACTION_OPENING_TARGET; - } - // - Checking that opening target is among authorized modes - if(!in_array($aTmpAction['opening_target'], static::$aOpeningTargets)) - { - throw new DOMFormatException('BrowseBrick : ' . $sTagName . '/action/opening_target has a wrong value. "'.$aTmpAction['opening_target'].'" given, '.implode('|', static::$aOpeningTargets).' expected.', null, null, $oActionOpeningTargetNode); - } + $oActionOpeningTargetNode = $oActionNode->GetOptionalElement('opening_target'); + if ($oActionOpeningTargetNode !== null) + { + $aTmpAction['opening_target'] = $oActionOpeningTargetNode->GetText(static::DEFAULT_ACTION_OPENING_TARGET); + } + else + { + $aTmpAction['opening_target'] = static::DEFAULT_ACTION_OPENING_TARGET; + } + // - Checking that opening target is among authorized modes + if (!in_array($aTmpAction['opening_target'], static::$aOpeningTargets)) + { + throw new DOMFormatException('BrowseBrick : '.$sTagName.'/action/opening_target has a wrong value. "'.$aTmpAction['opening_target'].'" given, '.implode('|', + static::$aOpeningTargets).' expected.', null, null, $oActionOpeningTargetNode); + } // Action rules + /** @var \Combodo\iTop\DesignElement $oRuleNode */ foreach ($oActionNode->GetNodes('./rules/rule') as $oRuleNode) { if ($oRuleNode->hasAttribute('id') && $oRuleNode->getAttribute('id') !== '') @@ -469,7 +521,8 @@ class BrowseBrick extends PortalBrick } else { - throw new DOMFormatException('BrowseBrick : ' . $sTagName . '/rules/rule tag must have an "id" attribute and it must not be empty', null, null, $oRuleNode); + throw new DOMFormatException('BrowseBrick : '.$sTagName.'/rules/rule tag must have an "id" attribute and it must not be empty', + null, null, $oRuleNode); } } @@ -477,7 +530,8 @@ class BrowseBrick extends PortalBrick } else { - throw new DOMFormatException('BrowseBrick : ' . $sTagName . '/* tag must have an "id" attribute and it must not be empty', null, null, $oActionNode); + throw new DOMFormatException('BrowseBrick : '.$sTagName.'/* tag must have an "id" attribute and it must not be empty', + null, null, $oActionNode); } } } @@ -495,13 +549,13 @@ class BrowseBrick extends PortalBrick break; } } - + // Checking if level has an oql if (!isset($aLevel['oql']) || $aLevel['oql'] === '') { throw new DOMFormatException('BrowseBrick : must have a valid tag', null, null, $oMDElement); } - + return $aLevel; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/CreateBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/CreateBrick.php index 08e514bf4..7b86d256b 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/CreateBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/CreateBrick.php @@ -27,18 +27,27 @@ use Combodo\iTop\DesignElement; /** * Description of CreateBrick - * - * @author Guillaume Lajarige + * + * @package Combodo\iTop\Portal\Brick + * @since 2.4.0 + * @author Guillaume Lajarige */ class CreateBrick extends PortalBrick { + // Overloaded constants const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-plus'; const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-plus fa-2x'; - const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig'; + const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/create/modal.html.twig'; + + /** @var string DEFAULT_CLASS */ const DEFAULT_CLASS = ''; - static $sRouteName = 'p_create_brick'; + // Overloaded variables + public static $sRouteName = 'p_create_brick'; + + /** @var string $sClass */ protected $sClass; + /** @var array $aRules */ protected $aRules; /** @@ -62,16 +71,17 @@ class CreateBrick extends PortalBrick return $this->sClass; } - /** - * Sets the class of the brick - * - * @param string $sClass - * - * @return \Combodo\iTop\Portal\Brick\CreateBrick - */ + /** + * Sets the class of the brick + * + * @param string $sClass + * + * @return \Combodo\iTop\Portal\Brick\CreateBrick + */ public function SetClass($sClass) { $this->sClass = $sClass; + return $this; } @@ -89,30 +99,32 @@ class CreateBrick extends PortalBrick * Sets the rules of the brick * * @param array $aRules - * - * @return \Combodo\iTop\Portal\Brick\CreateBrick + * + * @return \Combodo\iTop\Portal\Brick\CreateBrick */ public function SetRules($aRules) { $this->aRules = $aRules; + return $this; } - /** - * Load the brick's data from the xml passed as a ModuleDesignElement. - * This is used to set all the brick attributes at once. - * - * @param \Combodo\iTop\DesignElement $oMDElement - * - * @return \Combodo\iTop\Portal\Brick\CreateBrick - * - * @throws \DOMFormatException - */ + /** + * Load the brick's data from the xml passed as a ModuleDesignElement. + * This is used to set all the brick attributes at once. + * + * @param \Combodo\iTop\DesignElement $oMDElement + * + * @return \Combodo\iTop\Portal\Brick\CreateBrick + * + * @throws \DOMFormatException + */ public function LoadFromXml(DesignElement $oMDElement) { parent::LoadFromXml($oMDElement); // Checking specific elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) @@ -122,6 +134,7 @@ class CreateBrick extends PortalBrick break; case 'rules': + /** @var \Combodo\iTop\DesignElement $oRuleNode */ foreach ($oBrickSubNode->childNodes as $oRuleNode) { if ($oRuleNode->hasAttribute('id') && $oRuleNode->getAttribute('id') !== '') @@ -130,7 +143,8 @@ class CreateBrick extends PortalBrick } else { - throw new DOMFormatException('CreateBrick: /rules/rule tag must have an "id" attribute and it must not be empty', null, null, $oRuleNode); + throw new DOMFormatException('CreateBrick: /rules/rule tag must have an "id" attribute and it must not be empty', + null, null, $oRuleNode); } } break; diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/FilterBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/FilterBrick.php index 31cbf39ce..c55fb3d42 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/FilterBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/FilterBrick.php @@ -27,28 +27,44 @@ use Combodo\iTop\DesignElement; /** * Description of FilterBrick - * + * + * @package Combodo\iTop\Portal\Brick + * @since 2.4.0 * @author Guillaume Lajarige */ class FilterBrick extends PortalBrick { + // Overloaded constants const DEFAULT_VISIBLE_NAVIGATION_MENU = false; const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/filter/tile.html.twig'; const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-search'; const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-search fa-2x'; + /** @var string DEFAULT_TARGET_BRICK_CLASS */ const DEFAULT_TARGET_BRICK_CLASS = 'Combodo\\iTop\\Portal\\Brick\\BrowseBrick'; + /** @var string DEFAULT_SEARCH_PLACEHOLDER_VALUE */ const DEFAULT_SEARCH_PLACEHOLDER_VALUE = 'Brick:Portal:Filter:SearchInput:Placeholder'; + /** @var string DEFAULT_SEARCH_SUBMIT_LABEL */ const DEFAULT_SEARCH_SUBMIT_LABEL = 'Brick:Portal:Filter:SearchInput:Submit'; + /** @var string DEFAULT_SEARCH_SUBMIT_CLASS */ const DEFAULT_SEARCH_SUBMIT_CLASS = ''; + /** @var string $sTargetBrickId */ protected $sTargetBrickId; + /** @var string $sTargetBrickClass */ protected $sTargetBrickClass; + /** @var string $sTargetBrickTab */ protected $sTargetBrickTab; + /** @var string $sSearchPlaceholderValue */ protected $sSearchPlaceholderValue; + /** @var string $sSearchSubmitLabel */ protected $sSearchSubmitLabel; + /** @var string $sSearchSubmitClass */ protected $sSearchSubmitClass; + /** + * FilterBrick constructor. + */ public function __construct() { parent::__construct(); @@ -59,65 +75,111 @@ class FilterBrick extends PortalBrick $this->sSearchSubmitClass = static::DEFAULT_SEARCH_SUBMIT_CLASS; } + /** + * @return string + */ public function GetTargetBrickId() { return $this->sTargetBrickId; } + /** + * @return string + */ public function GetTargetBrickClass() { return $this->sTargetBrickClass; } + /** + * @return string + */ public function GetTargetBrickTab() { return $this->sTargetBrickTab; } + /** + * @return string + */ public function GetSearchPlaceholderValue() { return $this->sSearchPlaceholderValue; } + /** + * @return string + */ public function GetSearchSubmitLabel() { return $this->sSearchSubmitLabel; } + /** + * @return string + */ public function GetSearchSubmitClass() { return $this->sSearchSubmitClass; } + /** + * @param string $sTargetBrickId + * + * @return $this + */ public function SetTargetBrickId($sTargetBrickId) { $this->sTargetBrickId = $sTargetBrickId; return $this; } + /** + * @param string $sTargetBrickClass + */ public function SetTargetBrickClass($sTargetBrickClass) { $this->sTargetBrickClass = $sTargetBrickClass; } + /** + * @param string $sTargetBrickTab + * + * @return $this + */ public function SetTargetBrickTab($sTargetBrickTab) { $this->sTargetBrickTab = $sTargetBrickTab; return $this; } + /** + * @param string $sSearchPlaceholderValue + * + * @return $this + */ public function SetSearchPlaceholderValue($sSearchPlaceholderValue) { $this->sSearchPlaceholderValue = $sSearchPlaceholderValue; return $this; } + /** + * @param string $sSearchSubmitLabel + * + * @return $this + */ public function SetSearchSubmitLabel($sSearchSubmitLabel) { $this->sSearchSubmitLabel = $sSearchSubmitLabel; return $this; } + /** + * @param string $sSearchSubmitClass + * + * @return $this + */ public function SetSearchSubmitClass($sSearchSubmitClass) { $this->sSearchSubmitClass = $sSearchSubmitClass; @@ -139,11 +201,13 @@ class FilterBrick extends PortalBrick parent::LoadFromXml($oMDElement); // Checking specific elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) { case 'target_brick': + /** @var \Combodo\iTop\DesignElement $oTargetBrickNode */ foreach ($oBrickSubNode->childNodes as $oTargetBrickNode) { switch ($oTargetBrickNode->nodeName) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/ManageBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/ManageBrick.php index c08d144c8..4e72dbc95 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/ManageBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/ManageBrick.php @@ -30,149 +30,188 @@ use Combodo\iTop\DesignElement; class ManageBrick extends PortalBrick { + /** @var string ENUM_ACTION_VIEW */ const ENUM_ACTION_VIEW = 'view'; + /** @var string ENUM_ACTION_EDIT */ const ENUM_ACTION_EDIT = 'edit'; - const ENUM_TILE_MODE_TEXT = 'text'; - const ENUM_TILE_MODE_BADGE = 'badge'; - const ENUM_TILE_MODE_PIE = 'pie-chart'; - const ENUM_TILE_MODE_BAR = 'bar-chart'; - const ENUM_TILE_MODE_TOP = 'top-list'; + /** @var string ENUM_TILE_MODE_TEXT */ + const ENUM_TILE_MODE_TEXT = 'text'; + /** @var string ENUM_TILE_MODE_BADGE */ + const ENUM_TILE_MODE_BADGE = 'badge'; + /** @var string ENUM_TILE_MODE_PIE */ + const ENUM_TILE_MODE_PIE = 'pie-chart'; + /** @var string ENUM_TILE_MODE_BAR */ + const ENUM_TILE_MODE_BAR = 'bar-chart'; + /** @var string ENUM_TILE_MODE_TOP */ + const ENUM_TILE_MODE_TOP = 'top-list'; - const ENUM_DISPLAY_MODE_LIST = 'list'; - const ENUM_DISPLAY_MODE_PIE = 'pie-chart'; - const ENUM_DISPLAY_MODE_BAR = 'bar-chart'; + /** @var string ENUM_DISPLAY_MODE_LIST */ + const ENUM_DISPLAY_MODE_LIST = 'list'; + /** @var string ENUM_DISPLAY_MODE_PIE */ + const ENUM_DISPLAY_MODE_PIE = 'pie-chart'; + /** @var string ENUM_DISPLAY_MODE_BAR */ + const ENUM_DISPLAY_MODE_BAR = 'bar-chart'; + /** @var string ENUM_PAGE_TEMPLATE_PATH_TABLE */ const ENUM_PAGE_TEMPLATE_PATH_TABLE = 'itop-portal-base/portal/templates/bricks/manage/layout-table.html.twig'; - const ENUM_PAGE_TEMPLATE_PATH_CHART = 'itop-portal-base/portal/templates/bricks/manage/layout-chart.html.twig'; + /** @var string ENUM_PAGE_TEMPLATE_PATH_CHART */ + const ENUM_PAGE_TEMPLATE_PATH_CHART = 'itop-portal-base/portal/templates/bricks/manage/layout-chart.html.twig'; - const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-pencil-square'; + // Overloaded constants + const DEFAULT_DECORATION_CLASS_HOME = 'fa fa-pencil-square'; const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'fa fa-pencil-square fa-2x'; const DEFAULT_PAGE_TEMPLATE_PATH = self::ENUM_PAGE_TEMPLATE_PATH_TABLE; - const DEFAULT_OQL = ''; - const DEFAULT_OPENING_MODE = self::ENUM_ACTION_EDIT; const DEFAULT_DATA_LOADING = self::ENUM_DATA_LOADING_LAZY; - const DEFAULT_LIST_LENGTH = 20; - const DEFAULT_ZLIST_FIELDS = 'list'; - const DEFAULT_SHOW_TAB_COUNTS = false; - const DEFAULT_DISPLAY_MODE = self::ENUM_DISPLAY_MODE_LIST; - const DEFAULT_TILE_MODE = self::ENUM_TILE_MODE_TEXT; - const DEFAULT_GROUP_LIMIT = 0; - const DEFAULT_GROUP_SHOW_OTHERS = true; - const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/tile-default.html.twig'; const DEFAULT_TILE_CONTROLLER_ACTION = 'Combodo\\iTop\\Portal\\Controller\\ManageBrickController::TileAction'; + /** @var string DEFAULT_OQL */ + const DEFAULT_OQL = ''; + /** @var string DEFAULT_OPENING_MODE */ + const DEFAULT_OPENING_MODE = self::ENUM_ACTION_EDIT; + /** @var int DEFAULT_LIST_LENGTH */ + const DEFAULT_LIST_LENGTH = 20; + /** @var string DEFAULT_ZLIST_FIELDS */ + const DEFAULT_ZLIST_FIELDS = 'list'; + /** @var bool DEFAULT_SHOW_TAB_COUNTS */ + const DEFAULT_SHOW_TAB_COUNTS = false; + /** @var string DEFAULT_DISPLAY_MODE */ + const DEFAULT_DISPLAY_MODE = self::ENUM_DISPLAY_MODE_LIST; + /** @var string DEFAULT_TILE_MODE */ + const DEFAULT_TILE_MODE = self::ENUM_TILE_MODE_TEXT; + /** @var int DEFAULT_GROUP_LIMIT */ + const DEFAULT_GROUP_LIMIT = 0; + /** @var bool DEFAULT_GROUP_SHOW_OTHERS */ + const DEFAULT_GROUP_SHOW_OTHERS = true; + + /** @var array $aDisplayModes */ static $aDisplayModes = array( - self::ENUM_DISPLAY_MODE_LIST, - self::ENUM_DISPLAY_MODE_PIE, - self::ENUM_DISPLAY_MODE_BAR, - ); - static $aTileModes = array( - self::ENUM_TILE_MODE_TEXT, - self::ENUM_TILE_MODE_BADGE, - self::ENUM_TILE_MODE_PIE, - self::ENUM_TILE_MODE_BAR, - self::ENUM_TILE_MODE_TOP, - ); - static $aPresentationData = array( - self::ENUM_TILE_MODE_BADGE => array( - 'decorationCssClass' => 'fa fa-id-card-o fa-2x', - 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-badge.html.twig', - 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE, - 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST, - 'need_details' => true, - ), - self::ENUM_TILE_MODE_TOP => array( - 'decorationCssClass' => 'fa fa-signal fa-rotate-270 fa-2x', - 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-top-list.html.twig', - 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE, - 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST, - 'need_details' => true, - ), - self::ENUM_TILE_MODE_PIE => array( - 'decorationCssClass' => 'fa fa-pie-chart fa-2x', - 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig', - 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART, - 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_PIE, - 'need_details' => false, - ), - self::ENUM_TILE_MODE_BAR => array( - 'decorationCssClass' => 'fa fa-bar-chart fa-2x', - 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig', - 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART, - 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_BAR, - 'need_details' => false, - ), - self::ENUM_TILE_MODE_TEXT => array( - 'decorationCssClass' => 'fa fa-pencil-square fa-2x', - 'tileTemplate' => self::DEFAULT_TILE_TEMPLATE_PATH, - 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE, - 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST, - 'need_details' => true, - ), - ); + self::ENUM_DISPLAY_MODE_LIST, + self::ENUM_DISPLAY_MODE_PIE, + self::ENUM_DISPLAY_MODE_BAR, + ); + /** @var array $aTileModes */ + public static $aTileModes = array( + self::ENUM_TILE_MODE_TEXT, + self::ENUM_TILE_MODE_BADGE, + self::ENUM_TILE_MODE_PIE, + self::ENUM_TILE_MODE_BAR, + self::ENUM_TILE_MODE_TOP, + ); + /** @var array $aPresentationData */ + public static $aPresentationData = array( + self::ENUM_TILE_MODE_BADGE => array( + 'decorationCssClass' => 'fa fa-id-card-o fa-2x', + 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-badge.html.twig', + 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE, + 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST, + 'need_details' => true, + ), + self::ENUM_TILE_MODE_TOP => array( + 'decorationCssClass' => 'fa fa-signal fa-rotate-270 fa-2x', + 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-top-list.html.twig', + 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE, + 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST, + 'need_details' => true, + ), + self::ENUM_TILE_MODE_PIE => array( + 'decorationCssClass' => 'fa fa-pie-chart fa-2x', + 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig', + 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART, + 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_PIE, + 'need_details' => false, + ), + self::ENUM_TILE_MODE_BAR => array( + 'decorationCssClass' => 'fa fa-bar-chart fa-2x', + 'tileTemplate' => 'itop-portal-base/portal/templates/bricks/manage/tile-chart.html.twig', + 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_CHART, + 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_BAR, + 'need_details' => false, + ), + self::ENUM_TILE_MODE_TEXT => array( + 'decorationCssClass' => 'fa fa-pencil-square fa-2x', + 'tileTemplate' => self::DEFAULT_TILE_TEMPLATE_PATH, + 'layoutTemplate' => self::ENUM_PAGE_TEMPLATE_PATH_TABLE, + 'layoutDisplayMode' => self::ENUM_DISPLAY_MODE_LIST, + 'need_details' => true, + ), + ); - static $sRouteName = 'p_manage_brick'; + // Overloaded variables + public static $sRouteName = 'p_manage_brick'; + /** @var string $sOql */ protected $sOql; + /** @var string $sOpeningMode */ protected $sOpeningMode; + /** @var array $aGrouping */ protected $aGrouping; + /** @var array $aFields */ protected $aFields; + /** @var array $aExportFields */ protected $aExportFields; + /** @var bool $bShowTabCounts */ protected $bShowTabCounts; - protected $aAvailableDisplayModes = array(); - protected $sDefaultDisplayMode; - - protected $sTileMode; + /** @var array $aAvailableDisplayModes */ + protected $aAvailableDisplayModes = array(); + /** @var string $sDefaultDisplayMode */ + protected $sDefaultDisplayMode; + /** @var string $sTileMode */ + protected $sTileMode; + /** @var int $iGroupLimit */ protected $iGroupLimit; + /** @var bool $bGroupShowOthers */ protected $bGroupShowOthers; - /** - * Returns true if the $sDisplayMode need objects details for rendering. - * - * @param string $sDisplayMode - * - * @return bool - */ + /** + * Returns true if the $sDisplayMode need objects details for rendering. + * + * @param string $sDisplayMode + * + * @return bool + */ static public function AreDetailsNeededForDisplayMode($sDisplayMode) - { - $bNeedDetails = false; - foreach(static::$aPresentationData as $aData) - { - if($aData['layoutDisplayMode'] === $sDisplayMode) - { - $bNeedDetails = $aData['need_details']; - break; - } - } + { + $bNeedDetails = false; + foreach (static::$aPresentationData as $aData) + { + if ($aData['layoutDisplayMode'] === $sDisplayMode) + { + $bNeedDetails = $aData['need_details']; + break; + } + } - return $bNeedDetails; - } + return $bNeedDetails; + } - /** - * Returns the page template path for the $sDisplayMode - * - * @param string $sDisplayMode - * - * @return string - */ - static public function GetPageTemplateFromDisplayMode($sDisplayMode) - { - $sTemplate = static::DEFAULT_PAGE_TEMPLATE_PATH; - foreach(static::$aPresentationData as $aData) - { - if($aData['layoutDisplayMode'] === $sDisplayMode) - { - $sTemplate = $aData['layoutTemplate']; - break; - } - } + /** + * Returns the page template path for the $sDisplayMode + * + * @param string $sDisplayMode + * + * @return string + */ + static public function GetPageTemplateFromDisplayMode($sDisplayMode) + { + $sTemplate = static::DEFAULT_PAGE_TEMPLATE_PATH; + foreach (static::$aPresentationData as $aData) + { + if ($aData['layoutDisplayMode'] === $sDisplayMode) + { + $sTemplate = $aData['layoutTemplate']; + break; + } + } - return $sTemplate; - } + return $sTemplate; + } - public function __construct() + /** + * ManageBrick constructor. + */ + public function __construct() { parent::__construct(); @@ -182,7 +221,7 @@ class ManageBrick extends PortalBrick $this->aFields = array(); $this->aExportFields = array(); $this->bShowTabCounts = static::DEFAULT_SHOW_TAB_COUNTS; - $this->sDefaultDisplayMode = static::DEFAULT_DISPLAY_MODE; + $this->sDefaultDisplayMode = static::DEFAULT_DISPLAY_MODE; $this->sTileMode = static::DEFAULT_TILE_MODE; $this->iGroupLimit = static::DEFAULT_GROUP_LIMIT; @@ -252,33 +291,33 @@ class ManageBrick extends PortalBrick return $this->bShowTabCounts; } - /** - * Returns the brick default display mode - * - * @return string - */ - public function GetDefaultDisplayMode() - { - return $this->sDefaultDisplayMode; - } - - /** - * Sets the default display mode of the brick - * - * @param string $sDefaultDisplayMode - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick - */ - public function SetDefaultDisplayMode($sDefaultDisplayMode) - { - $this->sDefaultDisplayMode = $sDefaultDisplayMode; - - return $this; - } + /** + * Returns the brick default display mode + * + * @return string + */ + public function GetDefaultDisplayMode() + { + return $this->sDefaultDisplayMode; + } /** - * Returns the tile mode (display) - * + * Sets the default display mode of the brick + * + * @param string $sDefaultDisplayMode + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick + */ + public function SetDefaultDisplayMode($sDefaultDisplayMode) + { + $this->sDefaultDisplayMode = $sDefaultDisplayMode; + + return $this; + } + + /** + * Returns the tile mode (display) + * * @return string */ public function GetTileMode() @@ -287,11 +326,11 @@ class ManageBrick extends PortalBrick } /** - * Sets the tile mode (display) - * + * Sets the tile mode (display) + * * @param string $sTileMode - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function SetTileMode($sTileMode) { @@ -349,8 +388,8 @@ class ManageBrick extends PortalBrick * Sets the brick's objects opening mode * * @param string $sOpeningMode - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function SetOpeningMode($sOpeningMode) { @@ -363,8 +402,8 @@ class ManageBrick extends PortalBrick * Sets the grouping of the brick * * @param array $aGrouping - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function SetGrouping($aGrouping) { @@ -377,8 +416,8 @@ class ManageBrick extends PortalBrick * Sets the fields of the brick * * @param array $aFields - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function SetFields($aFields) { @@ -391,8 +430,8 @@ class ManageBrick extends PortalBrick * Sets if the brick should display objects count on tab * * @param bool $bShowTabCounts - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function SetShowTabCounts($bShowTabCounts) { @@ -407,9 +446,9 @@ class ManageBrick extends PortalBrick * Grouping "tabs" must be of form array("attribute" => value) * * @param string $sName (Must be "tabs" or -Not implemented yet, implicit grouping on y axis-) - * @param array $aGrouping - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * @param array $aGrouping + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function AddGrouping($sName, $aGrouping) { @@ -430,8 +469,8 @@ class ManageBrick extends PortalBrick * Removes a grouping by its name * * @param string $sName - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function RemoveGrouping($sName) { @@ -447,8 +486,8 @@ class ManageBrick extends PortalBrick * Adds a field to display from its attribute_code. * * @param string $sAttCode - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function AddField($sAttCode) { @@ -464,8 +503,8 @@ class ManageBrick extends PortalBrick * Removes a field * * @param string $sAttCode - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick */ public function RemoveField($sAttCode) { @@ -537,44 +576,46 @@ class ManageBrick extends PortalBrick return (isset($this->aGrouping['areas'])) ? $this->aGrouping['areas'] : false; } - /** - * @param string $sModeId - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick - * - * @throws \Exception - */ + /** + * @param string $sModeId + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @throws \Exception + */ public function AddAvailableDisplayMode($sModeId) { - if(!in_array($sModeId, static::$aDisplayModes)) - { - throw new Exception('ManageBrick: Display mode "' . $sModeId. '" must be one of the allowed display modes (' . implode(', ', static::$aDisplayModes) . ')'); - } + if (!in_array($sModeId, static::$aDisplayModes)) + { + throw new Exception('ManageBrick: Display mode "'.$sModeId.'" must be one of the allowed display modes ('.implode(', ', + static::$aDisplayModes).')'); + } $this->aAvailableDisplayModes[] = $sModeId; return $this; } - /** - * Removes $sModeId from the list of availables display modes - * - * @param string $sModeId - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick - */ - public function RemoveAvailableDisplayMode($sModeId) - { - if (isset($this->aAvailableDisplayModes[$sModeId])) - { - unset($this->aAvailableDisplayModes[$sModeId]); - } - return $this; - } + /** + * Removes $sModeId from the list of availables display modes + * + * @param string $sModeId + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick + */ + public function RemoveAvailableDisplayMode($sModeId) + { + if (isset($this->aAvailableDisplayModes[$sModeId])) + { + unset($this->aAvailableDisplayModes[$sModeId]); + } + + return $this; + } /** - * Returns the available display modes for the brick (page, not tile) - * + * Returns the available display modes for the brick (page, not tile) + * * @return string[] */ public function GetAvailablesDisplayModes() @@ -619,24 +660,25 @@ class ManageBrick extends PortalBrick return $this->IsGroupingByDistinctValues('areas'); } - /** - * Load the brick's data from the xml passed as a ModuleDesignElement. - * This is used to set all the brick attributes at once. - * - * @param \Combodo\iTop\DesignElement $oMDElement - * - * @return \Combodo\iTop\Portal\Brick\ManageBrick - * - * @throws \Exception - * @throws \DOMFormatException - * @throws \OQLException - */ + /** + * Load the brick's data from the xml passed as a ModuleDesignElement. + * This is used to set all the brick attributes at once. + * + * @param \Combodo\iTop\DesignElement $oMDElement + * + * @return \Combodo\iTop\Portal\Brick\ManageBrick + * + * @throws \Exception + * @throws \DOMFormatException + * @throws \OQLException + */ public function LoadFromXml(DesignElement $oMDElement) { parent::LoadFromXml($oMDElement); $bUseListFieldsForExport = false; // Checking specific elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) @@ -675,11 +717,13 @@ class ManageBrick extends PortalBrick break; case 'display_modes': + /** @var \Combodo\iTop\DesignElement $oDisplayNode */ foreach ($oBrickSubNode->GetNodes('./*') as $oDisplayNode) { switch ($oDisplayNode->nodeName) { case 'availables'; + /** @var \Combodo\iTop\DesignElement $oModeNode */ foreach ($oDisplayNode->childNodes as $oModeNode) { if (!$oModeNode->hasAttribute('id')) @@ -691,7 +735,8 @@ class ManageBrick extends PortalBrick $sModeId = $oModeNode->getAttribute('id'); if (!in_array($sModeId, static::$aDisplayModes)) { - throw new DOMFormatException('ManageBrick: Display mode has an invalid value. Expected '.implode('/', static::$aDisplayModes.', "'.$sModeId.'" given.'), + throw new DOMFormatException('ManageBrick: Display mode has an invalid value. Expected '.implode('/', + static::$aDisplayModes.', "'.$sModeId.'" given.'), null, null, $oModeNode); } @@ -699,12 +744,12 @@ class ManageBrick extends PortalBrick } break; - case 'default': - $this->SetDefaultDisplayMode($oDisplayNode->GetText(static::DEFAULT_DISPLAY_MODE)); - break; + case 'default': + $this->SetDefaultDisplayMode($oDisplayNode->GetText(static::DEFAULT_DISPLAY_MODE)); + break; case 'tile'; - $this->SetTileMode($oDisplayNode->GetText(static::DEFAULT_TILE_MODE)); + $this->SetTileMode($oDisplayNode->GetText(static::DEFAULT_TILE_MODE)); $aTileParametersForType = $this->GetPresentationDataForTileMode($this->sTileMode); $this->SetTileTemplatePath($aTileParametersForType['tileTemplate']); @@ -715,6 +760,7 @@ class ManageBrick extends PortalBrick break; case 'fields': + /** @var \Combodo\iTop\DesignElement $oFieldNode */ foreach ($oBrickSubNode->GetNodes('./field') as $oFieldNode) { if (!$oFieldNode->hasAttribute('id')) @@ -727,11 +773,13 @@ class ManageBrick extends PortalBrick break; case 'export': + /** @var \Combodo\iTop\DesignElement $oExportNode */ foreach ($oBrickSubNode->GetNodes('./*') as $oExportNode) { switch ($oExportNode->nodeName) { case 'fields': + /** @var \Combodo\iTop\DesignElement $oFieldNode */ foreach ($oExportNode->GetNodes('./field') as $oFieldNode) { if (!$oFieldNode->hasAttribute('id')) @@ -754,6 +802,7 @@ class ManageBrick extends PortalBrick case 'grouping': // Tabs grouping + /** @var \Combodo\iTop\DesignElement $oGroupingNode */ foreach ($oBrickSubNode->GetNodes('./tabs/*') as $oGroupingNode) { switch ($oGroupingNode->nodeName) @@ -781,6 +830,7 @@ class ManageBrick extends PortalBrick break; case 'groups': $aGroups = array(); + /** @var \Combodo\iTop\DesignElement $oGroupNode */ foreach ($oGroupingNode->GetNodes('./group') as $oGroupNode) { if (!$oGroupNode->hasAttribute('id')) @@ -792,6 +842,7 @@ class ManageBrick extends PortalBrick $aGroup = array(); $aGroup['id'] = $sGroupId; // We don't put the group id as the $aGroups key because the array will be sorted later in AddGrouping, which replace array keys by integer ordered keys + /** @var \Combodo\iTop\DesignElement $oGroupProperty */ foreach ($oGroupNode->childNodes as $oGroupProperty) { switch ($oGroupProperty->nodeName) @@ -833,21 +884,23 @@ class ManageBrick extends PortalBrick throw new DOMFormatException('ManageBrick: must have a valid tag', null, null, $oMDElement); } - // Checking that the brick has at least a display mode - if (count($this->GetAvailablesDisplayModes()) === 0) - { - $this->AddAvailableDisplayMode(static::DEFAULT_DISPLAY_MODE); - } - // Checking that default display mode in among the availables - if (!in_array($this->sDefaultDisplayMode, $this->aAvailableDisplayModes)) - { - throw new DOMFormatException('ManageBrick: Default display mode "' . $this->sDefaultDisplayMode . '" must be one of the available display modes (' . implode(', ', $this->aAvailableDisplayModes) . ')', null, null, $oMDElement); - } - // Checking that tile mode in among the availables - if (!in_array($this->sTileMode, static::$aTileModes)) - { - throw new DOMFormatException('ManageBrick: Tile mode "' . $this->sTileMode. '" must be one of the allowed tile modes (' . implode(', ', static::$aTileModes) . ')', null, null, $oMDElement); - } + // Checking that the brick has at least a display mode + if (count($this->GetAvailablesDisplayModes()) === 0) + { + $this->AddAvailableDisplayMode(static::DEFAULT_DISPLAY_MODE); + } + // Checking that default display mode in among the availables + if (!in_array($this->sDefaultDisplayMode, $this->aAvailableDisplayModes)) + { + throw new DOMFormatException('ManageBrick: Default display mode "'.$this->sDefaultDisplayMode.'" must be one of the available display modes ('.implode(', ', + $this->aAvailableDisplayModes).')', null, null, $oMDElement); + } + // Checking that tile mode in among the availables + if (!in_array($this->sTileMode, static::$aTileModes)) + { + throw new DOMFormatException('ManageBrick: Tile mode "'.$this->sTileMode.'" must be one of the allowed tile modes ('.implode(', ', + static::$aTileModes).')', null, null, $oMDElement); + } // Checking if specified fields, if not we put those from the details zlist if (empty($this->aFields)) @@ -871,7 +924,7 @@ class ManageBrick extends PortalBrick $sDecorationClassNavigationMenu = $this->GetDecorationClassNavigationMenu(); if (empty($sDecorationClassNavigationMenu) && isset(static::$aPresentationData[$this->sTileMode])) { - /** @var string $sDecorationClassNavigationMenu */ + /** @var string $sDecorationClassNavigationMenu */ $sDecorationClassNavigationMenu = static::$aPresentationData[$this->sTileMode]['decorationCssClass']; if (!empty($sDecorationClassNavigationMenu)) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/PortalBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/PortalBrick.php index 6fb13989b..779355f2b 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/PortalBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/PortalBrick.php @@ -28,47 +28,82 @@ use Combodo\iTop\DesignElement; /** * Description of PortalBrick - * + * * Classes that will be used only in the portal, not the console. * - * @author Guillaume Lajarige + * @package Combodo\iTop\Portal\Brick + * @since 2.3.0 + * @author Guillaume Lajarige */ abstract class PortalBrick extends AbstractBrick { - const ENUM_OPENING_TARGET_MODAL = 'modal'; - const ENUM_OPENING_TARGET_SELF = 'self'; - const ENUM_OPENING_TARGET_NEW = 'new'; + /** @var string ENUM_OPENING_TARGET_MODAL */ + const ENUM_OPENING_TARGET_MODAL = 'modal'; + /** @var string ENUM_OPENING_TARGET_SELF */ + const ENUM_OPENING_TARGET_SELF = 'self'; + /** @var string ENUM_OPENING_TARGET_NEW */ + const ENUM_OPENING_TARGET_NEW = 'new'; + /** @var int DEFAULT_WIDTH */ const DEFAULT_WIDTH = 6; + /** @var int DEFAULT_HEIGHT */ const DEFAULT_HEIGHT = 1; + /** @var bool DEFAULT_MODAL */ const DEFAULT_MODAL = false; + /** @var bool DEFAULT_VISIBLE_HOME */ const DEFAULT_VISIBLE_HOME = true; + /** @var bool DEFAULT_VISIBLE_NAVIGATION_MENU */ const DEFAULT_VISIBLE_NAVIGATION_MENU = true; + /** @var string DEFAULT_DECORATION_CLASS_HOME */ const DEFAULT_DECORATION_CLASS_HOME = ''; + /** @var string DEFAULT_DECORATION_CLASS_NAVIGATION_MENU */ const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = ''; + /** @var string DEFAULT_TILE_TEMPLATE_PATH */ const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/tile.html.twig'; + /** @var string|null DEFAULT_TILE_CONTROLLER_ACTION */ const DEFAULT_TILE_CONTROLLER_ACTION = null; - const DEFAULT_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL; + /** @var string DEFAULT_OPENING_TARGET */ + const DEFAULT_OPENING_TARGET = self::ENUM_OPENING_TARGET_MODAL; + /** @var string|null $sRouteName */ static $sRouteName = null; - static $aOpeningTargets = array(self::ENUM_OPENING_TARGET_MODAL, self::ENUM_OPENING_TARGET_SELF, self::ENUM_OPENING_TARGET_NEW); + /** @var array $aOpeningTargets */ + static $aOpeningTargets = array(self::ENUM_OPENING_TARGET_MODAL, self::ENUM_OPENING_TARGET_SELF, self::ENUM_OPENING_TARGET_NEW); + /** @var int $iWidth */ protected $iWidth; + /** @var int $iHeight */ protected $iHeight; + /** @var bool $bModal */ protected $bModal; + /** @var bool $bVisibleHome */ protected $bVisibleHome; + /** @var bool $bVisibleNavigationMenu */ protected $bVisibleNavigationMenu; + /** @var string $sDecorationClassHome */ protected $sDecorationClassHome; + /** @var string $sDecorationClassNavigationMenu */ protected $sDecorationClassNavigationMenu; + /** @var string $sTileTemplatePath */ protected $sTileTemplatePath; + /** @var string|null $sTileControllerAction */ protected $sTileControllerAction; - protected $sOpeningTarget; + /** @var string $sOpeningTarget */ + protected $sOpeningTarget; + // Vars below are itemization from parent class + /** @var float $fRankHome */ protected $fRankHome; + /** @var float $fRankNavigationMenu */ protected $fRankNavigationMenu; + /** @var string $sTitleHome */ protected $sTitleHome; + /** @var string $sTitleNavigationMenu */ protected $sTitleNavigationMenu; + /** + * @return string|null + */ public static function GetRouteName() { return static::$sRouteName; @@ -90,7 +125,7 @@ abstract class PortalBrick extends AbstractBrick $this->sDecorationClassNavigationMenu = static::DEFAULT_DECORATION_CLASS_NAVIGATION_MENU; $this->sTileTemplatePath = static::DEFAULT_TILE_TEMPLATE_PATH; $this->sTileControllerAction = static::DEFAULT_TILE_CONTROLLER_ACTION; - $this->sOpeningTarget = static::DEFAULT_OPENING_TARGET; + $this->sOpeningTarget = static::DEFAULT_OPENING_TARGET; } /** @@ -223,26 +258,27 @@ abstract class PortalBrick extends AbstractBrick return $this->sTileTemplatePath; } - /** - * Returns the brick's objects opening target (modal, new tab, current window) - * - * @return string - */ - public function GetOpeningTarget() - { - return $this->sOpeningTarget; - } + /** + * Returns the brick's objects opening target (modal, new tab, current window) + * + * @return string + */ + public function GetOpeningTarget() + { + return $this->sOpeningTarget; + } /** * Sets the width of the brick * * @param boolean $iWidth - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetWidth($iWidth) { $this->iWidth = $iWidth; + return $this; } @@ -250,12 +286,13 @@ abstract class PortalBrick extends AbstractBrick * Sets the width of the brick * * @param integer $iHeight - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetHeight($iHeight) { $this->iHeight = $iHeight; + return $this; } @@ -263,12 +300,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick will show in a modal dialog or not * * @param boolean $bModal - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetModal($bModal) { $this->bModal = $bModal; + return $this; } @@ -276,12 +314,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick is visible on the portal's home * * @param boolean $bVisibleHome - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetVisibleHome($bVisibleHome) { $this->bVisibleHome = $bVisibleHome; + return $this; } @@ -289,12 +328,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick is visible on the portal's navigation menu * * @param boolean $bVisibleNavigationMenu - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetVisibleNavigationMenu($bVisibleNavigationMenu) { $this->bVisibleNavigationMenu = $bVisibleNavigationMenu; + return $this; } @@ -302,12 +342,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick's rank on the portal's home * * @param float $fRankHome - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetRankHome($fRankHome) { $this->fRankHome = $fRankHome; + return $this; } @@ -315,12 +356,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick's rank on the portal's navigation menu * * @param float $fRankNavigationMenu - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetRankNavigationMenu($fRankNavigationMenu) { $this->fRankNavigationMenu = $fRankNavigationMenu; + return $this; } @@ -328,12 +370,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick's decoration class on the portal's home * * @param string $sDecorationClassHome - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetDecorationClassHome($sDecorationClassHome) { $this->sDecorationClassHome = $sDecorationClassHome; + return $this; } @@ -341,12 +384,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick's decoration class on the portal's navigation menu * * @param string $sDecorationClassNavigationMenu - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetDecorationClassNavigationMenu($sDecorationClassNavigationMenu) { $this->sDecorationClassNavigationMenu = $sDecorationClassNavigationMenu; + return $this; } @@ -354,12 +398,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick's title on the portal's home * * @param string $sTitleHome - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetTitleHome($sTitleHome) { $this->sTitleHome = $sTitleHome; + return $this; } @@ -367,12 +412,13 @@ abstract class PortalBrick extends AbstractBrick * Sets if the brick's title on the portal's navigation menu * * @param string $sTitleNavigationMenu - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetTitleNavigationMenu($sTitleNavigationMenu) { $this->sTitleNavigationMenu = $sTitleNavigationMenu; + return $this; } @@ -380,12 +426,13 @@ abstract class PortalBrick extends AbstractBrick * Sets the brick tile template path * * @param string $sTileTemplatePath - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetTileTemplatePath($sTileTemplatePath) { $this->sTileTemplatePath = $sTileTemplatePath; + return $this; } @@ -393,53 +440,56 @@ abstract class PortalBrick extends AbstractBrick * Sets the brick tile controller action * * @param string $sTileControllerAction - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick */ public function SetTileControllerAction($sTileControllerAction) { $this->sTileControllerAction = $sTileControllerAction; + return $this; } - /** - * Sets the brick's objects opening target - * - * @param string $sOpeningTarget - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick - */ - public function SetOpeningTarget($sOpeningTarget) - { - $this->sOpeningTarget = $sOpeningTarget; - return $this; - } + /** + * Sets the brick's objects opening target + * + * @param string $sOpeningTarget + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick + */ + public function SetOpeningTarget($sOpeningTarget) + { + $this->sOpeningTarget = $sOpeningTarget; - /** - * Load the brick's data from the xml passed as a ModuleDesignElement. - * This is used to set all the brick attributes at once. - * - * @param \Combodo\iTop\DesignElement $oMDElement - * - * @return \Combodo\iTop\Portal\Brick\PortalBrick - * - * @throws \DOMFormatException - */ + return $this; + } + + /** + * Load the brick's data from the xml passed as a ModuleDesignElement. + * This is used to set all the brick attributes at once. + * + * @param \Combodo\iTop\DesignElement $oMDElement + * + * @return \Combodo\iTop\Portal\Brick\PortalBrick + * + * @throws \DOMFormatException + */ public function LoadFromXml(DesignElement $oMDElement) { parent::LoadFromXml($oMDElement); // Checking specific elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) { case 'width': - $this->SetWidth((int) $oBrickSubNode->GetText(static::DEFAULT_WIDTH)); + $this->SetWidth((int)$oBrickSubNode->GetText(static::DEFAULT_WIDTH)); break; case 'height': - $this->SetHeight((int) $oBrickSubNode->GetText(static::DEFAULT_HEIGHT)); + $this->SetHeight((int)$oBrickSubNode->GetText(static::DEFAULT_HEIGHT)); break; case 'modal': @@ -473,10 +523,12 @@ abstract class PortalBrick extends AbstractBrick break; case 'templates': - $oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id=' . ModuleDesign::XPathQuote('tile') . ']'); + $oTemplateNodeList = $oBrickSubNode->GetNodes('template[@id='.ModuleDesign::XPathQuote('tile').']'); if ($oTemplateNodeList->length > 0) { - $this->SetTileTemplatePath($oTemplateNodeList->item(0)->GetText(static::DEFAULT_TILE_TEMPLATE_PATH)); + /** @var \Combodo\iTop\DesignElement $oTemplateNode */ + $oTemplateNode = $oTemplateNodeList->item(0); + $this->SetTileTemplatePath($oTemplateNode->GetText(static::DEFAULT_TILE_TEMPLATE_PATH)); } break; @@ -569,15 +621,17 @@ abstract class PortalBrick extends AbstractBrick $this->SetTileControllerAction($oBrickSubNode->GetText(static::DEFAULT_TILE_CONTROLLER_ACTION)); break; - case 'opening_target': - $sOpeningTarget = $oBrickSubNode->GetText(static::DEFAULT_OPENING_TARGET); - if (!in_array($sOpeningTarget, array(static::ENUM_OPENING_TARGET_MODAL, static::ENUM_OPENING_TARGET_NEW, static::ENUM_OPENING_TARGET_SELF))) - { - throw new DOMFormatException('PortalBrick : opening_target tag value must be modal|new|self ("' . $sOpeningTarget . '" given)', null, null, $oBrickSubNode); - } + case 'opening_target': + $sOpeningTarget = $oBrickSubNode->GetText(static::DEFAULT_OPENING_TARGET); + if (!in_array($sOpeningTarget, + array(static::ENUM_OPENING_TARGET_MODAL, static::ENUM_OPENING_TARGET_NEW, static::ENUM_OPENING_TARGET_SELF))) + { + throw new DOMFormatException('PortalBrick : opening_target tag value must be modal|new|self ("'.$sOpeningTarget.'" given)', + null, null, $oBrickSubNode); + } - $this->SetOpeningTarget($sOpeningTarget); - break; + $this->SetOpeningTarget($sOpeningTarget); + break; } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/PropertyNotFoundException.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/PropertyNotFoundException.php index 3b7f507f7..084eb8ca9 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/PropertyNotFoundException.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/PropertyNotFoundException.php @@ -1,8 +1,23 @@ */ class PropertyNotFoundException extends Exception { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Brick/UserProfileBrick.php b/datamodels/2.x/itop-portal-base/portal/src/Brick/UserProfileBrick.php index 51245a4e3..8a7ea14d5 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Brick/UserProfileBrick.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Brick/UserProfileBrick.php @@ -27,27 +27,43 @@ use Combodo\iTop\DesignElement; /** * Description of UserProfileBrick * + * @package Combodo\iTop\Portal\Brick + * @since 2.7.0 * @author Guillaume Lajarige */ class UserProfileBrick extends PortalBrick { - const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/user-profile/layout.html.twig'; + // Overloaded constants + const DEFAULT_PAGE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/user-profile/layout.html.twig'; const DEFAULT_TILE_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/user-profile/tile.html.twig'; const DEFAULT_VISIBLE_NAVIGATION_MENU = false; const DEFAULT_VISIBLE_HOME = false; const DEFAUT_TITLE = 'Brick:Portal:UserProfile:Title'; const DEFAULT_DECORATION_CLASS_HOME = 'glyphicon glyphicon-user'; const DEFAULT_DECORATION_CLASS_NAVIGATION_MENU = 'glyphicon glyphicon-user'; - const DEFAULT_SHOW_PICTURE_FORM = true; + + /** @var bool DEFAULT_SHOW_PICTURE_FORM */ + const DEFAULT_SHOW_PICTURE_FORM = true; + /** @var bool DEFAULT_SHOW_PREFERENCES_FORM */ const DEFAULT_SHOW_PREFERENCES_FORM = true; + /** @var bool DEFAULT_SHOW_PASSWORD_FORM */ const DEFAULT_SHOW_PASSWORD_FORM = true; + // Overloaded variables static $sRouteName = 'p_user_profile_brick'; + + /** @var array $aForm */ protected $aForm; + /** @var bool $bShowPictureForm */ protected $bShowPictureForm; + /** @var bool $bShowPreferencesForm */ protected $bShowPreferencesForm; + /** @var bool $bShowPasswordForm */ protected $bShowPasswordForm; + /** + * UserProfileBrick constructor. + */ public function __construct() { parent::__construct(); @@ -56,7 +72,7 @@ class UserProfileBrick extends PortalBrick 'id' => 'default-user-profile', 'type' => 'zlist', 'fields' => 'details', - 'layout' => null + 'layout' => null, ); $this->bShowPictureForm = static::DEFAULT_SHOW_PICTURE_FORM; $this->bShowPreferencesForm = static::DEFAULT_SHOW_PREFERENCES_FORM; @@ -142,14 +158,17 @@ class UserProfileBrick extends PortalBrick * This is used to set all the brick attributes at once. * * @param \Combodo\iTop\DesignElement $oMDElement + * * @return UserProfileBrick - * @throws DOMFormatException + * @throws DOMFormatException*@throws \Exception + * @throws \Exception */ public function LoadFromXml(DesignElement $oMDElement) { parent::LoadFromXml($oMDElement); // Checking specific elements + /** @var \Combodo\iTop\DesignElement $oBrickSubNode */ foreach ($oMDElement->GetNodes('./*') as $oBrickSubNode) { switch ($oBrickSubNode->nodeName) @@ -162,6 +181,7 @@ class UserProfileBrick extends PortalBrick $this->aForm['type'] = 'custom_list'; $this->aForm['fields'] = array(); + /** @var \Combodo\iTop\DesignElement $oFieldNode */ foreach ($oBrickSubNode->GetOptionalElement('fields')->GetNodes('field') as $oFieldNode) { $sFieldId = $oFieldNode->getAttribute('id'); @@ -201,7 +221,7 @@ class UserProfileBrick extends PortalBrick $this->aForm['layout'] = array( 'type' => (preg_match('/\{\{|\{\#|\{\%/', $sXml) === 1) ? 'twig' : 'xhtml', - 'content' => $sXml + 'content' => $sXml, ); } break; diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/AbstractController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/AbstractController.php index 80e54b780..3d76d63e0 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/AbstractController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/AbstractController.php @@ -28,8 +28,8 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; * Class AbstractController * * @package Combodo\iTop\Portal\Controller - * @author Guillaume Lajarige - * @since 2.3.0 + * @author Guillaume Lajarige + * @since 2.3.0 */ abstract class AbstractController extends Controller { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/BrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/BrickController.php index 94ca20789..589720343 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/BrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/BrickController.php @@ -26,8 +26,8 @@ namespace Combodo\iTop\Portal\Controller; * Class BrickController * * @package Combodo\iTop\Portal\Controller - * @author Guillaume Lajarige - * @since 2.3.0 + * @author Guillaume Lajarige + * @since 2.3.0 */ abstract class BrickController extends AbstractController { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php index 875de5537..9811b2390 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php @@ -40,8 +40,8 @@ use Combodo\iTop\Portal\Brick\BrowseBrick; * Class BrowseBrickController * * @package Combodo\iTop\Portal\Controller - * @author Guillaume Lajarige - * @since 2.3.0 + * @author Guillaume Lajarige + * @since 2.3.0 */ class BrowseBrickController extends BrickController { @@ -60,6 +60,7 @@ class BrowseBrickController extends BrickController * @throws \MySQLException * @throws \MySQLHasGoneAwayException * @throws \OQLException + * @throws \Exception */ public function DisplayAction(Request $oRequest, $sBrickId, $sBrowseMode = null, $sDataLoading = null) { @@ -77,7 +78,8 @@ class BrowseBrickController extends BrickController // Getting current browse mode (First from router pamater, then default brick value) $sBrowseMode = (!empty($sBrowseMode)) ? $sBrowseMode : $oBrick->GetDefaultBrowseMode(); // Getting current dataloading mode (First from router parameter, then query parameter, then default brick value) - $sDataLoading = ($sDataLoading !== null) ? $sDataLoading : $oRequestManipulator->ReadParam('sDataLoading', $oBrick->GetDataLoading()); + $sDataLoading = ($sDataLoading !== null) ? $sDataLoading : $oRequestManipulator->ReadParam('sDataLoading', + $oBrick->GetDataLoading()); // Getting search value $sSearchValue = $oRequestManipulator->ReadParam('sSearchValue', ''); if (!empty($sSearchValue)) @@ -93,17 +95,22 @@ class BrowseBrickController extends BrickController // Consistency checks if (!in_array($sBrowseMode, array_keys($aBrowseModes))) { - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Browse brick "' . $sBrickId . '" : Unknown browse mode "' . $sBrowseMode . '", availables are ' . implode(' / ', array_keys($aBrowseModes))); + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, + 'Browse brick "'.$sBrickId.'" : Unknown browse mode "'.$sBrowseMode.'", availables are '.implode(' / ', + array_keys($aBrowseModes))); } if (empty($aLevelsProperties)) { - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Browse brick "' . $sBrickId . '" : No levels to display.'); + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Browse brick "'.$sBrickId.'" : No levels to display.'); } // Building DBObjectSearch $oQuery = null; // ... In this case only we have to build a specific query for the current level only - if (in_array($sBrowseMode, array(BrowseBrick::ENUM_BROWSE_MODE_TREE, BrowseBrick::ENUM_BROWSE_MODE_MOSAIC)) && ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY)) + if (in_array($sBrowseMode, array( + BrowseBrick::ENUM_BROWSE_MODE_TREE, + BrowseBrick::ENUM_BROWSE_MODE_MOSAIC, + )) && ($sDataLoading === AbstractBrick::ENUM_DATA_LOADING_LAZY)) { // Will be handled later in the pagination part } @@ -123,12 +130,15 @@ class BrowseBrickController extends BrickController if ($i < $iLoopMax) { $aRealiasingMap = array(); - $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->Join($aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search'], DBSearch::JOIN_REFERENCED_BY, $aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['parent_att'], TREE_OPERATOR_EQUALS, $aRealiasingMap); + $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search'] = $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->Join($aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['search'], + DBSearch::JOIN_REFERENCED_BY, $aLevelsProperties[$aLevelsPropertiesKeys[$i + 1]]['parent_att'], + TREE_OPERATOR_EQUALS, $aRealiasingMap); foreach ($aLevelsPropertiesKeys as $sLevelAlias) { if (array_key_exists($sLevelAlias, $aRealiasingMap)) { - $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($aRealiasingMap[$sLevelAlias], $sLevelAlias); + $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($aRealiasingMap[$sLevelAlias], + $sLevelAlias); } } } @@ -164,7 +174,8 @@ class BrowseBrickController extends BrickController for ($k = 0; $k <= $iSearchLoopMax; $k++) { - $oSearchBinExpr = new BinaryExpression(new FieldExpression($sTmpFieldAttCode, $aLevelsPropertiesKeys[$i]), 'LIKE', new VariableExpression('search_value_' . $k)); + $oSearchBinExpr = new BinaryExpression(new FieldExpression($sTmpFieldAttCode, $aLevelsPropertiesKeys[$i]), + 'LIKE', new VariableExpression('search_value_'.$k)); if ($k === 0) { $oFieldBinExpr = $oSearchBinExpr; @@ -214,7 +225,7 @@ class BrowseBrickController extends BrickController // Note : $iSearchloopMax was initialized on the previous loop for ($j = 0; $j <= $iSearchLoopMax; $j++) { - $aQueryParams['search_value_' . $j] = '%' . $aSearchValues[$j] . '%'; + $aQueryParams['search_value_'.$j] = '%'.$aSearchValues[$j].'%'; } $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->SetInternalParams($aQueryParams); } @@ -228,7 +239,8 @@ class BrowseBrickController extends BrickController // - Check how many records there is. // - Update $sDataLoading with its new value regarding the number of record and the threshold $oCountSet = new DBObjectSet($oQuery); - $fThreshold = (float) MetaModel::GetModuleSetting($this->getParameter('combodo.portal.instance.id'), 'lazy_loading_threshold'); + $fThreshold = (float)MetaModel::GetModuleSetting($this->getParameter('combodo.portal.instance.id'), + 'lazy_loading_threshold'); $sDataLoading = ($oCountSet->Count() > $fThreshold) ? AbstractBrick::ENUM_DATA_LOADING_LAZY : AbstractBrick::ENUM_DATA_LOADING_FULL; unset($oCountSet); } @@ -241,8 +253,9 @@ class BrowseBrickController extends BrickController { case BrowseBrick::ENUM_BROWSE_MODE_LIST: // Retrieving parameters - $iPageNumber = (int) $oRequestManipulator->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT); - $iListLength = (int) $oRequestManipulator->ReadParam('iListLength', BrowseBrick::DEFAULT_LIST_LENGTH, FILTER_SANITIZE_NUMBER_INT); + $iPageNumber = (int)$oRequestManipulator->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT); + $iListLength = (int)$oRequestManipulator->ReadParam('iListLength', BrowseBrick::DEFAULT_LIST_LENGTH, + FILTER_SANITIZE_NUMBER_INT); // Getting total records number $oCountSet = new DBObjectSet($oQuery); @@ -293,7 +306,8 @@ class BrowseBrickController extends BrickController if (!$bFoundLevel) { - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Browse brick "' . $sBrickId . '" : Level alias "' . $sLevelAlias . '" is not defined for that brick.'); + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, + 'Browse brick "'.$sBrickId.'" : Level alias "'.$sLevelAlias.'" is not defined for that brick.'); } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/DefaultController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/DefaultController.php index a4e02df09..15e1767f6 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/DefaultController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/DefaultController.php @@ -31,8 +31,8 @@ use Symfony\Component\HttpFoundation\Response; * Class DefaultController * * @package Combodo\iTop\Portal\Controller - * @author Guillaume Lajarige - * @since 2.3.0 + * @author Guillaume Lajarige + * @since 2.3.0 */ class DefaultController extends AbstractController { @@ -49,7 +49,7 @@ class DefaultController extends AbstractController // Rendering tiles $aData['aTilesRendering'] = array(); - foreach($oBricksCollection->GetBricks() as $oBrick) + foreach ($oBricksCollection->GetBricks() as $oBrick) { // Doing it only for tile visible on home page to avoid unnecessary rendering if (($oBrick->GetVisibleHome() === true) && ($oBrick->GetTileControllerAction() !== null)) @@ -57,16 +57,17 @@ class DefaultController extends AbstractController $aControllerActionParts = explode('::', $oBrick->GetTileControllerAction()); if (count($aControllerActionParts) !== 2) { - return new Response('Tile controller action must be of form "\Namespace\ControllerClass::FunctionName" for brick "' . $oBrick->GetId() . '"', 500); + return new Response('Tile controller action must be of form "\Namespace\ControllerClass::FunctionName" for brick "'.$oBrick->GetId().'"', + 500); } $sControllerName = $aControllerActionParts[0]; $sControllerAction = $aControllerActionParts[1]; $oController = new $sControllerName(); - if(!$oController instanceof ContainerAwareInterface) + if (!$oController instanceof ContainerAwareInterface) { - return new Response('Tile controller must be implement ContainerAwareInterface for brick "' . $oBrick->GetId() . '"', 500); + return new Response('Tile controller must be implement ContainerAwareInterface for brick "'.$oBrick->GetId().'"', 500); } $oController->setContainer($this->container); /** @var Response $oResponse */ diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php index 7d2fe5dd8..8c7084cb2 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/ManageBrickController.php @@ -50,14 +50,15 @@ use VariableExpression; * Class ManageBrickController * * @package Combodo\iTop\Portal\Controller - * @author Bruno Da Silva - * @author Eric Espie - * @author Guillaume Lajarige - * @author Pierre Goiffon - * @since 2.3.0 + * @author Bruno Da Silva + * @author Eric Espie + * @author Guillaume Lajarige + * @author Pierre Goiffon + * @since 2.3.0 */ class ManageBrickController extends BrickController { + /** @var string EXCEL_EXPORT_TEMPLATE_PATH */ const EXCEL_EXPORT_TEMPLATE_PATH = 'itop-portal-base/portal/templates/bricks/manage/popup-export-excel.html.twig'; /** @@ -78,9 +79,9 @@ class ManageBrickController extends BrickController * @throws \OQLException */ public function DisplayAction(Request $oRequest, $sBrickId, $sGroupingTab, $sDisplayMode = null) - { - /** @var \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection */ - $oBrickCollection = $this->get('brick_collection'); + { + /** @var \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection */ + $oBrickCollection = $this->get('brick_collection'); /** @var \Combodo\iTop\Portal\Brick\ManageBrick $oBrick */ $oBrick = $oBrickCollection->GetBrickById($sBrickId); @@ -157,6 +158,7 @@ class ManageBrickController extends BrickController * @throws \MySQLException * @throws \MySQLHasGoneAwayException * @throws \OQLException + * @throws \Exception */ public function ExcelExportStartAction(Request $oRequest, $sBrickId, $sGroupingTab, $sGroupingArea) { @@ -266,6 +268,7 @@ class ManageBrickController extends BrickController * @throws \MySQLException * @throws \MySQLHasGoneAwayException * @throws \OQLException + * @throws \Exception */ public function GetData(Request $oRequest, $sBrickId, $sGroupingTab, $bNeedDetails = false) { @@ -395,8 +398,8 @@ class ManageBrickController extends BrickController } } - // - Adding search clause if necessary - $this->ManageSearchValue($aData, $oQuery, $sClass, $aColumnsAttrs); + // - Adding search clause if necessary + $this->ManageSearchValue($aData, $oQuery, $sClass, $aColumnsAttrs); // Preparing areas // - We need to retrieve distinct values for the grouping attribute @@ -427,7 +430,7 @@ class ManageBrickController extends BrickController 'label' => MetaModel::GetName($aDistinctResult['grouped_by_1']), // Caution : This works only because we froze the grouping areas on the finalclass attribute. 'condition' => $oConditionQuery, - 'count' => $aDistinctResult['_itop_count_'] + 'count' => $aDistinctResult['_itop_count_'], ); unset($oConditionQuery); } @@ -441,7 +444,7 @@ class ManageBrickController extends BrickController 'label' => MetaModel::GetName($sClass), // Caution : This works only because we froze the grouping areas on the finalclass attribute. 'condition' => null, - 'count' => 0 + 'count' => 0, ); } @@ -501,7 +504,8 @@ class ManageBrickController extends BrickController { // Retrieving parameters $iPageNumber = (int)$oRequestManipulator->ReadParam('iPageNumber', 1, FILTER_SANITIZE_NUMBER_INT); - $iListLength = (int)$oRequestManipulator->ReadParam('iListLength', ManageBrick::DEFAULT_LIST_LENGTH, FILTER_SANITIZE_NUMBER_INT); + $iListLength = (int)$oRequestManipulator->ReadParam('iListLength', ManageBrick::DEFAULT_LIST_LENGTH, + FILTER_SANITIZE_NUMBER_INT); // Getting total records number $oCountSet = new DBObjectSet($oQuery); @@ -579,7 +583,8 @@ class ManageBrickController extends BrickController if ($sItemAttr === $sMainActionAttrCode) { // Checking if we can edit the object - if (($oBrick->GetOpeningMode() === ManageBrick::ENUM_ACTION_EDIT) && $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $sCurrentClass, $oCurrentRow->GetKey())) + if (($oBrick->GetOpeningMode() === ManageBrick::ENUM_ACTION_EDIT) && $oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, + $sCurrentClass, $oCurrentRow->GetKey())) { $sActionType = ManageBrick::ENUM_ACTION_EDIT; } @@ -605,10 +610,11 @@ class ManageBrickController extends BrickController } } - /** @var AttributeDefinition $oAttDef */ + /** @var \AttributeDefinition $oAttDef */ $oAttDef = MetaModel::GetAttributeDef($sCurrentClass, $sItemAttr); if ($oAttDef->IsExternalKey()) { + /** @var \AttributeExternalKey $oAttDef */ $sValue = $oCurrentRow->GetAsHTML($sItemAttr.'_friendlyname'); $sSortValue = $oCurrentRow->Get($sItemAttr.'_friendlyname'); @@ -629,19 +635,24 @@ class ManageBrickController extends BrickController } } elseif ($oAttDef instanceof AttributeImage) - { - $oOrmDoc = $oCurrentRow->Get($sItemAttr); - if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty()) - { - $sUrl = $oUrlGenerator->generate('p_object_document_display', array('sObjectClass' => get_class($oCurrentRow), 'sObjectId' => $oCurrentRow->GetKey(), 'sObjectField' => $sItemAttr, 'cache' => 86400)); - } - else - { - $sUrl = $oAttDef->Get('default_image'); - } - $sValue = ''; - $sSortValue = null; - } + { + $oOrmDoc = $oCurrentRow->Get($sItemAttr); + if (is_object($oOrmDoc) && !$oOrmDoc->IsEmpty()) + { + $sUrl = $oUrlGenerator->generate('p_object_document_display', array( + 'sObjectClass' => get_class($oCurrentRow), + 'sObjectId' => $oCurrentRow->GetKey(), + 'sObjectField' => $sItemAttr, + 'cache' => 86400, + )); + } + else + { + $sUrl = $oAttDef->Get('default_image'); + } + $sValue = ''; + $sSortValue = null; + } elseif ($oAttDef instanceof AttributeTagSet) { /** @var \ormTagSet $oSetValues */ @@ -653,8 +664,8 @@ class ManageBrickController extends BrickController } else { - $sValue = $oAttDef->GetAsHTML($oCurrentRow->Get($sItemAttr)); - $sSortValue = $oCurrentRow->Get($sItemAttr); + $sValue = $oAttDef->GetAsHTML($oCurrentRow->Get($sItemAttr)); + $sSortValue = $oCurrentRow->Get($sItemAttr); } unset($oAttDef); @@ -662,18 +673,18 @@ class ManageBrickController extends BrickController 'att_code' => $sItemAttr, 'value' => $sValue, 'sort_value' => $sSortValue, - 'actions' => $aActions + 'actions' => $aActions, ); } // ... Checking menu extensions $aItemButtons = array(); /** @var iPopupMenuExtension $oExtensionInstance */ - foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) + foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) { foreach ($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJLISTITEM_ACTIONS, array( 'portal_id' => $sPortalId, - 'object' => $oCurrentRow + 'object' => $oCurrentRow, )) as $oMenuItem) { if (is_object($oMenuItem)) @@ -682,7 +693,7 @@ class ManageBrickController extends BrickController { $aItemButtons[] = $oMenuItem->GetMenuItem() + array( 'js_files' => $oMenuItem->GetLinkedScripts(), - 'type' => 'button' + 'type' => 'button', ); } elseif ($oMenuItem instanceof URLButtonItem) @@ -722,7 +733,7 @@ class ManageBrickController extends BrickController 'sTitle' => $aGroupingAreasValues[$sKey]['label'], 'aItems' => $aItems, 'iItemsCount' => $oSet->Count(), - 'aColumnsDefinition' => $aColumnsDefinition + 'aColumnsDefinition' => $aColumnsDefinition, ); } } @@ -736,7 +747,7 @@ class ManageBrickController extends BrickController if ($oRequest->isXmlHttpRequest()) { $aData = $aData + array( - 'data' => $aGroupingAreasData[$sGroupingArea]['aItems'] + 'data' => $aGroupingAreasData[$sGroupingArea]['aItems'], ); } else @@ -757,7 +768,7 @@ class ManageBrickController extends BrickController $aUrls[] = $oUrlGenerator->generate('p_manage_brick', array( 'sBrickId' => $sBrickId, 'sDisplayMode' => 'default', - 'sGroupingTab' => $aValues['value'] + 'sGroupingTab' => $aValues['value'], )); } @@ -812,16 +823,16 @@ class ManageBrickController extends BrickController // Note : This is a very naive search at the moment if (!empty($sSearchValue)) { - // Putting only valid attributes as one can define attributes of leaf classes in the brick definition (), but at this stage we are working on the abstract class. - // Note: This won't fix everything as the search will not be looking in all fields. - $aSearchListItems = array(); - foreach($aColumnsAttrs as $sColumnAttr) - { - if(MetaModel::IsValidAttCode($sClass, $sColumnAttr)) - { - $aSearchListItems[] = $sColumnAttr; - } - } + // Putting only valid attributes as one can define attributes of leaf classes in the brick definition (), but at this stage we are working on the abstract class. + // Note: This won't fix everything as the search will not be looking in all fields. + $aSearchListItems = array(); + foreach ($aColumnsAttrs as $sColumnAttr) + { + if (MetaModel::IsValidAttCode($sClass, $sColumnAttr)) + { + $aSearchListItems[] = $sColumnAttr; + } + } $oFullBinExpr = null; foreach ($aSearchListItems as $sSearchItemAttr) @@ -857,17 +868,18 @@ class ManageBrickController extends BrickController /** * Get the groups using a given attribute code. - * If a limit is given, the remaining groups are aggregated (groupby result and search request). + * If a limit is given, the remaining groups are aggregated (group by result and search request). * * @param \DBSearch $oQuery Initial query * @param string $sGroupingTabAttCode Attribute code to group by * @param \Combodo\iTop\Portal\Brick\ManageBrick $oBrick * - * @return array of results from the groupby request and the corrsponding search. + * @return array of results from the group by request and the corresponding search. * * @throws \CoreException * @throws \MySQLException * @throws \OQLException + * @throws \Exception */ protected function GroupByAttribute( DBSearch $oQuery, $sGroupingTabAttCode, ManageBrick $oBrick @@ -912,7 +924,7 @@ class ManageBrickController extends BrickController { $oConditionQuery = DBSearch::CloneWithAlias($oQuery, 'GTAB'); $oExpression = new BinaryExpression(new FieldExpression($sGroupingTabAttCode, - $oConditionQuery->GetClassAlias()), '=', new UnaryExpression($aDistinctResult['grouped_by_1'])); + $oConditionQuery->GetClassAlias()), '=', new UnaryExpression($aDistinctResult['grouped_by_1'])); $oConditionQuery->AddConditionExpression($oExpression); $sHtmlLabel = $oFieldExp->MakeValueLabel($oDistinctQuery, $aDistinctResult['grouped_by_1'], ''); @@ -935,7 +947,7 @@ class ManageBrickController extends BrickController { $iOtherCount += $aResult['_itop_count_']; $oExpr = new BinaryExpression(new FieldExpression($sGroupingTabAttCode, - $oConditionQuery->GetClassAlias()), '=', new UnaryExpression($aResult['grouped_by_1'])); + $oConditionQuery->GetClassAlias()), '=', new UnaryExpression($aResult['grouped_by_1'])); if (is_null($oExpression)) { $oExpression = $oExpr; diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php index 972f3351d..78db19de1 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/UserProfileBrickController.php @@ -42,11 +42,12 @@ use Combodo\iTop\Renderer\Bootstrap\BsFormRenderer; * Class UserProfileBrickController * * @package Combodo\iTop\Portal\Controller - * @author Guillaume Lajarige - * @since 2.3.0 + * @author Guillaume Lajarige + * @since 2.3.0 */ class UserProfileBrickController extends BrickController { + /** @var string ENUM_FORM_TYPE_PICTURE */ const ENUM_FORM_TYPE_PICTURE = 'picture'; /** @@ -133,16 +134,17 @@ class UserProfileBrickController extends BrickController $sCurContactId = $oCurContact->GetKey(); // Preparing forms - $aData['forms']['contact'] = $ObjectFormHandler->HandleForm($oRequest, $sFormMode, $sCurContactClass, $sCurContactId, $oBrick->GetForm()); + $aData['forms']['contact'] = $ObjectFormHandler->HandleForm($oRequest, $sFormMode, $sCurContactClass, $sCurContactId, + $oBrick->GetForm()); $aData['forms']['preferences'] = $this->HandlePreferencesForm($oRequest, $sFormMode); // - If user can change password, we display the form $aData['forms']['password'] = (UserRights::CanChangePassword()) ? $this->HandlePasswordForm($oRequest, $sFormMode) : null; $aData = $aData + array( - 'oBrick' => $oBrick, - 'sFormMode' => $sFormMode, - 'bDemoMode' => $bDemoMode, - ); + 'oBrick' => $oBrick, + 'sFormMode' => $sFormMode, + 'bDemoMode' => $bDemoMode, + ); $oResponse = $this->render($oBrick->GetPageTemplatePath(), $aData); } @@ -186,29 +188,36 @@ class UserProfileBrickController extends BrickController } } // - Submit - else if ($sOperation === 'submit') + else { - $sFormManagerClass = $oRequestManipulator->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW); - $sFormManagerData = $oRequestManipulator->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW); - if ($sFormManagerClass === null || $sFormManagerData === null) + if ($sOperation === 'submit') { - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameters formmanager_class and formamanager_data must be defined.'); - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameters formmanager_class and formmanager_data must be defined.'); - } + $sFormManagerClass = $oRequestManipulator->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW); + $sFormManagerData = $oRequestManipulator->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW); + if ($sFormManagerClass === null || $sFormManagerData === null) + { + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameters formmanager_class and formamanager_data must be defined.'); + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, + 'Parameters formmanager_class and formmanager_data must be defined.'); + } - // Rebuilding manager from json - $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); - // Applying modification to object - $aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW))); - // Reloading page only if preferences were changed - if (($aFormData['validation']['valid'] === true) && !empty($aFormData['validation']['messages']['success'])) - { - $aFormData['validation']['redirection'] = array( - 'url' => $oUrlGenerator->generate('p_user_profile_brick'), - ); + // Rebuilding manager from json + /** @var \Combodo\iTop\Form\FormManager $oFormManager */ + $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); + // Applying modification to object + $aFormData['validation'] = $oFormManager->OnSubmit(array( + 'currentValues' => $oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), + )); + // Reloading page only if preferences were changed + if (($aFormData['validation']['valid'] === true) && !empty($aFormData['validation']['messages']['success'])) + { + $aFormData['validation']['redirection'] = array( + 'url' => $oUrlGenerator->generate('p_user_profile_brick'), + ); + } } } - // Else, submit from another form + // Else, submit from another form // Preparing field_set data $aFieldSetData = array( @@ -244,7 +253,7 @@ class UserProfileBrickController extends BrickController // Handling form $sOperation = /** @var \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulator */ - $oRequestManipulator->ReadParam('operation', null); + $oRequestManipulator->ReadParam('operation', null); // - Create if ($sOperation === null) { @@ -255,27 +264,34 @@ class UserProfileBrickController extends BrickController $oFormManager = new PasswordFormManager(); $oFormManager->SetRenderer($oFormRenderer) ->Build(); - // - Checking if we have to make the form read only - if ($sFormMode === ObjectFormHandlerHelper::ENUM_MODE_VIEW) - { - $oFormManager->GetForm()->MakeReadOnly(); - } + // - Checking if we have to make the form read only + if ($sFormMode === ObjectFormHandlerHelper::ENUM_MODE_VIEW) + { + $oFormManager->GetForm()->MakeReadOnly(); + } } // - Submit - else if ($sOperation === 'submit') + else { - $sFormManagerClass = $oRequestManipulator->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW); - $sFormManagerData = $oRequestManipulator->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW); - if ($sFormManagerClass === null || $sFormManagerData === null) + if ($sOperation === 'submit') { - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameters formmanager_class and formamanager_data must be defined.'); - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameters formmanager_class and formmanager_data must be defined.'); - } + $sFormManagerClass = $oRequestManipulator->ReadParam('formmanager_class', null, FILTER_UNSAFE_RAW); + $sFormManagerData = $oRequestManipulator->ReadParam('formmanager_data', null, FILTER_UNSAFE_RAW); + if ($sFormManagerClass === null || $sFormManagerData === null) + { + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameters formmanager_class and formamanager_data must be defined.'); + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, + 'Parameters formmanager_class and formmanager_data must be defined.'); + } - // Rebuilding manager from json - $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); - // Applying modification to object - $aFormData['validation'] = $oFormManager->OnSubmit(array('currentValues' => $oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW))); + // Rebuilding manager from json + /** @var \Combodo\iTop\Form\FormManager $oFormManager */ + $oFormManager = $sFormManagerClass::FromJSON($sFormManagerData); + // Applying modification to object + $aFormData['validation'] = $oFormManager->OnSubmit(array( + 'currentValues' => $oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), + )); + } } // Else, submit from another form @@ -316,48 +332,53 @@ class UserProfileBrickController extends BrickController // - No operation specified if ($sOperation === null) { - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Operation parameter must be specified.'); + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Operation parameter must be specified.'); throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Operation parameter must be specified.'); } // - Submit - else if ($sOperation === 'submit') + else { - $oRequestFiles = $oRequest->files; - $oPictureFile = $oRequestFiles->get($sPictureAttCode); - if ($oPictureFile === null) + if ($sOperation === 'submit') { - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameter picture must be defined.'); - throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameter picture must be defined.'); - } + $oRequestFiles = $oRequest->files; + $oPictureFile = $oRequestFiles->get($sPictureAttCode); + if ($oPictureFile === null) + { + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameter picture must be defined.'); + throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameter picture must be defined.'); + } - try - { - // Retrieving image as an ORMDocument - $oImage = utils::ReadPostedDocument($sPictureAttCode); - // Retrieving current contact - /** @var \DBObject $oCurContact */ - $oCurContact = UserRights::GetContactObject(); - // Resizing image - $oAttDef = MetaModel::GetAttributeDef(get_class($oCurContact), $sPictureAttCode); - $aSize = utils::GetImageSize($oImage->GetData()); - $oImage = utils::ResizeImageToFit($oImage, $aSize[0], $aSize[1], $oAttDef->Get('storage_max_width'), $oAttDef->Get('storage_max_height')); - // Setting it to the contact - $oCurContact->Set($sPictureAttCode, $oImage); - // Forcing allowed writing on the object if necessary. - $oCurContact->AllowWrite(true); - $oCurContact->DBUpdate(); - } - catch (FileUploadException $e) - { - $aFormData['error'] = $e->GetMessage(); - } + try + { + // Retrieving image as an ORMDocument + $oImage = utils::ReadPostedDocument($sPictureAttCode); + // Retrieving current contact + /** @var \cmdbAbstractObject $oCurContact */ + $oCurContact = UserRights::GetContactObject(); + // Resizing image + $oAttDef = MetaModel::GetAttributeDef(get_class($oCurContact), $sPictureAttCode); + $aSize = utils::GetImageSize($oImage->GetData()); + $oImage = utils::ResizeImageToFit($oImage, $aSize[0], $aSize[1], $oAttDef->Get('storage_max_width'), + $oAttDef->Get('storage_max_height')); + // Setting it to the contact + $oCurContact->Set($sPictureAttCode, $oImage); + // Forcing allowed writing on the object if necessary. + $oCurContact->AllowWrite(true); + $oCurContact->DBUpdate(); + } + catch (FileUploadException $e) + { + $aFormData['error'] = $e->GetMessage(); + } - $aFormData['picture_url'] = $oImage->GetDownloadURL(get_class($oCurContact), $oCurContact->GetKey(), $sPictureAttCode); - $aFormData['validation'] = array( - 'valid' => true, - 'messages' => array(), - ); + $aFormData['picture_url'] = $oImage->GetDownloadURL(get_class($oCurContact), $oCurContact->GetKey(), $sPictureAttCode); + $aFormData['validation'] = array( + 'valid' => true, + 'messages' => array(), + ); + } } + // Else, submit from another form return $aFormData; diff --git a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/AbstractConfiguration.php b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/AbstractConfiguration.php index 34fc6a746..9a13d2155 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/AbstractConfiguration.php +++ b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/AbstractConfiguration.php @@ -28,30 +28,30 @@ use ModuleDesign; * Class AbstractConfiguration * * @package Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration - * @author Guillaume Lajarige - * @since 2.7.0 + * @author Guillaume Lajarige + * @since 2.7.0 */ class AbstractConfiguration { - /** @var \ModuleDesign $oModuleDesign */ - private $oModuleDesign; + /** @var \ModuleDesign $oModuleDesign */ + private $oModuleDesign; /** * AbstractConfiguration constructor. * * @param \ModuleDesign $oModuleDesign */ - public function __construct(ModuleDesign $oModuleDesign) - { - $this->oModuleDesign = $oModuleDesign; - } + public function __construct(ModuleDesign $oModuleDesign) + { + $this->oModuleDesign = $oModuleDesign; + } - /** - * @return \ModuleDesign - */ - public function GetModuleDesign() - { - return $this->oModuleDesign; - } + /** + * @return \ModuleDesign + */ + public function GetModuleDesign() + { + return $this->oModuleDesign; + } } \ No newline at end of file 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 bc5225f7e..6b81c4601 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 @@ -34,8 +34,8 @@ use DOMFormatException; * Class Basic * * @package Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration - * @author Guillaume Lajarige - * @since 2.7.0 + * @author Guillaume Lajarige + * @since 2.7.0 */ class Basic extends AbstractConfiguration { @@ -44,76 +44,76 @@ class Basic extends AbstractConfiguration * * @throws \Exception */ - public function Process(Container $oContainer) - { - try - { - // Parsing file - // - Default values - $aPortalConf = $this->GetInitialPortalConf(); - // - Global portal properties - $aPortalConf = $this->ParseGlobalProperties($aPortalConf); - // - Rectifying portal logo url - $aPortalConf = $this->AppendLogoUri($aPortalConf); - // - User allowed portals - $aPortalConf['portals'] = UserRights::GetAllowedPortals(); + public function Process(Container $oContainer) + { + try + { + // Parsing file + // - Default values + $aPortalConf = $this->GetInitialPortalConf(); + // - Global portal properties + $aPortalConf = $this->ParseGlobalProperties($aPortalConf); + // - Rectifying portal logo url + $aPortalConf = $this->AppendLogoUri($aPortalConf); + // - User allowed portals + $aPortalConf['portals'] = UserRights::GetAllowedPortals(); - // - class list - $aPortalConf['ui_extensions'] = $this->GetUiExtensions($oContainer); - } - catch (Exception $oException) - { - throw new Exception('Error while parsing portal configuration file : '.$oException->getMessage()); - } + // - class list + $aPortalConf['ui_extensions'] = $this->GetUiExtensions($oContainer); + } + catch (Exception $oException) + { + throw new Exception('Error while parsing portal configuration file : '.$oException->getMessage()); + } - $oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf); - } + $oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf); + } - /** - * Returns an array containing the initial portal configuration with all default values - * - * @return array - */ - private function GetInitialPortalConf() - { - $aPortalConf = array( - 'properties' => array( - '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( - 'bootstrap' => 'itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss', - 'portal' => 'itop-portal-base/portal/public/css/portal.scss', - 'others' => array(), - ), - 'templates' => array( - 'layout' => 'itop-portal-base/portal/templates/layout.html.twig', - 'home' => 'itop-portal-base/portal/templates/home/layout.html.twig', - ), - 'urlmaker_class' => null, - 'triggers_query' => null, - 'attachments' => array( - 'allow_delete' => true, - ), - 'allowed_portals' => array( - 'opening_mode' => null, - ), - ), - 'portals' => array(), - 'forms' => array(), - 'ui_extensions' => array( - 'css_files' => array(), - 'css_inline' => null, - 'js_files' => array(), - 'js_inline' => null, - 'html' => array(), - ), - 'bricks' => array(), - 'bricks_total_width' => 0, - ); + /** + * Returns an array containing the initial portal configuration with all default values + * + * @return array + */ + private function GetInitialPortalConf() + { + $aPortalConf = array( + 'properties' => array( + '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( + 'bootstrap' => 'itop-portal-base/portal/public/css/bootstrap-theme-combodo.scss', + 'portal' => 'itop-portal-base/portal/public/css/portal.scss', + 'others' => array(), + ), + 'templates' => array( + 'layout' => 'itop-portal-base/portal/templates/layout.html.twig', + 'home' => 'itop-portal-base/portal/templates/home/layout.html.twig', + ), + 'urlmaker_class' => null, + 'triggers_query' => null, + 'attachments' => array( + 'allow_delete' => true, + ), + 'allowed_portals' => array( + 'opening_mode' => null, + ), + ), + 'portals' => array(), + 'forms' => array(), + 'ui_extensions' => array( + 'css_files' => array(), + 'css_inline' => null, + 'js_files' => array(), + 'js_inline' => null, + 'html' => array(), + ), + 'bricks' => array(), + 'bricks_total_width' => 0, + ); - return $aPortalConf; - } + return $aPortalConf; + } /** * @param array $aPortalConf @@ -121,40 +121,40 @@ class Basic extends AbstractConfiguration * @return array * @throws \DOMFormatException */ - private function ParseGlobalProperties(array $aPortalConf) - { - /** @var \MFElement $oPropertyNode */ - foreach ($this->GetModuleDesign()->GetNodes('/module_design/properties/*') as $oPropertyNode) - { - switch ($oPropertyNode->nodeName) - { - case 'name': - case 'urlmaker_class': - case 'triggers_query': - $aPortalConf['properties'][$oPropertyNode->nodeName] = $oPropertyNode->GetText( - $aPortalConf['properties'][$oPropertyNode->nodeName] - ); - break; - case 'logo': - $aPortalConf['properties'][$oPropertyNode->nodeName] = $oPropertyNode->GetText( - $aPortalConf['properties'][$oPropertyNode->nodeName] - ); - break; - case 'themes': - case 'templates': - $aPortalConf = $this->ParseTemplateAndTheme($aPortalConf, $oPropertyNode); - break; - case 'attachments': - $aPortalConf = $this->ParseAttachments($aPortalConf, $oPropertyNode); - break; - case 'allowed_portals': - $aPortalConf = $this->ParseAllowedPortals($aPortalConf, $oPropertyNode); - break; - } - } + private function ParseGlobalProperties(array $aPortalConf) + { + /** @var \MFElement $oPropertyNode */ + foreach ($this->GetModuleDesign()->GetNodes('/module_design/properties/*') as $oPropertyNode) + { + switch ($oPropertyNode->nodeName) + { + case 'name': + case 'urlmaker_class': + case 'triggers_query': + $aPortalConf['properties'][$oPropertyNode->nodeName] = $oPropertyNode->GetText( + $aPortalConf['properties'][$oPropertyNode->nodeName] + ); + break; + case 'logo': + $aPortalConf['properties'][$oPropertyNode->nodeName] = $oPropertyNode->GetText( + $aPortalConf['properties'][$oPropertyNode->nodeName] + ); + break; + case 'themes': + case 'templates': + $aPortalConf = $this->ParseTemplateAndTheme($aPortalConf, $oPropertyNode); + break; + case 'attachments': + $aPortalConf = $this->ParseAttachments($aPortalConf, $oPropertyNode); + break; + case 'allowed_portals': + $aPortalConf = $this->ParseAllowedPortals($aPortalConf, $oPropertyNode); + break; + } + } - return $aPortalConf; - } + return $aPortalConf; + } /** * @param array $aPortalConf @@ -163,54 +163,54 @@ class Basic extends AbstractConfiguration * @return array * @throws \DOMFormatException */ - private function ParseTemplateAndTheme(array $aPortalConf, DesignElement $oPropertyNode) - { - /** @var \MFElement $oSubNode */ - foreach ($oPropertyNode->GetNodes('template|theme') as $oSubNode) - { - if (!$oSubNode->hasAttribute('id') || $oSubNode->GetText(null) === null) - { - throw new DOMFormatException( - 'Tag ' . $oSubNode->nodeName.' must have a "id" attribute as well as a value', - null, null, $oSubNode - ); - } + private function ParseTemplateAndTheme(array $aPortalConf, DesignElement $oPropertyNode) + { + /** @var \MFElement $oSubNode */ + foreach ($oPropertyNode->GetNodes('template|theme') as $oSubNode) + { + if (!$oSubNode->hasAttribute('id') || $oSubNode->GetText(null) === null) + { + throw new DOMFormatException( + 'Tag '.$oSubNode->nodeName.' must have a "id" attribute as well as a value', + null, null, $oSubNode + ); + } - $sNodeId = $oSubNode->getAttribute('id'); - switch ($oSubNode->nodeName) - { - case 'theme': - switch ($sNodeId) - { - case 'bootstrap': - case 'portal': - case 'custom': - $aPortalConf['properties']['themes'][$sNodeId] = $oSubNode->GetText(null); - break; - default: - $aPortalConf['properties']['themes']['others'][] = $oSubNode->GetText(null); - break; - } - break; - case 'template': - switch ($sNodeId) - { - case 'layout': - case 'home': - $aPortalConf['properties']['templates'][$sNodeId] = $oSubNode->GetText(null); - break; - default: - throw new DOMFormatException( - 'Value "'.$sNodeId.'" is not handled for template[@id]', - null, null, $oSubNode - ); - break; - } - break; - } - } + $sNodeId = $oSubNode->getAttribute('id'); + switch ($oSubNode->nodeName) + { + case 'theme': + switch ($sNodeId) + { + case 'bootstrap': + case 'portal': + case 'custom': + $aPortalConf['properties']['themes'][$sNodeId] = $oSubNode->GetText(null); + break; + default: + $aPortalConf['properties']['themes']['others'][] = $oSubNode->GetText(null); + break; + } + break; + case 'template': + switch ($sNodeId) + { + case 'layout': + case 'home': + $aPortalConf['properties']['templates'][$sNodeId] = $oSubNode->GetText(null); + break; + default: + throw new DOMFormatException( + 'Value "'.$sNodeId.'" is not handled for template[@id]', + null, null, $oSubNode + ); + break; + } + break; + } + } - return $aPortalConf; + return $aPortalConf; } /** @@ -219,26 +219,26 @@ class Basic extends AbstractConfiguration * * @return array */ - private function ParseAttachments(array $aPortalConf, DesignElement $oPropertyNode) - { - /** @var \MFElement $oSubNode */ - foreach ($oPropertyNode->GetNodes('*') as $oSubNode) - { - switch ($oSubNode->nodeName) - { - case 'allow_delete': - $sValue = $oSubNode->GetText(); - // If the text is null, we keep the default value - // Else we set it - if ($sValue !== null) - { - $aPortalConf['properties']['attachments'][$oSubNode->nodeName] = ($sValue === 'true') ? true : false; - } - break; - } - } + private function ParseAttachments(array $aPortalConf, DesignElement $oPropertyNode) + { + /** @var \MFElement $oSubNode */ + foreach ($oPropertyNode->GetNodes('*') as $oSubNode) + { + switch ($oSubNode->nodeName) + { + case 'allow_delete': + $sValue = $oSubNode->GetText(); + // If the text is null, we keep the default value + // Else we set it + if ($sValue !== null) + { + $aPortalConf['properties']['attachments'][$oSubNode->nodeName] = ($sValue === 'true') ? true : false; + } + break; + } + } - return$aPortalConf; + return $aPortalConf; } /** @@ -247,26 +247,26 @@ class Basic extends AbstractConfiguration * * @return array */ - private function ParseAllowedPortals(array $aPortalConf, DesignElement $oPropertyNode) - { - /** @var \MFElement $oSubNode */ - foreach ($oPropertyNode->GetNodes('*') as $oSubNode) - { - switch ($oSubNode->nodeName) - { - case 'opening_mode': - $sValue = $oSubNode->GetText(); - // If the text is null, we keep the default value - // Else we set it - if ($sValue !== null) - { - $aPortalConf['properties']['allowed_portals'][$oSubNode->nodeName] = ($sValue === 'self') ? 'self' : 'tab'; - } - break; - } - } + private function ParseAllowedPortals(array $aPortalConf, DesignElement $oPropertyNode) + { + /** @var \MFElement $oSubNode */ + foreach ($oPropertyNode->GetNodes('*') as $oSubNode) + { + switch ($oSubNode->nodeName) + { + case 'opening_mode': + $sValue = $oSubNode->GetText(); + // If the text is null, we keep the default value + // Else we set it + if ($sValue !== null) + { + $aPortalConf['properties']['allowed_portals'][$oSubNode->nodeName] = ($sValue === 'self') ? 'self' : 'tab'; + } + break; + } + } - return $aPortalConf; + return $aPortalConf; } /** @@ -275,17 +275,17 @@ class Basic extends AbstractConfiguration * @return array * @throws \Exception */ - private function AppendLogoUri(array $aPortalConf) - { - $sLogoUri = $aPortalConf['properties']['logo']; - if (!preg_match('/^http/', $sLogoUri)) - { - // We prefix it with the server base url - $sLogoUri = utils::GetAbsoluteUrlAppRoot().'env-'.utils::GetCurrentEnvironment().'/'.$sLogoUri; - } - $aPortalConf['properties']['logo'] = $sLogoUri; + private function AppendLogoUri(array $aPortalConf) + { + $sLogoUri = $aPortalConf['properties']['logo']; + if (!preg_match('/^http/', $sLogoUri)) + { + // We prefix it with the server base url + $sLogoUri = utils::GetAbsoluteUrlAppRoot().'env-'.utils::GetCurrentEnvironment().'/'.$sLogoUri; + } + $aPortalConf['properties']['logo'] = $sLogoUri; - return $aPortalConf; + return $aPortalConf; } /** @@ -295,74 +295,74 @@ class Basic extends AbstractConfiguration * @throws \Exception */ private function GetUiExtensions(Container $oContainer) - { - $aUIExtensions = array( - 'css_files' => array(), - 'css_inline' => null, - 'js_files' => array(), - 'js_inline' => null, - 'html' => array(), - ); - $aUIExtensionHooks = array( - iPortalUIExtension::ENUM_PORTAL_EXT_UI_BODY, - iPortalUIExtension::ENUM_PORTAL_EXT_UI_NAVIGATION_MENU, - iPortalUIExtension::ENUM_PORTAL_EXT_UI_MAIN_CONTENT, - ); + { + $aUIExtensions = array( + 'css_files' => array(), + 'css_inline' => null, + 'js_files' => array(), + 'js_inline' => null, + 'html' => array(), + ); + $aUIExtensionHooks = array( + iPortalUIExtension::ENUM_PORTAL_EXT_UI_BODY, + iPortalUIExtension::ENUM_PORTAL_EXT_UI_NAVIGATION_MENU, + iPortalUIExtension::ENUM_PORTAL_EXT_UI_MAIN_CONTENT, + ); - /** @var iPortalUIExtension $oExtensionInstance */ - foreach (MetaModel::EnumPlugins('iPortalUIExtension') as $oExtensionInstance) - { - // Adding CSS files - $aImportPaths = array($oContainer->getParameter('combodo.portal.base.absolute_path').'css/'); - foreach($oExtensionInstance->GetCSSFiles($oContainer) as $sCSSFile) - { - // Removing app root url as we need to pass a path on the file system (relative to app root) - $sCSSFilePath = str_replace(utils::GetAbsoluteUrlAppRoot(), '', $sCSSFile); - // Compiling SCSS file - $sCSSFileCompiled = $oContainer->getParameter('combodo.absolute_url').utils::GetCSSFromSASS($sCSSFilePath, - $aImportPaths); + /** @var iPortalUIExtension $oExtensionInstance */ + foreach (MetaModel::EnumPlugins('iPortalUIExtension') as $oExtensionInstance) + { + // Adding CSS files + $aImportPaths = array($oContainer->getParameter('combodo.portal.base.absolute_path').'css/'); + foreach ($oExtensionInstance->GetCSSFiles($oContainer) as $sCSSFile) + { + // Removing app root url as we need to pass a path on the file system (relative to app root) + $sCSSFilePath = str_replace(utils::GetAbsoluteUrlAppRoot(), '', $sCSSFile); + // Compiling SCSS file + $sCSSFileCompiled = $oContainer->getParameter('combodo.absolute_url').utils::GetCSSFromSASS($sCSSFilePath, + $aImportPaths); - if(!in_array($sCSSFileCompiled, $aUIExtensions['css_files'])) - { - $aUIExtensions['css_files'][] = $sCSSFileCompiled; - } - } + if (!in_array($sCSSFileCompiled, $aUIExtensions['css_files'])) + { + $aUIExtensions['css_files'][] = $sCSSFileCompiled; + } + } - // Adding CSS inline - $sCSSInline = $oExtensionInstance->GetCSSInline($oContainer); - if ($sCSSInline !== null) - { - $aUIExtensions['css_inline'] .= "\n\n".$sCSSInline; - } + // Adding CSS inline + $sCSSInline = $oExtensionInstance->GetCSSInline($oContainer); + if ($sCSSInline !== null) + { + $aUIExtensions['css_inline'] .= "\n\n".$sCSSInline; + } - // Adding JS files - $aUIExtensions['js_files'] = array_merge($aUIExtensions['js_files'], - $oExtensionInstance->GetJSFiles($oContainer)); + // Adding JS files + $aUIExtensions['js_files'] = array_merge($aUIExtensions['js_files'], + $oExtensionInstance->GetJSFiles($oContainer)); - // Adding JS inline - $sJSInline = $oExtensionInstance->GetJSInline($oContainer); - if ($sJSInline !== null) - { - // Note: Semi-colon is to prevent previous script that would have omitted it. - $aUIExtensions['js_inline'] .= "\n\n;\n".$sJSInline; - } + // Adding JS inline + $sJSInline = $oExtensionInstance->GetJSInline($oContainer); + if ($sJSInline !== null) + { + // Note: Semi-colon is to prevent previous script that would have omitted it. + $aUIExtensions['js_inline'] .= "\n\n;\n".$sJSInline; + } - // Adding HTML for each hook - foreach ($aUIExtensionHooks as $sUIExtensionHook) - { - $sFunctionName = 'Get'.$sUIExtensionHook.'HTML'; - $sHTML = $oExtensionInstance->$sFunctionName($oContainer); - if ($sHTML !== null) - { - if (!array_key_exists($sUIExtensionHook, $aUIExtensions['html'])) - { - $aUIExtensions['html'][$sUIExtensionHook] = ''; - } - $aUIExtensions['html'][$sUIExtensionHook] .= "\n\n".$sHTML; - } - } - } + // Adding HTML for each hook + foreach ($aUIExtensionHooks as $sUIExtensionHook) + { + $sFunctionName = 'Get'.$sUIExtensionHook.'HTML'; + $sHTML = $oExtensionInstance->$sFunctionName($oContainer); + if ($sHTML !== null) + { + if (!array_key_exists($sUIExtensionHook, $aUIExtensions['html'])) + { + $aUIExtensions['html'][$sUIExtensionHook] = ''; + } + $aUIExtensions['html'][$sUIExtensionHook] .= "\n\n".$sHTML; + } + } + } - return $aUIExtensions; - } + return $aUIExtensions; + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php index 8990d019b..7427d6f1b 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php +++ b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php @@ -31,8 +31,8 @@ use MetaModel; * Class Forms * * @package Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration - * @author Guillaume Lajarige - * @since 2.7.0 + * @author Guillaume Lajarige + * @since 2.7.0 */ class Forms extends AbstractConfiguration { @@ -41,239 +41,239 @@ class Forms extends AbstractConfiguration * * @throws \Exception */ - public function Process(Container $oContainer) - { - $aForms = array(); + public function Process(Container $oContainer) + { + $aForms = array(); - /** @var \MFElement $oFormNode */ - foreach ($this->GetModuleDesign()->GetNodes('/module_design/forms/form') as $oFormNode) - { - try - { - // Parsing form id - if ($oFormNode->getAttribute('id') === '') - { - throw new DOMFormatException('form tag must have an id attribute', null, null, $oFormNode); - } + /** @var \MFElement $oFormNode */ + foreach ($this->GetModuleDesign()->GetNodes('/module_design/forms/form') as $oFormNode) + { + try + { + // Parsing form id + if ($oFormNode->getAttribute('id') === '') + { + throw new DOMFormatException('form tag must have an id attribute', null, null, $oFormNode); + } - // Parsing form object class - if ($oFormNode->GetUniqueElement('class')->GetText() !== null) - { - // Parsing class - $sFormClass = $oFormNode->GetUniqueElement('class')->GetText(); + // Parsing form object class + if ($oFormNode->GetUniqueElement('class')->GetText() !== null) + { + // Parsing class + $sFormClass = $oFormNode->GetUniqueElement('class')->GetText(); - // Parsing properties - $aFormProperties = array( - 'display_mode' => ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE, - 'always_show_submit' => ApplicationHelper::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT, - ); - if ($oFormNode->GetOptionalElement('properties') !== null) - { - /** @var \MFElement $oPropertyNode */ - foreach ($oFormNode->GetOptionalElement('properties')->childNodes as $oPropertyNode) - { - switch ($oPropertyNode->nodeName) - { - case 'display_mode': - $aFormProperties['display_mode'] = $oPropertyNode->GetText(ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE); - break; - case 'always_show_submit': - $aFormProperties['always_show_submit'] = ($oPropertyNode->GetText('false') === 'true') ? true : false; - break; - } - } - } + // Parsing properties + $aFormProperties = array( + 'display_mode' => ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE, + 'always_show_submit' => ApplicationHelper::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT, + ); + if ($oFormNode->GetOptionalElement('properties') !== null) + { + /** @var \MFElement $oPropertyNode */ + foreach ($oFormNode->GetOptionalElement('properties')->childNodes as $oPropertyNode) + { + switch ($oPropertyNode->nodeName) + { + case 'display_mode': + $aFormProperties['display_mode'] = $oPropertyNode->GetText(ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE); + break; + case 'always_show_submit': + $aFormProperties['always_show_submit'] = ($oPropertyNode->GetText('false') === 'true') ? true : false; + break; + } + } + } - // Parsing available modes for that form (view, edit, create, apply_stimulus) - $aFormStimuli = array(); - if (($oFormNode->GetOptionalElement('modes') !== null) && ($oFormNode->GetOptionalElement('modes')->GetNodes('mode')->length > 0)) - { - $aModes = array(); - /** @var \MFElement $oModeNode */ - foreach ($oFormNode->GetOptionalElement('modes')->GetNodes('mode') as $oModeNode) - { - if ($oModeNode->getAttribute('id') !== '') - { - $aModes[] = $oModeNode->getAttribute('id'); - } - else - { - throw new DOMFormatException('Mode tag must have an id attribute', null, null, - $oFormNode); - } + // Parsing available modes for that form (view, edit, create, apply_stimulus) + $aFormStimuli = array(); + if (($oFormNode->GetOptionalElement('modes') !== null) && ($oFormNode->GetOptionalElement('modes')->GetNodes('mode')->length > 0)) + { + $aModes = array(); + /** @var \MFElement $oModeNode */ + foreach ($oFormNode->GetOptionalElement('modes')->GetNodes('mode') as $oModeNode) + { + if ($oModeNode->getAttribute('id') !== '') + { + $aModes[] = $oModeNode->getAttribute('id'); + } + else + { + throw new DOMFormatException('Mode tag must have an id attribute', null, null, + $oFormNode); + } - // If apply_stimulus mode, checking if stimuli are defined - if ($oModeNode->getAttribute('id') === 'apply_stimulus') - { - $oStimuliNode = $oModeNode->GetOptionalElement('stimuli'); - // if stimuli are defined, we overwrite the form that could have been set by the generic form - if ($oStimuliNode !== null) - { - /** @var \MFElement $oStimulusNode */ - foreach ($oStimuliNode->GetNodes('stimulus') as $oStimulusNode) - { - $sStimulusCode = $oStimulusNode->getAttribute('id'); + // If apply_stimulus mode, checking if stimuli are defined + if ($oModeNode->getAttribute('id') === 'apply_stimulus') + { + $oStimuliNode = $oModeNode->GetOptionalElement('stimuli'); + // if stimuli are defined, we overwrite the form that could have been set by the generic form + if ($oStimuliNode !== null) + { + /** @var \MFElement $oStimulusNode */ + foreach ($oStimuliNode->GetNodes('stimulus') as $oStimulusNode) + { + $sStimulusCode = $oStimulusNode->getAttribute('id'); - // Removing default form is present (in case the default forms were parsed before the current one (from current or parent class)) - if (isset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode])) - { - unset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode]); - } + // Removing default form is present (in case the default forms were parsed before the current one (from current or parent class)) + if (isset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode])) + { + unset($aForms[$sFormClass]['apply_stimulus'][$sStimulusCode]); + } - $aFormStimuli[] = $oStimulusNode->getAttribute('id'); - } - } - } - } - } - else - { - // If no mode was specified, we set it all but stimuli as it would have no sense that every transition forms - // have as many fields displayed as a regular edit form for example. - $aModes = array('view', 'edit', 'create'); - } + $aFormStimuli[] = $oStimulusNode->getAttribute('id'); + } + } + } + } + } + else + { + // If no mode was specified, we set it all but stimuli as it would have no sense that every transition forms + // have as many fields displayed as a regular edit form for example. + $aModes = array('view', 'edit', 'create'); + } - // Parsing fields - $aFields = array( - 'id' => $oFormNode->getAttribute('id'), - 'type' => null, - 'properties' => $aFormProperties, - 'fields' => null, - 'layout' => null, - ); - // ... either enumerated fields ... - if ($oFormNode->GetOptionalElement('fields') !== null) - { - $aFields['type'] = 'custom_list'; - $aFields['fields'] = array(); + // Parsing fields + $aFields = array( + 'id' => $oFormNode->getAttribute('id'), + 'type' => null, + 'properties' => $aFormProperties, + 'fields' => null, + 'layout' => null, + ); + // ... either enumerated fields ... + if ($oFormNode->GetOptionalElement('fields') !== null) + { + $aFields['type'] = 'custom_list'; + $aFields['fields'] = array(); - /** @var \MFElement $oFieldNode */ - foreach ($oFormNode->GetOptionalElement('fields')->GetNodes('field') as $oFieldNode) - { - $sFieldId = $oFieldNode->getAttribute('id'); - if ($sFieldId !== '') - { - $aField = array(); - // Parsing field options like read_only, hidden and mandatory - if ($oFieldNode->GetOptionalElement('read_only')) - { - $aField['readonly'] = ($oFieldNode->GetOptionalElement('read_only')->GetText('true') === 'true') ? true : false; - } - if ($oFieldNode->GetOptionalElement('mandatory')) - { - $aField['mandatory'] = ($oFieldNode->GetOptionalElement('mandatory')->GetText('true') === 'true') ? true : false; - } - if ($oFieldNode->GetOptionalElement('hidden')) - { - $aField['hidden'] = ($oFieldNode->GetOptionalElement('hidden')->GetText('true') === 'true') ? true : false; - } + /** @var \MFElement $oFieldNode */ + foreach ($oFormNode->GetOptionalElement('fields')->GetNodes('field') as $oFieldNode) + { + $sFieldId = $oFieldNode->getAttribute('id'); + if ($sFieldId !== '') + { + $aField = array(); + // Parsing field options like read_only, hidden and mandatory + if ($oFieldNode->GetOptionalElement('read_only')) + { + $aField['readonly'] = ($oFieldNode->GetOptionalElement('read_only')->GetText('true') === 'true') ? true : false; + } + if ($oFieldNode->GetOptionalElement('mandatory')) + { + $aField['mandatory'] = ($oFieldNode->GetOptionalElement('mandatory')->GetText('true') === 'true') ? true : false; + } + if ($oFieldNode->GetOptionalElement('hidden')) + { + $aField['hidden'] = ($oFieldNode->GetOptionalElement('hidden')->GetText('true') === 'true') ? true : false; + } - $aFields['fields'][$sFieldId] = $aField; - } - else - { - throw new DOMFormatException('Field tag must have an id attribute', null, null, - $oFormNode); - } - } - } - // ... or the default zlist - else - { - $aFields['type'] = 'zlist'; - $aFields['fields'] = 'details'; - } + $aFields['fields'][$sFieldId] = $aField; + } + else + { + throw new DOMFormatException('Field tag must have an id attribute', null, null, + $oFormNode); + } + } + } + // ... or the default zlist + else + { + $aFields['type'] = 'zlist'; + $aFields['fields'] = 'details'; + } - // Parsing presentation - if ($oFormNode->GetOptionalElement('twig') !== null) - { - // Extracting the twig template and removing the first and last lines (twig tags) - $sXml = $this->GetModuleDesign()->saveXML($oFormNode->GetOptionalElement('twig')); - $sXml = preg_replace('/^.+\n/', '', $sXml); - $sXml = preg_replace('/\n.+$/', '', $sXml); + // Parsing presentation + if ($oFormNode->GetOptionalElement('twig') !== null) + { + // Extracting the twig template and removing the first and last lines (twig tags) + $sXml = $this->GetModuleDesign()->saveXML($oFormNode->GetOptionalElement('twig')); + $sXml = preg_replace('/^.+\n/', '', $sXml); + $sXml = preg_replace('/\n.+$/', '', $sXml); - $aFields['layout'] = array( - 'type' => (preg_match('/\{\{|\{\#|\{\%/', $sXml) === 1) ? 'twig' : 'xhtml', - 'content' => $sXml, - ); - } + $aFields['layout'] = array( + 'type' => (preg_match('/\{\{|\{\#|\{\%/', $sXml) === 1) ? 'twig' : 'xhtml', + 'content' => $sXml, + ); + } - // Adding form for each class / mode - foreach ($aModes as $sMode) - { - // Initializing current class if necessary - if (!isset($aForms[$sFormClass])) - { - $aForms[$sFormClass] = array(); - } + // Adding form for each class / mode + foreach ($aModes as $sMode) + { + // Initializing current class if necessary + if (!isset($aForms[$sFormClass])) + { + $aForms[$sFormClass] = array(); + } - if ($sMode === 'apply_stimulus') - { - // Iterating over current class and child classes to fill stimuli forms - foreach (MetaModel::EnumChildClasses($sFormClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass) - { - // Initializing child class if necessary - if (!isset($aForms[$sChildClass][$sMode])) - { - $aForms[$sChildClass][$sMode] = array(); - } + if ($sMode === 'apply_stimulus') + { + // Iterating over current class and child classes to fill stimuli forms + foreach (MetaModel::EnumChildClasses($sFormClass, ENUM_CHILD_CLASSES_ALL) as $sChildClass) + { + // Initializing child class if necessary + if (!isset($aForms[$sChildClass][$sMode])) + { + $aForms[$sChildClass][$sMode] = array(); + } - // If stimuli are implicitly defined (empty tag), we define all those that have not already been by other forms. - $aChildStimuli = $aFormStimuli; - if (empty($aChildStimuli)) - { - // Stimuli already declared - $aDeclaredStimuli = array(); - if (array_key_exists($sChildClass, $aForms) && array_key_exists('apply_stimulus', - $aForms[$sChildClass])) - { - $aDeclaredStimuli = array_keys($aForms[$sChildClass]['apply_stimulus']); - } - // All stimuli - $aDatamodelStimuli = array_keys(MetaModel::EnumStimuli($sChildClass)); - // Missing stimuli - $aChildStimuli = array_diff($aDatamodelStimuli, $aDeclaredStimuli); - } + // If stimuli are implicitly defined (empty tag), we define all those that have not already been by other forms. + $aChildStimuli = $aFormStimuli; + if (empty($aChildStimuli)) + { + // Stimuli already declared + $aDeclaredStimuli = array(); + if (array_key_exists($sChildClass, $aForms) && array_key_exists('apply_stimulus', + $aForms[$sChildClass])) + { + $aDeclaredStimuli = array_keys($aForms[$sChildClass]['apply_stimulus']); + } + // All stimuli + $aDatamodelStimuli = array_keys(MetaModel::EnumStimuli($sChildClass)); + // Missing stimuli + $aChildStimuli = array_diff($aDatamodelStimuli, $aDeclaredStimuli); + } - foreach ($aChildStimuli as $sFormStimulus) - { - // Setting form if not defined OR if it was defined by a parent (abstract) class - if (!isset($aForms[$sChildClass][$sMode][$sFormStimulus]) || !empty($aFormStimuli)) - { - $aForms[$sChildClass][$sMode][$sFormStimulus] = $aFields; - $aForms[$sChildClass][$sMode][$sFormStimulus]['id'] = 'apply_stimulus-'.$sChildClass.'-'.$sFormStimulus; - } - } - } - } - elseif (!isset($aForms[$sFormClass][$sMode])) - { - $aForms[$sFormClass][$sMode] = $aFields; - } - else - { - throw new DOMFormatException('There is already a form for the class "'.$sFormClass.'" in "'.$sMode.'"', - null, null, $oFormNode); - } - } - } - else - { - throw new DOMFormatException('Class tag must be defined', null, null, $oFormNode); - } - } - catch (DOMFormatException $e) - { - throw new Exception('Could not create from [id="'.$oFormNode->getAttribute('id').'"] from XML because of a DOM problem : '.$e->getMessage()); - } - catch (Exception $e) - { - throw new Exception('Could not create from from XML : '.$oFormNode->Dump().' '.$e->getMessage()); - } - } + foreach ($aChildStimuli as $sFormStimulus) + { + // Setting form if not defined OR if it was defined by a parent (abstract) class + if (!isset($aForms[$sChildClass][$sMode][$sFormStimulus]) || !empty($aFormStimuli)) + { + $aForms[$sChildClass][$sMode][$sFormStimulus] = $aFields; + $aForms[$sChildClass][$sMode][$sFormStimulus]['id'] = 'apply_stimulus-'.$sChildClass.'-'.$sFormStimulus; + } + } + } + } + elseif (!isset($aForms[$sFormClass][$sMode])) + { + $aForms[$sFormClass][$sMode] = $aFields; + } + else + { + throw new DOMFormatException('There is already a form for the class "'.$sFormClass.'" in "'.$sMode.'"', + null, null, $oFormNode); + } + } + } + else + { + throw new DOMFormatException('Class tag must be defined', null, null, $oFormNode); + } + } + catch (DOMFormatException $e) + { + throw new Exception('Could not create from [id="'.$oFormNode->getAttribute('id').'"] from XML because of a DOM problem : '.$e->getMessage()); + } + catch (Exception $e) + { + throw new Exception('Could not create from from XML : '.$oFormNode->Dump().' '.$e->getMessage()); + } + } - $aPortalConf = $oContainer->getParameter('combodo.portal.instance.conf'); - $aPortalConf['forms'] = $aForms; - $oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf); - } + $aPortalConf = $oContainer->getParameter('combodo.portal.instance.conf'); + $aPortalConf['forms'] = $aForms; + $oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf); + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Lists.php b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Lists.php index e025f573b..bf553e18a 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Lists.php +++ b/datamodels/2.x/itop-portal-base/portal/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Lists.php @@ -28,8 +28,8 @@ use Symfony\Component\DependencyInjection\Container; * Class Lists * * @package Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration - * @author Guillaume Lajarige - * @since 2.7.0 + * @author Guillaume Lajarige + * @since 2.7.0 */ class Lists extends AbstractConfiguration { @@ -38,75 +38,75 @@ class Lists extends AbstractConfiguration * * @throws \DOMFormatException */ - public function Process(Container $oContainer) - { - $iDefaultItemRank = 0; - $aClassesLists = array(); + public function Process(Container $oContainer) + { + $iDefaultItemRank = 0; + $aClassesLists = array(); - // Parsing XML file - // - Each classes - /** @var \MFElement $oClassNode */ - foreach ($this->GetModuleDesign()->GetNodes('/module_design/classes/class') as $oClassNode) - { - $aClassLists = array(); - $sClassId = $oClassNode->getAttribute('id'); - if ($sClassId === null) - { - throw new DOMFormatException('Class tag must have an id attribute', null, null, $oClassNode); - } + // Parsing XML file + // - Each classes + /** @var \MFElement $oClassNode */ + foreach ($this->GetModuleDesign()->GetNodes('/module_design/classes/class') as $oClassNode) + { + $aClassLists = array(); + $sClassId = $oClassNode->getAttribute('id'); + if ($sClassId === null) + { + throw new DOMFormatException('Class tag must have an id attribute', null, null, $oClassNode); + } - // - Each lists - /** @var \MFElement $oListNode */ - foreach ($oClassNode->GetNodes('./lists/list') as $oListNode) - { - $aListItems = array(); - $sListId = $oListNode->getAttribute('id'); - if ($sListId === null) - { - throw new DOMFormatException('List tag of "'.$sClassId.'" class must have an id attribute', null, - null, $oListNode); - } + // - Each lists + /** @var \MFElement $oListNode */ + foreach ($oClassNode->GetNodes('./lists/list') as $oListNode) + { + $aListItems = array(); + $sListId = $oListNode->getAttribute('id'); + if ($sListId === null) + { + throw new DOMFormatException('List tag of "'.$sClassId.'" class must have an id attribute', null, + null, $oListNode); + } - // - Each items - /** @var \MFElement $oItemNode */ - foreach ($oListNode->GetNodes('./items/item') as $oItemNode) - { - $sItemId = $oItemNode->getAttribute('id'); - if ($sItemId === null) - { - throw new DOMFormatException('Item tag of "'.$sItemId.'" list must have an id attribute', null, - null, $oItemNode); - } + // - Each items + /** @var \MFElement $oItemNode */ + foreach ($oListNode->GetNodes('./items/item') as $oItemNode) + { + $sItemId = $oItemNode->getAttribute('id'); + if ($sItemId === null) + { + throw new DOMFormatException('Item tag of "'.$sItemId.'" list must have an id attribute', null, + null, $oItemNode); + } - $aItem = array( - 'att_code' => $sItemId, - 'rank' => $iDefaultItemRank, - ); + $aItem = array( + 'att_code' => $sItemId, + 'rank' => $iDefaultItemRank, + ); - $oRankNode = $oItemNode->GetOptionalElement('rank'); - if ($oRankNode !== null) - { - $aItem['rank'] = $oRankNode->GetText($iDefaultItemRank); - } + $oRankNode = $oItemNode->GetOptionalElement('rank'); + if ($oRankNode !== null) + { + $aItem['rank'] = $oRankNode->GetText($iDefaultItemRank); + } - $aListItems[] = $aItem; - } - // - Sorting list items by rank - usort($aListItems, function ($a, $b) { - return $a['rank'] > $b['rank']; - }); - $aClassLists[$sListId] = $aListItems; - } + $aListItems[] = $aItem; + } + // - Sorting list items by rank + usort($aListItems, function ($a, $b) { + return $a['rank'] > $b['rank']; + }); + $aClassLists[$sListId] = $aListItems; + } - // - Adding class only if it has at least one list - if (!empty($aClassLists)) - { - $aClassesLists[$sClassId] = $aClassLists; - } - } - $aPortalConf = $oContainer->getParameter('combodo.portal.instance.conf'); - $aPortalConf['lists'] = $aClassLists; - $oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf); - } + // - Adding class only if it has at least one list + if (!empty($aClassLists)) + { + $aClassesLists[$sClassId] = $aClassLists; + } + } + $aPortalConf = $oContainer->getParameter('combodo.portal.instance.conf'); + $aPortalConf['lists'] = $aClassLists; + $oContainer->setParameter('combodo.portal.instance.conf', $aPortalConf); + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/EventListener/ApplicationContextSetUrlMakerClass.php b/datamodels/2.x/itop-portal-base/portal/src/EventListener/ApplicationContextSetUrlMakerClass.php index 82ad2cb37..97cbbfc39 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/EventListener/ApplicationContextSetUrlMakerClass.php +++ b/datamodels/2.x/itop-portal-base/portal/src/EventListener/ApplicationContextSetUrlMakerClass.php @@ -19,21 +19,21 @@ * */ -/** - * Created by Bruno DA SILVA, working for Combodo - * Date: 04/03/19 - * Time: 17:36 - */ - namespace Combodo\iTop\Portal\EventListener; +use ApplicationContext; use Symfony\Component\HttpKernel\Event\GetResponseEvent; +/** + * Class ApplicationContextSetUrlMakerClass + * + * @package Combodo\iTop\Portal\EventListener + * @since 2.7.0 + * @author Bruno Da Silva + */ class ApplicationContextSetUrlMakerClass { - /** - * @var array - */ + /** @var array $aCombodoPortalInstanceConf */ private $aCombodoPortalInstanceConf; /** @@ -44,11 +44,14 @@ class ApplicationContextSetUrlMakerClass $this->aCombodoPortalInstanceConf = $aCombodoPortalInstanceConf; } + /** + * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $oGetResponseEvent + */ public function onKernelRequest(GetResponseEvent $oGetResponseEvent) { if ($this->aCombodoPortalInstanceConf['properties']['urlmaker_class'] !== null) { - \ApplicationContext::SetUrlMakerClass($this->aCombodoPortalInstanceConf['properties']['urlmaker_class']); + ApplicationContext::SetUrlMakerClass($this->aCombodoPortalInstanceConf['properties']['urlmaker_class']); } } } \ No newline at end of file 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 4553b5093..f51ac8436 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 @@ -25,7 +25,6 @@ use Exception; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use User; use Dict; use LoginWebPage; use UserRights; @@ -39,18 +38,18 @@ use ModuleDesign; */ class UserProvider implements ContainerAwareInterface { - /** @var \ModuleDesign */ + /** @var \ModuleDesign $oModuleDesign */ private $oModuleDesign; /** @var string $sPortalId */ private $sPortalId; - /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ - private $container; + /** @var \Symfony\Component\DependencyInjection\ContainerInterface $container */ + private $oContainer; /** * UserProvider constructor. * * @param \ModuleDesign $oModuleDesign - * @param \User $oUser + * @param string $sPortalId */ public function __construct(ModuleDesign $oModuleDesign, $sPortalId) { @@ -86,16 +85,16 @@ class UserProvider implements ContainerAwareInterface { throw new Exception('Could not load connected user.'); } - $this->container->set('combodo.current_user', $oUser); + $this->oContainer->set('combodo.current_user', $oUser); } /** * Sets the container. * - * @param \Symfony\Component\DependencyInjection\ContainerInterface|null $container + * @param \Symfony\Component\DependencyInjection\ContainerInterface|null $oContainer */ - public function setContainer(ContainerInterface $container = null) + public function setContainer(ContainerInterface $oContainer = null) { - $this->container = $container; + $this->oContainer = $oContainer; } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php index 9a42b2a7c..1d4fd9d57 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Form/ObjectFormManager.php @@ -38,6 +38,8 @@ use DBObjectSearch; use DBObjectSet; use DBSearch; use Dict; +use DOMDocument; +use DOMXPath; use Exception; use InlineImage; use IssueLog; @@ -53,38 +55,46 @@ use utils; * Description of ObjectFormManager * * @author Guillaume Lajarige - * @since 2.3.0 + * @since 2.3.0 */ class ObjectFormManager extends FormManager { + /** @var string ENUM_MODE_VIEW */ const ENUM_MODE_VIEW = 'view'; + /** @var string ENUM_MODE_EDIT */ const ENUM_MODE_EDIT = 'edit'; + /** @var string ENUM_MODE_CREATE */ const ENUM_MODE_CREATE = 'create'; + /** @var string ENUM_MODE_APPLY_STIMULUS */ const ENUM_MODE_APPLY_STIMULUS = 'apply_stimulus'; /** @var \Symfony\Component\DependencyInjection\ContainerInterface $oContainer */ protected $oContainer; - /** @var \DBObject $oObject */ + /** @var \cmdbAbstractObject $oObject */ protected $oObject; + /** @var string $sMode */ protected $sMode; + /** @var string $sActionRulesToken */ protected $sActionRulesToken; + /** @var array $aFormProperties */ protected $aFormProperties; + /** @var array $aCallbackUrls */ protected $aCallbackUrls = array(); - /** - * Creates an instance of \Combodo\iTop\Portal\Form\ObjectFormManager from JSON data that must contain at least : - * - formobject_class : The class of the object that is being edited/viewed - * - formmode : view|edit|create - * - values for parent - * - * @param string $sJson - * - * @return \Combodo\iTop\Portal\Form\ObjectFormManager - * - * @throws \Exception - * @throws \ArchivedObjectException - * @throws \CoreException - */ + /** + * Creates an instance of \Combodo\iTop\Portal\Form\ObjectFormManager from JSON data that must contain at least : + * - formobject_class : The class of the object that is being edited/viewed + * - formmode : view|edit|create + * - values for parent + * + * @param string $sJson + * + * @return \Combodo\iTop\Portal\Form\ObjectFormManager + * + * @throws \Exception + * @throws \ArchivedObjectException + * @throws \CoreException + */ static function FromJSON($sJson) { if (is_array($sJson)) @@ -168,6 +178,7 @@ class ObjectFormManager extends FormManager public function SetContainer(ContainerInterface $oContainer) { $this->oContainer = $oContainer; + return $this; } @@ -183,11 +194,13 @@ class ObjectFormManager extends FormManager /** * * @param \DBObject $oObject + * * @return \Combodo\iTop\Portal\Form\ObjectFormManager */ public function SetObject(DBObject $oObject) { $this->oObject = $oObject; + return $this; } @@ -203,11 +216,13 @@ class ObjectFormManager extends FormManager /** * * @param string $sMode + * * @return \Combodo\iTop\Portal\Form\ObjectFormManager */ public function SetMode($sMode) { $this->sMode = $sMode; + return $this; } @@ -223,11 +238,13 @@ class ObjectFormManager extends FormManager /** * * @param string $sActionRulesToken + * * @return \Combodo\iTop\Portal\Form\ObjectFormManager */ public function SetActionRulesToken($sActionRulesToken) { $this->sActionRulesToken = $sActionRulesToken; + return $this; } @@ -243,11 +260,13 @@ class ObjectFormManager extends FormManager /** * * @param array $aFormProperties + * * @return \Combodo\iTop\Portal\Form\ObjectFormManager */ public function SetFormProperties($aFormProperties) { $this->aFormProperties = $aFormProperties; + return $this; } @@ -263,23 +282,25 @@ class ObjectFormManager extends FormManager /** * * @param array $aCallbackUrls + * * @return \Combodo\iTop\Portal\Form\ObjectFormManager */ public function SetCallbackUrls($aCallbackUrls) { $this->aCallbackUrls = $aCallbackUrls; + return $this; } - /** - * Returns if the form manager is handling a transition form instead of a state form. - * - * @return bool - */ + /** + * Returns if the form manager is handling a transition form instead of a state form. + * + * @return bool + */ public function IsTransitionForm() - { - return ($this->sMode === static::ENUM_MODE_APPLY_STIMULUS); - } + { + return ($this->sMode === static::ENUM_MODE_APPLY_STIMULUS); + } /** * Creates a JSON string from the current object including : @@ -295,7 +316,9 @@ class ObjectFormManager extends FormManager $aJson = parent::ToJSON(); $aJson['formobject_class'] = get_class($this->oObject); if ($this->oObject->GetKey() > 0) + { $aJson['formobject_id'] = $this->oObject->GetKey(); + } $aJson['formmode'] = $this->sMode; $aJson['formactionrulestoken'] = $this->sActionRulesToken; $aJson['formproperties'] = $this->aFormProperties; @@ -303,15 +326,12 @@ class ObjectFormManager extends FormManager return $aJson; } - /** - * @throws \Exception - * @throws \CoreException - * @throws \OQLException - * @throws \Twig_Error_Loader - * @throws \Twig_Error_Runtime - * @throws \Twig_Error_Syntax - */ - public function Build() + /** + * @throws \CoreException + * @throws \OQLException + * @throws \Exception + */ + public function Build() { $sObjectClass = get_class($this->oObject); @@ -325,7 +345,7 @@ class ObjectFormManager extends FormManager } else { - $aFormId = 'objectform-' . ((isset($this->aFormProperties['id'])) ? $this->aFormProperties['id'] : 'default') . '-' . uniqid(); + $aFormId = 'objectform-'.((isset($this->aFormProperties['id'])) ? $this->aFormProperties['id'] : 'default').'-'.uniqid(); $oForm = new Form($aFormId); $oForm->SetTransactionId(utils::GetNewTransactionId()); } @@ -338,26 +358,26 @@ class ObjectFormManager extends FormManager case 'static': foreach ($this->aFormProperties['fields'] as $sAttCode => $aOptions) { - // When in a transition and no flags are specified for the field, we will retrieve its flags from DM later - if($this->IsTransitionForm() && empty($aOptions)) - { - $aFieldsDMOnlyAttCodes[] = $sAttCode; - continue; - } + // When in a transition and no flags are specified for the field, we will retrieve its flags from DM later + if ($this->IsTransitionForm() && empty($aOptions)) + { + $aFieldsDMOnlyAttCodes[] = $sAttCode; + continue; + } - // Otherwise we proceed as usual - $iFieldFlags = OPT_ATT_NORMAL; + // Otherwise we proceed as usual + $iFieldFlags = OPT_ATT_NORMAL; // Checking if field should be slave if (isset($aOptions['slave']) && ($aOptions['slave'] === true)) { $iFieldFlags = $iFieldFlags | OPT_ATT_SLAVE; } - // Checking if field should be must_change - if (isset($aOptions['must_change']) && ($aOptions['must_change'] === true)) - { - $iFieldFlags = $iFieldFlags | OPT_ATT_MUSTCHANGE; - } - // Checking if field should be must prompt + // Checking if field should be must_change + if (isset($aOptions['must_change']) && ($aOptions['must_change'] === true)) + { + $iFieldFlags = $iFieldFlags | OPT_ATT_MUSTCHANGE; + } + // Checking if field should be must prompt if (isset($aOptions['must_prompt']) && ($aOptions['must_prompt'] === true)) { $iFieldFlags = $iFieldFlags | OPT_ATT_MUSTPROMPT; @@ -372,11 +392,11 @@ class ObjectFormManager extends FormManager { $iFieldFlags = $iFieldFlags | OPT_ATT_READONLY; } - // Checking if field should be mandatory - if (isset($aOptions['mandatory']) && ($aOptions['mandatory'] === true)) - { - $iFieldFlags = $iFieldFlags | OPT_ATT_MANDATORY; - } + // Checking if field should be mandatory + if (isset($aOptions['mandatory']) && ($aOptions['mandatory'] === true)) + { + $iFieldFlags = $iFieldFlags | OPT_ATT_MANDATORY; + } // Finally, adding the attribute and its flags $aFieldsAtts[$sAttCode] = $iFieldFlags; } @@ -395,7 +415,7 @@ class ObjectFormManager extends FormManager // Checking if we need to render the template from twig to html in order to parse the fields if ($this->aFormProperties['layout']['type'] === 'twig') { - if($this->oContainer !== null) + if ($this->oContainer !== null) { /** @var \Combodo\iTop\Portal\Helper\ObjectFormHandlerHelper $oObjectFormHandler */ $oObjectFormHandler = $this->oContainer->get('object_form_handler'); @@ -416,70 +436,71 @@ class ObjectFormManager extends FormManager } // Parsing rendered template to find the fields - $oHtmlDocument = new \DOMDocument(); + $oHtmlDocument = new DOMDocument(); // Note: Loading as XML instead of HTML avoid some encoding issues (eg. 'é' was transformed to '˜©') - $oHtmlDocument->loadXML('' . $sRendered . ''); + $oHtmlDocument->loadXML(''.$sRendered.''); // Adding fields to the list - $oXPath = new \DOMXPath($oHtmlDocument); + $oXPath = new DOMXPath($oHtmlDocument); + /** @var \DOMElement $oFieldNode */ foreach ($oXPath->query('//div[contains(@class, "form_field")][@data-field-id]') as $oFieldNode) { $sFieldId = $oFieldNode->getAttribute('data-field-id'); $sFieldFlags = $oFieldNode->getAttribute('data-field-flags'); $iFieldFlags = OPT_ATT_NORMAL; - // When in a transition and no flags are specified for the field, we will retrieve its flags from DM later - if($this->IsTransitionForm() && $sFieldFlags === '') - { - // (Might have already been added from the "fields" property) - if(!in_array($sFieldId, $aFieldsDMOnlyAttCodes)) - { - $aFieldsDMOnlyAttCodes[] = $sFieldId; - } - continue; - } + // When in a transition and no flags are specified for the field, we will retrieve its flags from DM later + if ($this->IsTransitionForm() && $sFieldFlags === '') + { + // (Might have already been added from the "fields" property) + if (!in_array($sFieldId, $aFieldsDMOnlyAttCodes)) + { + $aFieldsDMOnlyAttCodes[] = $sFieldId; + } + continue; + } - // Otherwise we proceed as usual - foreach (explode(' ', $sFieldFlags) as $sFieldFlag) - { - if ($sFieldFlag !== '') - { - $sConst = 'OPT_ATT_' . strtoupper(str_replace('_', '', $sFieldFlag)); - if (defined($sConst)) - { - $iFieldFlags = $iFieldFlags | constant($sConst); - } - else - { - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Flag "' . $sFieldFlag . '" is not valid for field [@data-field-id="' . $sFieldId . '"] in form[@id="' . $this->aFormProperties['id'] . '"]'); - throw new Exception('Flag "' . $sFieldFlag . '" is not valid for field [@data-field-id="' . $sFieldId . '"] in form[@id="' . $this->aFormProperties['id'] . '"]'); - } - } - } + // Otherwise we proceed as usual + foreach (explode(' ', $sFieldFlags) as $sFieldFlag) + { + if ($sFieldFlag !== '') + { + $sConst = 'OPT_ATT_'.strtoupper(str_replace('_', '', $sFieldFlag)); + if (defined($sConst)) + { + $iFieldFlags = $iFieldFlags | constant($sConst); + } + else + { + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Flag "'.$sFieldFlag.'" is not valid for field [@data-field-id="'.$sFieldId.'"] in form[@id="'.$this->aFormProperties['id'].'"]'); + throw new Exception('Flag "'.$sFieldFlag.'" is not valid for field [@data-field-id="'.$sFieldId.'"] in form[@id="'.$this->aFormProperties['id'].'"]'); + } + } + } - // Checking if field has form_path, if not, we add it + // Checking if field has form_path, if not, we add it if (!$oFieldNode->hasAttribute('data-form-path')) { $oFieldNode->setAttribute('data-form-path', $oForm->GetId()); } - // Checking if field should be displayed opened (For linked set) - if($oFieldNode->hasAttribute('data-field-opened') && ($oFieldNode->getAttribute('data-field-opened') === 'true') ) - { - $aFieldsExtraData[$sFieldId]['opened'] = true; - } - // Checking field display mode - if($oFieldNode->hasAttribute('data-field-display-mode') && $oFieldNode->getAttribute('data-field-display-mode') !== '') - { - $aFieldsExtraData[$sFieldId]['display_mode'] = $oFieldNode->getAttribute('data-field-display-mode'); - } - elseif(isset($this->aFormProperties['properties']['display_mode'])) - { - $aFieldsExtraData[$sFieldId]['display_mode'] = $this->aFormProperties['properties']['display_mode']; - } - else - { - $aFieldsExtraData[$sFieldId]['display_mode'] = ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE; - } + // Checking if field should be displayed opened (For linked set) + if ($oFieldNode->hasAttribute('data-field-opened') && ($oFieldNode->getAttribute('data-field-opened') === 'true')) + { + $aFieldsExtraData[$sFieldId]['opened'] = true; + } + // Checking field display mode + if ($oFieldNode->hasAttribute('data-field-display-mode') && $oFieldNode->getAttribute('data-field-display-mode') !== '') + { + $aFieldsExtraData[$sFieldId]['display_mode'] = $oFieldNode->getAttribute('data-field-display-mode'); + } + elseif (isset($this->aFormProperties['properties']['display_mode'])) + { + $aFieldsExtraData[$sFieldId]['display_mode'] = $this->aFormProperties['properties']['display_mode']; + } + else + { + $aFieldsExtraData[$sFieldId]['display_mode'] = ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE; + } // Finally adding field to the list if (!array_key_exists($sFieldId, $aFieldsAtts)) @@ -495,36 +516,36 @@ class ObjectFormManager extends FormManager // Merging flags from metamodel with those from the form // Also, retrieving mandatory attributes from metamodel to be able to complete the form with them if necessary - // - // Note: When in a transition, we don't do this for fields that should be set from DM + // + // Note: When in a transition, we don't do this for fields that should be set from DM if ($this->aFormProperties['type'] !== 'static') { - if($this->IsTransitionForm()) - { - $aDatamodelAttCodes = $this->oObject->GetTransitionAttributes($this->aFormProperties['stimulus_code']); - } - else - { - $aDatamodelAttCodes = MetaModel::ListAttributeDefs($sObjectClass); - } + if ($this->IsTransitionForm()) + { + $aDatamodelAttCodes = $this->oObject->GetTransitionAttributes($this->aFormProperties['stimulus_code']); + } + else + { + $aDatamodelAttCodes = MetaModel::ListAttributeDefs($sObjectClass); + } foreach ($aDatamodelAttCodes as $sAttCode => $value) { - /** var AttributeDefinition $oAttDef */ + /** var AttributeDefinition $oAttDef */ - // Skipping fields that should come from DM only as they will be process later on - if(in_array($sAttCode, $aFieldsDMOnlyAttCodes)) - { - continue; - } + // Skipping fields that should come from DM only as they will be process later on + if (in_array($sAttCode, $aFieldsDMOnlyAttCodes)) + { + continue; + } // Retrieving object flags - if ($this->IsTransitionForm()) - { - // Retrieving only mandatory flag from DM when on a transition - $iFieldFlags = $value & OPT_ATT_MANDATORY; - $oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sAttCode); - } + if ($this->IsTransitionForm()) + { + // Retrieving only mandatory flag from DM when on a transition + $iFieldFlags = $value & OPT_ATT_MANDATORY; + $oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sAttCode); + } elseif ($this->oObject->IsNew()) { $iFieldFlags = $this->oObject->GetInitialStateAttributeFlags($sAttCode); @@ -536,27 +557,27 @@ class ObjectFormManager extends FormManager $oAttDef = $value; } - // Skipping fields that were not specified to DM only list (garbage collector) - if($this->IsTransitionForm() && !array_key_exists($sAttCode, $aFieldsAtts)) - { - if( (($value & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY && $oAttDef->IsNull($this->oObject->Get($sAttCode))) - || (($value & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT) - || (($value & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE)) - { - if(!in_array($sAttCode, $aFieldsDMOnlyAttCodes)) - { - $aFieldsDMOnlyAttCodes[] = $sAttCode; - } - } - continue; - } + // Skipping fields that were not specified to DM only list (garbage collector) + if ($this->IsTransitionForm() && !array_key_exists($sAttCode, $aFieldsAtts)) + { + if ((($value & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY && $oAttDef->IsNull($this->oObject->Get($sAttCode))) + || (($value & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT) + || (($value & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE)) + { + if (!in_array($sAttCode, $aFieldsDMOnlyAttCodes)) + { + $aFieldsDMOnlyAttCodes[] = $sAttCode; + } + } + continue; + } // Merging flags with those from the form definition // - If the field is in fields list if (array_key_exists($sAttCode, $aFieldsAtts)) { - // .. We merge them all - $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | $iFieldFlags; + // .. We merge them all + $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | $iFieldFlags; } // - or it is mandatory and has no value if ((($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) && ($this->oObject->Get($sAttCode) === '')) @@ -571,57 +592,57 @@ class ObjectFormManager extends FormManager } // Adding fields with DM flags only - // Note: This should only happen when in a transition - foreach($aFieldsDMOnlyAttCodes as $sAttCode) - { - // Retrieving object flags from DM - if ($this->IsTransitionForm()) - { - $aTransitionAtts = $this->oObject->GetTransitionAttributes($this->aFormProperties['stimulus_code']); - $iFieldFlags = $aTransitionAtts[$sAttCode]; - } - elseif ($this->oObject->IsNew()) - { - $iFieldFlags = $this->oObject->GetInitialStateAttributeFlags($sAttCode); - } - else - { - $iFieldFlags = $this->oObject->GetAttributeFlags($sAttCode); - } + // Note: This should only happen when in a transition + foreach ($aFieldsDMOnlyAttCodes as $sAttCode) + { + // Retrieving object flags from DM + if ($this->IsTransitionForm()) + { + $aTransitionAtts = $this->oObject->GetTransitionAttributes($this->aFormProperties['stimulus_code']); + $iFieldFlags = $aTransitionAtts[$sAttCode]; + } + elseif ($this->oObject->IsNew()) + { + $iFieldFlags = $this->oObject->GetInitialStateAttributeFlags($sAttCode); + } + else + { + $iFieldFlags = $this->oObject->GetAttributeFlags($sAttCode); + } - // Resetting/Forcing flag to read/write - $aFieldsAtts[$sAttCode] = OPT_ATT_NORMAL; - // Checking if field should be must_change - if(($iFieldFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE) - { - $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | OPT_ATT_MUSTCHANGE; - } - // Checking if field should be must_prompt - if(($iFieldFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT) - { - $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | OPT_ATT_MUSTPROMPT; - } - // Checking if field should be mandatory - if(($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) - { - $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | OPT_ATT_MANDATORY; - } - } + // Resetting/Forcing flag to read/write + $aFieldsAtts[$sAttCode] = OPT_ATT_NORMAL; + // Checking if field should be must_change + if (($iFieldFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE) + { + $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | OPT_ATT_MUSTCHANGE; + } + // Checking if field should be must_prompt + if (($iFieldFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT) + { + $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | OPT_ATT_MUSTPROMPT; + } + // Checking if field should be mandatory + if (($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) + { + $aFieldsAtts[$sAttCode] = $aFieldsAtts[$sAttCode] | OPT_ATT_MANDATORY; + } + } // Building the form foreach ($aFieldsAtts as $sAttCode => $iFieldFlags) { $oAttDef = MetaModel::GetAttributeDef(get_class($this->oObject), $sAttCode); - + /** @var Field $oField */ $oField = null; - if (is_callable(get_class($oAttDef) . '::MakeFormField')) + if (is_callable(get_class($oAttDef).'::MakeFormField')) { $oField = $oAttDef->MakeFormField($this->oObject); } - + // Failsafe for AttributeType that would not have MakeFormField and therefore could not be used in a form - if($oField !== null) + if ($oField !== null) { if ($this->sMode !== static::ENUM_MODE_VIEW) { @@ -638,20 +659,20 @@ class ObjectFormManager extends FormManager { $oField->SetReadOnly(true); } - // - Else if it's must change (transition), we force it as mustchange, not readonly and not hidden - elseif (($iFieldFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE && $this->IsTransitionForm()) - { - $oField->SetMustChange(true); - $oField->SetReadOnly(false); - $oField->SetHidden(false); - } - // - Else if it's must prompt (transition), we force it as not readonly and not hidden - elseif (($iFieldFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT && $this->IsTransitionForm()) - { - $oField->SetReadOnly(false); - $oField->SetHidden(false); - } - // - Else if it wasn't mandatory or already had a value, and it's hidden, we force it as hidden + // - Else if it's must change (transition), we force it as mustchange, not readonly and not hidden + elseif (($iFieldFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE && $this->IsTransitionForm()) + { + $oField->SetMustChange(true); + $oField->SetReadOnly(false); + $oField->SetHidden(false); + } + // - Else if it's must prompt (transition), we force it as not readonly and not hidden + elseif (($iFieldFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT && $this->IsTransitionForm()) + { + $oField->SetReadOnly(false); + $oField->SetHidden(false); + } + // - Else if it wasn't mandatory or already had a value, and it's hidden, we force it as hidden elseif (($iFieldFlags & OPT_ATT_HIDDEN) === OPT_ATT_HIDDEN) { $oField->SetHidden(true); @@ -663,39 +684,43 @@ class ObjectFormManager extends FormManager else { // Normal field, use "flags" set by AttDef::MakeFormField() - // Except if we are in a transition be cause $oAttDef doesn't know if the form is for a transition - if($this->IsTransitionForm()) - { - $oField->SetReadOnly(false); - $oField->SetHidden(false); - $oField->SetMandatory(false); - } + // Except if we are in a transition be cause $oAttDef doesn't know if the form is for a transition + if ($this->IsTransitionForm()) + { + $oField->SetReadOnly(false); + $oField->SetHidden(false); + $oField->SetMandatory(false); + } } - // Finally, if it's mandatory ... - if (($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) - { - // ... and when in a transition, we force it as mandatory - if($this->IsTransitionForm() && $oAttDef->IsNull($this->oObject->Get($sAttCode))) - { - $oField->SetMandatory(true); - } - // .. and has no value, we force it as mandatory - elseif($oAttDef->IsNull($this->oObject->Get($sAttCode))) - { - $oField->SetMandatory(true); - } - } + // Finally, if it's mandatory ... + if (($iFieldFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) + { + // ... and when in a transition, we force it as mandatory + if ($this->IsTransitionForm() && $oAttDef->IsNull($this->oObject->Get($sAttCode))) + { + $oField->SetMandatory(true); + } + // .. and has no value, we force it as mandatory + elseif ($oAttDef->IsNull($this->oObject->Get($sAttCode))) + { + $oField->SetMandatory(true); + } + } // Specific operation on field // - Field that require a transaction id - if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\TextAreaField', 'Combodo\\iTop\\Form\\Field\\CaseLogField'))) + if (in_array(get_class($oField), + array('Combodo\\iTop\\Form\\Field\\TextAreaField', 'Combodo\\iTop\\Form\\Field\\CaseLogField'))) { + /** @var \Combodo\iTop\Form\Field\TextAreaField|\Combodo\iTop\Form\Field\CaseLogField $oField */ $oField->SetTransactionId($oForm->GetTransactionId()); } // - Field that require a search endpoint - if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField', 'Combodo\\iTop\\Form\\Field\\LinkedSetField'))) + if (in_array(get_class($oField), + array('Combodo\\iTop\\Form\\Field\\SelectObjectField', 'Combodo\\iTop\\Form\\Field\\LinkedSetField'))) { + /** @var \Combodo\iTop\Form\Field\SelectObjectField|\Combodo\iTop\Form\Field\LinkedSetField $oField */ if ($this->oContainer !== null) { $sSearchEndpoint = $this->oContainer->get('url_generator')->generate('p_object_search_generic', array( @@ -710,6 +735,7 @@ class ObjectFormManager extends FormManager // - Field that require an information endpoint if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\LinkedSetField'))) { + /** @var \Combodo\iTop\Form\Field\LinkedSetField $oField */ if ($this->oContainer !== null) { $oField->SetInformationEndpoint($this->oContainer->get('url_generator')->generate('p_object_get_informations_json')); @@ -718,14 +744,17 @@ class ObjectFormManager extends FormManager // - Field that require to apply scope on its DM OQL if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField'))) { + /** @var \Combodo\iTop\Form\Field\SelectObjectField $oField */ if ($this->oContainer !== null) { $oScopeOriginal = ($oField->GetSearch() !== null) ? $oField->GetSearch() : DBSearch::FromOQL($oAttDef->GetValuesDef()->GetFilterExpression()); - $oScopeSearch = $this->oContainer->get('scope_validator')->GetScopeFilterForProfiles(UserRights::ListProfiles(), $oScopeOriginal->GetClass(), UR_ACTION_READ); + /** @var \DBSearch $oScopeSearch */ + $oScopeSearch = $this->oContainer->get('scope_validator')->GetScopeFilterForProfiles(UserRights::ListProfiles(), + $oScopeOriginal->GetClass(), UR_ACTION_READ); if ($oScopeSearch === null) { - IssueLog::Info(__METHOD__ . ' at line ' . __LINE__ . ' : User #' . UserRights::GetUserId() . ' has no scope query for ' . $oScopeOriginal->GetClass() . ' class.'); + IssueLog::Info(__METHOD__.' at line '.__LINE__.' : User #'.UserRights::GetUserId().' has no scope query for '.$oScopeOriginal->GetClass().' class.'); throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist')); } $oScopeOriginal = $oScopeOriginal->Intersect($oScopeSearch); @@ -739,21 +768,23 @@ class ObjectFormManager extends FormManager } } // - Field that require to check if the current value is among allowed ones - if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField'))) - { - // Note: We can't do this in AttributeExternalKey::MakeFormField() in the Field::SetOnFinalizeCallback() because at this point we have no information about the portal scope and ignore_silos flag, hence it always applies silos. - // As a workaround we have to manually check if the field's current value is among the scope + if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField'))) + { + // Note: We can't do this in AttributeExternalKey::MakeFormField() in the Field::SetOnFinalizeCallback() because at this point we have no information about the portal scope and ignore_silos flag, hence it always applies silos. + // As a workaround we have to manually check if the field's current value is among the scope $oField->VerifyCurrentValue(); - } + } // - Field that require processing on their subfields if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SubFormField'))) { + /** @var \Combodo\iTop\Form\Field\SubFormField $oField */ $oSubForm = $oField->GetForm(); if ($oAttDef->GetEditClass() === 'CustomFields') { // Retrieving only user data fields (not the metadata fields of the template) if ($oSubForm->HasField('user_data')) { + /** @var \Combodo\iTop\Form\Field\SubFormField $oUserDataField */ $oUserDataField = $oSubForm->GetField('user_data'); $oUserDataForm = $oUserDataField->GetForm(); foreach ($oUserDataForm->GetFields() as $oCustomField) @@ -761,21 +792,24 @@ class ObjectFormManager extends FormManager // - Field that require a search endpoint (OQL based dropdown list fields) if (in_array(get_class($oCustomField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField'))) { + /** @var \Combodo\iTop\Form\Field\SelectObjectField $oCustomField */ if ($this->oContainer !== null) { - $sSearchEndpoint = $this->oContainer->get('url_generator')->generate('p_object_search_generic', array( - 'sTargetAttCode' => $oAttDef->GetCode(), - 'sHostObjectClass' => get_class($this->oObject), - 'sHostObjectId' => ($this->oObject->IsNew()) ? null : $this->oObject->GetKey(), - 'ar_token' => $this->GetActionRulesToken(), - )); + $sSearchEndpoint = $this->oContainer->get('url_generator')->generate('p_object_search_generic', + array( + 'sTargetAttCode' => $oAttDef->GetCode(), + 'sHostObjectClass' => get_class($this->oObject), + 'sHostObjectId' => ($this->oObject->IsNew()) ? null : $this->oObject->GetKey(), + 'ar_token' => $this->GetActionRulesToken(), + )); $oCustomField->SetSearchEndpoint($sSearchEndpoint); } } // - Field that require to check if the current value is among allowed ones if (in_array(get_class($oCustomField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField'))) { + /** @var \Combodo\iTop\Form\Field\SelectObjectField $oCustomField */ $oCustomField->VerifyCurrentValue(); } } @@ -799,11 +833,12 @@ class ObjectFormManager extends FormManager // - LinkedSet if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\LinkedSetField'))) { - // - Overriding attributes to display + // - Overriding attributes to display if ($this->oContainer !== null) { // Note : This snippet is inspired from AttributeLinkedSet::MakeFormField() - $aAttCodesToDisplay = ApplicationHelper::GetLoadedListFromClass($this->oContainer->getParameter('combodo.portal.instance.conf')['lists'], $oField->GetTargetClass(), 'list'); + $aAttCodesToDisplay = ApplicationHelper::GetLoadedListFromClass($this->oContainer->getParameter('combodo.portal.instance.conf')['lists'], + $oField->GetTargetClass(), 'list'); // - Adding friendlyname attribute to the list is not already in it $sTitleAttCode = 'friendlyname'; if (($sTitleAttCode !== null) && !in_array($sTitleAttCode, $aAttCodesToDisplay)) @@ -820,10 +855,10 @@ class ObjectFormManager extends FormManager $oField->SetAttributesToDisplay($aAttributesToDisplay); } // - Displaying as opened - if(array_key_exists($sAttCode, $aFieldsExtraData) && array_key_exists('opened', $aFieldsExtraData[$sAttCode])) - { - $oField->SetDisplayOpened(true); - } + if (array_key_exists($sAttCode, $aFieldsExtraData) && array_key_exists('opened', $aFieldsExtraData[$sAttCode])) + { + $oField->SetDisplayOpened(true); + } } } else @@ -836,12 +871,12 @@ class ObjectFormManager extends FormManager } // Setting field display mode - if(array_key_exists($sAttCode, $aFieldsExtraData) && array_key_exists('display_mode', $aFieldsExtraData[$sAttCode])) - { - $oField->SetDisplayMode($aFieldsExtraData[$sAttCode]['display_mode']); - } + if (array_key_exists($sAttCode, $aFieldsExtraData) && array_key_exists('display_mode', $aFieldsExtraData[$sAttCode])) + { + $oField->SetDisplayMode($aFieldsExtraData[$sAttCode]['display_mode']); + } - $oForm->AddField($oField); + $oForm->AddField($oField); } // Checking dependencies to ensure that all needed fields are in the form @@ -879,27 +914,29 @@ class ObjectFormManager extends FormManager // Adding attachment field if ($bClassAllowed) { - $oField = new FileUploadField('attachments_for_form_' . $oForm->GetId()); + $oField = new FileUploadField('attachments_for_form_'.$oForm->GetId()); $oField->SetLabel(Dict::S('Portal:Attachments')) ->SetUploadEndpoint($this->oContainer->get('url_generator')->generate('p_object_attachment_add')) - ->SetDownloadEndpoint($this->oContainer->get('url_generator')->generate('p_object_attachment_download', array('sAttachmentId' => '-sAttachmentId-'))) + ->SetDownloadEndpoint($this->oContainer->get('url_generator')->generate('p_object_attachment_download', + array('sAttachmentId' => '-sAttachmentId-'))) ->SetTransactionId($oForm->GetTransactionId()) ->SetAllowDelete($this->oContainer->getParameter('combodo.portal.instance.conf')['properties']['attachments']['allow_delete']) ->SetObject($this->oObject); // Checking if we can edit attachments in the current state - if (($this->sMode === static::ENUM_MODE_VIEW) - || AttachmentPlugIn::IsReadonlyState($this->oObject, $this->oObject->GetState(), AttachmentPlugIn::ENUM_GUI_PORTALS) === true - || $oForm->GetEditableFieldCount(true) === 0) + if (($this->sMode === static::ENUM_MODE_VIEW) + || AttachmentPlugIn::IsReadonlyState($this->oObject, $this->oObject->GetState(), + AttachmentPlugIn::ENUM_GUI_PORTALS) === true + || $oForm->GetEditableFieldCount(true) === 0) { $oField->SetReadOnly(true); } // Adding attachements field in transition only if it is editable - if(!$this->IsTransitionForm() || ($this->IsTransitionForm() && !$oField->GetReadOnly()) ) - { - $oForm->AddField($oField); - } + if (!$this->IsTransitionForm() || ($this->IsTransitionForm() && !$oField->GetReadOnly())) + { + $oForm->AddField($oField); + } } } @@ -908,23 +945,26 @@ class ObjectFormManager extends FormManager $this->oRenderer->SetForm($this->oForm); } - /** - * Calls all form fields OnCancel method in order to delegate them the cleanup; - * - * @param array $aArgs - * - * @throws \DeleteException - * @throws \OQLException - */ + /** + * Calls all form fields OnCancel method in order to delegate them the cleanup; + * + * @param array $aArgs + * + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \DeleteException + * @throws \MySQLException + * @throws \OQLException + */ public function OnCancel($aArgs = null) { // Ask to each field to clean itself - /** @var \Combodo\iTop\Form\Field\Field $oField */ - foreach ($this->oForm->GetFields() as $oField) + /** @var \Combodo\iTop\Form\Field\Field $oField */ + foreach ($this->oForm->GetFields() as $oField) { $oField->OnCancel(); } - // Then clean inlineimages from rich text editor such as TextareaField + // Then clean inline images from rich text editor such as TextareaField // Note : This could be done by TextareaField::OnCancel(), but we consider that could have been done in this form outside the field. // Also, it would require the field to know the transaction id which it doesn't as of today. InlineImage::OnFormCancel(utils::GetUploadTempId($this->oForm->GetTransactionId())); @@ -933,31 +973,28 @@ class ObjectFormManager extends FormManager $this->CancelAttachments(); } - /** - * Validates the form and returns an array with the validation status and the messages. - * If the form is valid, creates/updates the object. - * - * eg : - * array( - * 'status' => true|false - * 'messages' => array( - * 'errors' => array() - * ) - * - * @param array $aArgs - * - * @return array - * - * @throws \ArchivedObjectException - * @throws \CoreException - * @throws \CoreUnexpectedValue - * @throws \MySQLException - * @throws \MySQLHasGoneAwayException - * @throws \OQLException - * @throws \Twig_Error_Loader - * @throws \Twig_Error_Runtime - * @throws \Twig_Error_Syntax - */ + /** + * Validates the form and returns an array with the validation status and the messages. + * If the form is valid, creates/updates the object. + * + * eg : + * array( + * 'status' => true|false + * 'messages' => array( + * 'errors' => array() + * ) + * + * @param array $aArgs + * + * @return array + * + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + * @throws \OQLException + */ public function OnSubmit($aArgs = null) { $aData = array( @@ -965,8 +1002,8 @@ class ObjectFormManager extends FormManager 'messages' => array( 'success' => array(), 'warnings' => array(), // Not used as of today, just to show that the structure is ready for change like this. - 'error' => array() - ) + 'error' => array(), + ), ); // Update object and form @@ -1020,7 +1057,9 @@ class ObjectFormManager extends FormManager if ($sTriggersQuery !== null) { $aParentClasses = MetaModel::EnumParentClasses($sObjectClass, ENUM_PARENT_CLASSES_ALL); - $oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL($sTriggersQuery), array(), array('parent_classes' => $aParentClasses)); + $oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL($sTriggersQuery), array(), + array('parent_classes' => $aParentClasses)); + /** @var \Trigger $oTrigger */ while ($oTrigger = $oTriggerSet->Fetch()) { $oTrigger->DoActivate($this->oObject->ToArgs('this')); @@ -1033,7 +1072,7 @@ class ObjectFormManager extends FormManager CMDBSource::Query('COMMIT'); // Resetting caselog fields value, otherwise the value will stay in it after submit. - $this->oForm->ResetCaseLogFields(); + $this->oForm->ResetCaseLogFields(); if ($bWasModified) { @@ -1046,7 +1085,7 @@ class ObjectFormManager extends FormManager CMDBSource::Query('ROLLBACK'); $aData['valid'] = false; $aData['messages']['error'] += array('_main' => array($e->getMessage())); - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Rollback during submit (' . $e->getMessage() . ')'); + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Rollback during submit ('.$e->getMessage().')'); } } else @@ -1059,22 +1098,19 @@ class ObjectFormManager extends FormManager return $aData; } - /** - * Updates the form and its fields with the current values - * - * Note : Doesn't update the object, see ObjectFormManager::OnSubmit() for that; - * - * @param array $aArgs - * - * @throws \Exception - * @throws \ArchivedObjectException - * @throws \CoreException - * @throws \CoreUnexpectedValue - * @throws \OQLException - * @throws \Twig_Error_Loader - * @throws \Twig_Error_Runtime - * @throws \Twig_Error_Syntax - */ + /** + * Updates the form and its fields with the current values + * + * Note : Doesn't update the object, see ObjectFormManager::OnSubmit() for that; + * + * @param array $aArgs + * + * @throws \ArchivedObjectException + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \OQLException + * @throws \Exception + */ public function OnUpdate($aArgs = null) { $aFormProperties = array(); @@ -1090,10 +1126,12 @@ class ObjectFormManager extends FormManager { if (MetaModel::IsValidAttCode($sObjectClass, $sAttCode)) { - /** @var \AttributeDefinition $oAttDef */ + /** @var \AttributeDefinition $oAttDef */ $oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode); if ($oAttDef->IsLinkSet()) { + /** @var \AttributeLinkedSet $oAttDef*/ + // Parsing JSON value // // Note : The value was passed as a string instead of an array because the attribute would not be included in the $aCurrentValues when empty. @@ -1101,46 +1139,47 @@ class ObjectFormManager extends FormManager $value = json_decode($value, true); /** @var \ormLinkSet $oLinkSet */ - $oLinkSet = $this->oObject->Get($sAttCode); - $sLinkedClass = $oAttDef->GetLinkedClass(); + $oLinkSet = $this->oObject->Get($sAttCode); + $sLinkedClass = $oAttDef->GetLinkedClass(); - // Checking links to remove - if(isset($value['remove'])) - { - foreach($value['remove'] as $iObjKey => $aObjData) - { - $oLinkSet->RemoveItem($iObjKey); - } - } + // Checking links to remove + if (isset($value['remove'])) + { + foreach ($value['remove'] as $iObjKey => $aObjData) + { + $oLinkSet->RemoveItem($iObjKey); + } + } // Checking links to add - if(isset($value['add'])) - { - foreach($value['add'] as $iObjKey => $aObjdata) - { - // Creating link when linkset is indirect... - if($oAttDef->IsIndirect()) - { - $oLink = MetaModel::NewObject($sLinkedClass); - $oLink->Set($oAttDef->GetExtKeyToRemote(), $iObjKey); - $oLink->Set($oAttDef->GetExtKeyToMe(), $this->oObject->GetKey()); - } - // ... or adding remote object when linkset id direct - else - { - // Note : AllowAllData set to true here instead of checking scope's flag because we are displaying a value that has been set and validated - $oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false, true); - } + if (isset($value['add'])) + { + foreach ($value['add'] as $iObjKey => $aObjdata) + { + // Creating link when linkset is indirect... + if ($oAttDef->IsIndirect()) + { + /** @var \AttributeLinkedSetIndirect $oAttDef*/ + $oLink = MetaModel::NewObject($sLinkedClass); + $oLink->Set($oAttDef->GetExtKeyToRemote(), $iObjKey); + $oLink->Set($oAttDef->GetExtKeyToMe(), $this->oObject->GetKey()); + } + // ... or adding remote object when linkset id direct + else + { + // Note : AllowAllData set to true here instead of checking scope's flag because we are displaying a value that has been set and validated + $oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false, true); + } - if($oLink !== null) - { - $oLinkSet->AddItem($oLink); - } - } - } + if ($oLink !== null) + { + $oLinkSet->AddItem($oLink); + } + } + } - // Checking links to modify - // TODO: Not implemented yet as we can't change lnk properties in the portal + // Checking links to modify + // TODO: Not implemented yet as we can't change lnk properties in the portal // Setting value in the object $this->oObject->Set($sAttCode, $oLinkSet); @@ -1156,17 +1195,17 @@ class ObjectFormManager extends FormManager $oTagSet->ApplyDelta(json_decode($value, true)); $this->oObject->Set($sAttCode, $oTagSet); } - elseif ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime - { - if ($value != null) - { - $value = $oAttDef->GetFormat()->Parse($value); + elseif ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime + { + if ($value != null) + { + $value = $oAttDef->GetFormat()->Parse($value); if (is_object($value)) { $value = $value->format($oAttDef->GetInternalFormat()); } } - $this->oObject->Set($sAttCode, $value); + $this->oObject->Set($sAttCode, $value); } elseif ($oAttDef->IsScalar() && is_array($value)) { @@ -1180,20 +1219,20 @@ class ObjectFormManager extends FormManager // This use case works in the console as it always send all fields, even hidden and read-only. // Different templates - if( isset($value['template_id']) - && ($value['template_id'] != $value['current_template_id']) ) + if (isset($value['template_id']) + && ($value['template_id'] != $value['current_template_id'])) { $this->oObject->Set($sAttCode, $value); } // Same template, different fields - elseif(isset($value['template_id'], $value['template_data']) + elseif (isset($value['template_id'], $value['template_data']) && ($value['template_id'] == $value['current_template_id']) - && ($value['template_data'] != $value['current_template_data']) ) + && ($value['template_data'] != $value['current_template_data'])) { $this->oObject->Set($sAttCode, $value); } // Update of current values - elseif(isset($value['user_data'])) + elseif (isset($value['user_data'])) { $this->oObject->Set($sAttCode, $value); } @@ -1223,17 +1262,17 @@ class ObjectFormManager extends FormManager $this->Build(); } - /** - * This is a temporary function until the Attachment refactoring is done. It should be remove once it's done. - * It is inspired from itop-attachments/main.attachments.php / UpdateAttachments() - * - * @param array $aAttachmentIds - * - * @throws \CoreException - * @throws \CoreUnexpectedValue - * @throws \DeleteException - * @throws \OQLException - */ + /** + * This is a temporary function until the Attachment refactoring is done. It should be remove once it's done. + * It is inspired from itop-attachments/main.attachments.php / UpdateAttachments() + * + * @param array $aAttachmentIds + * + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \DeleteException + * @throws \OQLException + */ protected function FinalizeAttachments($aAttachmentIds) { $aRemovedAttachmentsIds = (isset($aAttachmentIds['removed_attachments_ids'])) ? $aAttachmentIds['removed_attachments_ids'] : array(); @@ -1275,13 +1314,16 @@ class ObjectFormManager extends FormManager } } - /** - * This is a temporary function until the Attachment refactoring is done. It should be remove once it's done. - * It is inspired from itop-attachments/main.attachments.php / UpdateAttachments() - * - * @throws \OQLException - * @throws \DeleteException - */ + /** + * This is a temporary function until the Attachment refactoring is done. It should be remove once it's done. + * It is inspired from itop-attachments/main.attachments.php / UpdateAttachments() + * + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \DeleteException + * @throws \MySQLException + * @throws \OQLException + */ protected function CancelAttachments() { // Processing temporary attachments diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/PasswordFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/PasswordFormManager.php index 63f602655..be693ebb7 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Form/PasswordFormManager.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Form/PasswordFormManager.php @@ -35,16 +35,17 @@ use Combodo\iTop\Form\Field\PasswordField; * Description of PasswordFormManager * * @author Guillaume Lajarige - * @since 2.3.0 + * @since 2.3.0 */ class PasswordFormManager extends FormManager { + /** @var string FORM_TYPE */ const FORM_TYPE = 'change_password'; - /** - * @throws \Exception - */ - public function Build() + /** + * @throws \Exception + */ + public function Build() { // Building the form $oForm = new Form('change_password'); @@ -75,23 +76,23 @@ class PasswordFormManager extends FormManager $this->oRenderer->SetForm($this->oForm); } - /** - * Validates the form and returns an array with the validation status and the messages. - * If the form is valid, creates/updates the object. - * - * eg : - * array( - * 'status' => true|false - * 'messages' => array( - * 'errors' => array() - * ) - * - * @param array $aArgs - * - * @return array - * - * @throws \Exception - */ + /** + * Validates the form and returns an array with the validation status and the messages. + * If the form is valid, creates/updates the object. + * + * eg : + * array( + * 'status' => true|false + * 'messages' => array( + * 'errors' => array() + * ) + * + * @param array $aArgs + * + * @return array + * + * @throws \Exception + */ public function OnSubmit($aArgs = null) { $aData = array( @@ -99,8 +100,8 @@ class PasswordFormManager extends FormManager 'messages' => array( 'success' => array(), 'warnings' => array(), // Not used as of today, just to show that the structure is ready for change like this. - 'error' => array() - ) + 'error' => array(), + ), ); // Update object and form @@ -117,32 +118,50 @@ class PasswordFormManager extends FormManager $sOldPassword = $this->oForm->GetField('old_password')->GetCurrentValue(); $sNewPassword = $this->oForm->GetField('new_password')->GetCurrentValue(); $sConfirmPassword = $this->oForm->GetField('confirm_password')->GetCurrentValue(); - + if ($sOldPassword !== '' && $sNewPassword !== '' && $sConfirmPassword !== '') { if (!UserRights::CanChangePassword()) { $aData['valid'] = false; - $aData['messages']['error'] += array('_main' => array(Dict::Format('Brick:Portal:UserProfile:Password:CantChangeContactAdministrator', ITOP_APPLICATION_SHORT))); - } - else if (!UserRights::CheckCredentials($sAuthUser, $sOldPassword)) - { - $aData['valid'] = false; - $aData['messages']['error'] += array('old_password' => array(Dict::S('UI:Login:IncorrectOldPassword'))); - } - else if ($sNewPassword !== $sConfirmPassword) - { - $aData['valid'] = false; - $aData['messages']['error'] += array('confirm_password' => array(Dict::S('UI:Login:RetypePwdDoesNotMatch'))); - } - else if (!UserRights::ChangePassword($sOldPassword, $sNewPassword)) - { - $aData['valid'] = false; - $aData['messages']['error'] += array('confirm_password' => array(Dict::Format('Brick:Portal:UserProfile:Password:CantChangeForUnknownReason', ITOP_APPLICATION_SHORT))); + $aData['messages']['error'] += array( + '_main' => array( + Dict::Format('Brick:Portal:UserProfile:Password:CantChangeContactAdministrator', ITOP_APPLICATION_SHORT), + ), + ); } else { - $aData['messages']['success'] += array('_main' => array(Dict::S('Brick:Portal:Object:Form:Message:Saved'))); + if (!UserRights::CheckCredentials($sAuthUser, $sOldPassword)) + { + $aData['valid'] = false; + $aData['messages']['error'] += array('old_password' => array(Dict::S('UI:Login:IncorrectOldPassword'))); + } + else + { + if ($sNewPassword !== $sConfirmPassword) + { + $aData['valid'] = false; + $aData['messages']['error'] += array('confirm_password' => array(Dict::S('UI:Login:RetypePwdDoesNotMatch'))); + } + else + { + if (!UserRights::ChangePassword($sOldPassword, $sNewPassword)) + { + $aData['valid'] = false; + $aData['messages']['error'] += array( + 'confirm_password' => array( + Dict::Format('Brick:Portal:UserProfile:Password:CantChangeForUnknownReason', + ITOP_APPLICATION_SHORT), + ), + ); + } + else + { + $aData['messages']['success'] += array('_main' => array(Dict::S('Brick:Portal:Object:Form:Message:Saved'))); + } + } + } } } } @@ -150,7 +169,7 @@ class PasswordFormManager extends FormManager { $aData['valid'] = false; $aData['messages']['error'] += array('_main' => array($e->getMessage())); - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Exception during submit (' . $e->getMessage() . ')'); + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Exception during submit ('.$e->getMessage().')'); } } else @@ -159,16 +178,16 @@ class PasswordFormManager extends FormManager $aData['valid'] = false; $aData['messages']['error'] += $this->oForm->GetErrorMessages(); } - + return $aData; } - /** - * @param array $aArgs - * - * @throws \Exception - */ - public function OnUpdate($aArgs = null) + /** + * @param array $aArgs + * + * @throws \Exception + */ + public function OnUpdate($aArgs = null) { // We build the form @@ -187,12 +206,12 @@ class PasswordFormManager extends FormManager } } - /** - * @param array $aArgs - */ + /** + * @param array $aArgs + */ public function OnCancel($aArgs = null) { - + } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Form/PreferencesFormManager.php b/datamodels/2.x/itop-portal-base/portal/src/Form/PreferencesFormManager.php index 8b5cf4902..a5a64fb54 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Form/PreferencesFormManager.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Form/PreferencesFormManager.php @@ -36,16 +36,17 @@ use Combodo\iTop\Form\Field\SelectField; * Description of PreferencesFormManager * * @author Guillaume Lajarige - * @since 2.3.0 + * @since 2.3.0 */ class PreferencesFormManager extends FormManager { + /** @var string FORM_TYPE */ const FORM_TYPE = 'preferences'; - /** - * @throws \Exception - */ - public function Build() + /** + * @throws \Exception + */ + public function Build() { // Building the form $oForm = new Form('preferences'); @@ -65,7 +66,7 @@ class PreferencesFormManager extends FormManager $aChoices = array(); foreach (Dict::GetLanguages() as $sCode => $aLanguage) { - $aChoices[$sCode] = $aLanguage['description'] . ' (' . $aLanguage['localized_description'] . ')'; + $aChoices[$sCode] = $aLanguage['description'].' ('.$aLanguage['localized_description'].')'; } asort($aChoices); $oField->SetChoices($aChoices); @@ -77,25 +78,25 @@ class PreferencesFormManager extends FormManager $this->oRenderer->SetForm($this->oForm); } - /** - * Validates the form and returns an array with the validation status and the messages. - * If the form is valid, creates/updates the object. - * - * eg : - * array( - * 'status' => true|false - * 'messages' => array( - * 'errors' => array() - * ) - * - * @param array $aArgs - * - * @return array - * - * @throws \Exception - * @throws \MySQLException - * @throws \MySQLHasGoneAwayException - */ + /** + * Validates the form and returns an array with the validation status and the messages. + * If the form is valid, creates/updates the object. + * + * eg : + * array( + * 'status' => true|false + * 'messages' => array( + * 'errors' => array() + * ) + * + * @param array $aArgs + * + * @return array + * + * @throws \Exception + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + */ public function OnSubmit($aArgs = null) { $aData = array( @@ -103,8 +104,8 @@ class PreferencesFormManager extends FormManager 'messages' => array( 'success' => array(), 'warnings' => array(), // Not used as of today, just to show that the structure is ready for change like this. - 'error' => array() - ) + 'error' => array(), + ), ); // Update object and form @@ -130,7 +131,7 @@ class PreferencesFormManager extends FormManager $oCurUser->Set('language', $sLanguage); $iFieldChanged++; } - + // Updating only if preferences changed if ($iFieldChanged > 0) { @@ -148,7 +149,7 @@ class PreferencesFormManager extends FormManager CMDBSource::Query('ROLLBACK'); $aData['valid'] = false; $aData['messages']['error'] += array('_main' => array($e->getMessage())); - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Rollback during submit (' . $e->getMessage() . ')'); + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Rollback during submit ('.$e->getMessage().')'); } } else @@ -157,16 +158,16 @@ class PreferencesFormManager extends FormManager $aData['valid'] = false; $aData['messages']['error'] += $this->oForm->GetErrorMessages(); } - + return $aData; } - /** - * @param array $aArgs - * - * @throws \Exception - */ - public function OnUpdate($aArgs = null) + /** + * @param array $aArgs + * + * @throws \Exception + */ + public function OnUpdate($aArgs = null) { // We build the form @@ -185,12 +186,12 @@ class PreferencesFormManager extends FormManager } } - /** - * @param array $aArgs - */ + /** + * @param array $aArgs + */ public function OnCancel($aArgs = null) { - + } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php index 774932195..7d291b001 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/ApplicationHelper.php @@ -22,52 +22,47 @@ namespace Combodo\iTop\Portal\Helper; -use ApplicationContext; use cmdbAbstractObject; use Combodo\iTop\Portal\Brick\AbstractBrick; -use Combodo\iTop\Portal\Brick\PortalBrick; use DBObjectSearch; use DBObjectSet; use Dict; -use DOMFormatException; use Exception; -use iPortalUIExtension; use IssueLog; use MetaModel; -use ModuleDesign; use Silex\Application; use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\Debug\ExceptionHandler; use Symfony\Component\HttpKernel\Exception\HttpException; -use Twig_Environment; -use Twig_SimpleFilter; -use Twig_SimpleFunction; -use UserRights; -use utils; /** * Contains static methods to help loading / registering classes of the application. * Mostly used for Controllers / Routers / Entities initialization. * * @author Guillaume Lajarige + * @since 2.7.0 */ class ApplicationHelper { + /** @var string FORM_ENUM_DISPLAY_MODE_COSY */ const FORM_ENUM_DISPLAY_MODE_COSY = 'cosy'; + /** @var string FORM_ENUM_DISPLAY_MODE_COMPACT */ const FORM_ENUM_DISPLAY_MODE_COMPACT = 'compact'; + /** @var string FORM_DEFAULT_DISPLAY_MODE */ const FORM_DEFAULT_DISPLAY_MODE = self::FORM_ENUM_DISPLAY_MODE_COSY; + /** @var bool FORM_DEFAULT_ALWAYS_SHOW_SUBMIT */ const FORM_DEFAULT_ALWAYS_SHOW_SUBMIT = false; /** * Loads classes from the base portal * - * @deprecated Since 2.7.0 - * - * @param string $sScannedDir Directory to load the files from + * @param string $sScannedDir Directory to load the files from * @param string $sFilePattern Pattern of files to load - * @param string $sType Type of files to load, used only in the Exception message, can be anything + * @param string $sType Type of files to load, used only in the Exception message, can be anything * * @throws \Exception + * @deprecated Since 2.7.0 + * */ public static function LoadClasses($sScannedDir, $sFilePattern, $sType) { @@ -101,6 +96,8 @@ class ApplicationHelper * Note : It is only active when $oApp['debug'] is false * * @param Application $oApp + * + * @todo */ public static function RegisterExceptionHandler(Application $oApp) { @@ -118,7 +115,7 @@ class ApplicationHelper 'exception' => $oException, 'code' => $iErrorCode, 'error_title' => '', - 'error_message' => $oException->getMessage() + 'error_message' => $oException->getMessage(), ); switch ($iErrorCode) @@ -264,6 +261,7 @@ class ApplicationHelper */ public static function GetLoadedFormFromClass($aForms, $sClass, $sMode) { + $aForm = null; // We try to find the form for that class if (isset($aForms[$sClass]) && isset($aForms[$sClass][$sMode])) @@ -364,7 +362,7 @@ class ApplicationHelper * Form will look like the "Properties" tab of a $sClass object in the console. * * @param string $sClass - * @param bool $bAddLinksets + * @param bool $bAddLinksets * * @return array */ @@ -394,13 +392,13 @@ class ApplicationHelper // Count cols (not linksets) $iColCount = 0; - foreach($aPropertiesStruct as $sColId => $aColFieldsets) + foreach ($aPropertiesStruct as $sColId => $aColFieldsets) { - if(substr($sColId, 0, 1) !== '_') + if (substr($sColId, 0, 1) !== '_') { - foreach($aColFieldsets as $sFieldsetName => $aAttCodes) + foreach ($aColFieldsets as $sFieldsetName => $aAttCodes) { - if(substr($sFieldsetName, 0, 1) !== '_') + if (substr($sFieldsetName, 0, 1) !== '_') { $iColCount++; break; @@ -409,32 +407,32 @@ class ApplicationHelper } } // If no cols, return a default form with all fields one after another - if($iColCount === 0) + if ($iColCount === 0) { return array( 'id' => 'default', 'type' => 'zlist', 'fields' => 'details', - 'layout' => null + 'layout' => null, ); } // Warning, this might not be great when 12 modulo $iColCount is greater than 0. - $sColCSSClass = 'col-sm-'.floor(12/$iColCount); + $sColCSSClass = 'col-sm-'.floor(12 / $iColCount); $sLinksetsHTML = ""; $sRowHTML = "
\n"; - foreach($aPropertiesStruct as $sColId => $aColFieldsets) + foreach ($aPropertiesStruct as $sColId => $aColFieldsets) { $sColsHTML = "\t
\n"; - foreach($aColFieldsets as $sFieldsetName => $aAttCodes) + foreach ($aColFieldsets as $sFieldsetName => $aAttCodes) { // Add fieldset, not linkset - if(substr($sFieldsetName, 0, 1) !== '_') + if (substr($sFieldsetName, 0, 1) !== '_') { $sFieldsetHTML = "\t\t
\n"; $sFieldsetHTML .= "\t\t\t".htmlentities(Dict::S($sFieldsetName), ENT_QUOTES, 'UTF-8')."\n"; - foreach($aAttCodes as $sAttCode) + foreach ($aAttCodes as $sAttCode) { $sFieldsetHTML .= "\t\t\t
\n"; } @@ -444,9 +442,9 @@ class ApplicationHelper // Add to col $sColsHTML .= $sFieldsetHTML; } - elseif($bAddLinksets) + elseif ($bAddLinksets) { - foreach($aAttCodes as $sAttCode) + foreach ($aAttCodes as $sAttCode) { $sLinksetsHTML .= "
\n"; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php index b8b44d19e..094c1dfa8 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/BrowseBrickHelper.php @@ -31,24 +31,26 @@ use Dict; use MetaModel; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use UserRights; -use Combodo\iTop\Portal\Routing\UrlGenerator; +/** + * Class BrowseBrickHelper + * + * @package Combodo\iTop\Portal\Helper + * @since 2.7.0 + * @author Guillaume Lajarige + */ class BrowseBrickHelper { + /** @var string LEVEL_SEPARATOR */ const LEVEL_SEPARATOR = '-'; + /** @var array OPTIONAL_ATTRIBUTES */ const OPTIONAL_ATTRIBUTES = array('tooltip_att', 'description_att', 'image_att'); - /** - * @var \Combodo\iTop\Portal\Helper\SecurityHelper - */ + /** @var \Combodo\iTop\Portal\Helper\SecurityHelper */ private $oSecurityHelper; - /** - * @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper - */ + /** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper */ private $oScopeValidator; - /** - * @var \Combodo\iTop\Portal\Routing\UrlGenerator - */ + /** @var \Combodo\iTop\Portal\Routing\UrlGenerator */ private $oUrlGenerator; /** @@ -58,8 +60,8 @@ class BrowseBrickHelper * @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator */ - public function __construct(SecurityHelper $oSecurityHelper, ScopeValidatorHelper $oScopeValidator, UrlGeneratorInterface $oUrlGenerator) - { + public function __construct(SecurityHelper $oSecurityHelper, ScopeValidatorHelper $oScopeValidator, UrlGeneratorInterface $oUrlGenerator + ) { $this->oSecurityHelper = $oSecurityHelper; $this->oScopeValidator = $oScopeValidator; $this->oUrlGenerator = $oUrlGenerator; @@ -81,16 +83,18 @@ class BrowseBrickHelper * @throws \MySQLException * @throws \MySQLHasGoneAwayException * @throws \OQLException + * @throws \Exception */ public function TreeToFlatLevelsProperties(array $aLevels, array &$aLevelsProperties, $sLevelAliasPrefix = 'L') { foreach ($aLevels as $aLevel) { - $sCurrentLevelAlias = $sLevelAliasPrefix . static::LEVEL_SEPARATOR . $aLevel['id']; + $sCurrentLevelAlias = $sLevelAliasPrefix.static::LEVEL_SEPARATOR.$aLevel['id']; $oSearch = DBSearch::CloneWithAlias(DBSearch::FromOQL($aLevel['oql']), $sCurrentLevelAlias); // Restricting to the allowed scope - $oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $oSearch->GetClass(), UR_ACTION_READ); + $oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $oSearch->GetClass(), + UR_ACTION_READ); $oSearch = ($oScopeSearch !== null) ? $oSearch->Intersect($oScopeSearch) : null; // - Allowing all data if necessary if ($oScopeSearch !== null && $oScopeSearch->IsAllDataAllowed()) @@ -110,7 +114,7 @@ class BrowseBrickHelper 'image_att' => $aLevel['image_att'], 'search' => $oSearch, 'fields' => array(), - 'actions' => array() + 'actions' => array(), ); // Adding current level's fields @@ -123,24 +127,24 @@ class BrowseBrickHelper $aLevelsProperties[$sCurrentLevelAlias]['fields'][] = array( 'code' => $sFieldAttCode, 'label' => MetaModel::GetAttributeDef($oSearch->GetClass(), $sFieldAttCode)->GetLabel(), - 'hidden' => $aFieldProperties['hidden'] + 'hidden' => $aFieldProperties['hidden'], ); } } - // Flattening and adding sublevels + // Flattening and adding sub levels if (isset($aLevel['levels'])) { foreach ($aLevel['levels'] as $aChildLevel) { - // Checking if the sublevel if allowed + // Checking if the sub level if allowed $oChildSearch = DBSearch::FromOQL($aChildLevel['oql']); if ($this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $oChildSearch->GetClass())) { - // Adding the sublevel to this one - $aLevelsProperties[$sCurrentLevelAlias]['levels'][] = $sCurrentLevelAlias . static::LEVEL_SEPARATOR . $aChildLevel['id']; + // Adding the sub level to this one + $aLevelsProperties[$sCurrentLevelAlias]['levels'][] = $sCurrentLevelAlias.static::LEVEL_SEPARATOR.$aChildLevel['id']; - // Adding drilldown action if necessary + // Adding drill down action if necessary foreach ($aLevel['actions'] as $sId => $aAction) { if ($aAction['type'] === BrowseBrick::ENUM_ACTION_DRILLDOWN) @@ -162,11 +166,13 @@ class BrowseBrickHelper if (!array_key_exists($sId, $aLevelsProperties[$sCurrentLevelAlias]['actions'])) { // Adding action only if allowed - if (($aAction['type'] === BrowseBrick::ENUM_ACTION_VIEW) && !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, $oSearch->GetClass())) + if (($aAction['type'] === BrowseBrick::ENUM_ACTION_VIEW) && !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_READ, + $oSearch->GetClass())) { continue; } - elseif (($aAction['type'] === BrowseBrick::ENUM_ACTION_EDIT) && !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, $oSearch->GetClass())) + elseif (($aAction['type'] === BrowseBrick::ENUM_ACTION_EDIT) && !$this->oSecurityHelper->IsActionAllowed(UR_ACTION_MODIFY, + $oSearch->GetClass())) { continue; } @@ -190,8 +196,10 @@ class BrowseBrickHelper // We can only make translate a dictionnary entry with a class placeholder when the action has a class tag. if it has a factory method, we don't know yet what class is going to be created if ($aAction['factory']['type'] === BrowseBrick::ENUM_FACTORY_TYPE_CLASS) { - $aAction['title'] = Dict::Format('Brick:Portal:Browse:Action:CreateObjectFromThis', MetaModel::GetName($aAction['factory']['value'])); - $aAction['url'] = $this->oUrlGenerator->generate('p_object_create', array('sObjectClass' => $aAction['factory']['value'])); + $aAction['title'] = Dict::Format('Brick:Portal:Browse:Action:CreateObjectFromThis', + MetaModel::GetName($aAction['factory']['value'])); + $aAction['url'] = $this->oUrlGenerator->generate('p_object_create', + array('sObjectClass' => $aAction['factory']['value'])); } else { @@ -236,11 +244,16 @@ class BrowseBrickHelper case BrowseBrick::ENUM_ACTION_CREATE_FROM_THIS: if ($aAction['factory']['type'] === BrowseBrick::ENUM_FACTORY_TYPE_CLASS) { - $aAction['url'] = $this->oUrlGenerator->generate('p_object_create', array('sObjectClass' => $aAction['factory']['value'])); + $aAction['url'] = $this->oUrlGenerator->generate('p_object_create', + array('sObjectClass' => $aAction['factory']['value'])); } else { - $aAction['url'] = $this->oUrlGenerator->generate('p_object_create_from_factory', array('sEncodedMethodName' => base64_encode($aAction['factory']['value']), 'sObjectClass' => '-objectClass-', 'sObjectId' => '-objectId-')); + $aAction['url'] = $this->oUrlGenerator->generate('p_object_create_from_factory', array( + 'sEncodedMethodName' => base64_encode($aAction['factory']['value']), + 'sObjectClass' => '-objectClass-', + 'sObjectId' => '-objectId-', + )); } break; } @@ -255,9 +268,9 @@ class BrowseBrickHelper /** * Prepares the action rules for an array of DBObject items. * - * @param array $aItems + * @param array $aItems * @param string $sLevelsAlias - * @param array $aLevelsProperties + * @param array $aLevelsProperties * * @return array */ @@ -298,11 +311,13 @@ class BrowseBrickHelper * * @throws \CoreException * @throws \OQLException + * @throws \Exception */ public function AddToFlatItems(array $aCurrentRow, array &$aLevelsProperties) { $aRow = array(); + /** @var \DBObject $value */ foreach ($aCurrentRow as $key => $value) { // Retrieving objects from all levels @@ -313,18 +328,18 @@ class BrowseBrickHelper 'id' => $value->GetKey(), 'name' => $value->Get($aLevelsProperties[$key]['name_att']), 'class' => get_class($value), - 'action_rules_token' => $this->PrepareActionRulesForItems($aItems, $key, $aLevelsProperties) + 'action_rules_token' => $this->PrepareActionRulesForItems($aItems, $key, $aLevelsProperties), ); // Adding optional attributes if necessary - foreach(static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) + foreach (static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) { if ($aLevelsProperties[$key][$sOptionalAttribute] !== null) { $sPropertyName = substr($sOptionalAttribute, 0, -4); $oAttDef = MetaModel::GetAttributeDef(get_class($value), $aLevelsProperties[$key][$sOptionalAttribute]); - if($oAttDef instanceof AttributeImage) + if ($oAttDef instanceof AttributeImage) { $tmpAttValue = $value->Get($aLevelsProperties[$key][$sOptionalAttribute]); if ($sOptionalAttribute === 'image_att') @@ -335,7 +350,7 @@ class BrowseBrickHelper 'sObjectClass' => get_class($value), 'sObjectId' => $value->GetKey(), 'sObjectField' => $aLevelsProperties[$key][$sOptionalAttribute], - 'cache' => 86400 + 'cache' => 86400, )); } else @@ -360,7 +375,6 @@ class BrowseBrickHelper { $oAttDef = MetaModel::GetAttributeDef(get_class($value), $aField['code']); - $sHtmlForFieldValue = ''; switch (get_class($oAttDef)) { case 'AttributeTagSet': @@ -420,11 +434,12 @@ class BrowseBrickHelper { $aCurrentRowKeys = array_keys($aCurrentRow); $aCurrentRowValues = array_values($aCurrentRow); - $sCurrentIndex = $aCurrentRowKeys[0] . '::' . $aCurrentRowValues[0]->GetKey(); + /** @var \DBObject[] $aCurrentRowValues */ + $sCurrentIndex = $aCurrentRowKeys[0].'::'.$aCurrentRowValues[0]->GetKey(); // We make sure to keep all row objects through levels by copying them when processing the first level. // Otherwise they will be sliced through levels, one by one. - if($aCurrentRowObjects === null) + if ($aCurrentRowObjects === null) { $aCurrentRowObjects = $aCurrentRowValues; } @@ -437,25 +452,31 @@ class BrowseBrickHelper 'name' => $aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]]['name_att']), 'class' => get_class($aCurrentRowValues[0]), 'subitems' => array(), - 'action_rules_token' => $this->PrepareActionRulesForItems($aCurrentRowObjects, $aCurrentRowKeys[0], $aLevelsProperties) + 'action_rules_token' => $this->PrepareActionRulesForItems($aCurrentRowObjects, $aCurrentRowKeys[0], $aLevelsProperties), ); // Adding optional attributes if necessary - foreach(static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) + foreach (static::OPTIONAL_ATTRIBUTES as $sOptionalAttribute) { if ($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute] !== null) { $sPropertyName = substr($sOptionalAttribute, 0, -4); - $oAttDef = MetaModel::GetAttributeDef(get_class($aCurrentRowValues[0]), $aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]); + $oAttDef = MetaModel::GetAttributeDef(get_class($aCurrentRowValues[0]), + $aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]); - if($oAttDef instanceof AttributeImage) + if ($oAttDef instanceof AttributeImage) { $tmpAttValue = $aCurrentRowValues[0]->Get($aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute]); - if($sOptionalAttribute === 'image_att') + if ($sOptionalAttribute === 'image_att') { if (is_object($tmpAttValue) && !$tmpAttValue->IsEmpty()) { - $tmpAttValue = $this->oUrlGenerator->generate('p_object_document_display', array('sObjectClass' => get_class($aCurrentRowValues[0]), 'sObjectId' => $aCurrentRowValues[0]->GetKey(), 'sObjectField' => $aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute], 'cache' => 86400)); + $tmpAttValue = $this->oUrlGenerator->generate('p_object_document_display', array( + 'sObjectClass' => get_class($aCurrentRowValues[0]), + 'sObjectId' => $aCurrentRowValues[0]->GetKey(), + 'sObjectField' => $aLevelsProperties[$aCurrentRowKeys[0]][$sOptionalAttribute], + 'cache' => 86400, + )); } else { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/ContextManipulatorHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/ContextManipulatorHelper.php index 6b2ac2076..904ca491d 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/ContextManipulatorHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/ContextManipulatorHelper.php @@ -36,52 +36,64 @@ use BinaryExpression; use FieldExpression; use ScalarExpression; +/** + * Class ContextManipulatorHelper + * + * @package Combodo\iTop\Portal\Helper + * @since 2.3.0 + * @author Guillaume Lajarige + */ class ContextManipulatorHelper { + /** @var string ENUM_RULE_CALLBACK_BACK */ const ENUM_RULE_CALLBACK_BACK = 'back'; + /** @var string ENUM_RULE_CALLBACK_GOTO */ const ENUM_RULE_CALLBACK_GOTO = 'goto'; + /** @var string ENUM_RULE_CALLBACK_OPEN */ const ENUM_RULE_CALLBACK_OPEN = 'open'; + /** @var string ENUM_RULE_CALLBACK_OPEN_VIEW */ const ENUM_RULE_CALLBACK_OPEN_VIEW = 'view'; + /** @var string ENUM_RULE_CALLBACK_OPEN_EDIT */ const ENUM_RULE_CALLBACK_OPEN_EDIT = 'edit'; + /** @var string DEFAULT_RULE_CALLBACK_OPEN */ const DEFAULT_RULE_CALLBACK_OPEN = self::ENUM_RULE_CALLBACK_OPEN_VIEW; + /** @var array $aRules */ protected $aRules; - - /** @var \Symfony\Component\Routing\RouterInterface */ - private $oRouter; - /** @var \Combodo\iTop\Portal\Brick\BrickCollection */ - private $oBrickCollection; - /** - * @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper - */ - private $oScopeValidator; + /** @var \Symfony\Component\Routing\RouterInterface */ + private $oRouter; + /** @var \Combodo\iTop\Portal\Brick\BrickCollection */ + private $oBrickCollection; + /** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper */ + private $oScopeValidator; /** * ContextManipulatorHelper constructor. * - * @param \ModuleDesign $oModuleDesign - * @param \Symfony\Component\Routing\RouterInterface $oRouter - * @param \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection + * @param \ModuleDesign $oModuleDesign + * @param \Symfony\Component\Routing\RouterInterface $oRouter + * @param \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection * @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator * * @throws \DOMFormatException */ - public function __construct(ModuleDesign $oModuleDesign, RouterInterface $oRouter, BrickCollection $oBrickCollection, ScopeValidatorHelper $oScopeValidator) - { + public function __construct( + ModuleDesign $oModuleDesign, RouterInterface $oRouter, BrickCollection $oBrickCollection, ScopeValidatorHelper $oScopeValidator + ) { $this->aRules = array(); - $this->oRouter = $oRouter; - $this->oBrickCollection = $oBrickCollection; + $this->oRouter = $oRouter; + $this->oBrickCollection = $oBrickCollection; - $this->Init($oModuleDesign->GetNodes('/module_design/action_rules/action_rule')); - $this->oScopeValidator = $oScopeValidator; - } + $this->Init($oModuleDesign->GetNodes('/module_design/action_rules/action_rule')); + $this->oScopeValidator = $oScopeValidator; + } /** * Initializes the ScopeValidator by generating and caching the scopes compilation in the $this->sCachePath.$this->sFilename file. * * @param \DOMNodeList $oNodes - * - * @throws \Exception + * + * @throws \Exception * @throws \DOMFormatException */ public function Init(DOMNodeList $oNodes) @@ -89,7 +101,8 @@ class ContextManipulatorHelper $this->aRules = array(); // Iterating over the scope nodes - foreach ($oNodes as $oRuleNode) + /** @var \Combodo\iTop\DesignElement $oRuleNode */ + foreach ($oNodes as $oRuleNode) { // Retrieving mandatory id attribute $sRuleId = $oRuleNode->getAttribute('id'); @@ -107,17 +120,18 @@ class ContextManipulatorHelper 'preset' => array(), 'retrofit' => array(), 'submit' => null, - 'cancel' => null + 'cancel' => null, ); // Iterating over the rule's nodes + /** @var \Combodo\iTop\DesignElement $oSubNode */ foreach ($oRuleNode->childNodes as $oSubNode) { $sSubNodeName = $oSubNode->nodeName; switch ($sSubNodeName) { case 'source_class': - $aRule['source_oql'] = 'SELECT ' . $oSubNode->GetText(); + $aRule['source_oql'] = 'SELECT '.$oSubNode->GetText(); break; case 'source_oql': @@ -127,6 +141,7 @@ class ContextManipulatorHelper case 'presets': case 'retrofits': + /** @var \Combodo\iTop\DesignElement $oActionNode */ foreach ($oSubNode->childNodes as $oActionNode) { // Note : Caution, the index of $aRule is now $oActionNode->nodeName instead of $sSubNodeName, as we want to match iTopObjectCopier specs like told previously @@ -150,11 +165,11 @@ class ContextManipulatorHelper $sType = $oSubNode->getAttribute('xsi:type'); if ($sType === '') { - throw new DOMFormatException($sSubNodeName . ' must have an xsi:type attribute.', null, null, $oSubNode); + throw new DOMFormatException($sSubNodeName.' must have an xsi:type attribute.', null, null, $oSubNode); } if (($sType === static::ENUM_RULE_CALLBACK_OPEN) && ($sSubNodeName === 'cancel')) { - throw new DOMFormatException('Cancel tag cannot be of type ' . $sType . '.', null, null, $oSubNode); + throw new DOMFormatException('Cancel tag cannot be of type '.$sType.'.', null, null, $oSubNode); } $aRule[$sSubNodeName] = array('type' => $sType); @@ -220,47 +235,48 @@ class ContextManipulatorHelper return $this->aRules; } - /** - * Return the rule identified by its ID, as a hash array - * - * @param string $sId - * - * @return array - * @throws \Exception - */ + /** + * Return the rule identified by its ID, as a hash array + * + * @param string $sId + * + * @return array + * @throws \Exception + */ public function GetRule($sId) { if (!array_key_exists($sId, $this->aRules)) { - throw new Exception('Context creator : Could not find "' . $sId . '" in the rules list'); + throw new Exception('Context creator : Could not find "'.$sId.'" in the rules list'); } + return $this->aRules[$sId]; } - /** - * Prepare the $oObject passed as a reference with the $aData - * - * $aData must be of the form : - * array( - * 'rules' => array( - * 'rule-id-1', - * 'rule-id-2', - * ... - * ), - * 'sources' => array( - * => , - * => , - * ... - * ) - * ) - * - * @param array $aData - * @param \DBObject $oObject - * - * @throws \Exception - * @throws \CoreException - * @throws \OQLException - */ + /** + * Prepare the $oObject passed as a reference with the $aData + * + * $aData must be of the form : + * array( + * 'rules' => array( + * 'rule-id-1', + * 'rule-id-2', + * ... + * ), + * 'sources' => array( + * => , + * => , + * ... + * ) + * ) + * + * @param array $aData + * @param \DBObject $oObject + * + * @throws \Exception + * @throws \CoreException + * @throws \OQLException + */ public function PrepareObject(array $aData, DBObject &$oObject) { if (isset($aData['rules']) && isset($aData['sources'])) @@ -289,7 +305,7 @@ class ContextManipulatorHelper { if (is_array($sourceId)) { - throw new Exception('Context creator : ":id" parameter in rule "' . $sId . '" cannot be an array (This is a limitation of DBSearch)'); + throw new Exception('Context creator : ":id" parameter in rule "'.$sId.'" cannot be an array (This is a limitation of DBSearch)'); } $aSearchParams['id'] = $sourceId; @@ -306,7 +322,8 @@ class ContextManipulatorHelper for ($i = 0; $i < $iLoopMax; $i++) { // - Building full search expression - $oBinExpr = new BinaryExpression(new FieldExpression('id', $oSearch->GetClassAlias()), '=', new ScalarExpression($sourceId[$i])); + $oBinExpr = new BinaryExpression(new FieldExpression('id', $oSearch->GetClassAlias()), '=', + new ScalarExpression($sourceId[$i])); if ($i === 0) { $oFullBinExpr = $oBinExpr; @@ -326,7 +343,8 @@ class ContextManipulatorHelper } // Checking for silos - $oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sSearchClass, UR_ACTION_READ); + $oScopeSearch = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sSearchClass, + UR_ACTION_READ); if ($oScopeSearch->IsAllDataAllowed()) { $oSearch->AllowAllData(); @@ -364,28 +382,28 @@ class ContextManipulatorHelper } } - /** - * Returns a hash array of urls for each type of callback - * - * eg : - * array( - * 'submit' => 'http://localhost/', - * 'cancel' => null - * ); - * - * @param array $aData - * @param \DBObject $oObject - * @param boolean $bModal - * - * @return array - * - * @throws \Exception - */ + /** + * Returns a hash array of urls for each type of callback + * + * eg : + * array( + * 'submit' => 'http://localhost/', + * 'cancel' => null + * ); + * + * @param array $aData + * @param \DBObject $oObject + * @param boolean $bModal + * + * @return array + * + * @throws \Exception + */ public function GetCallbackUrls(array $aData, DBObject $oObject, $bModal = false) { $aResults = array( 'submit' => null, - 'cancel' => null + 'cancel' => null, ); if (isset($aData['rules'])) @@ -417,7 +435,8 @@ class ContextManipulatorHelper break; case static::ENUM_RULE_CALLBACK_OPEN: - $sCallbackUrl = ($oObject->IsNew()) ? null : $this->oRouter->generate('p_object_' . $aRule[$sCallbackName]['mode'], array('sObjectClass' => get_class($oObject), 'sObjectId' => $oObject->GetKey())); + $sCallbackUrl = ($oObject->IsNew()) ? null : $this->oRouter->generate('p_object_'.$aRule[$sCallbackName]['mode'], + array('sObjectClass' => get_class($oObject), 'sObjectId' => $oObject->GetKey())); break; } @@ -430,30 +449,31 @@ class ContextManipulatorHelper return $aResults; } - /** - * Prepares the rules as an array of rules and source objects so it can be tokenised - * - * @param array $aRules - * @param array $aObjects - * @return array - */ + /** + * Prepares the rules as an array of rules and source objects so it can be tokenised + * + * @param array $aRules + * @param array $aObjects + * + * @return array + */ public static function PrepareRulesForToken($aRules, $aObjects = array()) - { - // Getting necessary information from objects - $aSources = array(); - foreach ($aObjects as $oObject) - { - $aSources[get_class($oObject)] = $oObject->GetKey(); - } + { + // Getting necessary information from objects + $aSources = array(); + foreach ($aObjects as $oObject) + { + $aSources[get_class($oObject)] = $oObject->GetKey(); + } - // Preparing data - $aTokenRules = array( - 'rules' => $aRules, - 'sources' => $aSources - ); + // Preparing data + $aTokenRules = array( + 'rules' => $aRules, + 'sources' => $aSources, + ); - return $aTokenRules; - } + return $aTokenRules; + } /** * Encodes a token made out of the rules. @@ -463,33 +483,35 @@ class ContextManipulatorHelper * To retrieve it has * * @param array $aTokenRules - * + * * @return string */ public static function EncodeRulesToken($aTokenRules) { - // Returning tokenised data + // Returning tokenised data return base64_encode(json_encode($aTokenRules)); } - /** - * @param array $aRules - * @param array $aObjects - * @return string - */ + /** + * @param array $aRules + * @param array $aObjects + * + * @return string + */ public static function PrepareAndEncodeRulesToken($aRules, $aObjects = array()) - { - // Preparing rules before making a token - $aTokenRules = static::PrepareRulesForToken($aRules, $aObjects); + { + // Preparing rules before making a token + $aTokenRules = static::PrepareRulesForToken($aRules, $aObjects); - // Returning tokenised data - return static::EncodeRulesToken($aTokenRules); - } + // Returning tokenised data + return static::EncodeRulesToken($aTokenRules); + } /** * Decodes a token made out of the rules * * @param string $sToken + * * @return array */ public static function DecodeRulesToken($sToken) diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/LifecycleValidatorHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/LifecycleValidatorHelper.php index cad1e0352..cb39c5453 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/LifecycleValidatorHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/LifecycleValidatorHelper.php @@ -25,21 +25,44 @@ namespace Combodo\iTop\Portal\Helper; use Exception; use DOMNodeList; use DOMFormatException; +use ModuleDesign; use utils; use ProfilesConfig; use MetaModel; +/** + * Class LifecycleValidatorHelper + * + * @package Combodo\iTop\Portal\Helper + * @since 2.3.0 + * @author Guillaume Lajarige + */ class LifecycleValidatorHelper { + /** @var string DEFAULT_GENERATED_CLASS */ const DEFAULT_GENERATED_CLASS = 'PortalLifecycleValues'; + /** @var string|null $sCachePath */ protected $sCachePath; + /** @var string $sFilename */ protected $sFilename; + /** @var string $sInstancePrefix */ protected $sInstancePrefix; + /** @var string $sGeneratedClass */ protected $sGeneratedClass; + /** @var array $aProfilesMatrix */ protected $aProfilesMatrix; - public function __construct(\ModuleDesign $moduleDesign, $sPortalId, $sPortalCachePath = null) + /** + * LifecycleValidatorHelper constructor. + * + * @param \ModuleDesign $moduleDesign + * @param string $sPortalId + * @param string|null $sPortalCachePath + * + * @throws \DOMFormatException + */ + public function __construct(ModuleDesign $moduleDesign, $sPortalId, $sPortalCachePath = null) { $this->sFilename = "{$sPortalId}.lifecycle.php"; $this->sCachePath = $sPortalCachePath; @@ -47,7 +70,7 @@ class LifecycleValidatorHelper $this->sGeneratedClass = static::DEFAULT_GENERATED_CLASS; $this->aProfilesMatrix = array(); - $this->Init($moduleDesign->GetNodes('/module_design/classes/class')); + $this->Init($moduleDesign->GetNodes('/module_design/classes/class')); } /** @@ -96,7 +119,7 @@ class LifecycleValidatorHelper * This is used to create a unique lifecycle values class in the cache directory (/data/cache-) as there can be several instance of the portal. * * @param string $sInstancePrefix - * + * * @return \Combodo\iTop\Portal\Helper\LifecycleValidatorHelper */ public function SetInstancePrefix($sInstancePrefix) @@ -106,7 +129,8 @@ class LifecycleValidatorHelper $sInstancePrefix = str_replace(' ', '', $sInstancePrefix); $this->sInstancePrefix = $sInstancePrefix; - $this->sGeneratedClass = $this->sInstancePrefix . static::DEFAULT_GENERATED_CLASS; + $this->sGeneratedClass = $this->sInstancePrefix.static::DEFAULT_GENERATED_CLASS; + return $this; } @@ -114,7 +138,7 @@ class LifecycleValidatorHelper * Initializes the LifecycleValidator by generating and caching the lifecycles compilation in the $this->sCachePath.$this->sFilename file. * * @param \DOMNodeList $oNodes - * + * * @throws \DOMFormatException * @throws \Exception */ @@ -126,7 +150,7 @@ class LifecycleValidatorHelper $this->sCachePath = utils::GetCachePath(); } // Building full pathname for file - $sFilePath = $this->sCachePath . $this->sFilename; + $sFilePath = $this->sCachePath.$this->sFilename; // Creating file if not existing // Note: This is a temporary cache system, it should soon evolve to a cache provider (fs, apc, memcache, ...) @@ -137,7 +161,8 @@ class LifecycleValidatorHelper // This will be used to know which classes have been set, so we can set the missing ones. $aProfileClasses = array(); // Iterating over the class nodes - foreach ($oNodes as $oClassNode) + /** @var \Combodo\iTop\DesignElement $oClassNode */ + foreach ($oNodes as $oClassNode) { // Retrieving mandatory class id attribute $sClass = $oClassNode->getAttribute('id'); @@ -147,78 +172,80 @@ class LifecycleValidatorHelper } // Retrieving lifecycle node of the class - $oLifecycleNode = $oClassNode->GetOptionalElement('lifecycle'); - if($oLifecycleNode !== null) - { - // Iterating over scope nodes of the class - $oStimuliNode = $oLifecycleNode->GetOptionalElement('stimuli'); - if ($oStimuliNode !== null) - { - foreach ($oStimuliNode->GetNodes('./stimulus') as $oStimulusNode) - { - // Retrieving mandatory scope id attribute - $sStimulusId = $oStimulusNode->getAttribute('id'); - if ($sStimulusId === '') - { - throw new DOMFormatException('Stimulus tag must have an id attribute.', null, null, $oStimulusNode); - } + $oLifecycleNode = $oClassNode->GetOptionalElement('lifecycle'); + if ($oLifecycleNode !== null) + { + // Iterating over scope nodes of the class + $oStimuliNode = $oLifecycleNode->GetOptionalElement('stimuli'); + if ($oStimuliNode !== null) + { + /** @var \Combodo\iTop\DesignElement $oStimulusNode */ + foreach ($oStimuliNode->GetNodes('./stimulus') as $oStimulusNode) + { + // Retrieving mandatory scope id attribute + $sStimulusId = $oStimulusNode->getAttribute('id'); + if ($sStimulusId === '') + { + throw new DOMFormatException('Stimulus tag must have an id attribute.', null, null, $oStimulusNode); + } - // Retrieving profiles for the stimulus - $oProfilesNode = $oStimulusNode->GetOptionalElement('denied_profiles'); - $aProfilesNames = array(); - // If no profile is specified, we consider that it's for ALL the profiles - if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./denied_profile')->length === 0)) - { - foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) - { - $aProfilesNames[] = $aValue['name']; - } - } - else - { - foreach ($oProfilesNode->GetNodes('./denied_profile') as $oProfileNode) - { - // Retrieving mandatory profile id attribute - $sProfileId = $oProfileNode->getAttribute('id'); - if ($sProfileId === '') - { - throw new DOMFormatException('Profile tag must have an id attribute.', null, null, $oProfileNode); - } - $aProfilesNames[] = $sProfileId; - } - } + // Retrieving profiles for the stimulus + $oProfilesNode = $oStimulusNode->GetOptionalElement('denied_profiles'); + $aProfilesNames = array(); + // If no profile is specified, we consider that it's for ALL the profiles + if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./denied_profile')->length === 0)) + { + foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) + { + $aProfilesNames[] = $aValue['name']; + } + } + else + { + /** @var \Combodo\iTop\DesignElement $oProfileNode */ + foreach ($oProfilesNode->GetNodes('./denied_profile') as $oProfileNode) + { + // Retrieving mandatory profile id attribute + $sProfileId = $oProfileNode->getAttribute('id'); + if ($sProfileId === '') + { + throw new DOMFormatException('Profile tag must have an id attribute.', null, null, $oProfileNode); + } + $aProfilesNames[] = $sProfileId; + } + } - // - foreach ($aProfilesNames as $sProfileName) - { - // Stimulus profile id - $iProfileId = $this->GetProfileIdFromProfileName($sProfileName); + // + foreach ($aProfilesNames as $sProfileName) + { + // Stimulus profile id + $iProfileId = $this->GetProfileIdFromProfileName($sProfileName); - // Now that we have the queries infos, we are going to build the queries for that profile / class - $sMatrixPrefix = $iProfileId . '_' . $sClass; - // - Creating profile / class entry if not already present - if(!array_key_exists($sMatrixPrefix, $aProfiles)) - { - $aProfiles[$sMatrixPrefix] = array(); - } - // - Adding stimulus if not already present - if(!in_array($sStimulusId, $aProfiles[$sMatrixPrefix])) - { - $aProfiles[$sMatrixPrefix][] = $sStimulusId; - } - } - } + // Now that we have the queries infos, we are going to build the queries for that profile / class + $sMatrixPrefix = $iProfileId.'_'.$sClass; + // - Creating profile / class entry if not already present + if (!array_key_exists($sMatrixPrefix, $aProfiles)) + { + $aProfiles[$sMatrixPrefix] = array(); + } + // - Adding stimulus if not already present + if (!in_array($sStimulusId, $aProfiles[$sMatrixPrefix])) + { + $aProfiles[$sMatrixPrefix][] = $sStimulusId; + } + } + } - $aProfileClasses[] = $sClass; - } - } + $aProfileClasses[] = $sClass; + } + } } // Filling the array with missing classes from MetaModel, so we can have an inheritance principle on the stimuli // For each class explicitly given in the stimuli, we check if its child classes were also in the stimuli : // If not, we add them - // - // Note: Classes / Stimuli not in the matrix are implicitly ALLOWED. That can happen by omitting the in a + // + // Note: Classes / Stimuli not in the matrix are implicitly ALLOWED. That can happen by omitting the in a foreach ($aProfileClasses as $sProfileClass) { foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass) @@ -230,11 +257,11 @@ class LifecycleValidatorHelper { $iProfileId = $iKey; - // If the current profile has scope for that class in that mode, we duplicate it - if (isset($aProfiles[$iProfileId . '_' . $sProfileClass])) - { - $aProfiles[$iProfileId . '_' . $sChildClass] = $aProfiles[$iProfileId . '_' . $sProfileClass]; - } + // If the current profile has scope for that class in that mode, we duplicate it + if (isset($aProfiles[$iProfileId.'_'.$sProfileClass])) + { + $aProfiles[$iProfileId.'_'.$sChildClass] = $aProfiles[$iProfileId.'_'.$sProfileClass]; + } } } } @@ -262,63 +289,63 @@ class LifecycleValidatorHelper if (!class_exists($this->sGeneratedClass)) { - require_once $this->sCachePath . $this->sFilename; + require_once $this->sCachePath.$this->sFilename; } } - /** - * Returns an array of available stimuli for the $sProfile for the class $sClass - * - * @param string $sProfile - * @param string $sClass - * - * @return \DBSearch - * - * @throws \Exception - */ + /** + * Returns an array of available stimuli for the $sProfile for the class $sClass + * + * @param string $sProfile + * @param string $sClass + * + * @return array + * + * @throws \Exception + */ public function GetStimuliForProfile($sProfile, $sClass) { return $this->GetStimuliForProfiles(array($sProfile), $sClass); } - /** - * Returns an array of available stimuli for the $aProfiles for the class $sClass. - * Profiles are a OR condition. - * - * @param array $aProfiles - * @param string $sClass - * - * @return \DBSearch - * - * @throws \Exception - */ + /** + * Returns an array of available stimuli for the $aProfiles for the class $sClass. + * Profiles are a OR condition. + * + * @param array $aProfiles + * @param string $sClass + * + * @return array + * + * @throws \Exception + */ public function GetStimuliForProfiles($aProfiles, $sClass) { $aStimuli = array(); // Preparing available stimuli - foreach(MetaModel::EnumStimuli($sClass) as $sStimulusCode => $aData) - { - $aStimuli[$sStimulusCode] = true; - } + foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $aData) + { + $aStimuli[$sStimulusCode] = true; + } // Iterating on profiles to retrieving the different OQLs parts foreach ($aProfiles as $sProfile) { - // Retrieving matrix informtions + // Retrieving matrix information $iProfileId = $this->GetProfileIdFromProfileName($sProfile); // Retrieving profile stimuli $sLifecycleValuesClass = $this->sGeneratedClass; $aProfileMatrix = $sLifecycleValuesClass::GetProfileStimuli($iProfileId, $sClass); - foreach($aProfileMatrix as $sStimulusCode) - { - if(array_key_exists($sStimulusCode, $aStimuli)) - { - unset($aStimuli[$sStimulusCode]); - } - } + foreach ($aProfileMatrix as $sStimulusCode) + { + if (array_key_exists($sStimulusCode, $aStimuli)) + { + unset($aStimuli[$sStimulusCode]); + } + } } return array_keys($aStimuli); @@ -328,9 +355,9 @@ class LifecycleValidatorHelper * Returns the profile id from a string being either a constant or its name. * * @param string $sProfile - * + * * @return integer - * + * * @throws \Exception */ protected function GetProfileIdFromProfileName($sProfile) @@ -366,7 +393,7 @@ class LifecycleValidatorHelper // If profile was not found from its name or from a constant, we throw an exception if ($iProfileId === null) { - throw new Exception('Lifecycle validator : Could not find "' . $sProfile . '" in the profiles list'); + throw new Exception('Lifecycle validator : Could not find "'.$sProfile.'" in the profiles list'); } return $iProfileId; @@ -376,7 +403,7 @@ class LifecycleValidatorHelper * Returns a string containing the generated PHP class for the compiled scopes * * @param array $aProfiles - * + * * @return string */ protected function BuildPHPClass($aProfiles = array()) @@ -417,6 +444,7 @@ class $sClassName } EOF; + return $sPHP; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php index 68c49381e..424a4f2ce 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/ObjectFormHandlerHelper.php @@ -46,13 +46,16 @@ use UserRights; * Class ObjectFormHandlerHelper * * @package Combodo\iTop\Portal\Helper - * @author Guillaume Lajarige - * @since 2.7.0 + * @author Guillaume Lajarige + * @since 2.7.0 */ class ObjectFormHandlerHelper { + /** @var string ENUM_MODE_VIEW */ const ENUM_MODE_VIEW = 'view'; + /** @var string ENUM_MODE_EDIT */ const ENUM_MODE_EDIT = 'edit'; + /** @var string ENUM_MODE_CREATE */ const ENUM_MODE_CREATE = 'create'; /** @var \Combodo\iTop\Portal\Helper\RequestManipulatorHelper */ @@ -145,8 +148,10 @@ class ObjectFormHandlerHelper // Retrieve action rules information to auto-fill the form if available // Preparing object $this->oContextManipulator->PrepareObject($aActionRules, $oObject); - $aPrefillFormParam = array( 'user' => $_SESSION["auth_user"], - 'origin' => 'portal'); + $aPrefillFormParam = array( + 'user' => $_SESSION["auth_user"], + 'origin' => 'portal', + ); $oObject->PrefillForm('creation_from_0', $aPrefillFormParam); } else @@ -170,7 +175,7 @@ class ObjectFormHandlerHelper $aStimuli = Metamodel::EnumStimuli($sObjectClass); foreach ($oObject->EnumTransitions() as $sStimulusCode => $aTransitionDef) { - if($this->oSecurityHelper->IsStimulusAllowed($sStimulusCode, $sObjectClass, $oSetToCheckRights)) + if ($this->oSecurityHelper->IsStimulusAllowed($sStimulusCode, $sObjectClass, $oSetToCheckRights)) { $aFormData['buttons']['transitions'][$sStimulusCode] = $aStimuli[$sStimulusCode]->GetLabel(); } @@ -180,15 +185,15 @@ class ObjectFormHandlerHelper /** @var \iPopupMenuExtension $oExtensionInstance */ foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) { - foreach($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJDETAILS_ACTIONS, array('portal_id' => $this->sPortalId, 'object' => $oObject, 'mode' => $sMode)) as $oMenuItem) + foreach ($oExtensionInstance->EnumItems(iPopupMenuExtension::PORTAL_OBJDETAILS_ACTIONS, array('portal_id' => $this->sPortalId, 'object' => $oObject, 'mode' => $sMode)) as $oMenuItem) { if (is_object($oMenuItem)) { - if($oMenuItem instanceof JSButtonItem) + if ($oMenuItem instanceof JSButtonItem) { $aFormData['buttons']['actions'][] = $oMenuItem->GetMenuItem() + array('js_files' => $oMenuItem->GetLinkedScripts()); } - elseif($oMenuItem instanceof URLButtonItem) + elseif ($oMenuItem instanceof URLButtonItem) { $aFormData['buttons']['links'][] = $oMenuItem->GetMenuItem(); } @@ -197,11 +202,11 @@ class ObjectFormHandlerHelper } // Hiding submit button or changing its label if necessary - if(!empty($aFormData['buttons']['transitions']) && isset($aFormProperties['properties']) &&$aFormProperties['properties']['always_show_submit'] === false) + if (!empty($aFormData['buttons']['transitions']) && isset($aFormProperties['properties']) && $aFormProperties['properties']['always_show_submit'] === false) { unset($aFormData['buttons']['submit']); } - elseif($sMode === static::ENUM_MODE_EDIT) + elseif ($sMode === static::ENUM_MODE_EDIT) { $aFormData['buttons']['submit']['label'] = Dict::S('Portal:Button:Apply'); } @@ -225,7 +230,7 @@ class ObjectFormHandlerHelper // Note : We might need to distinguish form & renderer endpoints if (in_array($sMode, array('create', 'edit', 'view'))) { - $sFormEndpoint = $this->oUrlGenerator->generate('p_object_' . $sMode, array('sObjectClass' => $sObjectClass, 'sObjectId' => $sObjectId)); + $sFormEndpoint = $this->oUrlGenerator->generate('p_object_'.$sMode, array('sObjectClass' => $sObjectClass, 'sObjectId' => $sObjectId)); } else { @@ -252,9 +257,9 @@ class ObjectFormHandlerHelper // Update / Submit / Cancel $sFormManagerClass = $this->oRequestManipulator->ReadParam('formmanager_class', '', FILTER_UNSAFE_RAW); $sFormManagerData = $this->oRequestManipulator->ReadParam('formmanager_data', '', FILTER_UNSAFE_RAW); - if ( empty($sFormManagerClass) || empty($sFormManagerData) ) + if (empty($sFormManagerClass) || empty($sFormManagerData)) { - IssueLog::Error(__METHOD__ . ' at line ' . __LINE__ . ' : Parameters formmanager_class and formamanager_data must be defined.'); + IssueLog::Error(__METHOD__.' at line '.__LINE__.' : Parameters formmanager_class and formamanager_data must be defined.'); throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Parameters formmanager_class and formmanager_data must be defined.'); } @@ -280,7 +285,7 @@ class ObjectFormHandlerHelper 'currentValues' => $this->oRequestManipulator->ReadParam('current_values', array(), FILTER_UNSAFE_RAW), 'attachmentIds' => $this->oRequestManipulator->ReadParam('attachment_ids', array(), FILTER_UNSAFE_RAW), 'formProperties' => $aFormProperties, - 'applyStimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null) + 'applyStimulus' => $this->oRequestManipulator->ReadParam('apply_stimulus', null), ) ); if ($aFormData['validation']['valid'] === true) @@ -329,7 +334,7 @@ class ObjectFormHandlerHelper $sFormPath = $this->oRequestManipulator->ReadParam('form_path', ''); // Checking if the update was on a subform, if so we need to make the rendering for that part only - if ( !empty($sFormPath) && $sFormPath !== $oFormManager->GetForm()->GetId() ) + if (!empty($sFormPath) && $sFormPath !== $oFormManager->GetForm()->GetId()) { $oSubForm = $oFormManager->GetForm()->FindSubForm($sFormPath); $oSubFormRenderer = new BsFormRenderer($oSubForm); @@ -362,19 +367,32 @@ class ObjectFormHandlerHelper return $aFormData; } + /** + * @param $sId + * @param $sTwigString + * @param $aData + * + * @return string + * @throws \Twig\Error\LoaderError + * @throws \Twig\Error\RuntimeError + * @throws \Twig\Error\SyntaxError + * @throws \Twig_Error_Loader + * @throws \Twig_Error_Runtime + * @throws \Twig_Error_Syntax + */ public function RenderFormFromTwig($sId, $sTwigString, $aData) { // Creating sandbox twig env. to load and test the custom form template - $oTwig = new Twig_Environment(new Twig_Loader_Array( array($sId => $sTwigString) )); + $oTwig = new Twig_Environment(new Twig_Loader_Array(array($sId => $sTwigString))); // Manually registering filters and functions as we didn't find how to do it automatically $aFilters = $this->oAppExtension->getFilters(); - foreach($aFilters as $oFilter) + foreach ($aFilters as $oFilter) { $oTwig->addFilter($oFilter); } $aFunctions = $this->oAppExtension->getFunctions(); - foreach($aFunctions as $oFunction) + foreach ($aFunctions as $oFunction) { $oTwig->addFunction($oFunction); } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php index 9867de83c..6a29f0db7 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/RequestManipulatorHelper.php @@ -30,91 +30,91 @@ use Symfony\Component\HttpFoundation\RequestStack; * Handle basic requests manipulation. * * @author Guillaume Lajarige - * @since 2.5.1 + * @since 2.5.1 */ class RequestManipulatorHelper { - /** @var \Symfony\Component\HttpFoundation\RequestStack $oRequestStack */ - protected $oRequestStack; + /** @var \Symfony\Component\HttpFoundation\RequestStack $oRequestStack */ + protected $oRequestStack; - /** - * RequestManipulatorHelper constructor. - * - * @param \Symfony\Component\HttpFoundation\RequestStack $oRequestStack - */ - public function __construct(RequestStack $oRequestStack) - { - $this->oRequestStack = $oRequestStack; - } + /** + * RequestManipulatorHelper constructor. + * + * @param \Symfony\Component\HttpFoundation\RequestStack $oRequestStack + */ + public function __construct(RequestStack $oRequestStack) + { + $this->oRequestStack = $oRequestStack; + } - /** - * @return \Symfony\Component\HttpFoundation\Request - */ - public function GetCurrentRequest() - { - return $this->oRequestStack->getCurrentRequest(); - } + /** + * @return \Symfony\Component\HttpFoundation\Request + */ + public function GetCurrentRequest() + { + return $this->oRequestStack->getCurrentRequest(); + } - /** - * Returns if the request has a $sKey parameter. - * This looks in the GET arguments first, then PATH and finally the POST data. - * - * @param string $sKey - * - * @return bool - */ - public function HasParam($sKey) - { - if ($this->GetCurrentRequest()->query->has($sKey)) - { - return true; - } + /** + * Returns if the request has a $sKey parameter. + * This looks in the GET arguments first, then PATH and finally the POST data. + * + * @param string $sKey + * + * @return bool + */ + public function HasParam($sKey) + { + if ($this->GetCurrentRequest()->query->has($sKey)) + { + return true; + } - if ($this->GetCurrentRequest()->attributes->has($sKey)) - { - return true; - } + if ($this->GetCurrentRequest()->attributes->has($sKey)) + { + return true; + } - if ($this->GetCurrentRequest()->request->has($sKey)) - { - return true; - } + if ($this->GetCurrentRequest()->request->has($sKey)) + { + return true; + } - return false; - } + return false; + } - /** - * Returns the $sKey parameter from the request filtered with $iFilter. - * This looks in the GET arguments first, then the PATH and finally the POST data. - * - * Note: It is inspired by the \Symfony\Component\HttpFoundation\ParameterBag::filter() function and was necessary as we sometimes have parameters that can be either in the GET/PATH/POST arguments and need to be filtered. Silex only offer the possibility to filter parameter from a single ParameterBag, so we created this helper. - * - * @param string $sKey - * @param mixed $default - * @param int $iFilter Default is FILTER_SANITIZE_STRING - * - * @return mixed|null - * - * @since 2.5.1 - */ - public function ReadParam($sKey, $default = null, $iFilter = FILTER_SANITIZE_STRING) - { - if ($this->GetCurrentRequest()->query->has($sKey)) - { - return $this->GetCurrentRequest()->query->filter($sKey, $default, $iFilter); - } + /** + * Returns the $sKey parameter from the request filtered with $iFilter. + * This looks in the GET arguments first, then the PATH and finally the POST data. + * + * Note: It is inspired by the \Symfony\Component\HttpFoundation\ParameterBag::filter() function and was necessary as we sometimes have parameters that can be either in the GET/PATH/POST arguments and need to be filtered. Silex only offer the possibility to filter parameter from a single ParameterBag, so we created this helper. + * + * @param string $sKey + * @param mixed $default + * @param int $iFilter Default is FILTER_SANITIZE_STRING + * + * @return mixed|null + * + * @since 2.5.1 + */ + public function ReadParam($sKey, $default = null, $iFilter = FILTER_SANITIZE_STRING) + { + if ($this->GetCurrentRequest()->query->has($sKey)) + { + return $this->GetCurrentRequest()->query->filter($sKey, $default, $iFilter); + } - if ($this->GetCurrentRequest()->attributes->has($sKey)) - { - return $this->GetCurrentRequest()->attributes->filter($sKey, $default, $iFilter); - } + if ($this->GetCurrentRequest()->attributes->has($sKey)) + { + return $this->GetCurrentRequest()->attributes->filter($sKey, $default, $iFilter); + } - if ($this->GetCurrentRequest()->request->has($sKey)) - { - return $this->GetCurrentRequest()->request->filter($sKey, $default, $iFilter); - } + if ($this->GetCurrentRequest()->request->has($sKey)) + { + return $this->GetCurrentRequest()->request->filter($sKey, $default, $iFilter); + } - return $default; - } + return $default; + } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/ScopeValidatorHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/ScopeValidatorHelper.php index efa81d445..1f4f50a62 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/ScopeValidatorHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/ScopeValidatorHelper.php @@ -28,6 +28,7 @@ use DOMFormatException; use DOMNodeList; use Exception; use MetaModel; +use ModuleDesign; use ProfilesConfig; use UserRights; use utils; @@ -41,23 +42,44 @@ use utils; */ class ScopeValidatorHelper { + /** @var string ENUM_MODE_READ */ const ENUM_MODE_READ = 'r'; + /** @var string ENUM_MODE_WRITE */ const ENUM_MODE_WRITE = 'w'; + /** @var string ENUM_TYPE_ALLOW */ const ENUM_TYPE_ALLOW = 'allow'; + /** @var string ENUM_TYPE_RESTRICT */ const ENUM_TYPE_RESTRICT = 'restrict'; + + /** @var string DEFAULT_GENERATED_CLASS */ const DEFAULT_GENERATED_CLASS = '\\PortalScopesValues'; + /** @var bool DEFAULT_IGNORE_SILOS */ const DEFAULT_IGNORE_SILOS = false; + /** @var string|null $sCachePath */ protected $sCachePath; + /** @var string $sFilename */ protected $sFilename; + /** @var string $sInstancePrefix */ protected $sInstancePrefix; + /** @var string $sGeneratedClass */ protected $sGeneratedClass; + /** @var array $aProfilesMatrix */ protected $aProfilesMatrix; - public function __construct(\ModuleDesign $moduleDesign, $sPortalId, $sPortalCachePath = null) + /** + * ScopeValidatorHelper constructor. + * + * @param \ModuleDesign $moduleDesign + * @param string $sPortalId + * @param string|null $sPortalCachePath + * + * @throws \DOMFormatException + */ + public function __construct(ModuleDesign $moduleDesign, $sPortalId, $sPortalCachePath = null) { - $this->sFilename = "{$sPortalId}.scopes.php"; - $this->sCachePath = $sPortalCachePath; + $this->sFilename = "{$sPortalId}.scopes.php"; + $this->sCachePath = $sPortalCachePath; $this->sInstancePrefix = "{$sPortalId}-"; $this->sGeneratedClass = static::DEFAULT_GENERATED_CLASS; $this->aProfilesMatrix = array(); @@ -65,40 +87,41 @@ class ScopeValidatorHelper $this->Init($moduleDesign->GetNodes('/module_design/classes/class')); } - /** - * Initializes the ScopeValidator by generating and caching the scopes compilation in the $this->sCachePath.$this->sFilename file. - * - * @param DOMNodeList $oNodes - * @throws DOMFormatException - * @throws Exception - */ - public function Init(DOMNodeList $oNodes) - { - // Checking cache path - if ($this->sCachePath === null) - { - $this->sCachePath = utils::GetCachePath(); - } - // Building full pathname for file - $sFilePath = $this->sCachePath . $this->sFilename; + /** + * Initializes the ScopeValidator by generating and caching the scopes compilation in the $this->sCachePath.$this->sFilename file. + * + * @param DOMNodeList $oNodes + * + * @throws DOMFormatException + * @throws Exception + */ + public function Init(DOMNodeList $oNodes) + { + // Checking cache path + if ($this->sCachePath === null) + { + $this->sCachePath = utils::GetCachePath(); + } + // Building full pathname for file + $sFilePath = $this->sCachePath.$this->sFilename; - // Creating file if not existing - // Note : This is a temporary cache system, it should soon evolve to a cache provider (fs, apc, memcache, ...) - if (!file_exists($sFilePath)) - { - $this->InitGenerateAndWriteCache($oNodes, $sFilePath); - } + // Creating file if not existing + // Note : This is a temporary cache system, it should soon evolve to a cache provider (fs, apc, memcache, ...) + if (!file_exists($sFilePath)) + { + $this->InitGenerateAndWriteCache($oNodes, $sFilePath); + } - if (!class_exists($this->sGeneratedClass)) - { - require_once $this->sCachePath . $this->sFilename; - } - } + if (!class_exists($this->sGeneratedClass)) + { + require_once $this->sCachePath.$this->sFilename; + } + } - public static function EnumTypeValues() - { - return array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT); - } + public static function EnumTypeValues() + { + return array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT); + } /** * Returns the path where to cache the compiled scopes file @@ -146,6 +169,7 @@ class ScopeValidatorHelper * This is used to create a unique scope values class in the cache directory (/data/cache-) as there can be several instance of the portal. * * @param string $sInstancePrefix + * * @return \Combodo\iTop\Portal\Helper\ScopeValidatorHelper */ public function SetInstancePrefix($sInstancePrefix) @@ -155,7 +179,7 @@ class ScopeValidatorHelper $sInstancePrefix = str_replace(' ', '', $sInstancePrefix); $this->sInstancePrefix = $sInstancePrefix; - $this->sGeneratedClass = $this->sInstancePrefix . static::DEFAULT_GENERATED_CLASS; + $this->sGeneratedClass = $this->sInstancePrefix.static::DEFAULT_GENERATED_CLASS; return $this; } @@ -163,35 +187,35 @@ class ScopeValidatorHelper /** * Returns the DBSearch for the $sProfile in $iAction for the class $sClass * - * @param string $sProfile - * @param string $sClass + * @param string $sProfile + * @param string $sClass * @param integer $iAction - * + * * @return \DBSearch - * - * @throws \Exception - * @throws \CoreException - * @throws \OQLException + * + * @throws \Exception + * @throws \CoreException + * @throws \OQLException */ public function GetScopeFilterForProfile($sProfile, $sClass, $iAction = null) { return $this->GetScopeFilterForProfiles(array($sProfile), $sClass, $iAction); } - /** - * Returns the DBSearch for the $aProfiles in $iAction for the class $sClass. - * Profiles are a OR condition. - * - * @param array $aProfiles - * @param string $sClass - * @param integer $iAction - * - * @return \DBSearch - * - * @throws \Exception - * @throws \CoreException - * @throws \OQLException - */ + /** + * Returns the DBSearch for the $aProfiles in $iAction for the class $sClass. + * Profiles are a OR condition. + * + * @param array $aProfiles + * @param string $sClass + * @param integer $iAction + * + * @return \DBSearch + * + * @throws \Exception + * @throws \CoreException + * @throws \OQLException + */ public function GetScopeFilterForProfiles($aProfiles, $sClass, $iAction = null) { $oSearch = null; @@ -254,18 +278,18 @@ class ScopeValidatorHelper return $oSearch; } - /** - * Add the scope query (view or edit depending on $sAction) for $sClass to the $oQuery. - * - * @param \DBSearch $oQuery - * @param string $sClass - * @param int $sAction - * - * @return bool true if scope exists, false if scope is null - * - * @throws \CoreException - * @throws \OQLException - */ + /** + * Add the scope query (view or edit depending on $sAction) for $sClass to the $oQuery. + * + * @param \DBSearch $oQuery + * @param string $sClass + * @param int $sAction + * + * @return bool true if scope exists, false if scope is null + * + * @throws \CoreException + * @throws \OQLException + */ public function AddScopeToQuery(DBSearch &$oQuery, $sClass, $sAction = UR_ACTION_READ) { $oScopeQuery = $this->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sClass, $sAction); @@ -284,16 +308,16 @@ class ScopeValidatorHelper return false; } - /** - * Returns true if at least one of the $aProfiles has the ignore_silos flag set to true for the $sClass. - * - * @param array $aProfiles - * @param string $sClass - * - * @return boolean - * - * @throws \Exception - */ + /** + * Returns true if at least one of the $aProfiles has the ignore_silos flag set to true for the $sClass. + * + * @param array $aProfiles + * @param string $sClass + * + * @return boolean + * + * @throws \Exception + */ public function IsAllDataAllowedForScope($aProfiles, $sClass) { $bIgnoreSilos = false; @@ -301,7 +325,7 @@ class ScopeValidatorHelper // Iterating on profiles to retrieving the different OQLs parts foreach ($aProfiles as $sProfile) { - // Retrieving matrix informtions + // Retrieving matrix information $iProfileId = $this->GetProfileIdFromProfileName($sProfile); // Retrieving profile OQLs @@ -324,9 +348,9 @@ class ScopeValidatorHelper * Returns the profile id from a string being either a constant or its name. * * @param string $sProfile - * + * * @return integer - * + * * @throws \Exception */ protected function GetProfileIdFromProfileName($sProfile) @@ -362,7 +386,7 @@ class ScopeValidatorHelper // If profile was not found from its name or from a constant, we throw an exception if ($iProfileId === null) { - throw new Exception('Scope validator : Could not find "' . $sProfile . '" in the profiles list'); + throw new Exception('Scope validator : Could not find "'.$sProfile.'" in the profiles list'); } return $iProfileId; @@ -372,6 +396,7 @@ class ScopeValidatorHelper * Returns a string containing the generated PHP class for the compiled scopes * * @param array $aProfiles + * * @return string */ protected function BuildPHPClass($aProfiles = array()) @@ -415,212 +440,251 @@ EOF; return $sPHP; } - /** - * @param DOMNodeList $oNodes - * @param $sFilePath - * - * @throws DOMFormatException - * @throws \CoreException - * @throws \OQLException - */ - protected function InitGenerateAndWriteCache(DOMNodeList $oNodes, $sFilePath) - { -// - Build php array from xml - $aProfiles = array(); - // This will be used to know which classes have been set, so we can set the missing ones. - $aProfileClasses = array(); - // Iterating over the class nodes - foreach ($oNodes as $oClassNode) { - // retrieving mandatory class id attribute - $sClass = $oClassNode->getAttribute('id'); - if ($sClass === '') { - throw new DOMFormatException('Class tag must have an id attribute.', null, null, $oClassNode); - } + /** + * @param DOMNodeList $oNodes + * @param string $sFilePath + * + * @throws DOMFormatException + * @throws \CoreException + * @throws \OQLException + * @throws \Exception + */ + protected function InitGenerateAndWriteCache(DOMNodeList $oNodes, $sFilePath) + { + // - Build php array from xml + $aProfiles = array(); + // This will be used to know which classes have been set, so we can set the missing ones. + $aProfileClasses = array(); + // Iterating over the class nodes + /** @var \Combodo\iTop\DesignElement $oClassNode */ + foreach ($oNodes as $oClassNode) + { + // retrieving mandatory class id attribute + $sClass = $oClassNode->getAttribute('id'); + if ($sClass === '') + { + throw new DOMFormatException('Class tag must have an id attribute.', null, null, $oClassNode); + } - // Iterating over scope nodes of the class - $oScopesNode = $oClassNode->GetOptionalElement('scopes'); - if ($oScopesNode !== null) { - foreach ($oScopesNode->GetNodes('./scope') as $oScopeNode) { - // Retrieving mandatory scope id attribute - $sScopeId = $oScopeNode->getAttribute('id'); - if ($sScopeId === '') { - throw new DOMFormatException('Scope tag must have an id attribute.', null, null, $oScopeNode); - } + // Iterating over scope nodes of the class + $oScopesNode = $oClassNode->GetOptionalElement('scopes'); + if ($oScopesNode !== null) + { + /** @var \Combodo\iTop\DesignElement $oScopeNode */ + foreach ($oScopesNode->GetNodes('./scope') as $oScopeNode) + { + // Retrieving mandatory scope id attribute + $sScopeId = $oScopeNode->getAttribute('id'); + if ($sScopeId === '') + { + throw new DOMFormatException('Scope tag must have an id attribute.', null, null, $oScopeNode); + } - // Retrieving the type of query - // Note : This has been disabled as we don't want deny rules for now - // $oOqlViewTypeNode = $oClassNode->GetOptionalElement('oql_view_type'); - // $sOqlViewType = ($oOqlViewTypeNode !== null && ($oOqlViewTypeNode->GetText() === static::ENUM_TYPE_RESTRICT)) ? static::ENUM_TYPE_RESTRICT : static::ENUM_TYPE_ALLOW; - $sOqlViewType = static::ENUM_TYPE_ALLOW; - // Retrieving the view query - $oOqlViewNode = $oScopeNode->GetUniqueElement('oql_view'); - $sOqlView = $oOqlViewNode->GetText(); - if ($sOqlView === null) { - throw new DOMFormatException( - 'Scope tag in class must have a not empty oql_view tag', - null, - null, - $oScopeNode - ); - } - // Retrieving the edit query - $oOqlEditNode = $oScopeNode->GetOptionalElement('oql_edit'); - $sOqlEdit = (($oOqlEditNode !== null) && ($oOqlEditNode->GetText( - ) !== null)) ? $oOqlEditNode->GetText() : null; - // Retrieving ignore allowed org flag - $oIgnoreSilosNode = $oScopeNode->GetOptionalElement('ignore_silos'); - $bIgnoreSilos = (($oIgnoreSilosNode !== null) && ($oIgnoreSilosNode->GetText( - ) === 'true')) ? true : static::DEFAULT_IGNORE_SILOS; + // Retrieving the type of query + // Note : This has been disabled as we don't want deny rules for now + // $oOqlViewTypeNode = $oClassNode->GetOptionalElement('oql_view_type'); + // $sOqlViewType = ($oOqlViewTypeNode !== null && ($oOqlViewTypeNode->GetText() === static::ENUM_TYPE_RESTRICT)) ? static::ENUM_TYPE_RESTRICT : static::ENUM_TYPE_ALLOW; + $sOqlViewType = static::ENUM_TYPE_ALLOW; + // Retrieving the view query + $oOqlViewNode = $oScopeNode->GetUniqueElement('oql_view'); + $sOqlView = $oOqlViewNode->GetText(); + if ($sOqlView === null) + { + throw new DOMFormatException( + 'Scope tag in class must have a not empty oql_view tag', + null, + null, + $oScopeNode + ); + } + // Retrieving the edit query + $oOqlEditNode = $oScopeNode->GetOptionalElement('oql_edit'); + $sOqlEdit = (($oOqlEditNode !== null) && ($oOqlEditNode->GetText() !== null)) ? $oOqlEditNode->GetText() : null; + // Retrieving ignore allowed org flag + $oIgnoreSilosNode = $oScopeNode->GetOptionalElement('ignore_silos'); + $bIgnoreSilos = (($oIgnoreSilosNode !== null) && ($oIgnoreSilosNode->GetText() === 'true')) ? true : static::DEFAULT_IGNORE_SILOS; - // Retrieving profiles for the scope - $oProfilesNode = $oScopeNode->GetOptionalElement('allowed_profiles'); - $aProfilesNames = array(); - // If no profile is specified, we consider that it's for ALL the profiles - if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./allowed_profile')->length === 0)) { - foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) { - $aProfilesNames[] = $aValue['name']; - } - } else { - foreach ($oProfilesNode->GetNodes('./allowed_profile') as $oProfileNode) { - // Retrieving mandatory profile id attribute - $sProfileId = $oProfileNode->getAttribute('id'); - if ($sProfileId === '') { - throw new DOMFormatException( - 'Scope tag must have an id attribute.', - null, - null, - $oProfileNode - ); - } - $aProfilesNames[] = $sProfileId; - } - } + // Retrieving profiles for the scope + $oProfilesNode = $oScopeNode->GetOptionalElement('allowed_profiles'); + $aProfilesNames = array(); + // If no profile is specified, we consider that it's for ALL the profiles + if (($oProfilesNode === null) || ($oProfilesNode->GetNodes('./allowed_profile')->length === 0)) + { + foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) + { + $aProfilesNames[] = $aValue['name']; + } + } + else + { + /** @var \Combodo\iTop\DesignElement $oProfileNode */ + foreach ($oProfilesNode->GetNodes('./allowed_profile') as $oProfileNode) + { + // Retrieving mandatory profile id attribute + $sProfileId = $oProfileNode->getAttribute('id'); + if ($sProfileId === '') + { + throw new DOMFormatException( + 'Scope tag must have an id attribute.', + null, + null, + $oProfileNode + ); + } + $aProfilesNames[] = $sProfileId; + } + } - // - foreach ($aProfilesNames as $sProfileName) { - // Scope profile id - $iProfileId = $this->GetProfileIdFromProfileName($sProfileName); + // + foreach ($aProfilesNames as $sProfileName) + { + // Scope profile id + $iProfileId = $this->GetProfileIdFromProfileName($sProfileName); - // Now that we have the queries infos, we are going to build the queries for that profile / class - $sMatrixPrefix = $iProfileId.'_'.$sClass.'_'; - // - View query - $oViewFilter = DBSearch::FromOQL($sOqlView); - // ... We have to union the query if this profile has another scope for that class - if (array_key_exists($sMatrixPrefix.static::ENUM_MODE_READ, $aProfiles) && array_key_exists( - $sOqlViewType, - $aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ] - )) { - $oExistingFilter = DBSearch::FromOQL( - $aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ][$sOqlViewType] - ); - $aFilters = array($oExistingFilter, $oViewFilter); - $oResFilter = new DBUnionSearch($aFilters); + // Now that we have the queries infos, we are going to build the queries for that profile / class + $sMatrixPrefix = $iProfileId.'_'.$sClass.'_'; + // - View query + $oViewFilter = DBSearch::FromOQL($sOqlView); + // ... We have to union the query if this profile has another scope for that class + if (array_key_exists($sMatrixPrefix.static::ENUM_MODE_READ, $aProfiles) && array_key_exists( + $sOqlViewType, + $aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ] + )) + { + $oExistingFilter = DBSearch::FromOQL( + $aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ][$sOqlViewType] + ); + $aFilters = array($oExistingFilter, $oViewFilter); + $oResFilter = new DBUnionSearch($aFilters); - // Applying ignore_silos flag on result filter if necessary (As the union will remove it if it is not on all sub-queries) - if ($aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ]['ignore_silos'] === true) { - $bIgnoreSilos = true; - } - } else { - $oResFilter = $oViewFilter; - } - $aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ] = array( - $sOqlViewType => $oResFilter->ToOQL(), - 'ignore_silos' => $bIgnoreSilos - ); - // - Edit query - if ($sOqlEdit !== null) { - $oEditFilter = DBSearch::FromOQL($sOqlEdit); - // - If the queries are the same, we don't make an intersect, we just reuse the view query - if ($sOqlEdit === $sOqlView) { - // Do not intersect, edit query is identical to view query - } else { - if (($oEditFilter->GetClass() === $oViewFilter->GetClass()) && $oEditFilter->IsAny()) { - $oEditFilter = $oViewFilter; - // Do not intersect, edit query is identical to view query - } else { - // Intersect - $oEditFilter = $oViewFilter->Intersect($oEditFilter); - } - } + // Applying ignore_silos flag on result filter if necessary (As the union will remove it if it is not on all sub-queries) + if ($aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ]['ignore_silos'] === true) + { + $bIgnoreSilos = true; + } + } + else + { + $oResFilter = $oViewFilter; + } + $aProfiles[$sMatrixPrefix.static::ENUM_MODE_READ] = array( + $sOqlViewType => $oResFilter->ToOQL(), + 'ignore_silos' => $bIgnoreSilos, + ); + // - Edit query + if ($sOqlEdit !== null) + { + $oEditFilter = DBSearch::FromOQL($sOqlEdit); + // - If the queries are the same, we don't make an intersect, we just reuse the view query + if ($sOqlEdit === $sOqlView) + { + // Do not intersect, edit query is identical to view query + } + else + { + if (($oEditFilter->GetClass() === $oViewFilter->GetClass()) && $oEditFilter->IsAny()) + { + $oEditFilter = $oViewFilter; + // Do not intersect, edit query is identical to view query + } + else + { + // Intersect + $oEditFilter = $oViewFilter->Intersect($oEditFilter); + } + } - // ... We have to union the query if this profile has another scope for that class - if (array_key_exists( - $sMatrixPrefix.static::ENUM_MODE_WRITE, - $aProfiles - ) && array_key_exists( - $sOqlViewType, - $aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE] - )) { - $oExistingFilter = DBSearch::FromOQL( - $aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE][$sOqlViewType] - ); - $aFilters = array($oExistingFilter, $oEditFilter); - $oResFilter = new DBUnionSearch($aFilters); - } else { - $oResFilter = $oEditFilter; - } - $aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE] = array( - $sOqlViewType => $oResFilter->ToOQL(), - 'ignore_silos' => $bIgnoreSilos - ); - } - } - } + // ... We have to union the query if this profile has another scope for that class + if (array_key_exists( + $sMatrixPrefix.static::ENUM_MODE_WRITE, + $aProfiles + ) && array_key_exists( + $sOqlViewType, + $aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE] + )) + { + $oExistingFilter = DBSearch::FromOQL( + $aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE][$sOqlViewType] + ); + $aFilters = array($oExistingFilter, $oEditFilter); + $oResFilter = new DBUnionSearch($aFilters); + } + else + { + $oResFilter = $oEditFilter; + } + $aProfiles[$sMatrixPrefix.static::ENUM_MODE_WRITE] = array( + $sOqlViewType => $oResFilter->ToOQL(), + 'ignore_silos' => $bIgnoreSilos, + ); + } + } + } - $aProfileClasses[] = $sClass; - } - } + $aProfileClasses[] = $sClass; + } + } - // Filling the array with missing classes from MetaModel, so we can have an inheritance principle on the scope - // For each class explicitly given in the scopes, we check if its child classes were also in the scope : - // If not, we add them with the same OQL - foreach ($aProfileClasses as $sProfileClass) { - foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass) { - // If the child class is not in the scope, we are going to try to add it - if (!in_array($sChildClass, $aProfileClasses)) { - foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) { - $iProfileId = $iKey; - foreach (array(static::ENUM_MODE_READ, static::ENUM_MODE_WRITE) as $sAction) { - // If the current profile has scope for that class in that mode, we duplicate it - if (isset($aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction])) { - $aTmpProfile = $aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction]; - foreach ($aTmpProfile as $sType => $sOql) { - // IF condition is just to skip the 'ignore_silos' flag - if (in_array($sType, array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT))) { - $oTmpFilter = DBSearch::FromOQL($sOql); - $oTmpFilter->ChangeClass($sChildClass); + // Filling the array with missing classes from MetaModel, so we can have an inheritance principle on the scope + // For each class explicitly given in the scopes, we check if its child classes were also in the scope : + // If not, we add them with the same OQL + foreach ($aProfileClasses as $sProfileClass) + { + foreach (MetaModel::EnumChildClasses($sProfileClass) as $sChildClass) + { + // If the child class is not in the scope, we are going to try to add it + if (!in_array($sChildClass, $aProfileClasses)) + { + foreach (ProfilesConfig::GetProfilesValues() as $iKey => $aValue) + { + $iProfileId = $iKey; + foreach (array(static::ENUM_MODE_READ, static::ENUM_MODE_WRITE) as $sAction) + { + // If the current profile has scope for that class in that mode, we duplicate it + if (isset($aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction])) + { + $aTmpProfile = $aProfiles[$iProfileId.'_'.$sProfileClass.'_'.$sAction]; + foreach ($aTmpProfile as $sType => $sOql) + { + // IF condition is just to skip the 'ignore_silos' flag + if (in_array($sType, array(static::ENUM_TYPE_ALLOW, static::ENUM_TYPE_RESTRICT))) + { + $oTmpFilter = DBSearch::FromOQL($sOql); + $oTmpFilter->ChangeClass($sChildClass); - $aTmpProfile[$sType] = $oTmpFilter->ToOQL(); - } - } + $aTmpProfile[$sType] = $oTmpFilter->ToOQL(); + } + } - $aProfiles[$iProfileId.'_'.$sChildClass.'_'.$sAction] = $aTmpProfile; - } - } - } - } - } - } + $aProfiles[$iProfileId.'_'.$sChildClass.'_'.$sAction] = $aTmpProfile; + } + } + } + } + } + } - // - Build php class - $sPHP = $this->BuildPHPClass($aProfiles); + // - Build php class + $sPHP = $this->BuildPHPClass($aProfiles); - // - Write file on disk - // - Creating dir if necessary - if (!is_dir($this->sCachePath)) { - mkdir($this->sCachePath, 0777, true); - } - // -- Then creating the file - $ret = file_put_contents($sFilePath, $sPHP); - if ($ret === false) { - $iLen = strlen($sPHP); - $fFree = @disk_free_space(dirname($sFilePath)); - $aErr = error_get_last(); - throw new Exception( - "Failed to write '$sFilePath'. Last error: '{$aErr['message']}', content to write: $iLen bytes, available free space on disk: $fFree." - ); - } - } + // - Write file on disk + // - Creating dir if necessary + if (!is_dir($this->sCachePath)) + { + mkdir($this->sCachePath, 0777, true); + } + // -- Then creating the file + $ret = file_put_contents($sFilePath, $sPHP); + if ($ret === false) + { + $iLen = strlen($sPHP); + $fFree = @disk_free_space(dirname($sFilePath)); + $aErr = error_get_last(); + throw new Exception( + "Failed to write '$sFilePath'. Last error: '{$aErr['message']}', content to write: $iLen bytes, available free space on disk: $fFree." + ); + } + } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Helper/SecurityHelper.php b/datamodels/2.x/itop-portal-base/portal/src/Helper/SecurityHelper.php index b67ad46eb..aaee38856 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Helper/SecurityHelper.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Helper/SecurityHelper.php @@ -19,7 +19,6 @@ namespace Combodo\iTop\Portal\Helper; -use Silex\Application; use UserRights; use IssueLog; use MetaModel; @@ -35,22 +34,21 @@ use BinaryExpression; * * Handle security checks through the different layers (portal scopes, iTop silos, user rights) * - * @author Guillaume Lajarige + * @package Combodo\iTop\Portal\Helper + * @since 2.3.0 + * @author Guillaume Lajarige */ class SecurityHelper { - public static $aAllowedScopeObjectsCache = array( - UR_ACTION_READ => array(), - UR_ACTION_MODIFY => array(), - ); + /** @var array $aAllowedScopeObjectsCache */ + public static $aAllowedScopeObjectsCache = array( + UR_ACTION_READ => array(), + UR_ACTION_MODIFY => array(), + ); - /** - * @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper - */ + /** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator */ private $oScopeValidator; - /** - * @var \Combodo\iTop\Portal\Helper\LifecycleValidatorHelper - */ + /** @var \Combodo\iTop\Portal\Helper\LifecycleValidatorHelper $oLifecycleValidator */ private $oLifecycleValidator; /** @var bool $bDebug */ private $bDebug; @@ -71,32 +69,36 @@ class SecurityHelper /** - * Returns true if the current user is allowed to do the $sAction on an $sObjectClass object (with optionnal $sObjectId id) - * Checks are: - * - Has a scope query for the $sObjectClass / $sAction - * - Optionally, if $sObjectId provided: Is object within scope for $sObjectClass / $sObjectId / $sAction - * - Is allowed by datamodel for $sObjectClass / $sAction - * - * @param \Silex\Application $oApp - * @param string $sAction Must be in UR_ACTION_READ|UR_ACTION_MODIFY|UR_ACTION_CREATE - * @param string $sObjectClass - * @param string $sObjectId - * - * @return boolean - * - * @throws \CoreException - */ + * Returns true if the current user is allowed to do the $sAction on an $sObjectClass object (with optionnal $sObjectId id) + * Checks are: + * - Has a scope query for the $sObjectClass / $sAction + * - Optionally, if $sObjectId provided: Is object within scope for $sObjectClass / $sObjectId / $sAction + * - Is allowed by datamodel for $sObjectClass / $sAction + * + * @param string $sAction Must be in UR_ACTION_READ|UR_ACTION_MODIFY|UR_ACTION_CREATE + * @param string $sObjectClass + * @param string $sObjectId + * + * @return boolean + * + * @throws \CoreException + * @throws \MissingQueryArgument + * @throws \MySQLException + * @throws \MySQLHasGoneAwayException + * @throws \OQLException + */ public function IsActionAllowed($sAction, $sObjectClass, $sObjectId = null) { - $sDebugTracePrefix = __CLASS__ . ' / ' . __METHOD__ . ' : Returned false for action ' . $sAction . ' on ' . $sObjectClass . '::' . $sObjectId; + $sDebugTracePrefix = __CLASS__.' / '.__METHOD__.' : Returned false for action '.$sAction.' on '.$sObjectClass.'::'.$sObjectId; // Checking action type if (!in_array($sAction, array(UR_ACTION_READ, UR_ACTION_MODIFY, UR_ACTION_CREATE))) { if ($this->bDebug) { - IssueLog::Info($sDebugTracePrefix . ' as the action value could not be understood (' . UR_ACTION_READ . '/' . UR_ACTION_MODIFY . '/' . UR_ACTION_CREATE . ' expected'); + IssueLog::Info($sDebugTracePrefix.' as the action value could not be understood ('.UR_ACTION_READ.'/'.UR_ACTION_MODIFY.'/'.UR_ACTION_CREATE.' expected'); } + return false; } @@ -109,8 +111,9 @@ class SecurityHelper { if ($this->bDebug) { - IssueLog::Info($sDebugTracePrefix . ' as there was no scope defined for action ' . $sScopeAction . ' and profiles ' . implode('/', UserRights::ListProfiles())); + IssueLog::Info($sDebugTracePrefix.' as there was no scope defined for action '.$sScopeAction.' and profiles '.implode('/', UserRights::ListProfiles())); } + return false; } // - If action != create we do some additionnal checks @@ -119,49 +122,51 @@ class SecurityHelper // - Checking specific object if id is specified if ($sObjectId !== null) { - // Checking if object status is in cache (to avoid unnecessary query) - if(isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId]) ) - { - if(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] === false) - { - if ($this->bDebug) - { - IssueLog::Info($sDebugTracePrefix . ' as it was denied in the scope objects cache'); - } - return false; - } - } - else - { - // Modifying query to filter on the ID - // - Adding expression - $sObjectKeyAtt = MetaModel::DBGetKey($sObjectClass); - $oFieldExp = new FieldExpression($sObjectKeyAtt, $oScopeQuery->GetClassAlias()); - $oBinExp = new BinaryExpression($oFieldExp, '=', new VariableExpression('object_id')); - $oScopeQuery->AddConditionExpression($oBinExp); - // - Setting value - $aQueryParams = $oScopeQuery->GetInternalParams(); - $aQueryParams['object_id'] = $sObjectId; - $oScopeQuery->SetInternalParams($aQueryParams); - unset($aQueryParams); + // Checking if object status is in cache (to avoid unnecessary query) + if (isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId])) + { + if (static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] === false) + { + if ($this->bDebug) + { + IssueLog::Info($sDebugTracePrefix.' as it was denied in the scope objects cache'); + } - // - Checking if query result is null (which means that the user has no right to view this specific object) - $oSet = new DBObjectSet($oScopeQuery); - if ($oSet->Count() === 0) - { - // Updating cache - static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] = false; + return false; + } + } + else + { + // Modifying query to filter on the ID + // - Adding expression + $sObjectKeyAtt = MetaModel::DBGetKey($sObjectClass); + $oFieldExp = new FieldExpression($sObjectKeyAtt, $oScopeQuery->GetClassAlias()); + $oBinExp = new BinaryExpression($oFieldExp, '=', new VariableExpression('object_id')); + $oScopeQuery->AddConditionExpression($oBinExp); + // - Setting value + $aQueryParams = $oScopeQuery->GetInternalParams(); + $aQueryParams['object_id'] = $sObjectId; + $oScopeQuery->SetInternalParams($aQueryParams); + unset($aQueryParams); - if ($this->bDebug) - { - IssueLog::Info($sDebugTracePrefix . ' as there was no result for the following scope query : ' . $oScopeQuery->ToOQL(true)); - } - return false; - } + // - Checking if query result is null (which means that the user has no right to view this specific object) + $oSet = new DBObjectSet($oScopeQuery); + if ($oSet->Count() === 0) + { + // Updating cache + static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] = false; - // Updating cache - static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] = true; - } + if ($this->bDebug) + { + IssueLog::Info($sDebugTracePrefix.' as there was no result for the following scope query : '.$oScopeQuery->ToOQL(true)); + } + + return false; + } + + // Updating cache + static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass][$sObjectId] = true; + } } } @@ -172,32 +177,41 @@ class SecurityHelper //throw new SecurityException('User not allowed to view this object', array('class' => $sObjectClass, 'id' => $sObjectId)); if ($this->bDebug) { - IssueLog::Info($sDebugTracePrefix . ' as the user is not allowed to access this object according to the datamodel security (cf. Console settings)'); + IssueLog::Info($sDebugTracePrefix.' as the user is not allowed to access this object according to the datamodel security (cf. Console settings)'); } + return false; } return true; } + /** + * @param string $sStimulusCode + * @param string $sObjectClass + * @param \DBObjectSet|null $oInstanceSet + * + * @return bool + * @throws \Exception + */ public function IsStimulusAllowed($sStimulusCode, $sObjectClass, $oInstanceSet = null) { - // Checking DataModel layer - $aStimuliFromDatamodel = Metamodel::EnumStimuli($sObjectClass); + // Checking DataModel layer + $aStimuliFromDatamodel = Metamodel::EnumStimuli($sObjectClass); $iActionAllowed = (get_class($aStimuliFromDatamodel[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sObjectClass, $sStimulusCode, $oInstanceSet) : UR_ALLOWED_NO; - if( ($iActionAllowed === false) || ($iActionAllowed === UR_ALLOWED_NO) ) - { - return false; - } + if (($iActionAllowed === false) || ($iActionAllowed === UR_ALLOWED_NO)) + { + return false; + } - // Checking portal security layer - $aStimuliFromPortal = $this->oLifecycleValidator->GetStimuliForProfiles(UserRights::ListProfiles(), $sObjectClass); - if(!in_array($sStimulusCode, $aStimuliFromPortal)) - { - return false; - } + // Checking portal security layer + $aStimuliFromPortal = $this->oLifecycleValidator->GetStimuliForProfiles(UserRights::ListProfiles(), $sObjectClass); + if (!in_array($sStimulusCode, $aStimuliFromPortal)) + { + return false; + } - return true; + return true; } /** @@ -210,99 +224,101 @@ class SecurityHelper * @throws \CoreUnexpectedValue * @throws \MySQLException * @throws \OQLException + * @throws \Exception */ public function PreloadForCache(DBSearch $oSearch, $aExtKeysToPreload = null) - { - $sObjectClass = $oSearch->GetClass(); - $aObjectIds = array(); - $aExtKeysIds = array(); - $aColumnsToLoad = array(); + { + $sObjectClass = $oSearch->GetClass(); + $aObjectIds = array(); + $aExtKeysIds = array(); + $aColumnsToLoad = array(); - if($aExtKeysToPreload !== null) - { - foreach($aExtKeysToPreload as $sAttCode) - { - /** @var \AttributeDefinition $oAttDef */ - $oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode); - if($oAttDef->IsExternalKey()) - { - $aExtKeysIds[$oAttDef->GetTargetClass()] = array(); - $aColumnsToLoad[] = $sAttCode; - } - } - } + if ($aExtKeysToPreload !== null) + { + foreach ($aExtKeysToPreload as $sAttCode) + { + /** @var \AttributeDefinition $oAttDef */ + $oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode); + if ($oAttDef->IsExternalKey()) + { + /** @var \AttributeExternalKey $oAttDef */ + $aExtKeysIds[$oAttDef->GetTargetClass()] = array(); + $aColumnsToLoad[] = $sAttCode; + } + } + } - // Retrieving IDs of all objects - // Note: We have to clone $oSet otherwise the source object will be modified - $oSet = new DBObjectSet($oSearch); - $oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => $aColumnsToLoad)); - while($oCurrentRow = $oSet->Fetch()) - { - // Note: By presetting value to false, it is quicker to find which objects where not returned by the scope query later - $aObjectIds[$oCurrentRow->GetKey()] = false; + // Retrieving IDs of all objects + // Note: We have to clone $oSet otherwise the source object will be modified + $oSet = new DBObjectSet($oSearch); + $oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => $aColumnsToLoad)); + while ($oCurrentRow = $oSet->Fetch()) + { + // Note: By presetting value to false, it is quicker to find which objects where not returned by the scope query later + $aObjectIds[$oCurrentRow->GetKey()] = false; - // Preparing ExtKeys to preload - foreach($aColumnsToLoad as $sAttCode) - { - $iExtKey = $oCurrentRow->Get($sAttCode); - if($iExtKey > 0) - { - /** @var \AttributeExternalKey $oAttDef */ - $oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode); - if(!in_array($iExtKey, $aExtKeysIds[$oAttDef->GetTargetClass()])) - { - $aExtKeysIds[$oAttDef->GetTargetClass()][] = $iExtKey; - } - } - } - } + // Preparing ExtKeys to preload + foreach ($aColumnsToLoad as $sAttCode) + { + $iExtKey = $oCurrentRow->Get($sAttCode); + if ($iExtKey > 0) + { + /** @var \AttributeExternalKey $oAttDef */ + $oAttDef = MetaModel::GetAttributeDef($sObjectClass, $sAttCode); + if (!in_array($iExtKey, $aExtKeysIds[$oAttDef->GetTargetClass()])) + { + $aExtKeysIds[$oAttDef->GetTargetClass()][] = $iExtKey; + } + } + } + } - foreach(array(UR_ACTION_READ, UR_ACTION_MODIFY) as $sScopeAction) - { - // Retrieving scope query - /** @var DBSearch $oScopeQuery */ - $oScopeQuery = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sObjectClass, $sScopeAction); - if($oScopeQuery !== null) - { - // Restricting scope if specified - if(!empty($aObjectIds)) - { - $oScopeQuery->AddCondition('id', array_keys($aObjectIds), 'IN'); - } + foreach (array(UR_ACTION_READ, UR_ACTION_MODIFY) as $sScopeAction) + { + // Retrieving scope query + /** @var DBSearch $oScopeQuery */ + $oScopeQuery = $this->oScopeValidator->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sObjectClass, $sScopeAction); + if ($oScopeQuery !== null) + { + // Restricting scope if specified + if (!empty($aObjectIds)) + { + $oScopeQuery->AddCondition('id', array_keys($aObjectIds), 'IN'); + } - // Preparing object set - $oScopeSet = new DBObjectSet($oScopeQuery); - $oScopeSet->OptimizeColumnLoad(array()); + // Preparing object set + $oScopeSet = new DBObjectSet($oScopeQuery); + $oScopeSet->OptimizeColumnLoad(array()); - // Checking objects status - $aScopeObjectIds = $aObjectIds; - while($oCurrentRow = $oScopeSet->Fetch()) - { - $aScopeObjectIds[$oCurrentRow->GetKey()] = true; - } + // Checking objects status + $aScopeObjectIds = $aObjectIds; + while ($oCurrentRow = $oScopeSet->Fetch()) + { + $aScopeObjectIds[$oCurrentRow->GetKey()] = true; + } - // Updating cache - if(!isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass])) - { - static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass] = $aScopeObjectIds; - } - else - { - static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass] = array_merge_recursive(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass], $aScopeObjectIds); - } - } - } + // Updating cache + if (!isset(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass])) + { + static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass] = $aScopeObjectIds; + } + else + { + static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass] = array_merge_recursive(static::$aAllowedScopeObjectsCache[$sScopeAction][$sObjectClass], $aScopeObjectIds); + } + } + } - // Preloading ExtKeys - foreach($aExtKeysIds as $sTargetClass => $aTargetIds) - { - if(!empty($aTargetIds)) - { - $oTargetSearch = new DBObjectSearch($sTargetClass); - $oTargetSearch->AddCondition('id', $aTargetIds, 'IN'); + // Preloading ExtKeys + foreach ($aExtKeysIds as $sTargetClass => $aTargetIds) + { + if (!empty($aTargetIds)) + { + $oTargetSearch = new DBObjectSearch($sTargetClass); + $oTargetSearch->AddCondition('id', $aTargetIds, 'IN'); - static::PreloadForCache($oTargetSearch); - } - } - } + static::PreloadForCache($oTargetSearch); + } + } + } } 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 d2af3f303..6711f00b7 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Kernel.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Kernel.php @@ -1,4 +1,23 @@ environment; return utils::GetCachePath() . "/portals/$cacheDir"; } - public function getLogDir() + /** + * @return string + */ + public function getLogDir() { $logDir = $_ENV['PORTAL_ID'] . '-' . $this->environment; return utils::GetLogPath() . "/portals/$logDir"; } - public function registerBundles() + /** + * @return \Generator|iterable|\Symfony\Component\HttpKernel\Bundle\BundleInterface[] + */ + public function registerBundles() { $contents = require $this->getProjectDir().'/config/bundles.php'; foreach ($contents as $class => $envs) { @@ -40,7 +75,13 @@ class Kernel extends BaseKernel } } - protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader) + /** + * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container + * @param \Symfony\Component\Config\Loader\LoaderInterface $loader + * + * @throws \Exception + */ + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader) { $container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php')); // Feel free to remove the "container.autowiring.strict_mode" parameter @@ -55,7 +96,12 @@ class Kernel extends BaseKernel $loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob'); } - protected function configureRoutes(RouteCollectionBuilder $routes) + /** + * @param \Symfony\Component\Routing\RouteCollectionBuilder $routes + * + * @throws \Symfony\Component\Config\Exception\FileLoaderLoadException + */ + protected function configureRoutes(RouteCollectionBuilder $routes) { $confDir = $this->getProjectDir().'/config'; @@ -63,4 +109,20 @@ class Kernel extends BaseKernel $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob'); $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob'); } + + /** + * Checks if a given class name belongs to an active bundle. + * + * @param string $class A class name + * + * @return void true if the class belongs to an active bundle, false otherwise + * + * @api + * + * @deprecated Deprecated since version 2.6, to be removed in 3.0. + */ + public function isClassInActiveBundle($class) + { + // TODO: Implement isClassInActiveBundle() method. + } } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Routing/ItopExtensionsExtraRoutes.php b/datamodels/2.x/itop-portal-base/portal/src/Routing/ItopExtensionsExtraRoutes.php index 3af039521..b803fe226 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Routing/ItopExtensionsExtraRoutes.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Routing/ItopExtensionsExtraRoutes.php @@ -19,12 +19,6 @@ * */ -/** - * Created by Bruno DA SILVA, working for Combodo - * Date: 31/01/19 - * Time: 16:44 - */ - namespace Combodo\iTop\Portal\Routing; @@ -34,38 +28,45 @@ use Exception; * Class ItopExtensionsExtraRoutes * * @deprecated Compatibility layer for migrating brick's routes to iTop 2.7+ - * @package Combodo\iTop\Portal\Routing + * @package Combodo\iTop\Portal\Routing + * @since 2.7.0 + * @author Bruno Da Silva */ class ItopExtensionsExtraRoutes { - static private $routes = array(); + /** @var array $aRoutes */ + static private $aRoutes = array(); - /** - * @deprecated Since 2.7.0 - * - * @param array $extraRoutes - * - * @throws Exception - */ - public static function addRoutes($extraRoutes) - { - @trigger_error( - sprintf( - 'Usage of legacy route "%s" is deprecated. You should declare routes in YAML format.', - __FILE__ - ), - E_USER_DEPRECATED - ); + /** + * @param array $extraRoutes + * + * @throws Exception + * @deprecated Since 2.7.0 + * + */ + public static function AddRoutes($extraRoutes) + { + @trigger_error( + sprintf( + 'Usage of legacy route "%s" is deprecated. You should declare routes in YAML format.', + __FILE__ + ), + E_USER_DEPRECATED + ); - if (!is_array($extraRoutes)) { - throw new Exception('Only array are allowed as parameter to '.__METHOD__); - } + if (!is_array($extraRoutes)) + { + throw new Exception('Only array are allowed as parameter to '.__METHOD__); + } - self::$routes = array_merge(self::$routes, $extraRoutes); - } + self::$aRoutes = array_merge(self::$aRoutes, $extraRoutes); + } - public static function getRoutes() - { - return self::$routes; - } + /** + * @return array + */ + public static function GetRoutes() + { + return self::$aRoutes; + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/Routing/UrlGenerator.php b/datamodels/2.x/itop-portal-base/portal/src/Routing/UrlGenerator.php index 1bec35db5..7a8940a2e 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Routing/UrlGenerator.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Routing/UrlGenerator.php @@ -28,13 +28,16 @@ use Symfony\Component\Routing\Generator\UrlGenerator as BaseUrlGenerator; * Class UrlGenerator * * @package Combodo\iTop\Portal\Routing - * @since 2.7.0 + * @since 2.7.0 + * @author Bruno Da Silva + * @author Guillaume Lajarige */ class UrlGenerator extends BaseUrlGenerator { + /** @noinspection PhpTooManyParametersInspection */ /** * Overloading of the parent function to add the $_REQUEST parameters to the url parameters. - * This is used to keep additionnal parameters in the url, especially when portal is accessed from the /pages/exec.php + * This is used to keep additional parameters in the url, especially when portal is accessed from the /pages/exec.php * * Note: As of now, it only adds the exec_module/exec_page/portal_id/env_switch/debug parameters. Any other parameter will be ignored. * @@ -66,22 +69,26 @@ class UrlGenerator extends BaseUrlGenerator { $sExecModule = utils::ReadParam('exec_module', '', false, 'string'); $sExecPage = utils::ReadParam('exec_page', '', false, 'string'); - if ($sExecModule !== '' && $sExecPage !== '') { + if ($sExecModule !== '' && $sExecPage !== '') + { $aParameters['exec_module'] = $sExecModule; $aParameters['exec_page'] = $sExecPage; } // Optional parameters $sPortalId = utils::ReadParam('portal_id', '', false, 'string'); - if ($sPortalId !== '') { + if ($sPortalId !== '') + { $aParameters['portal_id'] = $sPortalId; } $sEnvSwitch = utils::ReadParam('env_switch', '', false, 'string'); - if ($sEnvSwitch !== '') { + if ($sEnvSwitch !== '') + { $aParameters['env_switch'] = $sEnvSwitch; } $sDebug = utils::ReadParam('debug', '', false, 'string'); - if ($sDebug !== '') { + if ($sDebug !== '') + { $aParameters['debug'] = $sDebug; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php index 8d0bae745..61d9b03c1 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Twig/AppExtension.php @@ -1,9 +1,24 @@ + */ class AppExtension extends AbstractExtension { - public function getFilters() - { - $filters = array(); - // Filter to translate a string via the Dict::S function - // Usage in twig: {{ 'String:ToTranslate'|dict_s }} - $filters[] = new Twig_SimpleFilter('dict_s', - function ($sStringCode, $sDefault = null, $bUserLanguageOnly = false) { - return Dict::S($sStringCode, $sDefault, $bUserLanguageOnly); - } - ); + /** + * @return array|\Twig\TwigFilter[]|\Twig_SimpleFilter[] + */ + public function getFilters() + { + $filters = array(); + // Filter to translate a string via the Dict::S function + // Usage in twig: {{ 'String:ToTranslate'|dict_s }} + $filters[] = new Twig_SimpleFilter('dict_s', + function ($sStringCode, $sDefault = null, $bUserLanguageOnly = false) { + return Dict::S($sStringCode, $sDefault, $bUserLanguageOnly); + } + ); - // Filter to format a string via the Dict::Format function - // Usage in twig: {{ 'String:ToTranslate'|dict_format() }} - $filters[] = new Twig_SimpleFilter('dict_format', - function ($sStringCode, $sParam01 = null, $sParam02 = null, $sParam03 = null, $sParam04 = null) { - return Dict::Format($sStringCode, $sParam01, $sParam02, $sParam03, $sParam04); - } - ); + // Filter to format a string via the Dict::Format function + // Usage in twig: {{ 'String:ToTranslate'|dict_format() }} + $filters[] = new Twig_SimpleFilter('dict_format', + function ($sStringCode, $sParam01 = null, $sParam02 = null, $sParam03 = null, $sParam04 = null) { + return Dict::Format($sStringCode, $sParam01, $sParam02, $sParam03, $sParam04); + } + ); - // Filter to enable base64 encode/decode - // Usage in twig: {{ 'String to encode'|base64_encode }} - $filters[] = new Twig_SimpleFilter('base64_encode', 'base64_encode'); - $filters[] = new Twig_SimpleFilter('base64_decode', 'base64_decode'); + // Filter to enable base64 encode/decode + // Usage in twig: {{ 'String to encode'|base64_encode }} + $filters[] = new Twig_SimpleFilter('base64_encode', 'base64_encode'); + $filters[] = new Twig_SimpleFilter('base64_decode', 'base64_decode'); - // Filter to enable json decode (encode already exists) - // Usage in twig: {{ aSomeArray|json_decode }} - $filters[] = new Twig_SimpleFilter('json_decode', function ($sJsonString, $bAssoc = false) { - return json_decode($sJsonString, $bAssoc); - } - ); + // Filter to enable json decode (encode already exists) + // Usage in twig: {{ aSomeArray|json_decode }} + $filters[] = new Twig_SimpleFilter('json_decode', function ($sJsonString, $bAssoc = false) { + return json_decode($sJsonString, $bAssoc); + } + ); - // Filter to add itopversion to an url - $filters[] = new Twig_SimpleFilter('add_itop_version', function ($sUrl) { - if (strpos($sUrl, '?') === false) - { - $sUrl = $sUrl."?itopversion=".ITOP_VERSION; - } - else - { - $sUrl = $sUrl."&itopversion=".ITOP_VERSION; - } + // Filter to add itopversion to an url + $filters[] = new Twig_SimpleFilter('add_itop_version', function ($sUrl) { + if (strpos($sUrl, '?') === false) + { + $sUrl = $sUrl."?itopversion=".ITOP_VERSION; + } + else + { + $sUrl = $sUrl."&itopversion=".ITOP_VERSION; + } - return $sUrl; - }); + return $sUrl; + }); - // Filter to add a module's version to an url - $filters[] = new Twig_SimpleFilter('add_module_version', function ($sUrl, $sModuleName) { - $sModuleVersion = utils::GetCompiledModuleVersion($sModuleName); + // Filter to add a module's version to an url + $filters[] = new Twig_SimpleFilter('add_module_version', function ($sUrl, $sModuleName) { + $sModuleVersion = utils::GetCompiledModuleVersion($sModuleName); - if (strpos($sUrl, '?') === false) - { - $sUrl = $sUrl."?moduleversion=".$sModuleVersion; - } - else - { - $sUrl = $sUrl."&moduleversion=".$sModuleVersion; - } + if (strpos($sUrl, '?') === false) + { + $sUrl = $sUrl."?moduleversion=".$sModuleVersion; + } + else + { + $sUrl = $sUrl."&moduleversion=".$sModuleVersion; + } - return $sUrl; - }); + return $sUrl; + }); - return $filters; - } + return $filters; + } - public function getFunctions() - { - $functions = array(); + /** + * @return array|\Twig\TwigFunction[]|\Twig_SimpleFunction[] + */ + public function getFunctions() + { + $functions = array(); - // Function to check our current environment - // Usage in twig: {% if is_development_environment() %} - $functions[] = new Twig_SimpleFunction('is_development_environment', function() - { - return utils::IsDevelopmentEnvironment(); - }); + // Function to check our current environment + // Usage in twig: {% if is_development_environment() %} + $functions[] = new Twig_SimpleFunction('is_development_environment', function () { + return utils::IsDevelopmentEnvironment(); + }); - // Function to get configuration parameter - // Usage in twig: {{ get_config_parameter('foo') }} - $functions[] = new Twig_SimpleFunction('get_config_parameter', function($sParamName) - { - $oConfig = MetaModel::GetConfig(); - return $oConfig->Get($sParamName); - }); + // Function to get configuration parameter + // Usage in twig: {{ get_config_parameter('foo') }} + $functions[] = new Twig_SimpleFunction('get_config_parameter', function ($sParamName) { + $oConfig = MetaModel::GetConfig(); - return $functions; - } + return $oConfig->Get($sParamName); + }); + + return $functions; + } } \ No newline at end of file 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 index 90028fedd..2a47b86e8 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/UrlMaker/AbstractPortalUrlMaker.php +++ b/datamodels/2.x/itop-portal-base/portal/src/UrlMaker/AbstractPortalUrlMaker.php @@ -31,42 +31,42 @@ use utils; /** * AbstractPortalUrlMaker - * + * * @author Guillaume Lajarige * @author Bruno Da Silva - * @since 2.3.0 + * @since 2.3.0 */ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker { - /** @var string PORTAL_ID */ + /** @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 - */ + /** + * 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'; + require MODULESROOT.'itop-portal-base/portal/config/bootstrap.php'; $sUrl = self::DoPrepareObjectURL($sClass, $iId, $sMode); - if(!empty($sPreviousPortalId)) + if (!empty($sPreviousPortalId)) { $_ENV['PORTAL_ID'] = $sPreviousPortalId; } @@ -76,7 +76,7 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker /** * @param string $sClass - * @param int $iId + * @param int $iId * @param string $sMode * * @return string|null @@ -155,9 +155,9 @@ abstract class AbstractPortalUrlMaker implements iDBObjectURLMaker */ private static function GetKernelInstance() { - if(!array_key_exists(static::PORTAL_ID, self::$aKernels)) + 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] = new Kernel($_SERVER['APP_ENV'], (bool)$_SERVER['APP_DEBUG']); self::$aKernels[static::PORTAL_ID]->boot(); } diff --git a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractStringVariableAccessor.php b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractStringVariableAccessor.php index 7d0498207..82fc2d8f3 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractStringVariableAccessor.php +++ b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractStringVariableAccessor.php @@ -1,19 +1,39 @@ getVariable(); - } + /** + * @return string + */ + public function __toString() + { + return $this->getVariable(); + } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractVariableAccessor.php b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractVariableAccessor.php index 401496856..fa76645be 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractVariableAccessor.php +++ b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/AbstractVariableAccessor.php @@ -1,30 +1,50 @@ mStoredVariable = $mVariableToStore; + $this->storedVariable = $variableToStore; } - + + /** + * @return string + */ public function getVariable() { - return $this->mStoredVariable; + return $this->storedVariable; } } \ No newline at end of file diff --git a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoCurrentContactPhotoUrl.php b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoCurrentContactPhotoUrl.php index c7af41ede..f14b8a9cb 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoCurrentContactPhotoUrl.php +++ b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoCurrentContactPhotoUrl.php @@ -19,12 +19,6 @@ * */ -/** - * Created by Bruno DA SILVA, working for Combodo - * Date: 28/02/19 - * Time: 16:59 - */ - namespace Combodo\iTop\Portal\VariableAccessor; @@ -33,15 +27,28 @@ use MetaModel; use User; use UserRights; +/** + * Class CombodoCurrentContactPhotoUrl + * + * @package Combodo\iTop\Portal\VariableAccessor + * @since 2.7.0 + * @author Bruno Da Silva + */ class CombodoCurrentContactPhotoUrl { - /** - * @var \User - */ + /** @var \User $oUser */ private $oUser; + /** @var string $sCombodoPortalInstanceAbsoluteUrl */ private $sCombodoPortalInstanceAbsoluteUrl; + /** @var string|null $sContactPhotoUrl */ private $sContactPhotoUrl; + /** + * CombodoCurrentContactPhotoUrl constructor. + * + * @param \User $oUser + * @param string $sCombodoPortalInstanceAbsoluteUrl + */ public function __construct(User $oUser, $sCombodoPortalInstanceAbsoluteUrl) { $this->oUser = $oUser; @@ -51,10 +58,11 @@ class CombodoCurrentContactPhotoUrl /** * @return string + * @throws \CoreException */ public function __toString() { - if($this->sContactPhotoUrl === null) + if ($this->sContactPhotoUrl === null) { $this->sContactPhotoUrl = $this->ComputeContactPhotoUrl(); } @@ -75,6 +83,7 @@ class CombodoCurrentContactPhotoUrl // - Checking if we can load the contact try { + /** @var \cmdbAbstractObject $oContact */ $oContact = UserRights::GetContactObject(); } catch (Exception $e) @@ -94,6 +103,7 @@ class CombodoCurrentContactPhotoUrl { if (MetaModel::IsValidAttCode(get_class($oContact), 'picture')) { + /** @var \ormDocument $oImage */ $oImage = $oContact->Get('picture'); if (is_object($oImage) && !$oImage->IsEmpty()) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoPortalInstanceConf.php b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoPortalInstanceConf.php index 14c011d58..44aa3739e 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoPortalInstanceConf.php +++ b/datamodels/2.x/itop-portal-base/portal/src/VariableAccessor/CombodoPortalInstanceConf.php @@ -1,13 +1,33 @@ + */ class CombodoPortalInstanceConf extends AbstractVariableAccessor { diff --git a/datamodels/2.x/itop-portal/index.php b/datamodels/2.x/itop-portal/index.php index 5b8dacd39..e80173a6f 100644 --- a/datamodels/2.x/itop-portal/index.php +++ b/datamodels/2.x/itop-portal/index.php @@ -1,21 +1,24 @@ +/** + * Copyright (C) 2013-2019 Combodo SARL + * + * This file is part of iTop. + * + * iTop is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * iTop is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * + * + */ /** * Backward Compatibility file for default portal. @@ -37,15 +40,15 @@ ); // Load current environment -if (file_exists(__DIR__ . '/../../approot.inc.php')) +if (file_exists(__DIR__.'/../../approot.inc.php')) { - require_once __DIR__ . '/../../approot.inc.php'; // When in env-xxxx folder + require_once __DIR__.'/../../approot.inc.php'; // When in env-xxxx folder } else { - require_once __DIR__ . '/../../../approot.inc.php'; // When in datamodels/x.x folder + require_once __DIR__.'/../../../approot.inc.php'; // When in datamodels/x.x folder } -require_once APPROOT . 'application/startup.inc.php'; +require_once APPROOT.'application/startup.inc.php'; // Protection against setup in the following configuration : ITIL Ticket with Enhanced Portal selected but neither UserRequest or Incident. Which would crash the portal. if (!class_exists('UserRequest') && !class_exists('Incident')) @@ -58,4 +61,4 @@ $sDir = basename(__DIR__); define('PORTAL_ID', $sDir); // Load frontal -require_once MODULESROOT . 'itop-portal-base/index.php'; +require_once MODULESROOT.'itop-portal-base/index.php'; diff --git a/datamodels/2.x/itop-portal/main.itop-portal.php b/datamodels/2.x/itop-portal/main.itop-portal.php index cb0205552..bdd5cd5b0 100644 --- a/datamodels/2.x/itop-portal/main.itop-portal.php +++ b/datamodels/2.x/itop-portal/main.itop-portal.php @@ -25,14 +25,14 @@ require_once APPROOT.'/lib/composer-vendor/autoload.php'; /** * iTopPortalEditUrlMaker - * + * * @author Guillaume Lajarige * @author Bruno Da Silva - * @since 2.3.0 + * @since 2.3.0 */ class iTopPortalEditUrlMaker extends AbstractPortalUrlMaker { - /** @var string PORTAL_ID */ + /** @var string PORTAL_ID */ const PORTAL_ID = 'itop-portal'; } @@ -41,7 +41,7 @@ class iTopPortalEditUrlMaker extends AbstractPortalUrlMaker * * @author Guillaume Lajarige * @author Bruno Da Silva - * @since 2.3.0 + * @since 2.3.0 */ class iTopPortalViewUrlMaker extends iTopPortalEditUrlMaker { @@ -52,7 +52,7 @@ class iTopPortalViewUrlMaker extends iTopPortalEditUrlMaker { return static::PrepareObjectURL($sClass, $iId, 'view'); } - + } // Default portal hyperlink (for notifications) is the edit hyperlink diff --git a/datamodels/2.x/itop-portal/module.itop-portal.php b/datamodels/2.x/itop-portal/module.itop-portal.php index 99a58b41e..4605713a4 100644 --- a/datamodels/2.x/itop-portal/module.itop-portal.php +++ b/datamodels/2.x/itop-portal/module.itop-portal.php @@ -1,5 +1,6 @@