mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge remote-tracking branch 'origin/support/2.7' into develop
# Conflicts: # core/log.class.inc.php # datamodels/2.x/itop-attachments/renderers.itop-attachments.php # js/search/search_form_criteria_enum.js # lib/composer/autoload_classmap.php # lib/composer/autoload_static.php # test/core/dictTest.php
This commit is contained in:
@@ -196,16 +196,19 @@ class privUITransactionSession
|
|||||||
*/
|
*/
|
||||||
class privUITransactionFile
|
class privUITransactionFile
|
||||||
{
|
{
|
||||||
|
/** @var int Value to use when no user logged */
|
||||||
|
const UNAUTHENTICATED_USER_ID = -666;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int current user id, or {@see self::UNAUTHENTICATED_USER_ID} if no user logged
|
||||||
* @throws \SecurityException if no connected user
|
|
||||||
*
|
*
|
||||||
* @since 2.6.5 2.7.6 3.0.0 N°4289 method creation
|
* @since 2.6.5 2.7.6 3.0.0 N°4289 method creation
|
||||||
*/
|
*/
|
||||||
private static function GetCurrentUserId() {
|
private static function GetCurrentUserId()
|
||||||
|
{
|
||||||
$iCurrentUserId = UserRights::GetConnectedUserId();
|
$iCurrentUserId = UserRights::GetConnectedUserId();
|
||||||
if ('' === $iCurrentUserId) {
|
if ('' === $iCurrentUserId) {
|
||||||
throw new SecurityException('Cannot creation transaction_id when no user logged');
|
$iCurrentUserId = static::UNAUTHENTICATED_USER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $iCurrentUserId;
|
return $iCurrentUserId;
|
||||||
|
|||||||
42
core/apc-service.class.inc.php
Normal file
42
core/apc-service.class.inc.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ApcService
|
||||||
|
* @since 2.7.6 N°4125
|
||||||
|
*/
|
||||||
|
class ApcService {
|
||||||
|
public function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $function_name
|
||||||
|
* @return bool
|
||||||
|
* @see function_exists()
|
||||||
|
*/
|
||||||
|
public function function_exists($function_name) {
|
||||||
|
return function_exists($function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|array $key
|
||||||
|
* @return mixed
|
||||||
|
* @see apc_fetch()
|
||||||
|
*/
|
||||||
|
function apc_fetch($key)
|
||||||
|
{
|
||||||
|
return apc_fetch($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array|string $key
|
||||||
|
* @param $var
|
||||||
|
* @param int $ttl
|
||||||
|
* @return array|bool
|
||||||
|
* @see apc_store()
|
||||||
|
*/
|
||||||
|
function apc_store($key, $var = NULL, $ttl = 0)
|
||||||
|
{
|
||||||
|
return apc_store($key, $var, $ttl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
@@ -35,6 +35,8 @@ class Dict
|
|||||||
protected static $m_aLanguages = array(); // array( code => array( 'description' => '...', 'localized_description' => '...') ...)
|
protected static $m_aLanguages = array(); // array( code => array( 'description' => '...', 'localized_description' => '...') ...)
|
||||||
protected static $m_aData = array();
|
protected static $m_aData = array();
|
||||||
protected static $m_sApplicationPrefix = null;
|
protected static $m_sApplicationPrefix = null;
|
||||||
|
/** @var \ApcService $m_oApcService */
|
||||||
|
protected static $m_oApcService = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $sLanguageCode
|
* @param $sLanguageCode
|
||||||
@@ -116,15 +118,17 @@ class Dict
|
|||||||
{
|
{
|
||||||
// Attempt to find the string in the user language
|
// Attempt to find the string in the user language
|
||||||
//
|
//
|
||||||
self::InitLangIfNeeded(self::GetUserLanguage());
|
$sLangCode = self::GetUserLanguage();
|
||||||
|
self::InitLangIfNeeded($sLangCode);
|
||||||
|
|
||||||
if (!array_key_exists(self::GetUserLanguage(), self::$m_aData))
|
if (!array_key_exists($sLangCode, self::$m_aData))
|
||||||
{
|
{
|
||||||
|
IssueLog::Warning("Cannot find $sLangCode in dictionnaries. default labels displayed");
|
||||||
// It may happen, when something happens before the dictionaries get loaded
|
// It may happen, when something happens before the dictionaries get loaded
|
||||||
return $sStringCode;
|
return $sStringCode;
|
||||||
}
|
}
|
||||||
$aCurrentDictionary = self::$m_aData[self::GetUserLanguage()];
|
$aCurrentDictionary = self::$m_aData[$sLangCode];
|
||||||
if (array_key_exists($sStringCode, $aCurrentDictionary))
|
if (is_array($aCurrentDictionary) && array_key_exists($sStringCode, $aCurrentDictionary))
|
||||||
{
|
{
|
||||||
return $aCurrentDictionary[$sStringCode];
|
return $aCurrentDictionary[$sStringCode];
|
||||||
}
|
}
|
||||||
@@ -135,7 +139,7 @@ class Dict
|
|||||||
self::InitLangIfNeeded(self::$m_sDefaultLanguage);
|
self::InitLangIfNeeded(self::$m_sDefaultLanguage);
|
||||||
|
|
||||||
$aDefaultDictionary = self::$m_aData[self::$m_sDefaultLanguage];
|
$aDefaultDictionary = self::$m_aData[self::$m_sDefaultLanguage];
|
||||||
if (array_key_exists($sStringCode, $aDefaultDictionary))
|
if (is_array($aDefaultDictionary) && array_key_exists($sStringCode, $aDefaultDictionary))
|
||||||
{
|
{
|
||||||
return $aDefaultDictionary[$sStringCode];
|
return $aDefaultDictionary[$sStringCode];
|
||||||
}
|
}
|
||||||
@@ -144,7 +148,7 @@ class Dict
|
|||||||
self::InitLangIfNeeded('EN US');
|
self::InitLangIfNeeded('EN US');
|
||||||
|
|
||||||
$aDefaultDictionary = self::$m_aData['EN US'];
|
$aDefaultDictionary = self::$m_aData['EN US'];
|
||||||
if (array_key_exists($sStringCode, $aDefaultDictionary))
|
if (is_array($aDefaultDictionary) && array_key_exists($sStringCode, $aDefaultDictionary))
|
||||||
{
|
{
|
||||||
return $aDefaultDictionary[$sStringCode];
|
return $aDefaultDictionary[$sStringCode];
|
||||||
}
|
}
|
||||||
@@ -203,7 +207,26 @@ class Dict
|
|||||||
{
|
{
|
||||||
self::$m_aLanguages = $aLanguagesList;
|
self::$m_aLanguages = $aLanguagesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.7.6 N°4125
|
||||||
|
* @return \ApcService
|
||||||
|
*/
|
||||||
|
public static function GetApcService() {
|
||||||
|
if (self::$m_oApcService === null){
|
||||||
|
self::$m_oApcService = new ApcService();
|
||||||
|
}
|
||||||
|
return self::$m_oApcService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.7.6 N°4125
|
||||||
|
* @param \ApcService $m_oApcService
|
||||||
|
*/
|
||||||
|
public static function SetApcService($oApcService) {
|
||||||
|
self::$m_oApcService = $oApcService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a language from the language dictionary, if not already loaded
|
* Load a language from the language dictionary, if not already loaded
|
||||||
* @param string $sLangCode Language code
|
* @param string $sLangCode Language code
|
||||||
@@ -212,20 +235,23 @@ class Dict
|
|||||||
public static function InitLangIfNeeded($sLangCode)
|
public static function InitLangIfNeeded($sLangCode)
|
||||||
{
|
{
|
||||||
if (array_key_exists($sLangCode, self::$m_aData)) return true;
|
if (array_key_exists($sLangCode, self::$m_aData)) return true;
|
||||||
|
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
|
|
||||||
if (function_exists('apc_fetch') && (self::$m_sApplicationPrefix !== null))
|
if (self::GetApcService()->function_exists('apc_fetch')
|
||||||
|
&& (self::$m_sApplicationPrefix !== null))
|
||||||
{
|
{
|
||||||
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
||||||
//
|
//
|
||||||
self::$m_aData[$sLangCode] = apc_fetch(self::$m_sApplicationPrefix.'-dict-'.$sLangCode);
|
self::$m_aData[$sLangCode] = self::GetApcService()->apc_fetch(self::$m_sApplicationPrefix.'-dict-'.$sLangCode);
|
||||||
if (self::$m_aData[$sLangCode] === false)
|
if (self::$m_aData[$sLangCode] === false) {
|
||||||
{
|
|
||||||
unset(self::$m_aData[$sLangCode]);
|
unset(self::$m_aData[$sLangCode]);
|
||||||
}
|
} else if (! is_array(self::$m_aData[$sLangCode])) {
|
||||||
else
|
// N°4125: we dont fix dictionnary corrupted cache (on iTop side).
|
||||||
{
|
// but we log an error in a dedicated channel to let itop administrator be aware of a potential APCu issue to fix.
|
||||||
|
IssueLog::Error("APCu corrupted data (with $sLangCode dictionnary). APCu configuration and running version should be troubleshooted...", LogChannels::APC);
|
||||||
|
$bResult = true;
|
||||||
|
} else {
|
||||||
$bResult = true;
|
$bResult = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,9 +260,10 @@ class Dict
|
|||||||
$sDictFile = APPROOT.'env-'.utils::GetCurrentEnvironment().'/dictionaries/'.str_replace(' ', '-', strtolower($sLangCode)).'.dict.php';
|
$sDictFile = APPROOT.'env-'.utils::GetCurrentEnvironment().'/dictionaries/'.str_replace(' ', '-', strtolower($sLangCode)).'.dict.php';
|
||||||
require_once($sDictFile);
|
require_once($sDictFile);
|
||||||
|
|
||||||
if (function_exists('apc_store') && (self::$m_sApplicationPrefix !== null))
|
if (self::GetApcService()->function_exists('apc_store')
|
||||||
|
&& (self::$m_sApplicationPrefix !== null))
|
||||||
{
|
{
|
||||||
apc_store(self::$m_sApplicationPrefix.'-dict-'.$sLangCode, self::$m_aData[$sLangCode]);
|
self::GetApcService()->apc_store(self::$m_sApplicationPrefix.'-dict-'.$sLangCode, self::$m_aData[$sLangCode]);
|
||||||
}
|
}
|
||||||
$bResult = true;
|
$bResult = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -549,6 +549,7 @@ class LogChannels
|
|||||||
public const PORTAL = 'portal';
|
public const PORTAL = 'portal';
|
||||||
public const CMDB_SOURCE = 'cmdbsource';
|
public const CMDB_SOURCE = 'cmdbsource';
|
||||||
public const CORE = 'core';
|
public const CORE = 'core';
|
||||||
|
public const APC = 'apc';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -556,7 +556,7 @@ JS
|
|||||||
'filename' => '<a href="'.$sDocDownloadUrl.'" target="_blank" class="$sIconClass">'.$sFileName.'</a>'.$sAttachmentMeta,
|
'filename' => '<a href="'.$sDocDownloadUrl.'" target="_blank" class="$sIconClass">'.$sFileName.'</a>'.$sAttachmentMeta,
|
||||||
'formatted-size' => $sFileFormattedSize,
|
'formatted-size' => $sFileFormattedSize,
|
||||||
'upload-date' => $sAttachmentDateFormatted,
|
'upload-date' => $sAttachmentDateFormatted,
|
||||||
'uploader' => $sAttachmentUploader,
|
'uploader' => $sAttachmentUploaderForHtml,
|
||||||
'type' => $sFileType,
|
'type' => $sFileType,
|
||||||
'js' => '',
|
'js' => '',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ $(function()
|
|||||||
for (var i in aSortedValues)
|
for (var i in aSortedValues)
|
||||||
{
|
{
|
||||||
var sValCode = aSortedValues[i][0];
|
var sValCode = aSortedValues[i][0];
|
||||||
var sValLabel = aSortedValues[i][1];
|
var sValLabel = $('<div/>').html(aSortedValues[i][1]).text();
|
||||||
//_makeListItemElement: function(sLabel, sValue, bInitChecked, bInitHidden,bObsolete, sAdditionalField)
|
//_makeListItemElement: function(sLabel, sValue, bInitChecked, bInitHidden,bObsolete, sAdditionalField)
|
||||||
var oValueElem = this._makeListItemElement(sValLabel, sValCode, false, false, aSortedValues[i][2], aSortedValues[i][3]);
|
var oValueElem = this._makeListItemElement(sValLabel, sValCode, false, false, aSortedValues[i][2], aSortedValues[i][3]);
|
||||||
oValueElem.appendTo(oDynamicListElem);
|
oValueElem.appendTo(oDynamicListElem);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ return array(
|
|||||||
'ActionEmail' => $baseDir . '/core/action.class.inc.php',
|
'ActionEmail' => $baseDir . '/core/action.class.inc.php',
|
||||||
'ActionNotification' => $baseDir . '/core/action.class.inc.php',
|
'ActionNotification' => $baseDir . '/core/action.class.inc.php',
|
||||||
'AjaxPage' => $baseDir . '/sources/application/WebPage/AjaxPage.php',
|
'AjaxPage' => $baseDir . '/sources/application/WebPage/AjaxPage.php',
|
||||||
|
'ApcService' => $baseDir . '/core/apc-service.class.inc.php',
|
||||||
'ApplicationContext' => $baseDir . '/application/applicationcontext.class.inc.php',
|
'ApplicationContext' => $baseDir . '/application/applicationcontext.class.inc.php',
|
||||||
'ApplicationException' => $baseDir . '/application/exceptions/ApplicationException.php',
|
'ApplicationException' => $baseDir . '/application/exceptions/ApplicationException.php',
|
||||||
'ApplicationMenu' => $baseDir . '/application/menunode.class.inc.php',
|
'ApplicationMenu' => $baseDir . '/application/menunode.class.inc.php',
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
'ActionEmail' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
'ActionEmail' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
||||||
'ActionNotification' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
'ActionNotification' => __DIR__ . '/../..' . '/core/action.class.inc.php',
|
||||||
'AjaxPage' => __DIR__ . '/../..' . '/sources/application/WebPage/AjaxPage.php',
|
'AjaxPage' => __DIR__ . '/../..' . '/sources/application/WebPage/AjaxPage.php',
|
||||||
|
'ApcService' => __DIR__ . '/../..' . '/core/apc-service.class.inc.php',
|
||||||
'ApplicationContext' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
'ApplicationContext' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
||||||
'ApplicationException' => __DIR__ . '/../..' . '/application/exceptions/ApplicationException.php',
|
'ApplicationException' => __DIR__ . '/../..' . '/application/exceptions/ApplicationException.php',
|
||||||
'ApplicationMenu' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
'ApplicationMenu' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||||
|
|||||||
@@ -178,5 +178,13 @@ class privUITransactionFileTest extends ItopDataTestCase
|
|||||||
$this->assertTrue($bUser1Login2, 'Login with user1 throw an error');
|
$this->assertTrue($bUser1Login2, 'Login with user1 throw an error');
|
||||||
$bResult = privUITransactionFile::RemoveTransaction($sTransactionIdUserSupport);
|
$bResult = privUITransactionFile::RemoveTransaction($sTransactionIdUserSupport);
|
||||||
$this->assertTrue($bResult, 'Token created by support user must be removed in the support user context');
|
$this->assertTrue($bResult, 'Token created by support user must be removed in the support user context');
|
||||||
|
|
||||||
|
// test when no user logged (combodo-unauthenticated-form module for example)
|
||||||
|
UserRights::_ResetSessionCache();
|
||||||
|
$sTransactionIdUnauthenticatedUser = privUITransactionFile::GetNewTransactionId();
|
||||||
|
$bResult = privUITransactionFile::IsTransactionValid($sTransactionIdUnauthenticatedUser, false);
|
||||||
|
$this->assertTrue($bResult, 'Token created by unauthenticated user must be valid when no user logged');
|
||||||
|
$bResult = privUITransactionFile::RemoveTransaction($sTransactionIdUnauthenticatedUser);
|
||||||
|
$this->assertTrue($bResult, 'Token created by unauthenticated user must be removed when no user logged');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
402
test/core/dictApcuTest.php
Normal file
402
test/core/dictApcuTest.php
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
<?php
|
||||||
|
// Copyright (c) 2010-2017 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
|
||||||
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: Eric
|
||||||
|
* Date: 30/10/2017
|
||||||
|
* Time: 13:43
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||||
|
|
||||||
|
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||||
|
use Dict;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @runTestsInSeparateProcesses
|
||||||
|
* @preserveGlobalState disabled
|
||||||
|
* @backupGlobals disabled
|
||||||
|
*/
|
||||||
|
class dictApcuTest extends ItopTestCase
|
||||||
|
{
|
||||||
|
private $sEnvName;
|
||||||
|
private $oApcService;
|
||||||
|
private $sDictionaryFolder;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
require_once (APPROOT.'core' . DIRECTORY_SEPARATOR . 'coreexception.class.inc.php');
|
||||||
|
require_once (APPROOT.'core' . DIRECTORY_SEPARATOR . 'dict.class.inc.php');
|
||||||
|
require_once (APPROOT.'core' . DIRECTORY_SEPARATOR . 'apc-service.class.inc.php');
|
||||||
|
|
||||||
|
$this->sEnvName = time();
|
||||||
|
$_SESSION['itop_env'] = $this->sEnvName;
|
||||||
|
|
||||||
|
$this->oApcService = $this->createMock(\ApcService::class);
|
||||||
|
Dict::SetApcService($this->oApcService);
|
||||||
|
Dict::EnableCache('toto');
|
||||||
|
|
||||||
|
Dict::SetLanguagesList(['FR FR' => 'fr', 'EN US' => 'en', 'DE DE' => 'de', 'RU RU' => 'de']);
|
||||||
|
|
||||||
|
$this->InitDictionnaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function InitDictionnaries(){
|
||||||
|
clearstatcache();
|
||||||
|
$this->sDictionaryFolder = APPROOT."env-$this->sEnvName" . DIRECTORY_SEPARATOR . "dictionaries";
|
||||||
|
@mkdir($this->sDictionaryFolder, 0777, true);
|
||||||
|
|
||||||
|
$sLabels = <<<STR
|
||||||
|
'label1' => 'fr1',
|
||||||
|
STR;
|
||||||
|
$this->InitDictionnary($this->sDictionaryFolder, 'FR FR', 'fr-fr', $sLabels);
|
||||||
|
|
||||||
|
$sLabels = <<<STR
|
||||||
|
'label1' => 'ru1',
|
||||||
|
'label2' => 'ru2',
|
||||||
|
STR;
|
||||||
|
$this->InitDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru', $sLabels);
|
||||||
|
$sLabels = <<<STR
|
||||||
|
'label1' => 'en1',
|
||||||
|
'label2' => 'en2',
|
||||||
|
'label3' => 'en3',
|
||||||
|
STR;
|
||||||
|
$this->InitDictionnary($this->sDictionaryFolder, 'EN US', 'en-us', $sLabels);
|
||||||
|
|
||||||
|
clearstatcache();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function InitDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename, $sLabels){
|
||||||
|
$sContent = <<<PHP
|
||||||
|
<?php
|
||||||
|
//
|
||||||
|
// Dictionary built by the compiler for the language "FR FR"
|
||||||
|
//
|
||||||
|
Dict::SetEntries('$sLanguageCode', array(
|
||||||
|
$sLabels
|
||||||
|
));
|
||||||
|
PHP;
|
||||||
|
file_put_contents($sDictionaryFolder . DIRECTORY_SEPARATOR . "$sLanguageCodeInFilename.dict.php", $sContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function InitBrokenDictionnary($sDictionaryFolder, $sLanguageCode, $sLanguageCodeInFilename){
|
||||||
|
$sContent = <<<PHP
|
||||||
|
<?php
|
||||||
|
//
|
||||||
|
// Dictionary built by the compiler for the language "FR FR"
|
||||||
|
//
|
||||||
|
Dict::SetEntries('$sLanguageCode', 'stringinsteadofanarray');
|
||||||
|
PHP;
|
||||||
|
file_put_contents($sDictionaryFolder . DIRECTORY_SEPARATOR . "$sLanguageCodeInFilename.dict.php", $sContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
foreach (glob(APPROOT."env-$this->sEnvName" . DIRECTORY_SEPARATOR . "dictionaries" . DIRECTORY_SEPARATOR . "*") as $sFile){
|
||||||
|
unlink($sFile);
|
||||||
|
}
|
||||||
|
rmdir(APPROOT."env-$this->sEnvName" . DIRECTORY_SEPARATOR . "dictionaries");
|
||||||
|
rmdir(APPROOT."env-$this->sEnvName");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function InitLangIfNeeded_NoApcProvider(){
|
||||||
|
return [
|
||||||
|
'apcu mocked' => [ 'bApcuMocked' => true ],
|
||||||
|
'integration test - apcu service like in production - install php-apcu before' => [ 'bApcuMocked' => false ],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider InitLangIfNeeded_NoApcProvider
|
||||||
|
*/
|
||||||
|
public function testInitLangIfNeeded_NoApc($bApcuMocked){
|
||||||
|
if ($bApcuMocked) {
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->never())
|
||||||
|
->method('apc_fetch');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->never())
|
||||||
|
->method('apc_store');
|
||||||
|
} else {
|
||||||
|
Dict::SetApcService(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//EN US default language
|
||||||
|
$this->assertEquals('en1', Dict::S('label1'));
|
||||||
|
$this->assertEquals('en2', Dict::S('label2'));
|
||||||
|
$this->assertEquals('en3', Dict::S('label3'));
|
||||||
|
$this->assertEquals('not_defined_label', Dict::S('not_defined_label'));
|
||||||
|
|
||||||
|
//default language set to RU RU
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
$this->assertEquals('ru1', Dict::S('label1'));
|
||||||
|
$this->assertEquals('ru2', Dict::S('label2'));
|
||||||
|
$this->assertEquals('en3', Dict::S('label3'));
|
||||||
|
$this->assertEquals('not_defined_label', Dict::S('not_defined_label'));
|
||||||
|
|
||||||
|
//user language set to FR FR
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('fr1', Dict::S('label1'));
|
||||||
|
$this->assertEquals('ru2', Dict::S('label2'));
|
||||||
|
$this->assertEquals('en3', Dict::S('label3'));
|
||||||
|
$this->assertEquals('not_defined_label', Dict::S('not_defined_label'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_LanguageMismatchDictionnary(){
|
||||||
|
//language mismatch!!
|
||||||
|
$sLabels = <<<STR
|
||||||
|
'label1' => 'de1',
|
||||||
|
STR;
|
||||||
|
$this->InitDictionnary($this->sDictionaryFolder, 'RU RU', 'de-de', $sLabels);
|
||||||
|
|
||||||
|
clearstatcache();
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_fetch');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->never())
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetUserLanguage('DE DE');
|
||||||
|
$this->assertEquals('label1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_BrokenUserDictionnary(){
|
||||||
|
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_fetch');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->never())
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetUserLanguage('DE DE');
|
||||||
|
$this->assertEquals('en1', Dict::S('label1'));
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
$this->assertEquals('ru1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_BrokenDictionnary_UserAndDefault(){
|
||||||
|
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de');
|
||||||
|
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_fetch');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->never())
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetUserLanguage('DE DE');
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
$this->assertEquals('en1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_BrokenDictionnary_ALL(){
|
||||||
|
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'DE DE', 'de-de');
|
||||||
|
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'RU RU', 'ru-ru');
|
||||||
|
$this->InitBrokenDictionnary($this->sDictionaryFolder, 'EN US', 'en-us');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_fetch');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->never())
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetUserLanguage('DE DE');
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
$this->assertEquals('label1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_ApcFromCache_PropertyInUserDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(1))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->with('toto-dict-FR FR')
|
||||||
|
->willReturn(['label1' => 'fr1']);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('fr1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_ApcStore_PropertyInUserDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(1))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->with('toto-dict-FR FR')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(1))
|
||||||
|
->method('apc_store')
|
||||||
|
->with('toto-dict-FR FR', ['label1' => 'fr1']);
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('fr1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//corrupted data not fixed
|
||||||
|
//we will return label from another dictionary (defaut one => russian here)
|
||||||
|
public function testInitLangIfNeeded_Apc_CorruptedCache_PropertyInUserDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(2))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'])
|
||||||
|
->willReturnOnConsecutiveCalls('corrupteddata', ['label1' => 'ru1']);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('ru1', Dict::S('label1'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_PropertyInDefaultLanguageDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(2))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'])
|
||||||
|
->willReturnOnConsecutiveCalls([], false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(1))
|
||||||
|
->method('apc_store')
|
||||||
|
->withConsecutive(['toto-dict-RU RU', ['label1' => 'ru1', 'label2' => 'ru2']]
|
||||||
|
);
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('ru2', Dict::S('label2'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//corrupted data not fixed
|
||||||
|
//we will return label from default language dictionary (EN here)
|
||||||
|
public function testInitLangIfNeeded_ApcCorrupted_PropertyInDefaultLanguageDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(3))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US'])
|
||||||
|
->willReturnOnConsecutiveCalls([], 'corrupteddata', ['label1' => 'en1', 'label2' => 'en2', 'label3' => 'en3']);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('en2', Dict::S('label2'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_PropertyInDictDefaultLanguageDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(3))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US'])
|
||||||
|
->willReturnOnConsecutiveCalls([], [], false);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(1))
|
||||||
|
->method('apc_store')
|
||||||
|
->withConsecutive(
|
||||||
|
['toto-dict-EN US', ['label1' => 'en1', 'label2' => 'en2', 'label3' => 'en3']]
|
||||||
|
);
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('en3', Dict::S('label3'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_ApcCorrupted_PropertyInDictDefaultLanguageDictionnary(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(3))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US'])
|
||||||
|
->willReturnOnConsecutiveCalls([], [], 'corrupteddata');
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('label3', Dict::S('label3'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_Apc_PropertyNotFound(){
|
||||||
|
$this->oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(3))
|
||||||
|
->method('apc_fetch')
|
||||||
|
->withConsecutive(['toto-dict-FR FR'], ['toto-dict-RU RU'], ['toto-dict-EN US'])
|
||||||
|
->willReturnOnConsecutiveCalls([], [], []);
|
||||||
|
|
||||||
|
$this->oApcService->expects($this->exactly(0))
|
||||||
|
->method('apc_store');
|
||||||
|
|
||||||
|
Dict::SetDefaultLanguage('RU RU');
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('undefined_label', Dict::S('undefined_label'));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,19 +38,83 @@ use Exception;
|
|||||||
*/
|
*/
|
||||||
class dictTest extends ItopTestCase
|
class dictTest extends ItopTestCase
|
||||||
{
|
{
|
||||||
|
private $sEnvName;
|
||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
require_once (APPROOT.'core/dict.class.inc.php');
|
|
||||||
require_once 'mockDict.incphp';
|
require_once(APPROOT.'core'.DIRECTORY_SEPARATOR.'apc-service.class.inc.php');
|
||||||
|
|
||||||
|
$this->sEnvName = time();
|
||||||
|
$sDictionaryFolder = APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries";
|
||||||
|
@mkdir($sDictionaryFolder, 0777, true);
|
||||||
|
|
||||||
|
$sContent = <<<PHP
|
||||||
|
<?php
|
||||||
|
//
|
||||||
|
// Dictionary built by the compiler for the language "FR FR"
|
||||||
|
//
|
||||||
|
Dict::SetEntries('FR FR', array(
|
||||||
|
'label1' => 'gabu',
|
||||||
|
));
|
||||||
|
PHP;
|
||||||
|
file_put_contents($sDictionaryFolder.DIRECTORY_SEPARATOR."fr-fr.dict.php", $sContent);
|
||||||
|
$sContent = <<<PHP
|
||||||
|
<?php
|
||||||
|
//
|
||||||
|
// Dictionary built by the compiler for the language "FR FR"
|
||||||
|
//
|
||||||
|
Dict::SetEntries('EN EN', array(
|
||||||
|
'label1' => 'zomeu',
|
||||||
|
));
|
||||||
|
PHP;
|
||||||
|
file_put_contents($sDictionaryFolder.DIRECTORY_SEPARATOR."en-en.dict.php", $sContent);
|
||||||
|
|
||||||
|
$_SESSION['itop_env'] = $this->sEnvName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function tearDown()
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function testType()
|
|
||||||
{
|
{
|
||||||
|
foreach (glob(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries".DIRECTORY_SEPARATOR."*") as $sFile) {
|
||||||
|
unlink($sFile);
|
||||||
|
}
|
||||||
|
rmdir(APPROOT."env-$this->sEnvName".DIRECTORY_SEPARATOR."dictionaries");
|
||||||
|
rmdir(APPROOT."env-$this->sEnvName");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function testType()
|
||||||
|
{
|
||||||
|
$_SESSION['itop_env'] = 'production';
|
||||||
$this->assertInternalType('string', Dict::S('Core:AttributeURL'));
|
$this->assertInternalType('string', Dict::S('Core:AttributeURL'));
|
||||||
$this->assertInternalType('string', Dict::Format('Change:AttName_SetTo', '1', '2'));
|
$this->assertInternalType('string', Dict::Format('Change:AttName_SetTo', '1', '2'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testInitLangIfNeeded_NoApc()
|
||||||
|
{
|
||||||
|
$oApcService = $this->createMock(\ApcService::class);
|
||||||
|
Dict::SetApcService($oApcService);
|
||||||
|
Dict::EnableCache('toto');
|
||||||
|
|
||||||
|
$oApcService->expects($this->any())
|
||||||
|
->method('function_exists')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$oApcService->expects($this->never())
|
||||||
|
->method('apc_fetch')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$oApcService->expects($this->never())
|
||||||
|
->method('apc_store')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
Dict::SetLanguagesList(['FR FR' => 'fr', 'EN EN' => 'en']);
|
||||||
|
Dict::SetUserLanguage('FR FR');
|
||||||
|
$this->assertEquals('gabu', Dict::S('label1'));
|
||||||
|
Dict::SetUserLanguage('EN EN');
|
||||||
|
$this->assertEquals('zomeu', Dict::S('label1'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user