Compare commits

..

2 Commits

Author SHA1 Message Date
Eric Espie
8bd72409f1 N°6716 - High memory Consomption and performance issue 2023-09-14 15:16:11 +02:00
Eric Espie
3eb06f8ada N°6716 - High memory Consomption and performance issue 2023-09-14 14:38:17 +02:00
3178 changed files with 34387 additions and 235217 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

View File

@@ -1,14 +1,7 @@
# iTop version history
```mermaid
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'themeVariables': {
'git0': 'lawngreen',
'git3': 'dodgerblue',
'git4': 'grey',
'git5': 'grey',
'git6': 'grey',
'git7': 'grey'
}, 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'showBranches': true,'mainBranchName': 'develop','rotateCommitLabel': true}} }%%
gitGraph
commit id: "2016-07-06" tag: "2.3.0" type: HIGHLIGHT
branch support/2.3 order: 900
@@ -75,10 +68,6 @@ gitGraph
branch support/3.1 order: 840
checkout support/3.1
commit id: "2023-08-09" tag: "3.1.0-2"
checkout support/2.7
commit id: "2023-08-10" tag: "2.7.9"
checkout support/3.1
commit id: "2023-12-20" tag: "3.1.1"
```
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).

6
.gitignore vendored
View File

@@ -37,9 +37,7 @@ tests/*/vendor/*
# iTop extensions
/extensions/**
!/extensions/.htaccess
!/extensions/readme.txt
!/extensions/web.config
# all logs but listing prevention
/log/**
@@ -47,10 +45,8 @@ tests/*/vendor/*
!/log/index.php
!/log/web.config
# PHPUnit: Cache file, local XML working copies
# PHPUnit cache file
/tests/php-unit-tests/.phpunit.result.cache
/tests/php-unit-tests/phpunit.xml
/tests/php-unit-tests/postbuild_integration.xml
# Jetbrains

View File

@@ -140,7 +140,7 @@ When your code is working, please:
* Pull request description: mind to add all the information useful to understand why you're suggesting this modification and anything necessary to dive into your work. Especially:
- Bugfixes: exact steps to reproduce the bug (given/when/then), description of the bug cause and what solution is implemented
- Enhancements: use cases, implementation details if needed
* Mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option ! (note that if you are working with an org fork, this option [won't be available](https://github.com/orgs/community/discussions/5634))
* Mind to check the "[Allow edits from maintainers](https://docs.github.com/en/github-ae@latest/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork)" option !
## 🙏 We are thankful
@@ -161,4 +161,4 @@ We have one sticker per contribution type. You might get multiple stickers with
Here is the design of each stickers for year 2022:
![iTop stickers 2023](.doc/contributing-guide/2023.contributing-stickers-side-by-side.png)
![iTop stickers 2022](.doc/contributing-guide/2022.contributing-stickers-side-by-side.png)

View File

@@ -87,11 +87,9 @@ We would like to give a special thank you 🤗 to the people from the community
- Castro, Randall Badilla
- Colantoni, Maria Laura
- Couronné, Guy
- Dejin, Bie (a.k.a [@bdejin](https://github.com/bdejin))
- Dvořák, Lukáš
- Goethals, Stefan
- Gumble, David
- Ji, Leeb (冀利斌) (a.k.a [@chileeb](https://github.com/chileeb))
- Kaltefleiter, Lars (a.k.a [@larhip](https://www.github.com/larhip))
- Khamit, Shamil
- Kincel, Martin
@@ -107,12 +105,9 @@ We would like to give a special thank you 🤗 to the people from the community
- Roháč, Richard (a.k.a [@RohacRichard](https://github.com/RohacRichard))
- Rosenke, Stephan
- Rudner, Björn (a.k.a [@rudnerbjoern](https://github.com/rudnerbjoern))
- Šafránek, Jaroslav (a.k.a [jkcinik](https://sourceforge.net/u/jkcinik/profile/) on SourceForge)
- Seki, Shoji
- Shilov, Vladimir
- Stetina, Pavel (a.k.a [@Stetinac](https://github.com/Stetinac))
- Stukalov, Ilya (a.k.a [@ilya](https://www.github.com/ilya)-stukalov)
- Tarjányi, Csaba (a.k.a [@tacsaby](https://github.com/tacsaby))
- Tulio, Marco
- Turrubiates, Miguel

View File

@@ -4,8 +4,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\WebPage\WebPage;
define('ADMIN_PROFILE_NAME', 'Administrator');
define('PORTAL_PROFILE_NAME', 'Portal user');
@@ -448,12 +446,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
UR_ACTION_BULK_DELETE => 'bd',
);
/**
* @var array $aUsersProfilesList Cache of users' profiles. Hash array of user ID => [profile ID => profile friendlyname, profile ID => profile friendlyname, ...]
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6887
*/
private $aUsersProfilesList = [];
// Installation: create the very first user
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
{
@@ -510,7 +502,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
}
protected $m_aUserOrgs = array(); // userid -> array of orgid
protected $m_aAdministrators = null; // [user id]
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
protected $m_aObjectActionGrants = array();
@@ -567,7 +558,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
// Cache
$this->m_aObjectActionGrants = array();
$this->m_aAdministrators = null;
}
public function LoadCache()
@@ -710,10 +700,12 @@ class UserRightsProfile extends UserRightsAddOnAPI
*/
private function GetAdministrators()
{
if ($this->m_aAdministrators === null)
static $aAdministrators = null;
if ($aAdministrators === null)
{
// Find all administrators
$this->m_aAdministrators = array();
$aAdministrators = array();
$oAdministratorsFilter = new DBObjectSearch('User');
$oLnkFilter = new DBObjectSearch('URP_UserProfile');
$oExpression = new FieldExpression('profileid', 'URP_UserProfile');
@@ -726,10 +718,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
$oSet->OptimizeColumnLoad(array('User' => array('login')));
while($oUser = $oSet->Fetch())
{
$this->m_aAdministrators[] = $oUser->GetKey();
$aAdministrators[] = $oUser->GetKey();
}
}
return $this->m_aAdministrators;
return $aAdministrators;
}
/**
@@ -766,12 +758,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
$sAction = self::$m_aActionCodes[$iActionCode];
$bStatus = null;
// Cache user's profiles
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
}
// Call the API of UserRights because it caches the list for us
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
foreach(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
{
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
if (!is_null($bGrant))
@@ -897,16 +885,11 @@ class UserRightsProfile extends UserRightsAddOnAPI
// Note: this code is VERY close to the code of IsActionAllowed()
$iUser = $oUser->GetKey();
// Cache user's profiles
if(false === array_key_exists($iUser, $this->aUsersProfilesList)){
$this->aUsersProfilesList[$iUser] = UserRights::ListProfiles($oUser);
}
// Note: The object set is ignored because it was interesting to optimize for huge data sets
// and acceptable to consider only the root class of the object set
$bStatus = null;
// Call the API of UserRights because it caches the list for us
foreach($this->aUsersProfilesList[$iUser] as $iProfile => $oProfile)
foreach(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
{
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
if (!is_null($bGrant))
@@ -935,9 +918,8 @@ class UserRightsProfile extends UserRightsAddOnAPI
}
/**
* @param string $sClass
* @return string|null Find out which attribute is corresponding the dimension 'owner org'
* returns null if no such attribute has been found (no filtering should occur)
* Find out which attribute is corresponding the the dimension 'owner org'
* returns null if no such attribute has been found (no filtering should occur)
*/
public static function GetOwnerOrganizationAttCode($sClass)
{

View File

@@ -17,8 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
define('ADMIN_PROFILE_NAME', 'Administrator');
define('PORTAL_PROFILE_NAME', 'Portal user');
@@ -582,10 +580,10 @@ class UserRightsProfile extends UserRightsAddOnAPI
/**
* Read and cache organizations allowed to the given user
*
* @param User $oUser
* @param string $sClass (not used here but can be used in overloads)
* @param $oUser
* @param $sClass (not used here but can be used in overloads)
*
* @return array keys of the User allowed org
* @return array
* @throws \CoreException
* @throws \Exception
*/

View File

@@ -17,8 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
define('ADMIN_PROFILE_ID', 1);
class UserRightsBaseClass extends cmdbAbstractObject

29
app.php
View File

@@ -1,29 +0,0 @@
<?php
/**
* Copyright (C) 2013-2023 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
*/
use Combodo\iTop\Kernel;
require_once __DIR__.'/lib/autoload_runtime.php';
require_once('approot.inc.php');
require_once('application/startup.inc.php');
return function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

View File

@@ -1,13 +1,12 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/
// cannot notify depreciation for now as this is still load in autoloader
//DeprecatedCallsLog::NotifyDeprecatedFile('moved to sources/Application/WebPage/AjaxPage.php, now loadable using autoloader');
use Combodo\iTop\Application\WebPage\AjaxPage;
/**
* Class ajax_page

View File

@@ -19,8 +19,6 @@
*/
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Symfony\Component\DependencyInjection\Container;
require_once(APPROOT.'application/newsroomprovider.class.inc.php');
@@ -272,14 +270,14 @@ interface iPreferencesExtension
{
/**
* @api
* @param WebPage $oPage
* @param \WebPage $oPage
*
*/
public function DisplayPreferences(WebPage $oPage);
/**
* @api
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sOperation
*
* @return bool true if the operation has been used
@@ -337,6 +335,7 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension
* A recommended pattern is to cache data by the mean of static members.
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
* @package UIExtensibilityAPI
*/
interface iApplicationUIExtension
@@ -488,6 +487,7 @@ interface iApplicationUIExtension
* @api
* @package UIExtensibilityAPI
* @since 2.7.0
* @deprecated
*/
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
{
@@ -560,7 +560,6 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
* or through the GUI.
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method. More details on each method PHPDoc.
* @package ORMExtensibilityAPI
*/
interface iApplicationObjectExtension
@@ -575,7 +574,6 @@ interface iApplicationObjectExtension
* Otherwise, the answer is definitively "yes, the object has changed".
*
* @api
* @deprecated 3.1.0 N°4756 No alternative available, this API was unstable and is abandoned
* @param \cmdbAbstractObject $oObject The target object
*
* @return boolean True if something has changed for the target object
@@ -589,7 +587,6 @@ interface iApplicationObjectExtension
* Anyhow, this API can be called in other contexts such as the CSV import tool.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_WRITE event instead
* @param \cmdbAbstractObject $oObject The target object
*
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
@@ -604,7 +601,6 @@ interface iApplicationObjectExtension
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_DELETE event instead
* @param \cmdbAbstractObject $oObject The target object
*
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
@@ -621,7 +617,6 @@ interface iApplicationObjectExtension
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
@@ -638,7 +633,6 @@ interface iApplicationObjectExtension
* The method is called right <b>after</b> the object has been written to the database.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
@@ -653,7 +647,6 @@ interface iApplicationObjectExtension
* The method is called right <b>before</b> the object will be deleted from the database.
*
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_DELETE event instead
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
@@ -667,7 +660,6 @@ interface iApplicationObjectExtension
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
* @package ORMExtensibilityAPI
* @since 2.7.0
*/
@@ -2017,8 +2009,6 @@ class RestUtils
*
* @return DBObject The object found
* @throws Exception If the input structure is not valid or it could not find exactly one object
*
* @see DBObject::CheckChangedExtKeysValues() generic method to check that we can access the linked object isn't used in that use case because values can be literal, OQL, friendlyname
*/
public static function FindObjectFromKey($sClass, $key, $bAllowNullValue = false)
{

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CaptureWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CLIPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -26,7 +26,7 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Html\HtmlFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\JsPopoverMenuItem;
@@ -42,9 +42,6 @@ use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetViewTable;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetViewTable;
use Combodo\iTop\Application\UI\Links\Set\LinkSetUIBlockFactory;
use Combodo\iTop\Application\WebPage\AjaxPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
@@ -288,7 +285,7 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \cmdbAbstractObject $oObj
* @param array $aParams
*
@@ -357,7 +354,7 @@ JS
* @param int $iKey The identifier of the object
* @param string $sMessageId Your id or one of the well-known ids: 'create', 'update' and 'apply_stimulus'
* @param string $sMessage The HTML message (must be correctly escaped)
* @param string $sSeverity Any of the WebPage::ENUM_SESSION_MESSAGE_SEVERITY_XXX constants
* @param string $sSeverity Any of the \WebPage::ENUM_SESSION_MESSAGE_SEVERITY_XXX constants
* @param float $fRank Ordering of the message: smallest displayed first (can be negative)
* @param bool $bMustNotExist Do not alter any existing message (considering the id)
*
@@ -379,7 +376,7 @@ JS
}
/**
* @param WebPage $oPage Warning, since 3.0.0 this parameter was kept for compatibility reason. You shouldn't write directly on the page!
* @param \WebPage $oPage Warning, since 3.0.0 this parameter was kept for compatibility reason. You shouldn't write directly on the page!
* When writing to the page, markup will be put above the real header of the panel.
* To insert something IN the panel, we now need to add UIBlocks in either the "subtitle" or "toolbar" sections of the array that will be returned.
* @param bool $bEditMode Deprecated parameter in iTop 3.0.0, use {@see GetDisplayMode()} and ENUM_DISPLAY_MODE_* constants instead
@@ -557,7 +554,7 @@ HTML
/**
* Display properties tab of an object
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method. Use {@see static::$sDisplayMode} instead
* @param string $sPrefix
* @param array $aExtraParams
@@ -596,7 +593,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $sAttCode
*
* @throws \Exception
@@ -637,7 +634,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method. Use {@see static::$sDisplayMode} instead
*
* @throws \CoreException
@@ -747,13 +744,7 @@ HTML
$oPage->SetCurrentTab($sTabCode, $oAttDef->GetLabel().$sCount, $sTabDescription);
$aArgs = array('this' => $this);
$sEditWhen = $oAttDef->GetEditWhen();
// Calculate if edit_when allows to edit based on current $bEditMode
$bIsEditableBasedOnEditWhen = ($sEditWhen === LINKSET_EDITWHEN_ALWAYS) ||
($bEditMode ? $sEditWhen === LINKSET_EDITWHEN_ON_HOST_EDITION : $sEditWhen === LINKSET_EDITWHEN_ON_HOST_DISPLAY);
$bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE)) || !$bIsEditableBasedOnEditWhen;
$bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE));
if ($bEditMode && (!$bReadOnly)) {
$sInputId = $this->m_iFormId.'_'.$sAttCode;
$sDisplayValue = ''; // not used
@@ -763,9 +754,9 @@ HTML
$oPage->add($sHTMLValue);
} else {
if ($oAttDef->IsIndirect()) {
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly);
$oBlockLinkSetViewTable = new BlockIndirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
} else {
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef, $bReadOnly);
$oBlockLinkSetViewTable = new BlockDirectLinkSetViewTable($oPage, $this, $sClass, $sAttCode, $oAttDef);
}
$oPage->AddUiBlock($oBlockLinkSetViewTable);
}
@@ -864,7 +855,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method. Use {@see static::$sDisplayMode} instead
* @param string $sPrefix
* @param array $aExtraParams
@@ -1068,7 +1059,7 @@ HTML
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode Note that this parameter is no longer used in this method, {@see static::$sDisplayMode} is used instead, but we cannot remove it as it part of the base interface (iDisplay)...
*
* @throws \ApplicationException
@@ -1115,7 +1106,7 @@ HTML
}
// Note: DisplayBareHeader is called before adding $oObjectDetails to the page, so it can inject HTML before it through $oPage.
/** @var iTopWebPage $oPage */
/** @var \iTopWebPage $oPage */
$aHeadersBlocks = $this->DisplayBareHeader($oPage, $bEditMode);
if (false === empty($aHeadersBlocks['subtitle'])) {
$oObjectDetails->AddSubTitleBlocks($aHeadersBlocks['subtitle']);
@@ -1150,7 +1141,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
*
* @throws \ArchivedObjectException
* @throws \CoreException
@@ -1173,7 +1164,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams See possible values in {@see DataTableUIBlockFactory::RenderDataTable()}
*
@@ -1235,7 +1226,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \DBObjectSet $oSet
* @param array $aExtraParams
*
@@ -1407,7 +1398,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams key used :
* <ul>
@@ -1530,7 +1521,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aParams
* @param string $sCharset
@@ -1689,7 +1680,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aParams
*
@@ -1902,7 +1893,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aParams
*
@@ -1980,7 +1971,7 @@ HTML
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param \CMDBObjectSet $oSet
* @param array $aExtraParams
*
@@ -2011,7 +2002,7 @@ HTML
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sClass
* @param string $sAttCode
* @param \AttributeDefinition $oAttDef
@@ -2749,7 +2740,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
*
* @throws \ArchivedObjectException
@@ -3154,7 +3145,7 @@ EOF
/**
* Select the derived class to create
* @param string $sClass
* @param WebPage $oP
* @param \WebPage $oP
* @param \ApplicationContext $oAppContext
* @param array $aPossibleClasses
* @param array $aHiddenFields
@@ -3249,7 +3240,7 @@ EOF
return $oBlock;
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sClass
* @param \DBObject|null $oSourceObject Object to use for the creation form, can be either the class to instantiate, an object to clone or an object to use (eg. already prefilled / modeled object)
* @param array $aArgs
@@ -3334,7 +3325,7 @@ EOF
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sStimulus
* @param array|null $aPrefillFormParam
* @param bool $bDisplayBareProperties Whether to display the object details or not
@@ -3712,7 +3703,7 @@ HTML;
if ($oAttDef->GetEditClass() == 'Document') {
/** @var \ormDocument $oDocument */
$oDocument = $this->Get($sAttCode);
if (is_object($oDocument) && !$oDocument->IsEmpty()) {
if (!$oDocument->IsEmpty()) {
$sFieldAsHtml = $this->GetAsHTML($sAttCode);
$sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_');
@@ -3747,7 +3738,7 @@ HTML;
/**
* Displays a blob document *inline* (if possible, depending on the type of the document)
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $sAttCode
*
* @return string
@@ -4547,7 +4538,7 @@ HTML;
return $res;
}
protected function PostInsertActions(): void
public function PostInsertActions(): void
{
parent::PostInsertActions();
@@ -4571,9 +4562,6 @@ HTML;
InlineImage::FinalizeInlineImages($this);
}
/**
* @deprecated 3.1.1 3.2.0 N°6966 We will have only one DBClone method in the future
*/
protected function DBCloneTracked_Internal($newKey = null)
{
/** @var cmdbAbstractObject $oNewObj */
@@ -4594,7 +4582,6 @@ HTML;
public function DBUpdate()
{
$this->LogCRUDEnter(__METHOD__);
$res = 0;
try {
if (count($this->ListChanges()) === 0) {
@@ -4614,7 +4601,7 @@ HTML;
return $res;
}
protected function PostUpdateActions(array $aChanges): void
public function PostUpdateActions(array $aChanges): void
{
parent::PostUpdateActions($aChanges);
@@ -4655,7 +4642,6 @@ HTML;
if (static::IsCrudStackEmpty()) {
// Avoid signaling the current object that links were modified
static::RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
$this->LogCRUDDebug(__METHOD__, var_export(self::$aObjectsAwaitingEventDbLinksChanged, true));
static::FireEventDbLinksChangedForAllObjects();
}
}
@@ -4664,15 +4650,7 @@ HTML;
return $oDeletionPlan;
}
protected function PostDeleteActions(): void
{
parent::PostDeleteActions();
}
/**
* @deprecated 3.1.1 3.2.0 N°6967 We will have only one DBDelete method in the future
*/
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
{
// Invoke extensions before the deletion (the deletion will do some cleanup and we might loose some information
/** @var \iApplicationObjectExtension $oExtensionInstance */
@@ -4835,7 +4813,7 @@ HTML;
/**
* Special display where the case log uses the whole "screen" at the bottom of the "Properties" tab
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sAttCode
* @param string $sComment
* @param string $sPrefix
@@ -4939,7 +4917,7 @@ HTML
/**
* Special display where the case log uses the whole "screen" at the bottom of the "Properties" tab
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sAttCode
* @param string $sComment
* @param string $sPrefix
@@ -5064,7 +5042,7 @@ HTML
* Display a form for modifying several objects at once
* The form will be submitted to the current page, with the specified additional values
*
* @param iTopWebPage $oP
* @param \iTopWebPage $oP
* @param string $sClass
* @param array $aSelectedObj
* @param string $sCustomOperation
@@ -5308,7 +5286,7 @@ EOF
/**
* Process the reply made from a form built with DisplayBulkModifyForm
*
* @param WebPage $oP
* @param \WebPage $oP
* @param string $sClass
* @param array $aSelectedObj
* @param string $sCustomOperation
@@ -5364,7 +5342,7 @@ EOF
$aErrors = $oObj->UpdateObjectFromPostedForm('');
$bResult = (count($aErrors) == 0);
if ($bResult) {
[$bResult, $aErrors] = $oObj->CheckToWrite();
list($bResult, $aErrors) = $oObj->CheckToWrite();
}
if ($bPreview) {
$sStatus = $bResult ? Dict::S('UI:BulkModifyStatusOk') : Dict::S('UI:BulkModifyStatusError');
@@ -5381,11 +5359,6 @@ EOF
'errors' => '<p>'.($bResult ? '' : implode('</p><p>', $aErrorsToDisplay)).'</p>',
);
if ($bResult && (!$bPreview)) {
// doing the check will load multiple times same objects :/
// but it shouldn't cost too much on execution time
// user can mitigate by selecting less extkeys/lnk to set and/or less objects to update 🤷‍♂️
$oObj->CheckChangedExtKeysValues();
$oObj->DBUpdate();
}
}
@@ -5448,7 +5421,7 @@ EOF
/**
* Perform all the needed checks to delete one (or more) objects
*
* @param WebPage $oP
* @param \WebPage $oP
* @param $sClass
* @param \DBObject[] $aObjects
* @param $bPreview
@@ -5954,16 +5927,6 @@ JS
$this->FireEvent(EVENT_DB_CHECK_TO_DELETE, ['deletion_plan' => $oDeletionPlan]);
}
/**
* @return void
* @throws \CoreException
* @since 3.1.2
*/
final protected function FireEventAboutToDelete(): void
{
$this->FireEvent(EVENT_DB_ABOUT_TO_DELETE);
}
/**
* @return void
* @throws \CoreException
@@ -5973,63 +5936,47 @@ JS
final protected function FireEventAfterDelete(): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->FireEventDbLinksChangedForCurrentObject();
$this->FireEvent(EVENT_DB_AFTER_DELETE);
}
/**
* Possibility for linked classes to be notified of current class modification
*
* If the passed object is an instance of a link class, then will register each remote object for modification using {@see static::RegisterObjectAwaitingEventDbLinksChanged()}
* If an external key was modified, register also the previous object that was linked previously.
*
* @uses static::RegisterObjectAwaitingEventDbLinksChanged()
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \Exception
*
* @throws ArchivedObjectException
* @throws CoreException
* @throws Exception
*
* @since 3.1.0 N°5906 method creation
* @since 3.1.1 3.2.0 N°6228 now just notify attributes having `with_php_computation`
* @since 3.1.0 N°5906
*/
final protected function NotifyAttachedObjectsOnLinkClassModification(): void
{
$sClass = get_class($this);
if (false === MetaModel::IsLinkClass($sClass)) {
return;
}
// previous values in case of link change
$aPreviousValues = $this->ListPreviousValuesForUpdatedAttributes();
$sClass = get_class($this);
$aClassExtKeyAttCodes = MetaModel::GetAttributesList($sClass, [AttributeExternalKey::class]);
foreach ($aClassExtKeyAttCodes as $sExternalKeyAttCode) {
/** @var AttributeExternalKey $oAttDef */
$oAttDef = MetaModel::GetAttributeDef($sClass, $sExternalKeyAttCode);
if (false === $this->DoesTargetObjectHavePhpComputation($oAttDef)) {
continue;
$aLnkClassExternalKeys = MetaModel::GetAttributesList($sClass, [AttributeExternalKey::class]);
foreach ($aLnkClassExternalKeys as $sExternalKeyAttCode) {
/** @var \AttributeExternalKey $oExternalKeyAttDef */
$oExternalKeyAttDef = MetaModel::GetAttributeDef($sClass, $sExternalKeyAttCode);
$sRemoteClassName = $oExternalKeyAttDef->GetTargetClass();
$sRemoteObjectId = $this->Get($sExternalKeyAttCode);
if ($sRemoteObjectId > 0) {
self::RegisterObjectAwaitingEventDbLinksChanged($sRemoteClassName, $sRemoteObjectId);
}
$sTargetObjectId = $this->Get($sExternalKeyAttCode);
$sTargetClass = $oAttDef->GetTargetClass();
if ($sTargetObjectId > 0) {
$this->LogCRUDDebug(__METHOD__, "Add $sTargetClass:$sTargetObjectId for DBLINKS_CHANGED");
self::RegisterObjectAwaitingEventDbLinksChanged($sTargetClass, $sTargetObjectId);
}
$sPreviousTargetObjectId = $aPreviousValues[$sExternalKeyAttCode] ?? 0;
if ($sPreviousTargetObjectId > 0) {
$this->LogCRUDDebug(__METHOD__, "Add $sTargetClass:$sPreviousTargetObjectId for DBLINKS_CHANGED");
self::RegisterObjectAwaitingEventDbLinksChanged($sTargetClass, $sPreviousTargetObjectId);
$sPreviousRemoteObjectId = $aPreviousValues[$sExternalKeyAttCode] ?? 0;
if ($sPreviousRemoteObjectId > 0) {
self::RegisterObjectAwaitingEventDbLinksChanged($sRemoteClassName, $sPreviousRemoteObjectId);
}
}
}
private function DoesTargetObjectHavePhpComputation(AttributeExternalKey $oAttDef): bool
{
/** @var AttributeLinkedSet $oAttDefMirrorLink */
$oAttDefMirrorLink = $oAttDef->GetMirrorLinkAttribute();
if (is_null($oAttDefMirrorLink) || false === $oAttDefMirrorLink->HasPHPComputation()){
return false;
}
return true;
}
/**
* Register one object for later EVENT_DB_LINKS_CHANGED event.
*
@@ -6064,12 +6011,7 @@ JS
$sClass = get_class($this);
$sId = $this->GetKey();
$bIsObjectAwaitingEventDbLinksChanged = self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
if (false === $bIsObjectAwaitingEventDbLinksChanged) {
return;
}
self::FireEventDbLinksChangedForObject($this);
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
self::FireEventDbLinksChangedForClassId($sClass, $sId);
}
/**
@@ -6101,15 +6043,9 @@ JS
// We want to avoid launching the listener twice, first here, and secondly after saving the Ticket in the listener
// By disabling the event to be fired, we can remove the current object from the attribute !
$oObject = MetaModel::GetObject($sClass, $sId, false);
self::FireEventDbLinksChangedForObject($oObject);
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
}
private static function FireEventDbLinksChangedForObject(DBObject $oObject)
{
self::SetEventDBLinksChangedBlocked(true);
// N°6408 The object can have been deleted
if (!is_null($oObject)) {
self::SetEventDBLinksChangedBlocked(true);
MetaModel::StartReentranceProtection($oObject);
$oObject->FireEvent(EVENT_DB_LINKS_CHANGED);
MetaModel::StopReentranceProtection($oObject);
@@ -6117,6 +6053,7 @@ JS
$oObject->DBUpdate();
}
}
self::RemoveObjectAwaitingEventDbLinksChanged($sClass, $sId);
cmdbAbstractObject::SetEventDBLinksChangedBlocked(false);
}

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/CSVPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -9,8 +9,6 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'application/dashboardlayout.class.inc.php');
require_once(APPROOT.'application/dashlet.class.inc.php');
@@ -424,7 +422,7 @@ abstract class Dashboard
}
/**
* @param WebPage $oPage *
* @param \WebPage $oPage *
* @param array $aExtraParams
*
* @throws \ReflectionException
@@ -515,7 +513,7 @@ EOF
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
* @param bool $bCanEdit
@@ -571,7 +569,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
*
* @throws \ReflectionException
* @throws \Exception
@@ -594,7 +592,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
*/
public function RenderDashletsProperties(WebPage $oPage, $aExtraParams = array())
@@ -920,7 +918,7 @@ class RuntimeDashboard extends Dashboard
{
$bCustomized = false;
$sDashboardFileSanitized = utils::RealPath(APPROOT.$sDashboardFile, APPROOT);
$sDashboardFileSanitized = utils::RealPath($sDashboardFile, APPROOT);
if (false === $sDashboardFileSanitized) {
throw new SecurityException('Invalid dashboard file !');
}
@@ -1111,7 +1109,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
*
* @throws \Exception
@@ -1143,7 +1141,7 @@ JS
$oToolbar->AddSubBlock($oActionButton);
$aActions = array();
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
$sFile = addslashes($this->sDefinitionFile);
$sJSExtraParams = json_encode($aExtraParams);
if ($this->HasCustomDashboard()) {
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
@@ -1230,7 +1228,7 @@ EOF
/**
* @param WebPage $oPage
* @param \WebPage $oPage
*
* @param array $aExtraParams
*
@@ -1266,12 +1264,12 @@ EOF
$sOkButtonLabel = Dict::S('UI:Button:Save');
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$sId = utils::HtmlEntities($this->sId);
$sLayoutClass = utils::HtmlEntities($this->sLayoutClass);
$sId = addslashes($this->sId);
$sLayoutClass = addslashes($this->sLayoutClass);
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
$sAutoReloadSec = (string) $this->iAutoReloadSec;
$sTitle = utils::HtmlEntities($this->sTitle);
$sFile = utils::HtmlEntities($this->GetDefinitionFile());
$sTitle = addslashes($this->sTitle);
$sFile = addslashes($this->GetDefinitionFile());
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
$sReloadURL = $this->GetReloadURL();
@@ -1490,7 +1488,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $sOQL
*
* @throws \DictExceptionMissingString

View File

@@ -19,7 +19,6 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardColumn;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardRow;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Dashboard presentation
@@ -107,7 +106,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $aCells
* @param bool $bEditMode
* @param array $aExtraParams

View File

@@ -23,7 +23,6 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\UIBlock;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'application/forms.class.inc.php');
@@ -223,7 +222,7 @@ abstract class Dashlet
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode
* @param bool $bEnclosingDiv
* @param array $aExtraParams
@@ -299,7 +298,7 @@ EOF
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
*
@@ -310,7 +309,7 @@ EOF
/**
* Rendering without the real data
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode
* @param array $aExtraParams
*

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<classes>
<class id="AbstractResource" _delta="define">
<parent>cmdbAbstractObject</parent>
@@ -270,23 +270,6 @@
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_ABOUT_TO_DELETE" _delta="define">
<description>An object is about to be deleted from the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::OnDelete</replaces>
<event_data>
<event_datum id="object">
<description>The object about to be deleted</description>
<type>DBObject</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
<event id="EVENT_DB_AFTER_DELETE" _delta="define">
<description>An object has been deleted into the database</description>
<sources>
@@ -531,18 +514,10 @@
<description>The object containing the document</description>
<type>DBObject</type>
</event_datum>
<event_datum id="att_code">
<description>The optional object attribute code hosting the document</description>
<type>string</type>
</event_datum>
<event_datum id="document">
<description>The document downloaded</description>
<type>ormDocument</type>
</event_datum>
<event_datum id="content_disposition">
<description>The content disposition of the document ("inline" or "attachment")</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>

View File

@@ -1,7 +1,5 @@
<?php
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
/**
@@ -63,8 +61,8 @@ class DataTable
}
/**
* @param WebPage $oPage
* @param DataTableSettings $oSettings
* @param \WebPage $oPage
* @param \DataTableSettings $oSettings
* @param $bActionsMenu
* @param $sSelectMode
* @param $bViewLink
@@ -143,7 +141,7 @@ class DataTable
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $iPageSize
* @param $iDefaultPageSize
* @param $iPageIndex
@@ -238,7 +236,7 @@ class DataTable
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $sSelectMode
*
* @return string
@@ -257,7 +255,7 @@ class DataTable
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $iPageSize
* @param $iDefaultPageSize
* @param $iPageIndex
@@ -350,7 +348,7 @@ EOF;
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $aExtraParams
*
* @return string
@@ -377,7 +375,7 @@ EOF;
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $aExtraParams
*
* @return string
@@ -407,7 +405,7 @@ EOF;
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $aColumns
* @param $bViewLink
* @param $iDefaultPageSize
@@ -660,7 +658,7 @@ EOF;
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $aColumns
* @param $sSelectMode
* @param $iPageSize
@@ -792,7 +790,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $iDefaultPageSize
* @param $iStart
*/
@@ -820,7 +818,7 @@ JS
class PrintableDataTable extends DataTable
{
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $iPageSize
* @param $iDefaultPageSize
* @param $iPageIndex
@@ -846,7 +844,7 @@ class PrintableDataTable extends DataTable
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param $aColumns
* @param $sSelectMode
* @param $iPageSize

View File

@@ -24,8 +24,6 @@ use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxBars\BlockChartAjaxBa
use Combodo\iTop\Application\UI\DisplayBlock\BlockChartAjaxPie\BlockChartAjaxPie;
use Combodo\iTop\Application\UI\DisplayBlock\BlockCsv\BlockCsv;
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Router\Router;
require_once(APPROOT.'/application/utils.inc.php');
@@ -597,7 +595,7 @@ class DisplayBlock
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
*
* @throws \ApplicationException
@@ -1356,7 +1354,7 @@ JS
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
*
* @return \Combodo\iTop\Application\UI\Base\iUIBlock
@@ -1380,7 +1378,7 @@ JS
/**
* @param array $aExtraParams
* @param WebPage $oPage
* @param \WebPage $oPage
*
* @throws \ArchivedObjectException
* @throws \ConfigException
@@ -1458,7 +1456,7 @@ JS
/**
* @param array $aExtraParams
* @param WebPage $oPage
* @param \WebPage $oPage
*
* @return \Combodo\iTop\Application\UI\Base\Layout\UIContentBlock
* @throws \ApplicationException
@@ -1566,7 +1564,7 @@ JS
/**
* @deprecated 3.1.0 N°5957
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
*
* @return \Combodo\iTop\Application\UI\Base\Component\Html\Html|\Combodo\iTop\Application\UI\Base\Layout\UIContentBlock|string
@@ -1666,7 +1664,7 @@ JS
/**
* @param array $aExtraParams
* @param WebPage $oPage
* @param \WebPage $oPage
*
* @throws \ArchivedObjectException
* @throws \CoreException
@@ -1832,7 +1830,7 @@ class MenuBlock extends DisplayBlock
* an object in with the same tab active by default as the tab that was active when selecting
* the "Modify..." action.
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
* @param string|null $sId
*
@@ -2044,7 +2042,7 @@ class MenuBlock extends DisplayBlock
}
//----------------------------------------------------
// Any style but NOT \DisplayBlock::ENUM_STYLE_LIST_IN_OBJECT (linksets) actions
// Any style but NOT "listInObject" (linksets) actions
//----------------------------------------------------
if ($this->m_sStyle !== static::ENUM_STYLE_LIST_IN_OBJECT) {
switch ($iSetCount) {

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/ErrorPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -1,8 +1,4 @@
<?php
use Combodo\iTop\Application\WebPage\CLIPage;
use Combodo\iTop\Application\WebPage\Page;
require_once('xlsxwriter.class.php');
class ExcelExporter

View File

@@ -1,36 +0,0 @@
<?php
/**
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6458 object creation
*/
class InvalidExternalKeyValueException extends CoreUnexpectedValue
{
private const ENUM_PARAMS_OBJECT = 'current_object';
private const ENUM_PARAMS_ATTCODE = 'attcode';
private const ENUM_PARAMS_ATTVALUE = 'attvalue';
private const ENUM_PARAMS_USER = 'current_user';
public function __construct($oObject, $sAttCode, $aContextData = null, $oPrevious = null)
{
$aContextData[self::ENUM_PARAMS_OBJECT] = get_class($oObject) . '::' . $oObject->GetKey();
$aContextData[self::ENUM_PARAMS_ATTCODE] = $sAttCode;
$aContextData[self::ENUM_PARAMS_ATTVALUE] = $oObject->Get($sAttCode);
$oCurrentUser = UserRights::GetUserObject();
if (false === is_null($oCurrentUser)) {
$aContextData[self::ENUM_PARAMS_USER] = get_class($oCurrentUser) . '::' . $oCurrentUser->GetKey();
}
parent::__construct('Attribute pointing to an object that is either non existing or not readable by the current user', $aContextData, '', $oPrevious);
}
public function GetAttCode(): string
{
return $this->getContextData()[self::ENUM_PARAMS_ATTCODE];
}
public function GetAttValue(): string
{
return $this->getContextData()[self::ENUM_PARAMS_ATTVALUE];
}
}

View File

@@ -15,7 +15,6 @@
//
// 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\WebPage\WebPage;
/**
* Helper class to build interactive forms to be used either in stand-alone
@@ -829,7 +828,7 @@ class DesignerFormField
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param string $sFormId
* @param string $sRenderMode
*

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/iTopWizardWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -119,11 +119,6 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnConnected(&$iErrorCode)
{
Session::Unset('login_temp_auth_user');
if (is_null(UserRights::GetUserObject())){
//N°7085 avoid infinite loop
IssueLog::Error("No user logged in. exit");
exit(-1);
}
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
@@ -139,4 +134,4 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
}
}
}
}
}

View File

@@ -140,11 +140,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
$sResetPasswordUrl = MetaModel::GetConfig()->Get('forgot_password.url');
if ($sResetPasswordUrl == '')
{
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
}
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
$aData = array(
'bEnableResetPassword' => $bEnableResetPassword,
'sResetPasswordUrl' => $sResetPasswordUrl,

View File

@@ -9,7 +9,6 @@
use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\TwigBase\Twig\Extension;
use Combodo\iTop\Application\WebPage\NiceWebPage;
use Twig\Environment;
use Twig\Loader\ChainLoader;
use Twig\Loader\FilesystemLoader;

View File

@@ -26,8 +26,6 @@
use Combodo\iTop\Application\Branding;
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\NiceWebPage;
use Combodo\iTop\Service\Events\EventData;
use Combodo\iTop\Service\Events\EventService;
@@ -92,7 +90,7 @@ class LoginWebPage extends NiceWebPage
parent::__construct($sTitle);
$this->SetStyleSheet();
$this->no_cache();
$this->add_http_headers();
$this->add_xframe_options();
}
public function SetStyleSheet()
@@ -250,7 +248,6 @@ class LoginWebPage extends NiceWebPage
$oEmail = new Email();
$oEmail->SetRecipientTO($sTo);
$sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
$sFrom = utils::IsNullOrEmptyString($sFrom) ? MetaModel::GetConfig()->Get('email_default_sender_address') : $sFrom;
$oEmail->SetRecipientFrom($sFrom);
$oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject', $oUser->Get('login')));
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);

View File

@@ -22,7 +22,6 @@
// Maintenance message display functions
// Only included by approot.inc.php
//
use Combodo\iTop\Application\WebPage\ErrorPage;
/**
* Use a setup page to display the maintenance message

View File

@@ -5,9 +5,6 @@
*/
use Combodo\iTop\Application\Helper\WebResourcesHelper;
use Combodo\iTop\Application\WebPage\ErrorPage;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/utils.inc.php');
require_once(APPROOT.'/application/template.class.inc.php');
@@ -106,7 +103,7 @@ class ApplicationMenu
{
self::$sFavoriteSiloQuery = $sOQL;
}
/**
* Get the query used to limit the list of displayed organizations in the drop-down menu
* @return string The OQL query returning a list of Organization objects
@@ -348,7 +345,7 @@ class ApplicationMenu
/**
* Entry point to display the whole menu into the web page, used by iTopWebPage
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aExtraParams
* @throws DictExceptionMissingString
*
@@ -422,7 +419,7 @@ EOF
/**
* Handles the display of the sub-menus (called recursively if necessary)
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param array $aMenus
* @param array $aExtraParams
* @param int $iActiveMenu
@@ -539,7 +536,7 @@ EOF
return -1;
}
/**
* Retrieves the currently active menu (if any, otherwise the first menu is the default)
* @return string The Id of the currently active menu
@@ -547,7 +544,7 @@ EOF
public static function GetActiveNodeId()
{
$oAppContext = new ApplicationContext();
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
$sMenuId = $oAppContext->GetCurrentValue('menu', null);
if ($sMenuId === null)
{
$sMenuId = self::GetDefaultMenuId();
@@ -657,7 +654,7 @@ abstract class MenuNode
/**
* Stimulus to check: if the user can 'apply' this stimulus, then she/he can see this menu
*/
*/
protected $m_aEnableStimuli;
/**
@@ -817,7 +814,7 @@ abstract class MenuNode
{
return false;
}
/**
* Add a limiting display condition for the same menu node. The conditions will be combined with a AND
* @param $oMenuNode MenuNode Another definition of the same menu node, with potentially different access restriction
@@ -990,7 +987,7 @@ class TemplateMenuNode extends MenuNode
* @var string
*/
protected $sTemplateFile;
/**
* Create a menu item based on a custom template and inserts it into the application's main menu
* @param string $sMenuId Unique identifier of the menu (used to identify the menu for bookmarking, and for getting the labels from the dictionary)
@@ -1061,7 +1058,7 @@ class OQLMenuNode extends MenuNode
* @var bool|null
*/
protected $bSearchFormOpen;
/**
* Extra parameters to be passed to the display block to fine tune its appearence
*/
@@ -1094,7 +1091,7 @@ class OQLMenuNode extends MenuNode
// Enhancement: we could set as the "enable" condition that the user has enough rights to "read" the objects
// of the class specified by the OQL...
}
/**
* Set some extra parameters to be passed to the display block to fine tune its appearence
* @param array $aParams paramCode => value. See DisplayBlock::GetDisplay for the meaning of the parameters
@@ -1114,7 +1111,7 @@ class OQLMenuNode extends MenuNode
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
$oTag = new ContextTag(ContextTag::TAG_OBJECT_SEARCH);
ContextTag::AddContext(ContextTag::TAG_OBJECT_SEARCH);
ApplicationMenu::CheckMenuIdEnabled($this->GetMenuId());
OQLMenuNode::RenderOQLSearch
(
@@ -1123,7 +1120,7 @@ class OQLMenuNode extends MenuNode
'Menu_'.$this->GetMenuId(),
$this->bSearch, // Search pane
$this->bSearchFormOpen, // Search open
$oPage,
$oPage,
array_merge($this->m_aParams, $aExtraParams),
true
);
@@ -1357,10 +1354,10 @@ class NewObjectMenuNode extends MenuNode
{
// Enable this menu, only if the current user has enough rights to create such an object, or an object of
// any child class
$aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself
$bActionIsAllowed = false;
foreach($aSubClasses as $sCandidateClass)
{
if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES))
@@ -1369,7 +1366,7 @@ class NewObjectMenuNode extends MenuNode
break; // Enough for now
}
}
return $bActionIsAllowed;
return $bActionIsAllowed;
}
/**
@@ -1511,7 +1508,7 @@ class DashboardMenuNode extends MenuNode
throw new Exception("Error: failed to load dashboard file: '{$this->sDashboardFile}'");
}
}
}
/**
@@ -1552,7 +1549,7 @@ class ShortcutContainerMenuNode extends MenuNode
$sName = $this->GetMenuId().'_'.$oShortcut->GetKey();
new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
}
// Complete the tree
//
parent::PopulateChildMenus();

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/NiceWebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/PDFPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -21,7 +21,6 @@ use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\TextArea;
use Combodo\iTop\Application\WebPage\WebPage;
abstract class Query extends cmdbAbstractObject
{

View File

@@ -16,7 +16,6 @@
// 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\UI\Base\Component\DataTable\DataTableSettings;
use Combodo\iTop\Application\WebPage\WebPage;
/**

View File

@@ -17,9 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/displayblock.class.inc.php');
/**
* This class manages the special template format used internally to build the iTop web pages

View File

@@ -7,7 +7,6 @@
use Combodo\iTop\Application\Helper\FormHelper;
use Combodo\iTop\Application\UI\Base\Component\Form\FormUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
require_once(APPROOT.'/application/displayblock.class.inc.php');
@@ -66,7 +65,7 @@ class UIExtKeyWidget
//public function __construct($sAttCode, $sClass, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sNameSuffix = '', $sFieldPrefix = '', $sFormPrefix = '')
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sAttCode
* @param string $sClass
* @param string $sTitle
@@ -133,7 +132,7 @@ class UIExtKeyWidget
}
/**
* @param WebPage $oPage
* @param \WebPage $oPage
* @param int $iMaxComboLength
* @param bool $bAllowTargetCreation
* @param string $sTitle
@@ -164,7 +163,7 @@ class UIExtKeyWidget
$oPage->add_linked_script('../js/extkeywidget.js');
$oPage->add_linked_script('../js/forms-json-utils.js');
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_MODIFY) && $bAllowTargetCreation);
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
$bExtensions = true;
$sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
$sAttrFieldPrefix = ($this->bSearchMode) ? '' : 'attr_';
@@ -445,7 +444,7 @@ JS
/**
* Get the HTML fragment corresponding to the ext key editing widget
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param int $iMaxComboLength
* @param boolean $bAllowTargetCreation
* @param string $sTitle
@@ -976,10 +975,6 @@ HTML
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
FormHelper::DisableAttributeBlobInputs($this->sTargetClass, $aFormExtraParams);
if(FormHelper::HasMandatoryAttributeBlobInputs($oNewObj)){
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
}
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), $aFormExtraParams);
$oPage->add(<<<HTML
</div>

View File

@@ -16,7 +16,6 @@
// 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\WebResourcesHelper;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Class UIHTMLEditorWidget

View File

@@ -6,7 +6,6 @@
use Combodo\iTop\Application\Helper\FormHelper;
use Combodo\iTop\Application\UI\Links\Direct\BlockDirectLinkSetEditTable;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
/**
@@ -144,10 +143,6 @@ JS
// Remove blob edition from creation form @see N°5863 to allow blob edition in modal context
FormHelper::DisableAttributeBlobInputs($sRealClass, $aFormExtraParams);
if(FormHelper::HasMandatoryAttributeBlobInputs($oObj)){
$oPage->AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE));
}
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aFormExtraParams);
}

View File

@@ -8,8 +8,6 @@ use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory
use Combodo\iTop\Application\UI\Base\Component\DataTable\StaticTable\FormTableRow\FormTableRow;
use Combodo\iTop\Application\UI\Links\Indirect\BlockIndirectLinkSetEditTable;
use Combodo\iTop\Application\UI\Links\Indirect\BlockObjectPickerDialog;
use Combodo\iTop\Application\WebPage\JsonPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
require_once(APPROOT.'application/displayblock.class.inc.php');

View File

@@ -24,8 +24,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/displayblock.class.inc.php');
class UIPasswordWidget

View File

@@ -21,8 +21,6 @@
*/
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/displayblock.class.inc.php');
class UISearchFormForeignKeys

View File

@@ -15,7 +15,6 @@
//
// 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\WebPage\iTopWebPage;
/**

View File

@@ -20,8 +20,6 @@
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\Hook\iKeyboardShortcut;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Module\ModuleService;
use ScssPhp\ScssPhp\Compiler;
use ScssPhp\ScssPhp\OutputStyle;
@@ -54,31 +52,22 @@ class utils
{
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_INTEGER = 'integer';
/**
* Datamodel class
* @var string
* @since 2.7.10 3.0.0
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6606 update PHPDoc
* @uses MetaModel::IsValidClass()
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_CLASS = 'class';
/**
* @var string
* @since 2.7.10 3.0.4 3.1.1 3.2.0 N°6606
* @uses class_exists()
*/
public const ENUM_SANITIZATION_FILTER_PHP_CLASS = 'php_class';
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_STRING = 'string';
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_CONTEXT_PARAM = 'context_param';
/**
@@ -93,22 +82,22 @@ class utils
public const ENUM_SANITIZATION_FILTER_OPERATION = 'operation';
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_PARAMETER = 'parameter';
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_FIELD_NAME = 'field_name';
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_TRANSACTION_ID = 'transaction_id';
/**
* @var string For XML / HTML node identifiers
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER = 'element_identifier';
/**
@@ -118,13 +107,12 @@ class utils
public const ENUM_SANITIZATION_FILTER_VARIABLE_NAME = 'variable_name';
/**
* @var string
* @since 2.7.10 3.0.0
* @since 3.0.0
*/
public const ENUM_SANITIZATION_FILTER_RAW_DATA = 'raw_data';
/**
* @var string
* @since 3.0.2 3.1.0 N°4899
* @since 2.7.10 N°6606
* @since 3.0.2, 3.1.0 N°4899
*/
public const ENUM_SANITIZATION_FILTER_URL = 'url';
@@ -167,8 +155,6 @@ class utils
private static $iNextId = 0;
private static $m_sAppRootUrl = null;
protected static function LoadParamFile($sParamFile)
{
if (!file_exists($sParamFile)) {
@@ -410,10 +396,6 @@ class utils
* @since 2.7.0 new 'element_identifier' filter
* @since 3.0.0 new utils::ENUM_SANITIZATION_* const
* @since 2.7.7, 3.0.2, 3.1.0 N°4899 - new 'url' filter
* @since 2.7.10 N°6606 use the utils::ENUM_SANITIZATION_* const
* @since 2.7.10 N°6606 new case for ENUM_SANITIZATION_FILTER_PHP_CLASS
*
* @link https://www.php.net/manual/en/filter.filters.sanitize.php PHP sanitization filters
*/
protected static function Sanitize_Internal($value, $sSanitizationFilter)
{
@@ -434,13 +416,6 @@ class utils
$retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
break;
case static::ENUM_SANITIZATION_FILTER_PHP_CLASS:
$retValue = $value;
if (!class_exists($value)) {
$retValue = false;
}
break;
case static::ENUM_SANITIZATION_FILTER_CONTEXT_PARAM:
case static::ENUM_SANITIZATION_FILTER_ROUTE:
case static::ENUM_SANITIZATION_FILTER_OPERATION:
@@ -506,7 +481,6 @@ class utils
// For URL
case static::ENUM_SANITIZATION_FILTER_URL:
// N°6350 - returns only valid URLs
$retValue = filter_var($value, FILTER_VALIDATE_URL);
break;
@@ -1050,7 +1024,7 @@ class utils
*/
public static function GetAbsoluteUrlAppRoot($bForceTrustProxy = false)
{
$sUrl = static::$m_sAppRootUrl;
static $sUrl = null;
if ($sUrl === null || $bForceTrustProxy)
{
$sUrl = self::GetConfig()->Get('app_root_url');
@@ -1071,9 +1045,8 @@ class utils
}
$sUrl = str_replace(SERVER_NAME_PLACEHOLDER, $sServerName, $sUrl);
}
static::$m_sAppRootUrl = $sUrl;
}
return static::$m_sAppRootUrl;
return $sUrl;
}
/**
@@ -1455,7 +1428,7 @@ class utils
/**
* Merge standard menu items with plugin provided menus items
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param int $iMenuId
* @param \DBObjectSet $param
* @param array $aActions
@@ -2501,17 +2474,15 @@ SQL;
$aHeaders = static::ParseHeaders($http_response_header);
$sMimeType = array_key_exists('Content-Type', $aHeaders) ? strtolower($aHeaders['Content-Type']) : 'application/x-octet-stream';
// Compute the file extension from the MIME Type
foreach ($aKnownExtensions as $sExtValue => $sMime) {
if ($sMime === $sMimeType) {
foreach($aKnownExtensions as $sExtValue => $sMime)
{
if ($sMime === $sMimeType)
{
$sExtension = '.'.$sExtValue;
break;
}
}
}
$sPathName = pathinfo($sPath, PATHINFO_FILENAME);
if (utils::IsNotNullOrEmptyString($sPathName)) {
$sFileName = $sPathName;
}
$sFileName .= $sExtension;
}
$oUploadedDoc = new ormDocument($sData, $sMimeType, $sFileName);
@@ -2958,7 +2929,7 @@ HTML;
$aResultPref = [];
$aShortcutPrefs = appUserPreferences::GetPref('keyboard_shortcuts', []);
// Note: Mind the 4 blackslashes, see utils::GetClassesForInterface()
$aShortcutClasses = utils::GetClassesForInterface(iKeyboardShortcut::class, '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]'));
$aShortcutClasses = utils::GetClassesForInterface('iKeyboardShortcut', '', array('[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]', '[\\\\/]tests[\\\\/]'));
foreach ($aShortcutClasses as $cShortcutPlugin) {
$sTriggeredElement = $cShortcutPlugin::GetShortcutTriggeredElementSelector();
@@ -3033,7 +3004,6 @@ HTML;
*
* @return bool if string null or empty
* @since 3.0.2 N°5302
* @since 2.7.10 N°6458 add method in the 2.7 branch
*/
public static function IsNullOrEmptyString(?string $sString): bool
{
@@ -3049,7 +3019,6 @@ HTML;
*
* @return bool if string is not null and not empty
* @since 3.0.2 N°5302
* @since 2.7.10 N°6458 add method in the 2.7 branch
*/
public static function IsNotNullOrEmptyString(?string $sString): bool
{

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/WebPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -24,8 +24,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'/application/uiwizard.class.inc.php');
class WizardHelper
@@ -353,7 +351,6 @@ class WizardHelper
/**
* @return string JS code to be executed for fields update
* @since 3.0.0 N°3198
* @deprecated 3.0.3-2 3.0.4 3.1.1 3.2.0 Use {@see \WizardHelper::AddJsForUpdateFields()} instead
*/
public function GetJsForUpdateFields()
{
@@ -366,32 +363,6 @@ class WizardHelper
JS;
}
/**
* Add necessary JS snippets (to the page) to be executed for fields update
*
* @param WebPage $oPage
* @return void
* @since 3.0.3-2 3.0.4 3.1.1 3.2.0 N°6766
*/
public function AddJsForUpdateFields(WebPage $oPage)
{
$sWizardHelperJsVar = (!is_null($this->m_aData['m_sWizHelperJsVarName'])) ? utils::Sanitize($this->m_aData['m_sWizHelperJsVarName'], '', utils::ENUM_SANITIZATION_FILTER_PARAMETER) : 'oWizardHelper'.$this->GetFormPrefix();
$sWizardHelperJson = $this->ToJSON();
$oPage->add_script(<<<JS
{$sWizardHelperJsVar}.m_oData = {$sWizardHelperJson};
{$sWizardHelperJsVar}.UpdateFields();
JS
);
$oPage->add_ready_script(<<<JS
if ({$sWizardHelperJsVar}.m_oDependenciesUpdatedPromiseResolve !== null){
{$sWizardHelperJsVar}.m_oDependenciesUpdatedPromiseResolve();
}
JS
);
}
/*
* Function with an old pattern of code
* @deprecated 3.1.0
@@ -400,9 +371,11 @@ JS
{
$aSet = json_decode($sJsonSet, true); // true means hash array instead of object
$oSet = CMDBObjectSet::FromScratch($sLinkClass);
foreach ($aSet as $aLinkObj) {
foreach ($aSet as $aLinkObj)
{
$oLink = MetaModel::NewObject($sLinkClass);
foreach ($aLinkObj as $sAttCode => $value) {
foreach ($aLinkObj as $sAttCode => $value)
{
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
if (($oAttDef->IsExternalKey()) && ($value != '') && ($value > 0))
{

View File

@@ -1,6 +1,6 @@
<?php
/**
* @deprecated 3.0.0 will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
* @deprecated will be removed in 3.1.0 - moved to sources/Application/WebPage/XMLPage.php, now loadable using autoloader
* @license http://opensource.org/licenses/AGPL-3.0
* @copyright Copyright (C) 2010-2023 Combodo SARL
*/

View File

@@ -11,7 +11,7 @@ define('APPCONF', APPROOT.'conf/');
*
* @see ITOP_CORE_VERSION to get full iTop core version
*/
define('ITOP_DESIGN_LATEST_VERSION', '3.2');
define('ITOP_DESIGN_LATEST_VERSION', '3.1');
/**
* Constant containing the iTop core version, whatever application was built
@@ -23,13 +23,11 @@ define('ITOP_DESIGN_LATEST_VERSION', '3.2');
* @used-by utils::GetItopVersionWikiSyntax()
* @used-by iTopModulesPhpVersionIntegrationTest
*/
define('ITOP_CORE_VERSION', '3.2.0');
define('ITOP_CORE_VERSION', '3.1.0');
/**
* @var string
* @since 3.0.4 3.1.0 3.2.0 N°6274 Allow to test if PHPUnit is currently running. Starting with PHPUnit 9.5 we'll be able to replace it with $GLOBALS['phpunit_version']
* @since 3.0.4 3.1.1 3.2.0 N°6976 Fix constant name (DeprecatedCallsLog error handler was never set)
* @since 3.0.4 N°6274 Allow to test if PHPUnit is currently running. Starting with PHPUnit 9.5 we'll be able to replace it with $GLOBALS['phpunit_version']
*/
const ITOP_PHPUNIT_RUNNING_CONSTANT_NAME = 'ITOP_PHPUNIT_RUNNING';
define('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME', 'ITOP_PHPUNIT_RUNNING');
require_once APPROOT.'bootstrap.inc.php';

View File

@@ -4,7 +4,7 @@
"type": "project",
"license": "AGPL-3.0-only",
"require": {
"php": ">=8.1.0 <8.2.0",
"php": ">=7.4.0 <8.2.0",
"ext-ctype": "*",
"ext-dom": "*",
"ext-gd": "*",
@@ -23,24 +23,18 @@
"pear/archive_tar": "~1.4.14",
"pelago/emogrifier": "^6.0.0",
"scssphp/scssphp": "^1.10.3",
"symfony/console": "~6.4.0",
"symfony/dotenv": "~6.4.0",
"symfony/form": "~6.4.0",
"symfony/framework-bundle": "~6.4.0",
"symfony/http-foundation": "~6.4.0",
"symfony/http-kernel": "~6.4.0",
"symfony/runtime": "~6.4.0",
"symfony/serializer": "^6.4",
"symfony/twig-bundle": "~6.4.0",
"symfony/validator": "~6.4.0",
"symfony/var-dumper": "~6.4.0",
"symfony/yaml": "~6.4.0",
"symfony/console": "5.4.*",
"symfony/dotenv": "5.4.*",
"symfony/framework-bundle": "5.4.*",
"symfony/http-foundation": "5.4.*",
"symfony/http-kernel": "5.4.*",
"symfony/twig-bundle": "5.4.*",
"symfony/yaml": "5.4.*",
"thenetworg/oauth2-azure": "^2.0"
},
"require-dev": {
"symfony/stopwatch": "~6.4.0",
"symfony/web-profiler-bundle": "~6.4.0",
"symfony/debug-bundle": "~6.4.0"
"symfony/stopwatch": "5.4.*",
"symfony/web-profiler-bundle": "5.4.*"
},
"suggest": {
"ext-libsodium": "Required to use the AttributeEncryptedString.",
@@ -52,7 +46,7 @@
},
"config": {
"platform": {
"php": "8.1.0"
"php": "7.4.0"
},
"vendor-dir": "lib",
"preferred-install": {
@@ -60,10 +54,7 @@
},
"sort-packages": true,
"classmap-authoritative": true,
"platform-check": true,
"allow-plugins": {
"symfony/runtime": true
}
"platform-check": true
},
"autoload": {
"classmap": [
@@ -81,9 +72,6 @@
"application/logindefault.class.inc.php",
"application/loginexternal.class.inc.php",
"application/loginurl.class.inc.php"
],
"files": [
"sources/alias.php"
]
},
"conflict": {
@@ -93,9 +81,6 @@
"symfony": {
"allow-contrib": false,
"require": "3.4.*"
},
"runtime": {
"dotenv_path": "symfony/.env"
}
},
"scripts": {

2069
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -60,7 +60,6 @@ class DbConnectionWrapper
*
* @param \mysqli|null $oMysqli
* @since 3.0.4 3.1.1 3.2.0 Param $oMysqli becomes nullable
* @since 3.1.0-4 N°6848 backport of restoring cnx on null parameter value
*/
public static function SetDbConnectionMockForQuery(?mysqli $oMysqli = null): void
{

View File

@@ -17,7 +17,6 @@
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Persistent classes (internal): user defined actions
@@ -202,39 +201,12 @@ abstract class ActionNotification extends Action
MetaModel::Init_SetZListItems('details', array('name', 'description', 'status', 'trigger_list'));
// - Attributes to be displayed for a list
MetaModel::Init_SetZListItems('list', array('finalclass', 'description', 'status'));
MetaModel::Init_AddAttribute(new AttributeApplicationLanguage("language", array("sql"=>"language", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Search criteria
// - Criteria of the std search form
// MetaModel::Init_SetZListItems('standard_search', array('name'));
// - Default criteria of the search form
// MetaModel::Init_SetZListItems('default_search', array('name'));
}
/**
* @param $sLanguage
* @param $sLanguageCode
*
* @return array [$sPreviousLanguage, $aPreviousPluginProperties]
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \DictExceptionUnknownLanguage
* @since 3.2.0
*/
public function SetNotificationLanguage($sLanguage = null, $sLanguageCode = null){
$sPreviousLanguage = Dict::GetUserLanguage();
$aPreviousPluginProperties = ApplicationContext::GetPluginProperties('QueryLocalizerPlugin');
$sLanguage = $sLanguage ?? $this->Get('language');
$sLanguageCode = $sLanguageCode ?? $sLanguage;
if (!utils::IsNullOrEmptyString($sLanguage)) {
// If a language is specified for this action, force this language
// when rendering all placeholders inside this message
Dict::SetUserLanguage($sLanguage);
AttributeDateTime::LoadFormatFromConfig();
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $sLanguageCode);
}
return [$sPreviousLanguage, $aPreviousPluginProperties];
}
}
/**
@@ -301,6 +273,7 @@ class ActionEmail extends ActionNotification
MetaModel::Init_AddAttribute(new AttributeTemplateString("subject", array("allowed_values" => null, "sql" => "subject", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeTemplateHTML("body", array("allowed_values" => null, "sql" => "body", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("importance", array("allowed_values" => new ValueSetEnum('low,normal,high'), "sql" => "importance", "default_value" => 'normal', "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeApplicationLanguage("language", array("sql"=>"language", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeBlob("html_template", array("is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeEnum("ignore_notify", array("allowed_values" => new ValueSetEnum('yes,no'), "sql" => "ignore_notify", "default_value" => 'yes', "is_null_allowed" => false, "depends_on" => array())));
@@ -588,7 +561,15 @@ class ActionEmail extends ActionNotification
'attachments' => [],
];
$sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass();
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
$sPreviousLanguage = Dict::GetUserLanguage();
$aPreviousPluginProperties = ApplicationContext::GetPluginProperties('QueryLocalizerPlugin');
if ($this->Get('language') !== '') {
// If a language is specified for this action, force this language
// when rendering all placeholders inside this message
Dict::SetUserLanguage($this->Get('language'));
AttributeDateTime::LoadFormatFromConfig();
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $this->Get('language'));
}
try
{
@@ -620,7 +601,9 @@ class ActionEmail extends ActionNotification
}
finally {
ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker);
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
Dict::SetUserLanguage($sPreviousLanguage);
AttributeDateTime::LoadFormatFromConfig();
ApplicationContext::SetPluginProperty('QueryLocalizerPlugin', 'language_code', $aPreviousPluginProperties['language_code'] ?? null);
}
if (!is_null($oLog)) {

View File

@@ -6,7 +6,6 @@
use Combodo\iTop\Application\UI\Base\Component\FieldBadge\FieldBadgeUIBlockFactory;
use Combodo\iTop\Application\UI\Links\Set\BlockLinkSetDisplayAsProperty;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Form\Field\LabelField;
use Combodo\iTop\Form\Field\TextAreaField;
use Combodo\iTop\Form\Form;
@@ -92,12 +91,6 @@ define('LINKSET_EDITMODE_ACTIONS', 2); // Show the usual 'Actions' popup menu
define('LINKSET_EDITMODE_INPLACE', 3); // The "linked" objects can be created/modified/deleted in place
define('LINKSET_EDITMODE_ADDREMOVE', 4); // The "linked" objects can be added/removed in place
define('LINKSET_EDITWHEN_NEVER', 0); // The linkset cannot be edited at all from inside this object
define('LINKSET_EDITWHEN_ON_HOST_EDITION', 1); // The only possible action is to open a new window to create a new object
define('LINKSET_EDITWHEN_ON_HOST_DISPLAY', 2); // Show the usual 'Actions' popup menu
define('LINKSET_EDITWHEN_ALWAYS', 3); // Show the usual 'Actions' popup menu
define('LINKSET_DISPLAY_STYLE_PROPERTY', 'property');
define('LINKSET_DISPLAY_STYLE_TAB', 'tab');
@@ -798,7 +791,7 @@ abstract class AttributeDefinition
public function HasAValue($proposedValue): bool
{
// Default implementation, we don't really know what type $proposedValue will be
return !(is_null($proposedValue));
return is_null($proposedValue);
}
/**
@@ -1710,15 +1703,6 @@ class AttributeLinkedSet extends AttributeDefinition
public function GetEditMode()
{
return $this->GetOptional('edit_mode', LINKSET_EDITMODE_ACTIONS);
}
/**
* @return int see LINKSET_EDITWHEN_* constants
* @since 3.1.1 3.2.0 N°6385
*/
public function GetEditWhen(): int
{
return $this->GetOptional('edit_when', LINKSET_EDITWHEN_ALWAYS);
}
/**
@@ -1740,20 +1724,11 @@ class AttributeLinkedSet extends AttributeDefinition
* @return bool true if Attribute has constraints
* @since 3.1.0 N°6228
*/
public function HasPHPConstraint(): bool
public function GetHasConstraint()
{
return $this->GetOptional('with_php_constraint', false);
}
/**
* @return bool true if Attribute has computation (DB_LINKS_CHANGED event propagation, `with_php_computation` attribute xml property), false otherwise
* @since 3.1.1 3.2.0 N°6228
*/
public function HasPHPComputation(): bool
{
return $this->GetOptional('with_php_computation', false);
}
public function GetLinkedClass()
{
return $this->Get('linked_class');
@@ -8609,7 +8584,7 @@ class AttributeBlob extends AttributeDefinition
public function RecordAttChange(DBObject $oObject, $original, $value): void
{
// N°6502 Don't record history if only the download count has changed
if ((null !== $original) && (null !== $value) && $original->EqualsExceptDownloadsCount($value)) {
if ($original->EqualsExceptDownloadsCount($value)) {
return;
}
@@ -12997,7 +12972,7 @@ class AttributeRedundancySettings extends AttributeDBField
* Display an option (form, or current value)
*
* @param string $sCurrentValue
* @param WebPage $oPage
* @param \WebPage $oPage
* @param string $sFormPrefix
* @param bool $bEditMode
* @param string $sUserOption

View File

@@ -25,7 +25,6 @@ MetaModel::IncludeModule('application/audit.domain.class.inc.php');
MetaModel::IncludeModule('application/query.class.inc.php');
MetaModel::IncludeModule('setup/moduleinstallation.class.inc.php');
MetaModel::IncludeModule('core/event.class.inc.php');
MetaModel::IncludeModule('core/action.class.inc.php');
MetaModel::IncludeModule('core/trigger.class.inc.php');

View File

@@ -6,9 +6,6 @@
// The BOM is added at the head of exported UTF-8 CSV data, and removed (if present) from input UTF-8 data.
// This helps MS-Excel (Version > 2007, Windows only) in changing its interpretation of a CSV file (by default Excel reads data as ISO-8859-1 -not 100% sure!)
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
define('UTF8_BOM', chr(239).chr(187).chr(191)); // 0xEF, 0xBB, 0xBF

View File

@@ -17,9 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
define('EXPORTER_DEFAULT_CHUNK_SIZE', 1000);
class BulkExportException extends Exception
@@ -152,9 +149,7 @@ abstract class BulkExport
$this->oSearch = null;
$this->iChunkSize = 0;
$this->sFormatCode = null;
$this->aStatusInfo = [
'show_obsolete_data' => utils::ShowObsoleteData(),
];
$this->aStatusInfo = array();
$this->oBulkExportResult = null;
$this->sTmpFile = '';
$this->bLocalizeOutput = false;
@@ -208,17 +203,15 @@ abstract class BulkExport
if ($oInfo && ($oInfo->Get('user_id') == UserRights::GetUserId()))
{
$sFormatCode = $oInfo->Get('format');
$aStatusInfo = json_decode($oInfo->Get('status_info'),true);
$oSearch = DBObjectSearch::unserialize($oInfo->Get('search'));
$oSearch->SetShowObsoleteData($aStatusInfo['show_obsolete_data']);
$oBulkExporter = self::FindExporter($sFormatCode, $oSearch);
if ($oBulkExporter)
{
$oBulkExporter->SetFormat($sFormatCode);
$oBulkExporter->SetObjectList($oSearch);
$oBulkExporter->SetChunkSize($oInfo->Get('chunk_size'));
$oBulkExporter->SetStatusInfo($aStatusInfo);
$oBulkExporter->SetStatusInfo(json_decode($oInfo->Get('status_info'), true));
$oBulkExporter->SetLocalizeOutput($oInfo->Get('localize_output'));
@@ -296,7 +289,6 @@ abstract class BulkExport
*/
public function SetObjectList(DBSearch $oSearch)
{
$oSearch->SetShowObsoleteData($this->aStatusInfo['show_obsolete_data']);
$this->oSearch = $oSearch;
}
@@ -394,7 +386,7 @@ abstract class BulkExport
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -438,8 +438,7 @@ abstract class CMDBObject extends DBObject
}
/**
* @deprecated 3.1.0 N°5232 N°6966 simply use {@see DBObject::DBClone()} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
* @deprecated 3.1.0 N°5232 not used
*/
public function DBCloneTracked(CMDBChange $oChange, $newKey = null)
{
@@ -447,9 +446,6 @@ abstract class CMDBObject extends DBObject
$this->DBCloneTracked_Internal($newKey);
}
/**
* @deprecated 3.1.1 3.2.0 N°6966 We will have only one DBClone method in the future
*/
protected function DBCloneTracked_Internal($newKey = null)
{
$newKey = parent::DBClone($newKey);
@@ -474,13 +470,23 @@ abstract class CMDBObject extends DBObject
public function DBDelete(&$oDeletionPlan = null)
{
$this->LogCRUDEnter(__METHOD__);
$oDeletionPlan = parent::DBDelete($oDeletionPlan);
$oDeletionPlan = $this->DBDeleteTracked_Internal($oDeletionPlan);
$this->LogCRUDExit(__METHOD__);
return $oDeletionPlan;
}
/**
* @deprecated 3.1.1 3.2.0 N°6967 We will have only one DBDelete method in the future
* @param null $oDeletionPlan
*
* @return \DeletionPlan|null
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \DeleteException
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
protected function DBDeleteTracked_Internal(&$oDeletionPlan = null)
{

View File

@@ -3,7 +3,7 @@
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// 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.
@@ -42,12 +42,6 @@ class CMDBSource
const ENUM_DB_VENDOR_MARIADB = 'MariaDB';
const ENUM_DB_VENDOR_PERCONA = 'Percona';
/**
* @since 2.7.10 3.0.4 3.1.2 3.0.2 N°6889 constant creation
* @internal will be removed in a future version
*/
const MYSQL_DEFAULT_PORT = 3306;
/**
* Error: 1205 SQLSTATE: HY000 (ER_LOCK_WAIT_TIMEOUT)
* Message: Lock wait timeout exceeded; try restarting transaction
@@ -218,19 +212,16 @@ class CMDBSource
/**
* @param string $sDbHost initial value ("p:domain:port" syntax)
* @param string $sServer server variable to update
* @param int|null $iPort port variable to update, will return null if nothing is specified in $sDbHost
*
* @since 2.7.10 3.0.4 3.1.2 3.2.0 N°6889 will return null in $iPort if port isn't present in $sDbHost. Use {@see MYSQL_DEFAULT_PORT} if needed
*
* @link http://php.net/manual/en/mysqli.persistconns.php documentation for the "p:" prefix (persistent connexion)
* @param int $iPort port variable to update
*/
public static function InitServerAndPort($sDbHost, &$sServer, &$iPort)
{
$aConnectInfo = explode(':', $sDbHost);
$bUsePersistentConnection = false;
if (strcasecmp($aConnectInfo[0], 'p') === 0)
if (strcasecmp($aConnectInfo[0], 'p') == 0)
{
// we might have "p:" prefix to use persistent connections (see http://php.net/manual/en/mysqli.persistconns.php)
$bUsePersistentConnection = true;
$sServer = $aConnectInfo[0].':'.$aConnectInfo[1];
}
@@ -248,6 +239,10 @@ class CMDBSource
{
$iPort = (int)($aConnectInfo[1]);
}
else
{
$iPort = 3306;
}
}
/**
@@ -385,7 +380,7 @@ class CMDBSource
public static function GetDBVendor()
{
$sDBVendor = static::ENUM_DB_VENDOR_MYSQL;
$sVersionComment = static::GetServerVariable('version') . ' - ' . static::GetServerVariable('version_comment');
if(preg_match('/mariadb/i', $sVersionComment) === 1)
{
@@ -395,7 +390,7 @@ class CMDBSource
{
$sDBVendor = static::ENUM_DB_VENDOR_PERCONA;
}
return $sDBVendor;
}
@@ -939,7 +934,7 @@ class CMDBSource
{
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
}
while ($aRow = $oResult->fetch_array($iMode))
{
$aData[] = $aRow;
@@ -1093,7 +1088,7 @@ class CMDBSource
if (!array_key_exists($iKey, $aTableInfo["Fields"])) return false;
$aFieldData = $aTableInfo["Fields"][$iKey];
if (!array_key_exists("Key", $aFieldData)) return false;
return ($aFieldData["Key"] == "PRI");
return ($aFieldData["Key"] == "PRI");
}
public static function IsAutoIncrement($sTable, $sField)
@@ -1104,7 +1099,7 @@ class CMDBSource
$aFieldData = $aTableInfo["Fields"][$sField];
if (!array_key_exists("Extra", $aFieldData)) return false;
//MyHelpers::debug_breakpoint($aFieldData);
return (strstr($aFieldData["Extra"], "auto_increment"));
return (strstr($aFieldData["Extra"], "auto_increment"));
}
public static function IsField($sTable, $sField)
@@ -1371,13 +1366,13 @@ class CMDBSource
public static function GetTableFieldsList($sTable)
{
assert(!empty($sTable));
$aTableInfo = self::GetTableInfo($sTable);
if (empty($aTableInfo)) return array(); // #@# or an error ?
return array_keys($aTableInfo["Fields"]);
}
// Cache the information about existing tables, and their fields
private static $m_aTablesInfo = array();
private static function _TablesInfoCacheReset($sTableName = null)
@@ -1510,7 +1505,7 @@ class CMDBSource
{
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql));
}
$aRows = array();
while ($aRow = $oResult->fetch_array(MYSQLI_ASSOC))
{
@@ -1519,7 +1514,7 @@ class CMDBSource
$oResult->free();
return $aRows;
}
/**
* Returns the value of the specified server variable
* @param string $sVarName Name of the server variable
@@ -1535,7 +1530,7 @@ class CMDBSource
/**
* Returns the privileges of the current user
* @return string privileges in a raw format
*/
*/
public static function GetRawPrivileges()
{
try
@@ -1561,8 +1556,8 @@ class CMDBSource
/**
* Determine the slave status of the server
* @return bool true if the server is slave
*/
* @return bool true if the server is slave
*/
public static function IsSlaveServer()
{
try

View File

@@ -29,7 +29,7 @@ define('ITOP_APPLICATION_SHORT', 'iTop');
*
* @see ITOP_CORE_VERSION to get iTop core version
*/
define('ITOP_VERSION', '3.2.0-dev');
define('ITOP_VERSION', '3.1.1-dev');
define('ITOP_VERSION_NAME', 'Fullmoon');
define('ITOP_REVISION', 'svn');
@@ -889,14 +889,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'forgot_password.url' => [
'type' => 'string',
'description' => 'Set this value to your "forgot password" service URL if it should be handled out of '.ITOP_APPLICATION_SHORT.'. Note that it will apply to all users (iTop users, LDAP users, ...)',
'default' => '',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'deadline_format' => [
'type' => 'string',
'description' => 'The format used for displaying "deadline" attributes: any string with the following placeholders: $date$, $difference$',
@@ -1201,30 +1193,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.enabled' => [
'type' => 'bool',
'description' => 'Whether or not the whole mechanism to track active sessions is enabled. See PHP session.gc_maxlifetime setting to configure session expiration.',
'default' => false,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.gc_threshold' => [
'type' => 'integer',
'description' => 'fallback in case cron is not active: probability in percent that session files are cleanup during any itop request (100 means always)',
'default' => 1,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'sessions_tracking.gc_duration_in_seconds' => [
'type' => 'integer',
'description' => 'fallback in case cron is not active: when a cleanup is triggered cleanup duration will not exceed this duration (in seconds).',
'default' => 1,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'transaction_storage' => [
'type' => 'string',
'description' => 'The type of mechanism to use for storing the unique identifiers for transactions (Session|File).',
@@ -1603,22 +1571,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'notifications.itop.read_notification_retention' => [
'type' => 'integer',
'description' => 'Duration in days after which iTop read notifications will be deleted',
'default' => 182,
'value' => 182,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'notifications.itop.newsroom_cache_time' => [
'type' => 'integer',
'description' => 'Duration in min between each fetch for notifications in newsroom',
'default' => 5,
'value' => 5,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'regenerate_session_id_enabled' => [
'type' => 'bool',
'description' => 'If true then session id will be regenerated on each login, to prevent session fixation.',
@@ -1667,14 +1619,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'security.enable_header_xcontent_type_options' => [
'type' => 'bool',
'description' => 'If set to false, iTop will stop sending the X-Content-Type-Options HTTP header. This header could trigger CORB protection on certain resources (JSON, XML, HTML, text) therefore blocking them.',
'default' => true,
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'security.disable_inline_documents_sandbox' => [
'type' => 'bool',
'description' => 'If true then the sandbox for documents displayed in a browser tab will be disabled; enabling scripts and other interactive content. Note that setting this to true will open the application to potential XSS attacks!',
@@ -1739,14 +1683,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'application.secret' => [
'type' => 'string',
'description' => 'Application secret, uses this value for encrypting the cookies used in the remember me functionality and for creating signed URIs when using ESI (Edge Side Includes).',
'default' => '',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
];
public function IsProperty($sPropCode)
@@ -1926,15 +1862,6 @@ class Config
*/
protected $m_iPasswordHashAlgo;
/**
* Symfony uses this value for encrypting the cookies used in the remember me functionality and for creating signed URIs when using ESI (Edge Side Includes).
*
* @see https://symfony.com/doc/current/reference/configuration/framework.html#secret
* @since 3.2.0 - N°6934 - Symfony 6.4 - upgrade Symfony bundles to 6.4
* @var string
*/
protected $m_sAppSecret;
/**
* Config constructor.
*
@@ -1979,7 +1906,6 @@ class Config
$this->m_aCharsets = array();
$this->m_bQueryCacheEnabled = DEFAULT_QUERY_CACHE_ENABLED;
$this->m_iPasswordHashAlgo = DEFAULT_HASH_ALGO;
$this->m_sAppSecret = bin2hex(random_bytes(16));
//define default encryption params according to php install
$aEncryptParams = SimpleCrypt::GetNewDefaultParams();
@@ -2140,7 +2066,6 @@ class Config
$this->m_sEncryptionLibrary = isset($MySettings['encryption_library']) ? trim($MySettings['encryption_library']) : $this->m_sEncryptionLibrary;
$this->m_aCharsets = isset($MySettings['csv_import_charsets']) ? $MySettings['csv_import_charsets'] : array();
$this->m_iPasswordHashAlgo = isset($MySettings['password_hash_algo']) ? $MySettings['password_hash_algo'] : $this->m_iPasswordHashAlgo;
$this->m_sAppSecret = isset($MySettings['application.secret']) ? trim($MySettings['application.secret']) : $this->m_sAppSecret;
}
protected function Verify()
@@ -2276,11 +2201,6 @@ class Config
return $this->m_sEncryptionKey;
}
public function GetAppSecret()
{
return $this->m_sAppSecret;
}
public function GetEncryptionLibrary()
{
return $this->m_sEncryptionLibrary;
@@ -2369,24 +2289,6 @@ class Config
$this->m_sAllowedLoginTypes = implode('|', $aAllowedLoginTypes);
}
/**
* @since 2.7.11 N°7085
* Add login mode if not configured already
* @param string $sLoginMode
*
* @return void
*/
public function AddAllowedLoginTypes($sLoginMode)
{
$aAllowedLoginTypes = $this->GetAllowedLoginTypes();
if (in_array($sLoginMode, $aAllowedLoginTypes)){
return;
}
$aAllowedLoginTypes[] = $sLoginMode;
$this->SetAllowedLoginTypes($aAllowedLoginTypes);
}
public function SetExternalAuthenticationVariable($sExtAuthVariable)
{
$this->m_sExtAuthVariable = $sExtAuthVariable;
@@ -2397,12 +2299,6 @@ class Config
$this->m_sEncryptionKey = $sKey;
}
public function SetAppSecret($sKey)
{
$this->m_sAppSecret = $sKey;
}
public function SetCSVImportCharsets($aCharsets)
{
$this->m_aCharsets = $aCharsets;
@@ -2454,7 +2350,6 @@ class Config
$aSettings['encryption_library'] = $this->m_sEncryptionLibrary;
$aSettings['csv_import_charsets'] = $this->m_aCharsets;
$aSettings['password_hash_algo'] = $this->m_iPasswordHashAlgo;
$aSettings['application.secret'] = $this->m_sAppSecret;
foreach ($this->m_aModuleSettings as $sModule => $aProperties)
{
@@ -2567,8 +2462,7 @@ class Config
'encryption_key' => $this->m_sEncryptionKey,
'encryption_library' => $this->m_sEncryptionLibrary,
'csv_import_charsets' => $this->m_aCharsets,
'password_hash_algo' => $this->m_iPasswordHashAlgo,
'application.secret' => $this->m_sAppSecret,
'password_hash_algo' => $this->m_iPasswordHashAlgo
);
foreach ($aOtherValues as $sKey => $value)
{

View File

@@ -8,13 +8,10 @@ use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\Helper\ExportHelper;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: CSV export
@@ -103,7 +100,7 @@ class CSVBulkExport extends TabularBulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
@@ -117,7 +114,6 @@ class CSVBulkExport extends TabularBulkExport
case 'csv_options':
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:CSVOptions'));
$oPanel->AddSubBlock(ExportHelper::GetAlertForExcelMaliciousInjection());
$oMulticolumn = MultiColumnUIBlockFactory::MakeStandard();
$oPanel->AddSubBlock($oMulticolumn);

View File

@@ -1,268 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<classes>
<class id="ActioniTopNotification" _delta="define">
<php_parent>
<name>ActionNotification</name>
</php_parent>
<parent>cmdbAbstractObject</parent>
<properties>
<category>grant_by_profile,core/cmdb,application</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_action_itop_notif</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="title"/>
</attributes>
</naming>
</properties>
<fields>
<field id="title" xsi:type="AttributeString">
<sql>title</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="message" xsi:type="AttributeText">
<sql>message</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="icon" xsi:type="AttributeImage">
<sql>icon</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<display_max_width>96</display_max_width>
<display_max_height>96</display_max_height>
<storage_max_width>256</storage_max_width>
<storage_max_height>256</storage_max_height>
<default_image>null</default_image>
</field>
<field id="priority" xsi:type="AttributeEnum">
<sql>priority</sql>
<values>
<value id="1">
<code>1</code>
</value>
<value id="2">
<code>2</code>
</value>
<value id="3">
<code>3</code>
</value>
<value id="4">
<code>4</code>
</value>
</values>
<default_value>4</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="recipients" xsi:type="AttributeOQL">
<sql>recipients</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="url" xsi:type="AttributeString">
<sql>url</sql>
<default_value>$this->url()$</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
</fields>
<presentation>
<details>
<items>
<item id="col:col1">
<items>
<item id="fieldset:ActioniTopNotification:content">
<items>
<item id="name">
<rank>10</rank>
</item>
<item id="status">
<rank>20</rank>
</item>
<item id="language">
<rank>30</rank>
</item>
<item id="title">
<rank>40</rank>
</item>
<item id="message">
<rank>50</rank>
</item>
</items>
</item>
</items>
</item>
<item id="col:col2">
<items>
<item id="fieldset:ActioniTopNotification:settings">
<items>
<item id="priority">
<rank>10</rank>
</item>
<item id="icon">
<rank>20</rank>
</item>
<item id="recipients">
<rank>30</rank>
</item>
<item id="url">
<rank>40</rank>
</item>
</items>
</item>
</items>
</item>
</items>
</details>
<list>
<items>
<item id="title">
<rank>10</rank>
</item>
<item id="status">
<rank>20</rank>
</item>
<item id="language">
<rank>30</rank>
</item>
</items>
</list>
</presentation>
<methods>
<method id="DoExecute">
<comment> /**
*
* Create EventiTopNotification for each recipient
* @param $oTrigger
* @param $aContextArgs
*
* @return void
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MySQLException
* @throws \OQLException
*/</comment>
<static>false</static>
<access>public</access>
<code><![CDATA[
public function DoExecute($oTrigger, $aContextArgs)
{
$oRecipientsSearch = DBObjectSearch::FromOQL($this->Get('recipients'));
$oRecipientsSearch->AllowAllData();
$oRecipientsSet = new DBObjectSet($oRecipientsSearch);
[$sPreviousLanguage, $aPreviousPluginProperties] = $this->SetNotificationLanguage();
while ($oRecipient = $oRecipientsSet->Fetch()) {
$oEvent = new EventiTopNotification();
$oEvent->Set('title', MetaModel::ApplyParams($this->Get('title'), $aContextArgs));
$oEvent->Set('message', MetaModel::ApplyParams($this->Get('message'), $aContextArgs));
$oIcon = !$this->Get('icon')->IsEmpty() ? $this->Get('icon') : MetaModel::GetAttributeDef('EventiTopNotification', 'icon')->MakeRealValue(Combodo\iTop\Application\Branding::GetCompactMainLogoAbsoluteUrl(), $oEvent);
$oEvent->Set('icon', $oIcon);
$oEvent->Set('priority', $this->Get('priority'));
$oEvent->Set('contact_id', $oRecipient->GetKey());
$oEvent->Set('trigger_id', $oTrigger->GetKey());
$oEvent->Set('action_id', $this->GetKey());
$iObjectId = array_key_exists('this->object()', $aContextArgs) ? $aContextArgs['this->object()']->GetKey() : 0;
$oEvent->Set('object_id', $iObjectId);
$oEvent->Set('url', MetaModel::ApplyParams($this->Get('url'), $aContextArgs));
$oEvent->DBInsertNoReload();
}
$this->SetNotificationLanguage($sPreviousLanguage, $aPreviousPluginProperties['language_code'] ?? null);
}
]]></code>
</method>
</methods>
</class>
<class id="EventiTopNotification" _delta="define">
<php_parent>
<name>EventNotification</name>
</php_parent>
<parent>cmdbAbstractObject</parent>
<properties>
<category>core/cmdb,view_in_gui</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>priv_event_itop_notif</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="title"/>
</attributes>
</naming>
</properties>
<fields>
<field id="title" xsi:type="AttributeString">
<sql>title</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="icon" xsi:type="AttributeImage">
<sql>icon</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<default_image>null</default_image>
</field>
<field id="priority" xsi:type="AttributeEnum">
<sql>priority</sql>
<values>
<value id="1">
<code>1</code>
</value>
<value id="2">
<code>2</code>
</value>
<value id="3">
<code>3</code>
</value>
<value id="4">
<code>4</code>
</value>
</values>
<default_value>4</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="url" xsi:type="AttributeURL">
<sql>url</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
<target>_blank</target>
</field>
<field id="read" xsi:type="AttributeEnum">
<sql>read</sql>
<values>
<value id="yes">
<code>yes</code>
</value>
<value id="no">
<code>no</code>
</value>
</values>
<default_value>no</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="read_date" xsi:type="AttributeDateTime">
<sql>read_date</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="contact_id" xsi:type="AttributeExternalKey">
<sql>contact_id</sql>
<target_class>Contact</target_class>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
</fields>
<presentation/>
<methods/>
</class>
</classes>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<user_rights>
<profiles>
<profile id="1024" _delta="define">
@@ -545,50 +282,8 @@
<field id="obj_attcode" xsi:type="AttributeString"/>
</fields>
</class>
<class id="DefaultWorkingTimeComputer" _delta="define">
<interfaces>
<interface id="iWorkingTimeComputer"/>
</interfaces>
</class>
<class id="ActionNotification" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>Action</parent>
<properties>
<category>grant_by_profile,core/cmdb</category>
</properties>
<fields>
<field id="name" xsi:type="AttributeString"/>
<field id="description" xsi:type="AttributeString"/>
<field id="status" xsi:type="AttributeEnum"/>
<field id="trigger_list" xsi:type="AttributeLinkedSetIndirect"/>
<field id="language" xsi:type="AttributeApplicationLanguage"/>
</fields>
</class>
<class id="EventNotification" _delta="define">
<!-- Generated by toolkit/export-class-to-meta.php -->
<parent>Event</parent>
<properties>
<category>core/cmdb,view_in_gui</category>
</properties>
<fields>
<field id="message" xsi:type="AttributeText"/>
<field id="date" xsi:type="AttributeDateTime"/>
<field id="userinfo" xsi:type="AttributeString"/>
<field id="trigger_id" xsi:type="AttributeExternalKey">
<target_class>Trigger</target_class>
</field>
<field id="action_id" xsi:type="AttributeExternalKey">
<target_class>Action</target_class>
</field>
<field id="object_id" xsi:type="AttributeInteger"/>
<field id="trigger_id_friendlyname" xsi:type="AttributeExternalField"/>
<field id="trigger_id_finalclass_recall" xsi:type="AttributeExternalField"/>
<field id="action_id_friendlyname" xsi:type="AttributeExternalField"/>
<field id="action_id_finalclass_recall" xsi:type="AttributeExternalField"/>
</fields>
</class>
</classes>
<attribute_properties_definition _delta="define">
<attribute_properties_definition _delta="define">
<properties>
<property id="sql">
<php_param>sql</php_param>
@@ -807,12 +502,6 @@
<type>boolean</type>
<default>false</default>
</property>
<property id="with_php_computation">
<php_param>with_php_computation</php_param>
<mandatory>false</mandatory>
<type>boolean</type>
<default>false</default>
</property>
<property id="create_temporary_object">
<php_param>create_temporary_object</php_param>
<mandatory>false</mandatory>

File diff suppressed because it is too large Load Diff

View File

@@ -16,14 +16,8 @@
// 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\WebResourcesHelper;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\MedallionIcon\MedallionIcon;
use Combodo\iTop\Application\UI\Base\Component\Panel\Panel;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\iTopPDF;
use Combodo\iTop\Application\WebPage\PDFPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
/**
@@ -65,7 +59,7 @@ class DisplayableNode extends GraphNode
public function GetWidth()
{
return max(32, 5 * mb_strlen($this->GetProperty('label'))); // approximation of the text's bounding box
return max(32, 5*strlen($this->GetProperty('label'))); // approximation of the text's bounding box
}
public function GetHeight()
@@ -494,7 +488,7 @@ class DisplayableNode extends GraphNode
if ($bNoLabel)
{
// simulate a fake label with the approximate same size as the true label
$sLabel = str_repeat('x', mb_strlen($this->GetProperty('label', $this->GetId())));
$sLabel = str_repeat('x',strlen($this->GetProperty('label', $this->GetId())));
$sDot = 'label="'.$sLabel.'"';
}
else
@@ -1418,8 +1412,6 @@ class DisplayableGraph extends SimpleGraph
/**
* Display the graph inside the given page, with the "filter" drawer above it
*
* @deprecated 3.1.1 3.2.0 N°3767 Use \DisplayableGraph::DisplayFilterBox() and \DisplayableGraph::DisplayGraph() instead
*
* @param WebPage $oP
* @param array $aResults
* @param string $sRelation
@@ -1433,35 +1425,10 @@ class DisplayableGraph extends SimpleGraph
*
* @throws \CoreException
* @throws \DictExceptionMissingString
*
*/
function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array(), bool $bLazyLoading = false)
{
$oP->AddSubBlock($this->DisplayFilterBox($oP, $aResults, $bLazyLoading));
$this->DisplayGraph($oP, $sRelation, $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams, $bLazyLoading);
}
/**
* Display only the graph inside the given page, with the parameters of filter box draw with DisplayFilterBox
*
* @param WebPage $oP
* @param string $sRelation
* @param ApplicationContext $oAppContext
* @param array $aExcludedObjects
* @param string $sObjClass
* @param int $iObjKey
* @param string $sContextKey
* @param array $aContextParams
* @param bool $bLazyLoading
*
* @throws \CoreException
* @throws \DictExceptionMissingString
*
* @since 3.1.1 3.2.0 N°3767
*/
function DisplayGraph(WebPage $oP, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects, $sObjClass, $iObjKey, $sContextKey, $aContextParams = array(), bool $bLazyLoading = false): void
{
list($aExcludedByClass, $aAdditionalContexts) = $this->GetFilteringData($sContextKey, $aContextParams, $aExcludedObjects);
list($aExcludedByClass, $aAdditionalContexts) = $this->DisplayFiltering($sContextKey, $aContextParams, $aExcludedObjects, $oP, $aResults, $bLazyLoading);
$iGroupingThreshold = utils::ReadParam('g', 5);
@@ -1546,10 +1513,12 @@ class DisplayableGraph extends SimpleGraph
$oP->add_ready_script(" $('#$sId').simple_graph(".json_encode($aParams).");");
} else {
$oP->add_script("function Load(){var aExcluded = []; $('input[name^=excluded]').each( function() {if (!$(this).prop('checked')) { aExcluded.push($(this).val()); }} ); var params= $.extend(".json_encode($aParams).", {excluded_classes: aExcluded}); $('#$sId').simple_graph(params);}");
$oP->add_ready_script("$('#graph').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');$('#impacted_objects_lists').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');$('#impacted_groups').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');");
$oP->add_ready_script("$('#impacted_objects_lists').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');$('#impacted_groups').html('".utils::TextToHtml(Dict::S('Relation:impacts/NoFilteredData'))."');");
}
}
catch (Exception $e) {
catch(Exception $e)
{
$oP->add('<div>'.$e->getMessage().'</div>');
}
$oP->add_script(
@@ -1583,7 +1552,7 @@ EOF
* @param string $sContextKey
* @param array $aContextParams
* @param array $aExcludedObjects
* @param WebPage $oP
* @param \WebPage $oP
* @param array $aResults
* @param bool $bLazyLoading
*
@@ -1594,41 +1563,23 @@ EOF
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @deprecated 3.1.1 3.2.0 N°3767 Use \DisplayableGraph::DisplayFilterBox() and \DisplayableGraph::GetFilteringData() instead
*/
public function DisplayFiltering(string $sContextKey, array $aContextParams, array $aExcludedObjects, WebPage $oP, array $aResults, bool $bLazyLoading = false): array
{
$oP->Add($this->DisplayFilterBox($oP, $aResults, $bLazyLoading));
return $this->GetFilteringData($sContextKey, $aContextParams, $aExcludedObjects);
}
/**
* @param WebPage $oP
* @param array $aResults
* @param bool $bLazyLoading
*
* @return UIContentBlock
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \ReflectionException
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*
* @since 3.1.1 3.2.0 N°3767
*/
public function DisplayFilterBox(WebPage $oP, array $aResults, bool $bLazyLoading = false): UIContentBlock
{
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
$aExcludedByClass = array();
foreach ($aExcludedObjects as $oObj) {
if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
$aExcludedByClass[get_class($oObj)] = array();
}
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
}
$sSftShort = Dict::S('UI:ElementsDisplayed');
$oBlock = UIContentBlockUIBlockFactory::MakeStandard(null, ['not-printable']);
$oP->add("<div class=\"not-printable\">\n");
$oUiSearchBlock = new Panel($sSftShort, [], Panel::ENUM_COLOR_SCHEME_CYAN, 'dh_flash');
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"])
->SetIsCollapsible(true);
$oUiHtmlBlock = new Html(
$oUiSearchBlock->SetCSSClasses(["ibo-search-form-panel", "display_block"]);
$oUiSearchBlock->SetIsCollapsible(true);
$oUiHtmlBlock = new Combodo\iTop\Application\UI\Base\Component\Html\Html(
<<<EOF
<div id="ds_flash" class="search_box ibo-display-graph--search-box">
@@ -1675,23 +1626,11 @@ EOF
$oUiHtmlBlock->AddHtml("<button type=\"button\" id=\"ReloadMovieBtn\" class=\"ibo-button ibo-is-neutral ibo-is-regular\" onClick=\"$sOnCLick\">".Dict::S('UI:Button:Refresh')."</button></div></form>");
}
$oUiHtmlBlock->AddHtml("</div>\n");
$oUiHtmlBlock->AddHtml("</div>\n"); // class="not-printable"
$oUiSearchBlock->AddSubBlock($oUiHtmlBlock);
$oBlock->AddSubBlock($oUiSearchBlock);
$oP->AddUiBlock($oUiSearchBlock);
return $oBlock;
}
public function GetFilteringData(string $sContextKey, array $aContextParams, array $aExcludedObjects): array
{
$aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
$aExcludedByClass = array();
foreach ($aExcludedObjects as $oObj) {
if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
$aExcludedByClass[get_class($oObj)] = array();
}
$aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
}
$aAdditionalContexts = array();
foreach ($aContextDefs as $sKey => $aDefinition) {
$aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => (array_key_exists('default', $aDefinition) && ($aDefinition['default'] == 'yes')));

View File

@@ -46,15 +46,6 @@ class EMail implements iEMail
const ORIGINAL_FORMAT = 1; // Original format, consisting in serializing the whole object, inculding the Swift Mailer's object.
// Did not work with attachements since their binary representation cannot be stored as a valid UTF-8 string
const FORMAT_V2 = 2; // New format, only the raw data are serialized (base64 encoded if needed)
/** @var int ENUM_SEND_DEFAULT This option can be used when sending an e-mail to respect the default configuration parameter. */
const ENUM_SEND_DEFAULT = 0;
/** @var int ENUM_SEND_FORCE_SYNCHRONOUS This option can be used when sending an e-mail to ignore the default and force synchronous sending instead. Example of a use case: instant e-mail test. */
const ENUM_SEND_FORCE_SYNCHRONOUS = 1;
/** @var int ENUM_SEND_FORCE_ASYNCHRONOUS This option can be used when sending an e-mail to ignore the default and force synchronous sending instead. Example of a use case: Bulk mails. */
const ENUM_SEND_FORCE_ASYNCHRONOUS = 2;
public function __construct()
{

View File

@@ -1,7 +1,4 @@
<?php
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Copyright (C) 2013-2023 Combodo SARL
*
@@ -245,33 +242,44 @@ class EventIssue extends Event
{
if (is_string($sValue))
{
if (mb_strlen($sValue) < 256) {
if (strlen($sValue) < 256)
{
$aPost[$sKey] = $sValue;
} else {
$aPost[$sKey] = "!long string: ".mb_strlen($sValue)." chars";
}
} else {
else
{
$aPost[$sKey] = "!long string: ".strlen($sValue). " chars";
}
}
else
{
// Not a string (avoid warnings in case the value cannot be easily casted into a string)
$aPost[$sKey] = @(string)$sValue;
$aPost[$sKey] = @(string) $sValue;
}
}
$this->Set('arguments_post', $aPost);
} else {
}
else
{
$this->Set('arguments_post', array());
}
$sLength = mb_strlen($this->Get('issue'));
if ($sLength > 255) {
$this->Set('issue', mb_substr($this->Get('issue'), 0, 210)." -truncated ($sLength chars)");
$sLength = strlen($this->Get('issue'));
if ($sLength > 255)
{
$this->Set('issue', substr($this->Get('issue'), 0, 200)." -truncated ($sLength chars)");
}
$sLength = mb_strlen($this->Get('impact'));
if ($sLength > 255) {
$this->Set('impact', mb_substr($this->Get('impact'), 0, 210)." -truncated ($sLength chars)");
$sLength = strlen($this->Get('impact'));
if ($sLength > 255)
{
$this->Set('impact', substr($this->Get('impact'), 0, 200)." -truncated ($sLength chars)");
}
$sLength = mb_strlen($this->Get('page'));
if ($sLength > 255) {
$this->Set('page', mb_substr($this->Get('page'), 0, 210)." -truncated ($sLength chars)");
$sLength = strlen($this->Get('page'));
if ($sLength > 255)
{
$this->Set('page', substr($this->Get('page'), 0, 200)." -truncated ($sLength chars)");
}
}
}

View File

@@ -10,9 +10,6 @@ use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\Helper\ExportHelper;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
require_once(APPROOT.'application/xlsxwriter.class.php');
@@ -71,7 +68,7 @@ class ExcelBulkExport extends TabularBulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
@@ -85,7 +82,6 @@ class ExcelBulkExport extends TabularBulkExport
case 'xlsx_options':
$oPanel = PanelUIBlockFactory::MakeNeutral(Dict::S('Core:BulkExport:XLSXOptions'));
$oPanel->AddSubBlock(ExportHelper::GetAlertForExcelMaliciousInjection());
$oMulticolumn = MultiColumnUIBlockFactory::MakeStandard();
$oPanel->AddSubBlock($oMulticolumn);

View File

@@ -101,7 +101,7 @@ EOF;
EOF;
SetupUtils::builddir(dirname($sFilePath));
file_put_contents($sFilePath, $content, LOCK_EX);
file_put_contents($sFilePath, $content);
}
}
Dict::SetUserLanguage($sUserLang);

View File

@@ -15,8 +15,6 @@
//
// 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\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: HTML export
@@ -39,7 +37,7 @@ class HTMLBulkExport extends TabularBulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -3,7 +3,6 @@
* @copyright Copyright (C) 2010-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\Core\Kpi\KpiLogData;
use Combodo\iTop\Service\Module\ModuleService;
@@ -405,31 +404,16 @@ class ExecutionKPI
$this->ResetCounters();
}
/**
* Compute statistics for a call to an extension
* Note: not working in dev mode (with links to env-production)
*
* @param object|string $object object called
* @param string $sMethod method called on the object
* @param string $sMessage additional message
*
* @return bool true if an extension was found for this object::method
* @throws \ReflectionException
*/
public function ComputeStatsForExtension($object, string $sMethod, string $sMessage = ''): bool
public function ComputeStatsForExtension($object, $sMethod)
{
if (!self::IsEnabled()) {
return true;
return;
}
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
if (utils::StartsWith($sSignature, '[')) {
$this->ComputeStats('Extension', "$sSignature $sMessage");
return true;
$this->ComputeStats('Extension', $sSignature);
}
return false;
}
public function ComputeStats($sOperation, $sArguments)

View File

@@ -3,7 +3,7 @@
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// 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.
@@ -576,11 +576,6 @@ class LogChannels
public const DATATABLE = 'Datatable';
public const DEADLOCK = 'DeadLock';
/**
* @var string Everything related to PHP sessions tracking
* @since 3.1.1 3.2.0 N°6901
*/
public const SESSIONTRACKER = 'SessionTracker';
/**
* @var string Everything related to the datamodel CRUD
@@ -1143,13 +1138,9 @@ class DeprecatedCallsLog extends LogAPI
parent::Enable($sTargetFile);
if (
(
(false === defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME))
|| (defined(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME) && (constant(ITOP_PHPUNIT_RUNNING_CONSTANT_NAME) !== true))
)
(false === defined('ITOP_PHPUNIT_RUNNING_CONSTANT_NAME'))
&& static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD)
) {
IssueLog::Trace('Setting '.static::class.' error handler to catch DEPRECATED', static::ENUM_CHANNEL_PHP_LIBMETHOD);
set_error_handler([static::class, 'DeprecatedNoticesErrorHandler'], E_DEPRECATED | E_USER_DEPRECATED);
}
}
@@ -1680,8 +1671,6 @@ class ExceptionLog extends LogAPI
*/
private static function GetLastEventIssue()
{
$oRet = self::$oLastEventIssue;
self::$oLastEventIssue = null;
return $oRet;
return self::$oLastEventIssue;
}
}

View File

@@ -1241,7 +1241,7 @@ abstract class MetaModel
}
$sTable = self::DBGetTable($sClass);
// Could be completed later with all the classes that are using a given table
// Could be completed later with all the classes that are using a given table
if (!array_key_exists($sTable, $aTables)) {
$aTables[$sTable] = array();
}
@@ -1445,10 +1445,8 @@ abstract class MetaModel
*
* @return AttributeDefinition[]
* @throws \CoreException
*
* @see GetAttributesList for attcode list
*/
final public static function ListAttributeDefs($sClass)
final static public function ListAttributeDefs($sClass)
{
self::_check_subclass($sClass);
return self::$m_aAttribDefs[$sClass];
@@ -1461,10 +1459,8 @@ abstract class MetaModel
* @param string[] $aDesiredAttTypes Array of AttributeDefinition classes to filter the list on
* @param string|null $sListCode If provided, attributes will be limited to those in this zlist
*
* @return string[] list of attcodes
* @return array
* @throws \CoreException
*
* @see ListAttributeDefs to get AttributeDefinition array instead
*/
final public static function GetAttributesList(string $sClass, array $aDesiredAttTypes = [], ?string $sListCode = null)
{
@@ -3526,7 +3522,7 @@ abstract class MetaModel
}
// Set the "host class" as soon as possible, since HierarchicalKeys use it for their 'target class' as well
// and this needs to be know early (for Init_IsKnowClass 19 lines below)
// and this needs to be know early (for Init_IsKnowClass 19 lines below)
$oAtt->SetHostClass($sTargetClass);
// Some attributes could refer to a class
@@ -3568,7 +3564,7 @@ abstract class MetaModel
self::$m_aAttribDefs[$sTargetClass][$oAtt->GetCode()] = $oAtt;
self::$m_aAttribOrigins[$sTargetClass][$oAtt->GetCode()] = $sTargetClass;
// Note: it looks redundant to put targetclass there, but a mix occurs when inheritance is used
// Note: it looks redundant to put targetclass there, but a mix occurs when inheritance is used
}
/**
@@ -3768,7 +3764,7 @@ abstract class MetaModel
self::$m_aStimuli[$sTargetClass][$oStimulus->GetCode()] = $oStimulus;
// I wanted to simplify the syntax of the declaration of objects in the biz model
// Therefore, the reference to the host class is set there
// Therefore, the reference to the host class is set there
$oStimulus->SetHostClass($sTargetClass);
}
@@ -4223,78 +4219,40 @@ abstract class MetaModel
}
else
{
$aCurrentUser = [];
$aCurrentContact = [];
$aCurrentUser = array();
$aCurrentContact = array();
foreach ($aExpectedArgs as $expression)
{
$aName = explode('->', $expression->GetName());
if ($aName[0] == 'current_contact_id') {
$aPlaceholders['current_contact_id'] = UserRights::GetContactId();
} else if ($aName[0] == 'current_user') {
}
if ($aName[0] == 'current_user') {
array_push($aCurrentUser, $aName[1]);
} else if ($aName[0] == 'current_contact') {
}
if ($aName[0] == 'current_contact') {
array_push($aCurrentContact, $aName[1]);
}
}
if (count($aCurrentUser) > 0) {
static::FillObjectPlaceholders($aPlaceholders, 'current_user', UserRights::GetUserObject(), $aCurrentUser);
$oUser = UserRights::GetUserObject();
$aPlaceholders['current_user->object()'] = $oUser;
foreach ($aCurrentUser as $sField) {
$aPlaceholders['current_user->'.$sField] = $oUser->Get($sField);
}
}
if (count($aCurrentContact) > 0) {
static::FillObjectPlaceholders($aPlaceholders, 'current_contact', UserRights::GetContactObject(), $aCurrentContact);
$oPerson = UserRights::GetContactObject();
$aPlaceholders['current_contact->object()'] = $oPerson;
foreach ($aCurrentContact as $sField) {
$aPlaceholders['current_contact->'.$sField] = $oPerson->Get($sField);
}
}
}
return $aPlaceholders;
}
/**
* @since 3.1.1 N°6824
* @param array $aPlaceholders
* @param string $sPlaceHolderPrefix
* @param ?\DBObject $oObject
* @param array $aCurrentUser
*
* @return void
*
*/
private static function FillObjectPlaceholders(array &$aPlaceholders, string $sPlaceHolderPrefix, ?\DBObject $oObject, array $aCurrentUser) : void {
$sPlaceHolderKey = $sPlaceHolderPrefix."->object()";
if (is_null($oObject)){
$aContext = [
"current_user_id" => UserRights::GetUserId(),
"null object type" => $sPlaceHolderPrefix,
"fields" => $aCurrentUser,
];
IssueLog::Warning("Unresolved placeholders due to null object in current context", null,
$aContext);
$aPlaceholders[$sPlaceHolderKey] = Dict::Format("Core:Placeholder:CannotBeResolved", $sPlaceHolderKey);
foreach ($aCurrentUser as $sField) {
$sPlaceHolderKey = $sPlaceHolderPrefix . "->$sField";
$aPlaceholders[$sPlaceHolderKey] = Dict::Format("Core:Placeholder:CannotBeResolved", $sPlaceHolderKey);
}
} else {
$aPlaceholders[$sPlaceHolderKey] = $oObject;
foreach ($aCurrentUser as $sField) {
$sPlaceHolderKey = $sPlaceHolderPrefix . "->$sField";
// Mind that the "id" is not viewed as a valid att. code by \MetaModel::IsValidAttCode() so we have to test it manually
if ($sField !== "id" && false === MetaModel::IsValidAttCode(get_class($oObject), $sField)){
$aContext = [
"current_user_id" => UserRights::GetUserId(),
"obj_class" => get_class($oObject),
"placeholder" => $sPlaceHolderKey,
"invalid_field" => $sField,
];
IssueLog::Warning("Unresolved placeholder due to invalid attribute", null,
$aContext);
$aPlaceholders[$sPlaceHolderKey] = Dict::Format("Core:Placeholder:CannotBeResolved", $sPlaceHolderKey);
continue;
}
$aPlaceholders[$sPlaceHolderKey] = $oObject->Get($sField);
}
}
}
/**
* @param \DBSearch $oFilter
*
@@ -5156,7 +5114,7 @@ abstract class MetaModel
*/
protected static function DBCreateTables($aCallback = null)
{
[$aErrors, $aSugFix, $aCondensedQueries] = self::DBCheckFormat();
list($aErrors, $aSugFix, $aCondensedQueries) = self::DBCheckFormat();
//$sSQL = implode('; ', $aCondensedQueries); Does not work - multiple queries not allowed
foreach($aCondensedQueries as $sQuery)
@@ -5178,7 +5136,7 @@ abstract class MetaModel
*/
protected static function DBCreateViews()
{
[$aErrors, $aSugFix] = self::DBCheckViews();
list($aErrors, $aSugFix) = self::DBCheckViews();
foreach($aSugFix as $sClass => $aTarget)
{
@@ -6521,7 +6479,7 @@ abstract class MetaModel
$aCache['m_aExtensionClassNames'] = self::$m_aExtensionClassNames;
$aCache['m_Category2Class'] = self::$m_Category2Class;
$aCache['m_aRootClasses'] = self::$m_aRootClasses; // array of "classname" => "rootclass"
$aCache['m_aParentClasses'] = self::$m_aParentClasses; // array of ("classname" => array of "parentclass")
$aCache['m_aParentClasses'] = self::$m_aParentClasses; // array of ("classname" => array of "parentclass")
$aCache['m_aChildClasses'] = self::$m_aChildClasses; // array of ("classname" => array of "childclass")
$aCache['m_aClassParams'] = self::$m_aClassParams; // array of ("classname" => array of class information)
$aCache['m_aAttribDefs'] = self::$m_aAttribDefs; // array of ("classname" => array of attributes)
@@ -6779,13 +6737,7 @@ abstract class MetaModel
if ($bMustBeFound && empty($aRow))
{
$sNotFoundErrorMessage = "No result for the single row query";
IssueLog::Info($sNotFoundErrorMessage, LogChannels::CMDB_SOURCE, [
'class' => $sClass,
'key' => $iKey,
'sql_query' => $sSQL,
]);
throw new CoreException($sNotFoundErrorMessage);
throw new CoreException("No result for the single row query: '$sSQL'");
}
return $aRow;
@@ -6927,22 +6879,6 @@ abstract class MetaModel
return $iCount === 1;
}
public static function GetFinalClassName(string $sClass, int $iKey): string
{
if (MetaModel::IsStandaloneClass($sClass)) {
return $sClass;
}
$sRootClass = MetaModel::GetRootClass($sClass);
$sTable = MetaModel::DBGetTable($sRootClass);
$sKeyCol = MetaModel::DBGetKey($sRootClass);
$sEscapedKey = CMDBSource::Quote($iKey);
$sFinalClassField = Metamodel::DBGetClassField($sRootClass);
$sQuery = "SELECT `{$sFinalClassField}` FROM `{$sTable}` WHERE `{$sKeyCol}` = {$sEscapedKey}";
return CMDBSource::QueryToScalar($sQuery);
}
/**
* Search for the specified class and id. If the object is archived it will be returned anyway (this is for pre-2.4
* module compatibility, see N.1108)

View File

@@ -22,9 +22,7 @@
* A class to serialize the execution of some code sections
* Emulates the API of PECL Mutex class
* Relies on MySQL locks because the API sem_get is not always present in the
* installed PHP.
*
* @link https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html MySQL locking functions documentation
* installed PHP.
*
* @copyright Copyright (C) 2013-2023 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0

View File

@@ -20,7 +20,6 @@ use Combodo\iTop\Application\UI\Base\Component\CollapsibleSection\CollapsibleSec
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\iUIBlock;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Renderer\BlockRenderer;
define('CASELOG_VISIBLE_ITEMS', 2);

View File

@@ -17,7 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Events\EventData;
use Combodo\iTop\Service\Events\EventService;

View File

@@ -8,13 +8,10 @@ use Combodo\iTop\Application\UI\Base\Component\FieldSet\FieldSetUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Html\Html;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Input\SelectUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\PDFPage;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: PDF export, based on the HTML export converted to PDF
@@ -52,7 +49,7 @@ class PDFBulkExport extends HTMLBulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock
@@ -71,6 +68,8 @@ class PDFBulkExport extends HTMLBulkExport
//page format
$oSelectFormat = SelectUIBlockFactory::MakeForSelectWithLabel("page_size", Dict::S('Core:BulkExport:PDFPageSize'));
$oSelectFormat->SetIsLabelBefore(false);
//$oSelectFormat->AddCSSClass('ibo-input-checkbox');
$oFieldSetFormat->AddSubBlock($oSelectFormat);
$aPossibleFormat = ['A3', 'A4', 'Letter'];
@@ -80,7 +79,10 @@ class PDFBulkExport extends HTMLBulkExport
}
$oFieldSetFormat->AddSubBlock(new Html('</br>'));
$oSelectOrientation = SelectUIBlockFactory::MakeForSelectWithLabel("page_orientation", Dict::S('Core:BulkExport:PDFPageOrientation'));
$oSelectOrientation = SelectUIBlockFactory::MakeForSelectWithLabel("page_orientation",
Dict::S('Core:BulkExport:PDFPageOrientation'));
$oSelectOrientation->SetIsLabelBefore(false);
//$oSelectOrientation->AddCSSClass('ibo-input-checkbox');
$oFieldSetFormat->AddSubBlock($oSelectOrientation);
$aPossibleOrientation = ['P', 'L'];

View File

@@ -10,8 +10,6 @@ use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: "spreadsheet" export: a simplified HTML export in which the date/time columns are split in two column: date AND time
@@ -36,7 +34,7 @@ class SpreadsheetBulkExport extends TabularBulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -6,7 +6,6 @@
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: Tabular export: abstract base class for all "tabular" exports.
@@ -23,7 +22,7 @@ abstract class TabularBulkExport extends BulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -17,8 +17,6 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
/**
* <p>Stores data for {@link AttributeTagSet} fields
@@ -298,7 +296,7 @@ abstract class TagSetFieldData extends cmdbAbstractObject
/**
* Display Tag Usage
*
* @param WebPage $oPage
* @param \WebPage $oPage
* @param bool $bEditMode
*
* @throws \CoreException

View File

@@ -256,38 +256,6 @@ abstract class TriggerOnObject extends Trigger
}
}
/**
* Activate trigger based on attribute list given instead of changed attributes
*
* @param array $aContextArgs
* @param array|null $aAttributes if null default to changed attributes
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
* @since 3.1.1 3.2.0 N°6228
*/
public function DoActivateForSpecificAttributes(array $aContextArgs, ?array $aAttributes)
{
if (isset($aContextArgs['this->object()']))
{
/** @var \DBObject $oObject */
$oObject = $aContextArgs['this->object()'];
if (is_null($aAttributes)) {
$aChanges = $oObject->ListPreviousValuesForUpdatedAttributes();
} else {
$aChanges = array_fill_keys($aAttributes, true);
}
if (false === $this->IsTargetObject($oObject->GetKey(), $aChanges)) {
return;
}
}
parent::DoActivate($aContextArgs);
}
/**
* @param $iObjectId
* @param array $aChanges

View File

@@ -1,7 +1,6 @@
<?php
use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\WebPage\WebPage;
define('UR_ALLOWED_NO', 0);
define('UR_ALLOWED_YES', 1);
@@ -249,7 +248,7 @@ abstract class User extends cmdbAbstractObject
"depends_on" => array(),
)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("profile_list",array("linked_class" => "URP_UserProfile", "ext_key_to_me" => "userid", "ext_key_to_remote" => "profileid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), "display_style" => 'property', "with_php_constraint" => true, "with_php_computation" => true)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("profile_list",array("linked_class" => "URP_UserProfile", "ext_key_to_me" => "userid", "ext_key_to_remote" => "profileid", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), "display_style" => 'property', "with_php_constraint" => true)));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("allowed_org_list", array("linked_class" => "URP_UserOrg", "ext_key_to_me" => "userid", "ext_key_to_remote" => "allowed_org_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array(), 'with_php_constraint' => true)));
MetaModel::Init_AddAttribute(new AttributeCaseLog("log", array("sql" => 'log', "is_null_allowed" => true, "default_value" => '', "allowed_values" => null, "depends_on" => array(), "always_load_in_tables" => false)));
@@ -857,8 +856,6 @@ class UserRights
}
/**
* Set the current user (as part of the login process)
*
* @param string $sLogin Login of the concerned user
* @param string $sAuthentication
*
@@ -868,7 +865,7 @@ class UserRights
*/
public static function Login($sLogin, $sAuthentication = 'any')
{
self::ResetCurrentUserData();
static::Logoff();
$oUser = self::FindUser($sLogin, $sAuthentication);
if (is_null($oUser))
@@ -888,8 +885,6 @@ class UserRights
}
/**
* Reset current user and cleanup associated SESSION data
*
* @return void
* @since 3.0.4 3.1.1 3.2.0
*/
@@ -1124,7 +1119,9 @@ class UserRights
}
/**
* @return string connected {@see User} login field value, otherwise empty string
* Return the current user login or an empty string if nobody connected.
*
* @return string
*/
public static function GetUser()
{
@@ -1572,9 +1569,9 @@ class UserRights
/**
* @param string $sClass
* @param int $iActionCode see UR_ACTION_* constants
* @param DBObjectSet $oInstanceSet
* @param User $oUser
* @param int $iActionCode
* @param \DBObjectSet $oInstanceSet
* @param \User $oUser
*
* @return int (UR_ALLOWED_YES|UR_ALLOWED_NO|UR_ALLOWED_DEPENDS)
* @throws \CoreException

View File

@@ -8,8 +8,6 @@ use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\Column\ColumnUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactory;
use Combodo\iTop\Application\WebPage\Page;
use Combodo\iTop\Application\WebPage\WebPage;
/**
* Bulk export: XML export
@@ -32,7 +30,7 @@ class XMLBulkExport extends BulkExport
}
/**
* @param WebPage $oP
* @param \WebPage $oP
* @param $sPartId
*
* @return UIContentBlock

View File

@@ -13,9 +13,6 @@ $body-overflow-x: hidden !default;
$body-overflow-y: auto !default;
/*N°5786 - Avoid strong text to always be grey (default Bulma color for this var.) so strong text can keep its color. This is mostly for text within the .ibo-is-html-content. */
$text-strong: inherit !default;
/**
* customize Bulma content variables
* See https://bulma.io/documentation/elements/content/

View File

@@ -1,75 +0,0 @@
/**
* Widgets Factory.
*
* @package FormSDK
* @since 3.2.0
*/
/* debug purpose */
.form-type-pictograms{
display: inline-block;
float: right;
margin-left: 5px;
color: grey;
cursor: pointer;
padding: 0px 5px;
border-radius: 8px;
font-size: 0.9rem;
}
.form-type-pictograms i{
width: 15px;
}
.complete .form-type-pictograms .pattern:after{
content: '\f00c';
font-family: "Font Awesome 6 Free";
font-weight: 900;
background-color: #20b220;
border-radius: 50%;
font-size: 7px;
color: white;
position: relative;
top: -10px;
padding: 2px;
}
/* form label */
.form-label.required:after{
content: '*';
color: #e63535;
margin-left: 3px;
}
.cke_focus .cke_contents{
border: 1px #86b7fe solid;
outline: 0;
border-radius: 6px;
box-shadow: 0 0 0 0.25rem rgba(13,110,253,.25);
}
.form_interval_horizontal{
display: flex;
}
.form_interval_horizontal > div{
margin-right: 8px;
}
.form-compound-fieldset{
padding: 8px;
border-radius: 10px;
border: 1px dashed lightgrey;
}
.form-layout-row{
display: flex;
flex-direction: row;
}
.form-layout-column{
margin: 10px;
}
.form-layout-column:first-child{
margin-left: 0px;
}
.form-layout-column:last-child{
margin-right: 0px;
}

View File

@@ -1,88 +0,0 @@
.layout-grow{
flex-grow: 1;
}
.custom-container{
position: relative;
border-radius: 10px;
padding: 40px 20px 0px;
}
.custom-container:before{
content: 'Custom Layout CSS';
font-weight: 500;
position: absolute;
left: 50%;
top: -10px;
transform: translateX(-50%);
/*border: 1px solid #9c21af;*/
background-color: white;
padding: 5px 15px;
border-radius: 10px;
}
.container-flower{
background-color: #f3deff;
background-size: 500px;
background-repeat: no-repeat;
background-position-x: right;
background-position-y: bottom;
background: linear-gradient( to right bottom, rgb(248 242 251) 50%, rgb(241 187 255) );
padding-bottom: 200px;
}
.container-flower fieldset{
position: relative;
z-index: 1;
}
.container-flower:after{
content: '';
width: 300px;
height: 200px;
background-image: url('../../sources/FormImplementation/Resources/6662396.png');
background-size: 300px;
position: absolute;
bottom: 0px;
right: 0px;
border-radius: 10px;
}
.container-flower .col-form-label{
color: #8d63b7;
}
.container-flower .form-compound-fieldset{
border: 1px solid #8d63b7;
}
.container-color{
position: relative;
border-radius: 10px;
background-color: #faf7ff;
}
.container-color .form-compound-fieldset{
background-color: #ebe4f6;
border: none;
}
.container-color2{
position: relative;
border-radius: 10px;
background-color: #f7f9ff;
}
.container-color2 .form-compound-fieldset{
background-color: #e8edf9;
border: none;
}
.error-label{
color: #d32f2f;
}
.container-color2 .form-compound-fieldset fieldset{
border-bottom: 1px dashed #a3adc5;
}
.container-color2 .form-compound-fieldset fieldset:last-child{
border-bottom: none;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<constants>
</constants>
<classes>

View File

@@ -7,6 +7,6 @@
*/
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'CAS:Error:UserNotAllowed' => '用户被禁止登录',
'CAS:Login:SignIn' => '使用CAS登录',
'CAS:Login:SignInTooltip' => '点击这里使用CAS服务器认证',
'CAS:Login:SignIn' => '使用CAS 登录',
'CAS:Login:SignInTooltip' => '点击这里使用CAS 服务器认证',
));

View File

@@ -5,7 +5,7 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'authent-cas/3.2.0',
'authent-cas/3.1.0',
array(
// Identification
//

View File

@@ -35,5 +35,5 @@
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:UserExternal' => '外部用户',
'Class:UserExternal+' => '用户在'.ITOP_APPLICATION_SHORT.'外部验证身份',
'Class:UserExternal+' => '用户在 '.ITOP_APPLICATION_SHORT.' 外部验证身份',
));

View File

@@ -27,7 +27,7 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'authent-external/3.2.0',
'authent-external/3.1.0',
array(
// Identification
//

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<classes>
<class id="UserLDAP" _delta="define">
<parent>cmdbAbstractObject</parent>
@@ -355,26 +355,4 @@
</presentation>
</class>
</classes>
<meta>
<classes>
<class id="UserInternal" _delta="define_if_not_exists">
<fields>
<field id="contactid" xsi:type="AttributeExternalKey">
<target_class>Contact</target_class>
</field>
<field id="first_name" xsi:type="AttributeExternalField"/>
<field id="last_name" xsi:type="AttributeExternalField"/>
<field id="status" xsi:type="AttributeEnum"/>
<field id="org_id" xsi:type="AttributeExternalField"/>
<field id="email" xsi:type="AttributeExternalField"/>
<field id="login" xsi:type="AttributeString"/>
<field id="language" xsi:type="AttributeApplicationLanguage"/>
<field id="status" xsi:type="AttributeEnum"/>
<field id="allowed_org_list" xsi:type="AttributeLinkedSetIndirect"/>
<field id="profile_list" xsi:type="AttributeLinkedSetIndirect"/>
<field id="log" xsi:type="AttributeCaseLog"/>
</fields>
</class>
</classes>
</meta>
</itop_design>

View File

@@ -21,6 +21,6 @@
*/
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'Class:UserLDAP' => 'LDAP felhasználó',
'Class:UserLDAP+' => 'LDAP vagy AD felhasználó',
'Class:UserLDAP+' => '',
'UserLDAP:server' => 'LDAP specifics~~',
));

View File

@@ -34,7 +34,7 @@
// Class: UserLDAP
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:UserLDAP' => 'LDAP用户',
'Class:UserLDAP+' => '用户身份由LDAP认证',
'UserLDAP:server' => 'LDAP详情',
'Class:UserLDAP' => 'LDAP 用户',
'Class:UserLDAP+' => '用户身份由LDAP 认证',
'UserLDAP:server' => 'LDAP specifics~~',
));

View File

@@ -9,7 +9,7 @@ if (function_exists('ldap_connect'))
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'authent-ldap/3.2.0',
'authent-ldap/3.1.0',
array(
// Identification
//

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.2">
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<module_parameters>
<parameters id="authent-local" _delta="define">
<password_validation.pattern>^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,}$</password_validation.pattern>

View File

@@ -21,7 +21,7 @@
*/
Dict::Add('HU HU', 'Hungarian', 'Magyar', array(
'Class:UserLocal' => ITOP_APPLICATION_SHORT.' felhasználó',
'Class:UserLocal+' => 'Rendszeren belül létrehozott felhasználó',
'Class:UserLocal+' => '',
'Class:UserLocal/Attribute:password' => 'Jelszó',
'Class:UserLocal/Attribute:password+' => '',
'Class:UserLocal/Attribute:expiration' => 'Jelszó lejárati ideje',

View File

@@ -35,11 +35,11 @@
//
Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:UserLocal' => ITOP_APPLICATION_SHORT.' 用户',
'Class:UserLocal+' => '用户由'.ITOP_APPLICATION_SHORT.'验证身份',
'Class:UserLocal+' => '用户由 '.ITOP_APPLICATION_SHORT.' 验证身份',
'Class:UserLocal/Attribute:password' => '密码',
'Class:UserLocal/Attribute:password+' => '用于验证用户身份的字符串',
'Class:UserLocal/Attribute:expiration' => '密码过期',
'Class:UserLocal/Attribute:expiration+' => '密码过期状态 (需要一个扩展才能生效)',
'Class:UserLocal/Attribute:expiration+' => '密码过期状态(需要一个扩展才能生效)',
'Class:UserLocal/Attribute:expiration/Value:can_expire' => '允许过期',
'Class:UserLocal/Attribute:expiration/Value:can_expire+' => '',
'Class:UserLocal/Attribute:expiration/Value:never_expire' => '永不过期',
@@ -50,7 +50,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
'Class:UserLocal/Attribute:expiration/Value:otp_expire+' => '用户不允许修改密码.',
'Class:UserLocal/Attribute:password_renewed_date' => '密码更新',
'Class:UserLocal/Attribute:password_renewed_date+' => '上次修改密码的时间',
'Error:UserLocalPasswordValidator:UserPasswordPolicyRegex:ValidationFailed' => '密码必须至少8个字符, 包含大小写, 数字和特殊字符.',
'Error:UserLocalPasswordValidator:UserPasswordPolicyRegex:ValidationFailed' => '密码必须至少8个字符,包含大小写,数字和特殊字符.',
'UserLocal:password:expiration' => '下面的区域需要插件扩展',
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => '不允许用户为自己设置 "一次性密码" 的失效期限',
'Class:UserLocal/Error:OneTimePasswordChangeIsNotAllowed' => '不允许用户为自己设置"一次性密码"的失效期限',
));

View File

@@ -3,7 +3,7 @@
SetupWebPage::AddModule(
__FILE__, // Path to the current file, all other file names are relative to the directory containing this file
'authent-local/3.2.0',
'authent-local/3.1.0',
array(
// Identification
//

Some files were not shown because too many files have changed in this diff Show More