Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 2 additions & 20 deletions application/startup.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Service\Startup\StartupService;

require_once(APPROOT.'core/cmdbobject.class.inc.php');
require_once(APPROOT.'application/utils.inc.php');
Expand Down Expand Up @@ -69,26 +70,7 @@

$sSwitchEnv = utils::ReadParam('switch_env', null);
$bAllowCache = true;
if (($sSwitchEnv != null) && file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE) && (Session::Get('itop_env') !== $sSwitchEnv)) {
Session::Set('itop_env', $sSwitchEnv);
$sEnv = $sSwitchEnv;
$bAllowCache = false;
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset')) {
// Zend opcode cache
opcache_reset();
}
if (function_exists('apc_clear_cache')) {
// APC(u) cache
apc_clear_cache();
}
// TODO: reset the credentials as well ??
} elseif (Session::IsSet('itop_env')) {
$sEnv = Session::Get('itop_env');
} else {
$sEnv = ITOP_DEFAULT_ENV;
Session::Set('itop_env', ITOP_DEFAULT_ENV);
}
$sEnv = StartupService::SetItopEnvironment($sSwitchEnv, $bAllowCache);
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
try {
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
Expand Down
1 change: 1 addition & 0 deletions lib/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@
'Combodo\\iTop\\Service\\Router\\Exception\\RouteNotFoundException' => $baseDir . '/sources/Service/Router/Exception/RouteNotFoundException.php',
'Combodo\\iTop\\Service\\Router\\Exception\\RouterException' => $baseDir . '/sources/Service/Router/Exception/RouterException.php',
'Combodo\\iTop\\Service\\Router\\Router' => $baseDir . '/sources/Service/Router/Router.php',
'Combodo\\iTop\\Service\\Startup\\StartupService' => $baseDir . '/sources/Service/Startup/StartupService.php',
'Combodo\\iTop\\Service\\SummaryCard\\SummaryCardService' => $baseDir . '/sources/Service/SummaryCard/SummaryCardService.php',
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectConfig' => $baseDir . '/sources/Service/TemporaryObjects/TemporaryObjectConfig.php',
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectGC' => $baseDir . '/sources/Service/TemporaryObjects/TemporaryObjectGC.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,7 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
'Combodo\\iTop\\Service\\Router\\Exception\\RouteNotFoundException' => __DIR__ . '/../..' . '/sources/Service/Router/Exception/RouteNotFoundException.php',
'Combodo\\iTop\\Service\\Router\\Exception\\RouterException' => __DIR__ . '/../..' . '/sources/Service/Router/Exception/RouterException.php',
'Combodo\\iTop\\Service\\Router\\Router' => __DIR__ . '/../..' . '/sources/Service/Router/Router.php',
'Combodo\\iTop\\Service\\Startup\\StartupService' => __DIR__ . '/../..' . '/sources/Service/Startup/StartupService.php',
'Combodo\\iTop\\Service\\SummaryCard\\SummaryCardService' => __DIR__ . '/../..' . '/sources/Service/SummaryCard/SummaryCardService.php',
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectConfig' => __DIR__ . '/../..' . '/sources/Service/TemporaryObjects/TemporaryObjectConfig.php',
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectGC' => __DIR__ . '/../..' . '/sources/Service/TemporaryObjects/TemporaryObjectGC.php',
Expand Down
58 changes: 58 additions & 0 deletions sources/Service/Startup/StartupService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Combodo\iTop\Service\Startup;

use Combodo\iTop\Application\Helper\Session;
use CoreException;
use IssueLog;

class StartupService
{
/**
* @param string|null $sSwitchEnv
* @param bool $bAllowCache
*
* @return string
* @throws CoreException
*/
public static function SetItopEnvironment(?string $sSwitchEnv, bool &$bAllowCache): string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the meaning of $bAllowCache? it seems not related to opcache/apccache.

maybe you could document what is its purpose.

Copy link
Copy Markdown
Contributor Author

@Lenaick Lenaick Jun 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a boolean that determines whether the APC cache can be used or not, in conjunction with the apc_cache.enabled parameter
In the case of the environment switch, the cache must not be used
I've updated the documentation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a small explanation in the php doc for both parameters would be handy?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you could change all local method and remove staitc which is not so usefull. and not recommended by phpunit (no mock possible)

{
if (static::IsBuildEnvironment($sSwitchEnv)) {
$oException = new CoreException("Switching to environment '$sSwitchEnv' is not allowed since it is a build environment");
IssueLog::Exception("Trying to switch to environment '$sSwitchEnv' is not allowed since it is a build environment", $oException);
throw $oException;
}

if (
($sSwitchEnv != null)
&& file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE)
&& (Session::Get('itop_env') !== $sSwitchEnv)
) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Check existence first This rejects every *-build value before checking whether it is a real environment or whether a switch would occur. A request like ?switch_env=does-not-exist-build used to fall through to the current session/default environment because the config file did not exist; now it throws during startup and logs an exception for a value that would otherwise be ignored.

Suggested change
if (static::IsBuildEnvironment($sSwitchEnv)) {
$oException = new CoreException("Switching to environment '$sSwitchEnv' is not allowed since it is a build environment");
IssueLog::Exception("Trying to switch to environment '$sSwitchEnv' is not allowed since it is a build environment", $oException);
throw $oException;
}
if (
($sSwitchEnv != null)
&& file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE)
&& (Session::Get('itop_env') !== $sSwitchEnv)
) {
if (
($sSwitchEnv != null)
&& file_exists(APPCONF.$sSwitchEnv.'/'.ITOP_CONFIG_FILE)
&& (Session::Get('itop_env') !== $sSwitchEnv)
) {
if (static::IsBuildEnvironment($sSwitchEnv)) {
$oException = new CoreException("Switching to environment '$sSwitchEnv' is not allowed since it is a build environment");
IssueLog::Exception("Trying to switch to environment '$sSwitchEnv' is not allowed since it is a build environment", $oException);
throw $oException;
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Session::Set('itop_env', $sSwitchEnv);
$sEnv = $sSwitchEnv;
$bAllowCache = false;
// Reset the opcache since otherwise the PHP "model" files may still be cached !!
if (function_exists('opcache_reset')) {
// Zend opcode cache
opcache_reset();
}
if (function_exists('apc_clear_cache')) {
// APC(u) cache
apc_clear_cache();
}
// TODO: reset the credentials as well ??
} elseif (Session::IsSet('itop_env')) {
$sEnv = Session::Get('itop_env');
Comment on lines +44 to +45
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Validate session environment The new guard only checks the requested switch_env, but setup writes the build environment into $_SESSION['itop_env'] during RunTimeEnvironment::InitDataModel(). On the next normal application request with no switch_env, this branch returns production-build from the session and startup.inc.php starts MetaModel from conf/production-build/config-itop.php, so the build environment remains selectable through existing session state.

} else {
$sEnv = ITOP_DEFAULT_ENV;
Session::Set('itop_env', ITOP_DEFAULT_ENV);
}

return $sEnv;
}

public static function IsBuildEnvironment(?string $sEnv): bool
{
return $sEnv != null && str_ends_with($sEnv, '-build');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Service\Startup;

use Combodo\iTop\Service\Startup\StartupService;
use Combodo\iTop\Test\UnitTest\ItopTestCase;
use CoreException;

class StartupServiceTest extends ItopTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceItopFile('application/utils.inc.php');
}

public function testSetItopEnvironmentUsesDefaultWhenEnvironmentIsNull(): void
{
$bAllowCache = true;
$sEnv = StartupService::SetItopEnvironment(null, $bAllowCache);
$this->assertEquals(ITOP_DEFAULT_ENV, $sEnv);
$this->assertTrue($bAllowCache);
}

public function testSetItopEnvironmentWithValidEnvironment(): void
{
$bAllowCache = true;
$sEnv = StartupService::SetItopEnvironment('test', $bAllowCache);
$this->assertEquals('test', $sEnv);
$this->assertFalse($bAllowCache);
}

public function testSetItopEnvironmentThrowsForBuildEnvironment()
{
$bAllowCache = true;
$this->expectException(CoreException::class);
$this->expectExceptionMessage("Switching to environment 'test-build' is not allowed since it is a build environment");
StartupService::SetItopEnvironment('test-build', $bAllowCache);
}

public function testIsBuildEnvironment()
{
$this->assertTrue(StartupService::IsBuildEnvironment('test-build'));
$this->assertFalse(StartupService::IsBuildEnvironment('test'));
$this->assertFalse(StartupService::IsBuildEnvironment(null));
}
}