Compare commits

...

36 Commits

Author SHA1 Message Date
Anne-Cath
9f5bcd8b27 Update autoload 2026-03-02 14:54:07 +01:00
Anne-Cath
3ff05a6257 Fix rebase 2026-03-02 10:58:56 +01:00
Anne-Cath
b39a39a930 update composer 2026-03-02 10:25:14 +01:00
Anne-Cath
e6b8c49186 Remove IssueLog used for develop 2026-03-02 10:24:48 +01:00
Anne-Cath
3da3c6e79c Added "Allow delete Object" and "deny delete Object" when replica is deleted 2026-03-02 10:24:32 +01:00
Anne-Cath
30466cdd2f WIP
- Add access rights management
- Manage mass updates
- Add tooltips to buttons
2026-03-02 10:23:18 +01:00
acognet
f1526fda06 Add english dictionnary 2026-03-02 09:32:02 +01:00
acognet
9e094a632d Add operation on replica 2026-03-02 09:31:37 +01:00
Molkobain
94a36c0066 Merge remote-tracking branch 'origin/support/3.2' into develop 2026-02-26 09:30:14 +01:00
Molkobain
62e09f1224 N°8604 N°8605 - Add authentication to combodo-db-tools binaries (#817)
* N°8604 N°8605 - Add autoloader and dedicated classes for binaries utils

* N°8605 - Harden security

* N°8604 - Harden security

* N°8604 N°8605 - Fixes from code review

* N°8604 N°8605 - Improve robustness whether module is in datamodels/2.x or env-xxx folder
2026-02-26 09:29:20 +01:00
Eric Espie
57a0b5691f Merge support/3.2 into develop 2026-02-25 10:44:19 +01:00
Eric Espié
f82389d156 N°8632 - Various fixes (#814)
* N°8632 - Check existence of parameter file within iTop

* N°8632 - block parameter file from request

* log on error

* PHP CS fixer

* N°8632 - param files must be outside iTop

* PHP CS fixer

* Update webservices/export.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/php-unit-tests/unitary-tests/application/utilsTest.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

*  Fix CI

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-25 10:42:04 +01:00
Molkobain
9e21976424 Merge remote-tracking branch 'origin/support/3.2' into develop 2026-02-24 21:10:57 +01:00
Molkobain
f558093f5d N°8796 - Add PHP-CS-Fixer cache file to .gitignore file 2026-02-24 21:10:06 +01:00
Eric Espie
5201a1ed3b PHP CS fixer 2026-02-24 16:38:21 +01:00
Eric Espie
dad39c3ebe Merge support/3.2 into develop 2026-02-24 13:55:55 +01:00
odain
29920bfeb7 cleanup: log level in setUp + remove ls cli 2026-02-24 11:26:48 +01:00
odain
2313ee2bbd cleanup: log level in setUp + remove ls cli 2026-02-24 11:22:24 +01:00
jf-cbd
22b0c431a0 🌐 Add French translations in fr.dict.itop-config-mgmt.php 2026-02-23 18:51:57 +01:00
Thomas Casteleyn
499b3bca88 N°7570 - feat(Typology): Add useful tabs to certain typology classes (#756) 2026-02-23 17:28:56 +01:00
Stephen Abello
aede5ea7b8 Fix CI by updating files code style 2026-02-23 16:25:08 +01:00
Stephen Abello
da6c443a35 Fix CI by updating files code style 2026-02-23 16:08:20 +01:00
Stephen Abello
9c39efd9af N°8549 - Update inline images secret (#815) 2026-02-23 15:42:21 +01:00
jf-cbd
d5f2303ed2 N°8673 - Avoid server overload when user access news page with a lot of unread news (#816) 2026-02-23 15:35:31 +01:00
Eric Espié
48e584503e N°8782 - Union queries allow all data (#807)
* 8782 - Union queries allow all data

* N°8782 - Union queries allow all data
2026-02-23 15:10:09 +01:00
Benjamin DALSASS
454a1b26eb N°8603 N°8601 - Remove unnecessary quotes in reload url injection 2026-02-23 10:22:10 +01:00
Benjamin Dalsass
4853ca444e N°8910 - Upgrade Symfony packages (#811) 2026-02-23 06:54:26 +01:00
Benjamin Dalsass
330539abd2 N°8601 N°8603 dashboards issues (#813) 2026-02-23 06:51:40 +01:00
Stephen Abello
5357a0c060 Fix code style 2026-02-21 14:26:21 +01:00
lenaick.moreira
fc22cce037 N°8854 - Replace trigger_error() usage with E_USER_ERROR 2026-02-20 10:07:30 +01:00
lenaick.moreira
34c8a57814 N°8851 - Explicit nullable in functions parameters 2026-02-20 10:07:30 +01:00
Stephen Abello
b91e6c384a Merge branch 'support/3.2' into develop 2026-02-19 17:39:47 +01:00
Stephen Abello
2247691e58 Fix CI by updating files code style 2026-02-19 16:59:25 +01:00
Stephen Abello
f014b43761 Merge branch 'support/3.2' into develop 2026-02-19 16:16:56 +01:00
Stephen Abello
076d49abc2 Dump autoloader 2026-02-19 16:15:58 +01:00
Stephen Abello
9fd0ffd84e N°8545 - Standardize return message from password reset (#812)
* N°8545 - Standardize return message from password reset

* N°8545 - Change log severity depending on the error source

* Add copyrights

* Update application/loginwebpage.class.inc.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update application/loginwebpage.class.inc.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Avoid using dictionary entries in logs

* Update application/loginwebpage.class.inc.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-19 16:12:34 +01:00
361 changed files with 7318 additions and 2391 deletions

3
.gitignore vendored
View File

@@ -58,6 +58,9 @@ tests/*/vendor/*
/tests/php-unit-tests/phpunit.xml
/tests/php-unit-tests/postbuild_integration.xml
# PHP CS Fixer: Cache file
/.php-cs-fixer.cache
# Jetbrains
/.idea/**

View File

@@ -524,6 +524,11 @@ JS
$sLabel = Dict::S('Tag:Synchronized');
$sSynchroTagId = 'synchro_icon-'.$this->GetKey();
$aTags[$sSynchroTagId] = ['title' => $sTip, 'css_classes' => 'ibo-object-details--tag--synchronized', 'decoration_classes' => 'fas fa-lock', 'label' => $sLabel];
if (UserRights::IsActionAllowed('SynchroReplica', UR_ACTION_READ)) {
$sFilter = 'SELECT SynchroReplica WHERE dest_class=\''.get_class($this).'\' AND dest_id='.$this->GetKey();
$sUrlSearchReplica = 'UI.php?operation=search&filter='.urlencode(json_encode([$sFilter, [], []]));
$oPage->add_ready_script("$('#$sSynchroTagId').on('click',function() {window.location = '$sUrlSearchReplica' });");
}
}
}
@@ -5632,7 +5637,7 @@ JS
* @return void
* @since 3.1.0
*/
final public function AddAttributeFlags(string $sAttCode, int $iFlags, string $sTargetState = '', string $sReason = null): void
final public function AddAttributeFlags(string $sAttCode, int $iFlags, string $sTargetState = '', ?string $sReason = null): void
{
if (!isset($this->aAttributesFlags[$sTargetState])) {
$this->aAttributesFlags[$sTargetState] = [];
@@ -5655,7 +5660,7 @@ JS
* @return void
* @since 3.1.0
*/
final public function ForceAttributeFlags(string $sAttCode, int $iFlags, string $sTargetState = '', string $sReason = null): void
final public function ForceAttributeFlags(string $sAttCode, int $iFlags, string $sTargetState = '', ?string $sReason = null): void
{
if (!isset($this->aAttributesFlags[$sTargetState])) {
$this->aAttributesFlags[$sTargetState] = [];
@@ -5696,7 +5701,7 @@ JS
* @return void
* @since 3.1.0
*/
final public function AddInitialAttributeFlags(string $sAttCode, int $iFlags, string $sReason = null)
final public function AddInitialAttributeFlags(string $sAttCode, int $iFlags, ?string $sReason = null)
{
if (!isset($this->aInitialAttributesFlags)) {
$this->aInitialAttributesFlags = [];
@@ -5718,7 +5723,7 @@ JS
* @return void
* @since 3.1.0
*/
final public function ForceInitialAttributeFlags(string $sAttCode, int $iFlags, string $sReason = null)
final public function ForceInitialAttributeFlags(string $sAttCode, int $iFlags, ?string $sReason = null)
{
if (!isset($this->aInitialAttributesFlags)) {
$this->aInitialAttributesFlags = [];

View File

@@ -1029,7 +1029,7 @@ EOF
var dashboard = $('.ibo-dashboard#$sDivId')
dashboard.block();
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php',
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: '$sReloadURL' },
{ operation: 'toggle_dashboard', dashboard_id: '$sId', file: '$sFile', extra_params: $sExtraParams, reload_url: $sReloadURL },
function(data) {
dashboard.html(data);
dashboard.unblock();

View File

@@ -1940,7 +1940,7 @@ class MenuBlock extends DisplayBlock
$sSelectedClassName = MetaModel::GetName($sSelectedClass);
// Check rights on class
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && (($oReflectionClass->IsSubclassOf('cmdbAbstractObject') || $sSelectedClass === 'SynchroReplica'));
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE);
// Refine filter on selected class so bullk actions occur on the right class
@@ -1951,7 +1951,15 @@ class MenuBlock extends DisplayBlock
// Action label dict code has a specific suffix for "Link" / "Remote" aliases to allow dedicated labels in linksets.
$sActionLabelCodeSuffix = in_array($sSelectedAlias, ['Link', 'Remote']) ? $sSelectedAlias : 'Class';
if ($bIsBulkModifyAllowed) {
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:ModifyAll:'.$sSelectedAlias, Dict::Format('UI:Menu:ModifyAll_'.$sActionLabelCodeSuffix, $sSelectedClassName));
if($sSelectedClass === 'SynchroReplica'){
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:UnlinkAll:', Dict::S('Class:SynchroReplica/Action:unlink_all'),'unlink');
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:UnLinkSynchroAll:', Dict::S('Class:SynchroReplica/Action:unlinksynchro_all'),'unlinksynchro');
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:SynchroAll:', Dict::S('Class:SynchroReplica/Action:synchro_all'),'synchro');
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:AllowDeleteAll:', Dict::S('Class:SynchroReplica/Action:allowdelete_all'),'allowdelete');
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:DenyDeleteAll:', Dict::S('Class:SynchroReplica/Action:denydelete_all'),'denydelete');
} else {
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:ModifyAll:'.$sSelectedAlias, Dict::Format('UI:Menu:ModifyAll_'.$sActionLabelCodeSuffix, $sSelectedClassName));
}
}
if ($bIsBulkDeleteAllowed) {
$this->AddBulkDeleteObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:BulkDelete:'.$sSelectedAlias, Dict::Format('UI:Menu:BulkDelete_'.$sActionLabelCodeSuffix, $sSelectedClassName));
@@ -2471,11 +2479,11 @@ class MenuBlock extends DisplayBlock
* @since 3.1.0
* @internal
*/
protected function AddBulkModifyObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:ModifyAll', $sActionLabel = 'UI:Menu:ModifyAll'): void
protected function AddBulkModifyObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:ModifyAll', $sActionLabel = 'UI:Menu:ModifyAll', $sOperationName = 'modify'): void
{
$aActions[$sActionIdentifier] = [
'label' => Dict::S($sActionLabel),
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_modify_all&class=$sClass&filter=".urlencode($sFilter)),
'url' => $this->PrepareUrlForStandardMenuAction($sClass, 'operation=select_for_'.$sOperationName.'_all&class='.$sClass.'&filter='.urlencode($sFilter)),
] + $this->GetDefaultParamsForMenuAction();
}

View File

@@ -0,0 +1,10 @@
<?php
/**
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ForgotPasswordApplicationException extends Exception
{
}

View File

@@ -0,0 +1,10 @@
<?php
/**
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ForgotPasswordUserInputException extends Exception
{
}

View File

@@ -221,15 +221,15 @@ class LoginWebPage extends NiceWebPage
if ($oUser != null) {
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token')) {
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
throw new ForgotPasswordUserInputException('External accounts do not allow password reset');
}
if (!$oUser->CanChangePassword()) {
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
throw new ForgotPasswordUserInputException('The account does not allow password reset');
}
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
if ($sTo == '') {
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
throw new ForgotPasswordUserInputException('Missing email address for this account');
}
// This token allows the user to change the password without knowing the previous one
@@ -255,17 +255,21 @@ class LoginWebPage extends NiceWebPage
case EMAIL_SEND_ERROR:
default:
IssueLog::Error('Failed to send the email with the NEW password for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
throw new Exception(Dict::S('UI:ResetPwd-Error-Send'));
throw new ForgotPasswordApplicationException('Failed to send the password reset email for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
}
}
$oTwigContext = new LoginTwigRenderer();
$aVars = $oTwigContext->GetDefaultVars();
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
} catch (Exception $e) {
$this->DisplayForgotPwdForm(true, $e->getMessage());
} catch (ForgotPasswordApplicationException $e) {
IssueLog::Error('Failed to process the forgot password request for user "'.$sAuthUser.'" [reason='.get_class($e).']: '.$e->getMessage());
} catch (ForgotPasswordUserInputException $e) {
IssueLog::Info('Failed to process the forgot password request for user "'.$sAuthUser.'" [reason='.get_class($e).']: '.$e->getMessage());
} catch (\Throwable $e) {
IssueLog::Error('Unexpected error while processing the forgot password request for user "'.$sAuthUser.'": '.$e->getMessage());
}
$oTwigContext = new LoginTwigRenderer();
$aVars = $oTwigContext->GetDefaultVars();
$oTwigContext->Render($this, 'forgotpwdsent.html.twig', $aVars);
}
public function DisplayResetPwdForm($sErrorMessage = null)

View File

@@ -34,7 +34,7 @@ interface iNewsroomProvider
* @param User $oUser The user for who to check if the provider is applicable.
* return bool
*/
public function IsApplicable(User $oUser = null);
public function IsApplicable(?User $oUser = null);
/**
* The human readable (localized) label for this provider
@@ -139,7 +139,7 @@ abstract class NewsroomProviderBase implements iNewsroomProvider
*/
abstract public function GetViewAllURL();
public function IsApplicable(User $oUser = null)
public function IsApplicable(?User $oUser = null)
{
return false;
}

View File

@@ -151,7 +151,7 @@ abstract class Query extends cmdbAbstractObject
* @return string|null
* @since 3.1.0
*/
abstract public function GetExportUrl(array $aValues = null): ?string;
abstract public function GetExportUrl(?array $aValues = null): ?string;
/**
* Update last export information.
@@ -227,7 +227,7 @@ class QueryOQL extends Query
}
/** @inheritdoc */
public function GetExportUrl(array $aValues = null): ?string
public function GetExportUrl(?array $aValues = null): ?string
{
try {
// retrieve attributes

View File

@@ -181,6 +181,9 @@ class utils
protected static function LoadParamFile($sParamFile)
{
if (utils::RealPath($sParamFile, APPROOT) !== false) {
throw new Exception("File '".utils::HtmlEntities($sParamFile)."' should be outside iTop");
}
if (!file_exists($sParamFile)) {
throw new Exception("Could not find the parameter file: '".utils::HtmlEntities($sParamFile)."'");
}
@@ -1284,7 +1287,7 @@ class utils
* @throws \CoreException
* @throws \Exception
*/
public static function ExecITopScript(string $sScriptName, array $aArguments, string $sAuthUser = null, string $sAuthPwd = null)
public static function ExecITopScript(string $sScriptName, array $aArguments, ?string $sAuthUser = null, ?string $sAuthPwd = null)
{
$aDisabled = explode(', ', ini_get('disable_functions'));
if (in_array('exec', $aDisabled)) {
@@ -1374,7 +1377,7 @@ class utils
* @return string A path to a folder into which any module can store cache data
* The corresponding folder is created or cleaned upon code compilation
*/
public static function GetCachePath(string $sEnvironment = null): string
public static function GetCachePath(?string $sEnvironment = null): string
{
if (is_null($sEnvironment)) {
$sEnvironment = MetaModel::GetEnvironment();

389
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -199,7 +199,7 @@ class CellStatus_SearchIssue extends CellStatus_Issue
* @param null $sAllowedValues : used for additional message that provides allowed values $sAllowedValues for current class
* @param string|null $sAllowedValuesSearch : used to search all allowed values
*/
public function __construct($sSerializedSearch, $sReason, $sClass = null, $sAllowedValues = null, string $sAllowedValuesSearch = null)
public function __construct($sSerializedSearch, $sReason, $sClass = null, $sAllowedValues = null, ?string $sAllowedValuesSearch = null)
{
parent::__construct(null, null, $sReason);
$this->sSerializedSearch = $sSerializedSearch;
@@ -876,7 +876,7 @@ class BulkChange
return $aResults;
}
protected function CreateObject(&$aResult, $iRow, $aRowData, CMDBChange $oChange = null)
protected function CreateObject(&$aResult, $iRow, $aRowData, ?CMDBChange $oChange = null)
{
$oTargetObj = MetaModel::NewObject($this->m_sClass);
@@ -965,7 +965,7 @@ class BulkChange
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
*/
protected function UpdateObject(&$aResult, $iRow, $oTargetObj, $aRowData, CMDBChange $oChange = null)
protected function UpdateObject(&$aResult, $iRow, $oTargetObj, $aRowData, ?CMDBChange $oChange = null)
{
$aResult[$iRow] = $this->PrepareObject($oTargetObj, $aRowData, $aErrors);
@@ -1008,7 +1008,7 @@ class BulkChange
*
* @throws \BulkChangeException
*/
protected function UpdateMissingObject(&$aResult, $iRow, $oTargetObj, CMDBChange $oChange = null)
protected function UpdateMissingObject(&$aResult, $iRow, $oTargetObj, ?CMDBChange $oChange = null)
{
$aResult[$iRow] = $this->PrepareMissingObject($oTargetObj, $aErrors);
@@ -1043,7 +1043,7 @@ class BulkChange
}
}
public function Process(CMDBChange $oChange = null)
public function Process(?CMDBChange $oChange = null)
{
if ($oChange) {
CMDBObject::SetCurrentChange($oChange);

View File

@@ -2567,7 +2567,7 @@ abstract class DBObject implements iDisplay
*
* @see \RestUtils::FindObjectFromKey for the same check in the REST endpoint
*/
final public function CheckChangedExtKeysValues(callable $oIsObjectLoadableCallback = null)
final public function CheckChangedExtKeysValues(?callable $oIsObjectLoadableCallback = null)
{
if (is_null($oIsObjectLoadableCallback)) {
$oIsObjectLoadableCallback = function ($sClass, $sId) {
@@ -3727,7 +3727,7 @@ abstract class DBObject implements iDisplay
* @throws \MySQLException
* @throws \OQLException
*/
private function ActivateOnObjectUpdateTriggers(?DBObject $oObject, array $aAttributes = null): void
private function ActivateOnObjectUpdateTriggers(?DBObject $oObject, ?array $aAttributes = null): void
{
if (is_null($oObject)) {
return;

View File

@@ -650,7 +650,7 @@ abstract class DBSearch
*
* @throws OQLException
*/
public static function FromOQL($sQuery, $aParams = null, ModelReflection $oMetaModel = null)
public static function FromOQL($sQuery, $aParams = null, ?ModelReflection $oMetaModel = null)
{
if (empty($sQuery)) {
return null;

View File

@@ -59,7 +59,7 @@ class DBUnionSearch extends DBSearch
public function AllowAllData($bAllowAllData = true)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->AllowAllData();
$oSearch->AllowAllData($bAllowAllData);
}
}

View File

@@ -453,7 +453,7 @@ class DesignElement extends \DOMElement
* @throws Exception
* @since 3.1.2 3.2.0 N°6974
*/
public static function _FindNode(DOMNode $oParent, DesignElement $oRefNode, string $sSearchId = null): ?DesignElement
public static function _FindNode(DOMNode $oParent, DesignElement $oRefNode, ?string $sSearchId = null): ?DesignElement
{
$oNodes = self::_FindNodes($oParent, $oRefNode, $sSearchId);
if ($oNodes instanceof DOMNodeList) {
@@ -477,7 +477,7 @@ class DesignElement extends \DOMElement
* @return \DOMNodeList|false|mixed
* @since 3.1.2 3.2.0 N°6974
*/
public static function _FindNodes(DOMNode $oParent, DesignElement $oRefNode, string $sSearchId = null)
public static function _FindNodes(DOMNode $oParent, DesignElement $oRefNode, ?string $sSearchId = null)
{
if ($oParent instanceof DOMDocument) {
$oDoc = $oParent->firstChild->ownerDocument;

View File

@@ -632,7 +632,7 @@ class DisplayableGroupNode extends DisplayableNode
$this->aObjects = [];
}
public function AddObject(DBObject $oObj = null)
public function AddObject(?DBObject $oObj = null)
{
if (is_object($oObj)) {
$sPrevClass = $this->GetObjectClass();

View File

@@ -1656,7 +1656,7 @@ class PHP_ParserGenerator_Data
function emit_code($out, PHP_ParserGenerator_Rule $rp, &$lineno)
{
$linecnt = 0;
/* Generate code to do the reduce action */
if ($rp->code) {
$this->tplt_linedir($out, $rp->line, $this->filename);

View File

@@ -1084,7 +1084,7 @@ static public $yy_action = array(
function yy_find_shift_action($iLookAhead)
{
$stateno = $this->yystack[$this->yyidx]->stateno;
/* if ($this->yyidx < 0) return self::YY_NO_ACTION; */
if (!isset(self::$yy_shift_ofst[$stateno])) {
// no shift actions
@@ -1767,7 +1767,7 @@ throw new OQLParserParseFailureException($this->m_sSourceQuery, $this->m_iLine,
function yy_syntax_error($yymajor, $TOKEN)
{
#line 25 "..\oql-parser.y"
throw new OQLParserSyntaxErrorException($this->m_sSourceQuery, $this->m_iLine, $this->m_iCol, $this->tokenName($yymajor), $TOKEN);
#line 1779 "..\oql-parser.php"
}
@@ -1806,7 +1806,7 @@ throw new OQLParserSyntaxErrorException($this->m_sSourceQuery, $this->m_iLine, $
// $yyact; /* The parser action. */
// $yyendofinput; /* True if we are at the end of input */
$yyerrorhit = 0; /* True if yymajor has invoked an error */
/* (re)initialize the parser, if necessary */
if ($this->yyidx === null || $this->yyidx < 0) {
/* if ($yymajor == 0) return; // not sure why this was here... */
@@ -1819,7 +1819,7 @@ throw new OQLParserSyntaxErrorException($this->m_sSourceQuery, $this->m_iLine, $
array_push($this->yystack, $x);
}
$yyendofinput = ($yymajor==0);
if (self::$yyTraceFILE) {
fprintf(
self::$yyTraceFILE,
@@ -1828,7 +1828,7 @@ throw new OQLParserSyntaxErrorException($this->m_sSourceQuery, $this->m_iLine, $
self::$yyTokenName[$yymajor]
);
}
do {
$yyact = $this->yy_find_shift_action($yymajor);
if ($yymajor < self::YYERRORSYMBOL
@@ -2002,7 +2002,7 @@ class OQLParser extends OQLParserRaw
$this->m_sSourceQuery = $sQuery;
// no constructor - parent::__construct();
}
public function doParse($token, $value, $iCurrPosition = 0)
{
$this->m_iColPrev = $this->m_iCol;
@@ -2016,7 +2016,7 @@ class OQLParser extends OQLParserRaw
$this->doParse(0, 0);
return $this->my_result;
}
public function __destruct()
{
// Bug in the original destructor, causing an infinite loop !

View File

@@ -370,7 +370,7 @@ class ormCaseLog
/**
* Produces an HTML representation, aimed at being used within the iTop framework
*/
public function GetAsHTML(WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
public function GetAsHTML(?WebPage $oP = null, $bEditMode = false, $aTransfoHandler = null)
{
$bPrintableVersion = (utils::ReadParam('printable', '0') == '1');

View File

@@ -362,8 +362,7 @@ class ormDocument
throw new Exception("Invalid id ($id) for class '$sClass' - the object does not exist or you are not allowed to view it");
}
}
if (($sSecretField != null) && ($oObj->Get($sSecretField) != $sSecretValue)) {
usleep(200);
if (($sSecretField != null) && !hash_equals($oObj->Get($sSecretField), $sSecretValue)) {
throw new Exception("Invalid secret for class '$sClass' - the object does not exist or you are not allowed to view it");
}
/** @var \ormDocument $oDocument */

View File

@@ -93,7 +93,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
* @param DBObjectSet|null $oOriginalSet
* @throws Exception
*/
public function __construct($sHostClass, $sAttCode, DBObjectSet $oOriginalSet = null)
public function __construct($sHostClass, $sAttCode, ?DBObjectSet $oOriginalSet = null)
{
$this->sHostClass = $sHostClass;
$this->sAttCode = $sAttCode;

View File

@@ -72,9 +72,12 @@ $ibo-panel--icon--spacing--as-medallion--is-sticking: $ibo-panel--icon--spacing-
$ibo-panel--icon--bottom--as-medallion--is-sticking: -12px !default;
$ibo-panel--icon--border--as-medallion--is-sticking: 1px $ibo-panel--base-border-style $ibo-panel--base-border-color !default;
$ibo-panel--icon-background--size--must-contain: contain !default;
$ibo-panel--icon-background--size--must-cover: cover !default;
$ibo-panel--icon-background--size--must-zoomout: 66.67% !default;
$ibo-panel--icon-background--size--must-contain: contain !default; // deprecated, to be removed in favor of $ibo-panel--icon-img--size--must-contain
$ibo-panel--icon-background--size--must-cover: cover !default; // deprecated, to be removed in favor of $ibo-panel--icon-img--size--must-cover
$ibo-panel--icon-background--size--must-zoomout: 66.67% !default; // deprecated, to be removed in favor of $ibo-panel--icon-img--size--must-zoomout
$ibo-panel--icon-img--size--must-contain: $ibo-panel--icon-background--size--must-contain !default; // TODO remove when dealing with N°9317
$ibo-panel--icon-img--size--must-cover: $ibo-panel--icon-background--size--must-cover !default; // TODO remove when dealing with N°9317
$ibo-panel--icon-img--size--must-zoomout: $ibo-panel--icon-background--size--must-zoomout !default; // TODO remove when dealing with N°9317
$ibo-panel--title--font-size--is-sticking: $ibo-font-size-150 !default;
$ibo-panel--title--color: $ibo-color-grey-900 !default;
@@ -179,24 +182,25 @@ $ibo-panel--is-selectable--body--after--font-size: $ibo-font-size-700 !default;
min-height: $ibo-panel--icon--size;
}
.ibo-panel--icon-background {
.ibo-panel--icon-img, .ibo-panel--icon-background { // second class is deprecated, remove it when dealing with N°9317
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: $ibo-panel--icon-background--size--must-contain;
background-size: $ibo-panel--icon-img--size--must-contain;
}
.ibo-panel--icon-background--must-contain {
background-size: $ibo-panel--icon-background--size--must-contain;
.ibo-panel--icon-img--must-contain, .ibo-panel--icon-background--must-contain { // second class is deprecated, remove it when dealing with N°9317
background-size: $ibo-panel--icon-img--size--must-contain;
}
.ibo-panel--icon-background--must-cover {
background-size: $ibo-panel--icon-background--size--must-cover;
.ibo-panel--icon-img--must-cover, .ibo-panel--icon-background--must-cover { // second class is deprecated, remove it when dealing with N°9317
background-size: $ibo-panel--icon-img--size--must-cover;
}
.ibo-panel--icon-background--must-zoomout {
background-size: $ibo-panel--icon-background--size--must-zoomout;
.ibo-panel--icon-img--must-zoomout, .ibo-panel--icon-background--must-zoomout { // second class is deprecated, remove it when dealing with N°9317
width: $ibo-panel--icon-img--size--must-zoomout;
height: $ibo-panel--icon-img--size--must-zoomout;
}
.ibo-panel--title {

View File

@@ -11,9 +11,12 @@ $ibo-title--icon--size: 90px !default;
$ibo-title--icon--size-2: 80px !default;
$ibo-title--icon--size-3: 70px !default;
$ibo-title--icon-background--size--must-contain: contain !default;
$ibo-title--icon-background--size--must-cover: cover !default;
$ibo-title--icon-background--size--must-zoomout: 66.67% !default;
$ibo-title--icon-background--size--must-contain: contain !default; // deprecated, to be removed in favor of $ibo-title--icon-img--size--must-contain
$ibo-title--icon-background--size--must-cover: cover !default; // deprecated, to be removed in favor of $ibo-title--icon-img--size--must-cover
$ibo-title--icon-background--size--must-zoomout: 66.67% !default; // deprecated, to be removed in favor of $ibo-title--icon-img--size--must-zoomout
$ibo-title--icon-img--size--must-contain: $ibo-title--icon-background--size--must-contain !default; // TODO remove when dealing with N°9317
$ibo-title--icon-img--size--must-cover: $ibo-title--icon-background--size--must-cover !default; // TODO remove when dealing with N°9317
$ibo-title--icon-img--size--must-zoomout: $ibo-title--icon-background--size--must-zoomout !default; // TODO remove when dealing with N°9317
.ibo-title {
@@ -44,24 +47,23 @@ $ibo-title--icon-background--size--must-zoomout: 66.67% !default;
min-height: $ibo-title--icon--size-3;
}
.ibo-title--icon-background {
.ibo-title--icon-img, .ibo-title--icon-background { // second class is deprecated, remove it when dealing with N°9317
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: $ibo-title--icon-background--size--must-contain;
object-position: center;
background-size: $ibo-title--icon-img--size--must-contain;
}
.ibo-title--icon-background--must-contain {
background-size: $ibo-title--icon-background--size--must-contain;
.ibo-title--icon-img--must-contain, .ibo-title--icon-background--must-contain { // second class is deprecated, remove it when dealing with N°9317
background-size: $ibo-title--icon-img--size--must-contain;
}
.ibo-title--icon-background--must-cover {
background-size: $ibo-title--icon-background--size--must-cover;
.ibo-title--icon-img--must-cover, .ibo-title--icon-background--must-cover { // second class is deprecated, remove it when dealing with N°9317
background-size: $ibo-title--icon-img--size--must-cover;
}
.ibo-title--icon-background--must-zoomout {
background-size: $ibo-title--icon-background--size--must-zoomout;
.ibo-title--icon-img--must-zoomout, .ibo-title--icon-background--must-zoomout { // second class is deprecated, remove it when dealing with N°9317
background-size: $ibo-title--icon-img--size--must-zoomout;
}
.ibo-title--for-object-details {

View File

@@ -29,7 +29,7 @@ $ibo-vendors-selectize--element--active--background: $ibo-color-blue-100 !defaul
$ibo-vendors-selectize--element--active--color: $ibo-color-grey-900 !default;
$ibo-vendors-selectize--dropdown--background-color: $ibo-vendors-selectize-input--background-color !default;
$ibo-vendors-selectize--dropdown--color: $ibo-vendors-selectize-input--color!default;
$ibo-vendors-selectize--dropdown--color: $ibo-vendors-selectize-input--color !default;
$ibo-vendors-selectize--header--padding-x: 8px !default;
$ibo-vendors-selectize--header--padding-y: 5px !default;

View File

@@ -10,22 +10,87 @@
*/
use Combodo\iTop\Core\MetaModel\HierarchicalKey;
use Combodo\iTop\DBTools\Enum\BinExitCode;
use Combodo\iTop\DBTools\Exception\AuthenticationException;
require_once('../../../approot.inc.php');
// env-xxx folders
if (file_exists(__DIR__.'/../../../approot.inc.php')) {
require_once __DIR__.'/../../../approot.inc.php';
}
// datamodel/2.x and data/xxx-modules folders
elseif (file_exists(__DIR__.'/../../../../approot.inc.php')) {
require_once __DIR__.'/../../../../approot.inc.php';
}
require_once APPROOT.'application/startup.inc.php';
foreach (MetaModel::GetClasses() as $sClass) {
if (!MetaModel::HasTable($sClass)) {
continue;
}
// Prepare output page
$sPageTitle = "Database maintenance tools - Report";
$bIsModeCLI = utils::IsModeCLI();
if ($bIsModeCLI) {
$oP = new CLIPage($sPageTitle);
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
// Check (once) all the attributes that are hierarchical keys
if ((MetaModel::GetAttributeOrigin($sClass, $sAttCode) == $sClass) && $oAttDef->IsHierarchicalKey()) {
echo "Rebuild hierarchical key $sAttCode from $sClass.\n";
HierarchicalKey::Rebuild($sClass, $sAttCode, $oAttDef);
}
}
SetupUtils::CheckPhpAndExtensionsForCli($oP, BinExitCode::FATAL->value);
} else {
$oP = new WebPage($sPageTitle);
}
echo "Done\n";
// Authentication logic
try {
utils::UseParamFile();
if ($bIsModeCLI) {
$sAuthUser = utils::ReadParam('auth_user', null, true, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$sAuthPwd = utils::ReadParam('auth_pwd', null, true, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
if (utils::IsNullOrEmptyString($sAuthUser) || utils::IsNullOrEmptyString($sAuthPwd)) {
throw new AuthenticationException("Access credentials not provided, usage: php rebuildhk.php --auth_user=<login> --auth_pwd=<password> [--param_file=<file_path>]");
}
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) {
UserRights::Login($sAuthUser);
} else {
throw new AuthenticationException("Access wrong credentials ('$sAuthUser')");
}
} else {
// Check user rights and prompt if needed
LoginWebPage::DoLoginEx(null, true);
}
if (!UserRights::IsAdministrator()) {
throw new AuthenticationException("Access restricted to administrators");
}
} catch (AuthenticationException $oException) {
$oP->p($oException->getMessage());
$oP->output();
exit(BinExitCode::ERROR->value);
} catch (Exception $oException) {
$oP->p("Error: ".$oException->GetMessage());
$oP->output();
exit(BinExitCode::FATAL->value);
}
// Business logic
try {
foreach (MetaModel::GetClasses() as $sClass) {
if (!MetaModel::HasTable($sClass)) {
continue;
}
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
// Check (once) all the attributes that are hierarchical keys
if ((MetaModel::GetAttributeOrigin($sClass, $sAttCode) == $sClass) && $oAttDef->IsHierarchicalKey()) {
$oP->p("Rebuild hierarchical key $sAttCode from $sClass.");
HierarchicalKey::Rebuild($sClass, $sAttCode, $oAttDef);
}
}
}
$oP->p("Done");
$oP->output();
} catch (AuthenticationException $oException) {
$oP->p($oException->getMessage());
$oP->output();
exit(BinExitCode::ERROR->value);
} catch (Exception $oException) {
$oP->p("Error: ".$oException->GetMessage());
$oP->output();
exit(BinExitCode::FATAL->value);
}

View File

@@ -5,22 +5,93 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
use Combodo\iTop\DBTools\Enum\BinExitCode;
use Combodo\iTop\DBTools\Exception\AuthenticationException;
use Combodo\iTop\DBTools\Service\DBAnalyzerUtils;
require_once('../../../approot.inc.php');
require_once(APPROOT.'application/startup.inc.php');
require_once('../db_analyzer.class.inc.php');
require_once('../src/Service/DBAnalyzerUtils.php');
$oDBAnalyzer = new DatabaseAnalyzer(0);
$aResults = $oDBAnalyzer->CheckIntegrity([]);
if (empty($aResults)) {
echo "Database OK\n";
exit(0);
// env-xxx folders
if (file_exists(__DIR__.'/../../../approot.inc.php')) {
require_once __DIR__.'/../../../approot.inc.php';
}
// datamodel/2.x and data/xxx-modules folders
elseif (file_exists(__DIR__.'/../../../../approot.inc.php')) {
require_once __DIR__.'/../../../../approot.inc.php';
}
$sReportFile = DBAnalyzerUtils::GenerateReport($aResults);
require_once APPROOT.'application/startup.inc.php';
require_once APPROOT.'application/loginwebpage.class.inc.php';
echo "Report generated: {$sReportFile}.log\n";
require_once __DIR__.'/../db_analyzer.class.inc.php';
// Prepare output page
$sPageTitle = "Database maintenance tools - Report";
$bIsModeCLI = utils::IsModeCLI();
if ($bIsModeCLI) {
$oP = new CLIPage($sPageTitle);
SetupUtils::CheckPhpAndExtensionsForCli($oP, BinExitCode::FATAL->value);
} else {
$oP = new WebPage($sPageTitle);
}
// Authentication logic
try {
utils::UseParamFile();
if ($bIsModeCLI) {
$sAuthUser = utils::ReadParam('auth_user', null, true, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$sAuthPwd = utils::ReadParam('auth_pwd', null, true, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
if (utils::IsNullOrEmptyString($sAuthUser) || utils::IsNullOrEmptyString($sAuthPwd)) {
throw new AuthenticationException("Access credentials not provided, usage: php report.php --auth_user=<login> --auth_pwd=<password> [--param_file=<file_path>]");
}
if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) {
UserRights::Login($sAuthUser);
} else {
throw new AuthenticationException("Access wrong credentials ('$sAuthUser')");
}
} else {
// Check user rights and prompt if needed
LoginWebPage::DoLoginEx(null, true);
}
if (!UserRights::IsAdministrator()) {
throw new AuthenticationException("Access restricted to administrators");
}
} catch (AuthenticationException $oException) {
$sExceptionMessage = $oP instanceof WebPage ? utils::EscapeHtml($oException->getMessage()) : $oException->getMessage();
$oP->p($sExceptionMessage);
$oP->output();
exit(BinExitCode::ERROR->value);
} catch (Exception $oException) {
$sExceptionMessage = $oP instanceof WebPage ? utils::EscapeHtml($oException->getMessage()) : $oException->getMessage();
$oP->p("Error: ".$sExceptionMessage);
$oP->output();
exit(BinExitCode::FATAL->value);
}
// Business logic
try {
$oDBAnalyzer = new DatabaseAnalyzer(0);
$aResults = $oDBAnalyzer->CheckIntegrity([]);
if (empty($aResults)) {
$oP->p("Database OK");
$oP->output();
exit(BinExitCode::SUCCESS->value);
}
$sReportFile = DBAnalyzerUtils::GenerateReport($aResults);
$oP->p("Report generated: {$sReportFile}.log");
$oP->output();
} catch (AuthenticationException $oException) {
$sExceptionMessage = $oP instanceof WebPage ? utils::EscapeHtml($oException->getMessage()) : $oException->getMessage();
$oP->p($sExceptionMessage);
$oP->output();
exit(BinExitCode::ERROR->value);
} catch (Exception $oException) {
$sExceptionMessage = $oP instanceof WebPage ? utils::EscapeHtml($oException->getMessage()) : $oException->getMessage();
$oP->p("Error: ".$sExceptionMessage);
$oP->output();
exit(BinExitCode::FATAL->value);
}

View File

@@ -0,0 +1,9 @@
{
"name": "combodo/combodo-db-tools",
"license": "AGPL-3.0-only",
"autoload": {
"psr-4": {
"Combodo\\iTop\\DBTools\\": "src/"
}
}
}

View File

@@ -0,0 +1,18 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "38292b9b3a56c6c8776285a17c58034e",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.6.0"
}

View File

@@ -43,6 +43,7 @@ SetupWebPage::AddModule(
// Components
//
'datamodel' => [
'vendor/autoload.php',
'src/Service/DBToolsUtils.php',
'src/Service/DBAnalyzerUtils.php',
],

View File

@@ -0,0 +1,18 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\DBTools\Enum;
/**
* Enum for the exit codes of the bin scripts
*/
enum BinExitCode: int
{
case SUCCESS = 0;
case ERROR = -1;
case FATAL = -2;
}

View File

@@ -0,0 +1,12 @@
<?php
/*
* @copyright Copyright (C) 2010-2026 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\DBTools\Exception;
class AuthenticationException extends \Exception
{
}

View File

@@ -0,0 +1,22 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
throw new RuntimeException($err);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit38292b9b3a56c6c8776285a17c58034e::getLoader();

View File

@@ -0,0 +1,579 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@@ -0,0 +1,378 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = strtr(__DIR__, '\\', '/');
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
}
}
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed;
}
}

View File

@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,15 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Combodo\\iTop\\DBTools\\Enum\\BinExitCode' => $baseDir . '/src/Enum/BinExitCode.php',
'Combodo\\iTop\\DBTools\\Exception\\AuthenticationException' => $baseDir . '/src/Exception/AuthenticationException.php',
'Combodo\\iTop\\DBTools\\Service\\BinUtils' => $baseDir . '/src/Service/BinUtils.php',
'Combodo\\iTop\\DBTools\\Service\\DBAnalyzerUtils' => $baseDir . '/src/Service/DBAnalyzerUtils.php',
'Combodo\\iTop\\DBTools\\Service\\DBToolsUtils' => $baseDir . '/src/Service/DBToolsUtils.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
);

View File

@@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
);

View File

@@ -0,0 +1,10 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Combodo\\iTop\\DBTools\\' => array($baseDir . '/src'),
);

View File

@@ -0,0 +1,37 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit38292b9b3a56c6c8776285a17c58034e
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit38292b9b3a56c6c8776285a17c58034e', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit38292b9b3a56c6c8776285a17c58034e', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit38292b9b3a56c6c8776285a17c58034e::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
return $loader;
}
}

View File

@@ -0,0 +1,41 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit38292b9b3a56c6c8776285a17c58034e
{
public static $prefixLengthsPsr4 = array (
'C' =>
array (
'Combodo\\iTop\\DBTools\\' => 21,
),
);
public static $prefixDirsPsr4 = array (
'Combodo\\iTop\\DBTools\\' =>
array (
0 => __DIR__ . '/../..' . '/src',
),
);
public static $classMap = array (
'Combodo\\iTop\\DBTools\\Enum\\BinExitCode' => __DIR__ . '/../..' . '/src/Enum/BinExitCode.php',
'Combodo\\iTop\\DBTools\\Exception\\AuthenticationException' => __DIR__ . '/../..' . '/src/Exception/AuthenticationException.php',
'Combodo\\iTop\\DBTools\\Service\\BinUtils' => __DIR__ . '/../..' . '/src/Service/BinUtils.php',
'Combodo\\iTop\\DBTools\\Service\\DBAnalyzerUtils' => __DIR__ . '/../..' . '/src/Service/DBAnalyzerUtils.php',
'Combodo\\iTop\\DBTools\\Service\\DBToolsUtils' => __DIR__ . '/../..' . '/src/Service/DBToolsUtils.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit38292b9b3a56c6c8776285a17c58034e::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit38292b9b3a56c6c8776285a17c58034e::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit38292b9b3a56c6c8776285a17c58034e::$classMap;
}, null, ClassLoader::class);
}
}

View File

@@ -0,0 +1,5 @@
{
"packages": [],
"dev": true,
"dev-package-names": []
}

View File

@@ -0,0 +1,23 @@
<?php return array(
'root' => array(
'name' => 'combodo/combodo-db-tools',
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => null,
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'combodo/combodo-db-tools' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => null,
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@@ -199,15 +199,15 @@ function RaiseAlarm($sMessage)
//////////
// Main
try {
utils::UseParamFile();
} catch (Exception $e) {
echo "Error: ".$e->GetMessage()."\n";
exit;
}
if (utils::IsModeCLI()) {
SetupUtils::CheckPhpAndExtensionsForCli(new CLIPage('Check backup utility'));
try {
utils::UseParamFile();
} catch (Exception $e) {
echo 'Error: '.$e->GetMessage()."\n";
exit;
}
$oP = new CLIPage('Check backup utility');
SetupUtils::CheckPhpAndExtensionsForCli($oP);
echo date('Y-m-d H:i:s')." - running check-backup utility\n";
try {

View File

@@ -88,16 +88,15 @@ if (utils::IsModeCLI()) {
$oP = new CLIPage(GetOperationName());
SetupUtils::CheckPhpAndExtensionsForCli($oP);
try {
utils::UseParamFile();
} catch (Exception $e) {
ExitError($oP, $e->GetMessage());
}
} else {
$oP = new WebPage(GetOperationName());
}
try {
utils::UseParamFile();
} catch (Exception $e) {
ExitError($oP, $e->GetMessage());
}
ExecuteMainOperation($oP);
$oP->output();

View File

@@ -24,7 +24,7 @@ class DBRestore extends DBBackup
/** @var string */
private $sDBUser;
public function __construct(\Config $oConfig = null)
public function __construct(?\Config $oConfig = null)
{
parent::__construct($oConfig);

View File

@@ -4415,6 +4415,11 @@
<extkey_attcode>osfamily_id</extkey_attcode>
<target_attcode>name</target_attcode>
</field>
<field id="ospatches_list" xsi:type="AttributeLinkedSet">
<linked_class>OSPatch</linked_class>
<ext_key_to_me>osversion_id</ext_key_to_me>
<edit_mode>in_place</edit_mode>
</field>
</fields>
<methods/>
<presentation>
@@ -4426,6 +4431,9 @@
<item id="osfamily_id">
<rank>20</rank>
</item>
<item id="ospatches_list">
<rank>30</rank>
</item>
</items>
</details>
<search>
@@ -4481,6 +4489,11 @@
<storage_max_height>128</storage_max_height>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="osversions_list" xsi:type="AttributeLinkedSet">
<linked_class>OSVersion</linked_class>
<ext_key_to_me>osfamily_id</ext_key_to_me>
<edit_mode>in_place</edit_mode>
</field>
</fields>
<methods/>
<presentation>
@@ -4492,6 +4505,9 @@
<item id="logo">
<rank>20</rank>
</item>
<item id="osversions_list">
<rank>30</rank>
</item>
</items>
</details>
<search>
@@ -4563,6 +4579,16 @@
<count_max>0</count_max>
<duplicates/>
</field>
<field id="models_list" xsi:type="AttributeLinkedSet">
<linked_class>Model</linked_class>
<ext_key_to_me>brand_id</ext_key_to_me>
<edit_mode>in_place</edit_mode>
</field>
<field id="iosversions_list" xsi:type="AttributeLinkedSet">
<linked_class>IOSVersion</linked_class>
<ext_key_to_me>brand_id</ext_key_to_me>
<edit_mode>in_place</edit_mode>
</field>
</fields>
<methods/>
<presentation>
@@ -4574,9 +4600,15 @@
<item id="logo">
<rank>20</rank>
</item>
<item id="physicaldevices_list">
<item id="models_list">
<rank>30</rank>
</item>
<item id="physicaldevices_list">
<rank>40</rank>
</item>
<item id="iosversions_list">
<rank>50</rank>
</item>
</items>
</details>
<search>
@@ -4894,6 +4926,11 @@
<extkey_attcode>brand_id</extkey_attcode>
<target_attcode>name</target_attcode>
</field>
<field id="networkdevices_list" xsi:type="AttributeLinkedSet">
<linked_class>NetworkDevice</linked_class>
<ext_key_to_me>iosversion_id</ext_key_to_me>
<edit_mode>add_only</edit_mode>
</field>
</fields>
<methods/>
<presentation>
@@ -4905,6 +4942,9 @@
<item id="brand_id">
<rank>20</rank>
</item>
<item id="networkdevices_list">
<rank>30</rank>
</item>
</items>
</details>
<search>

View File

@@ -1073,6 +1073,8 @@ Dict::Add('EN US', 'English', 'English', [
'Class:OSVersion/Attribute:osfamily_id+' => '',
'Class:OSVersion/Attribute:osfamily_name' => 'OS family name',
'Class:OSVersion/Attribute:osfamily_name+' => '',
'Class:OSVersion/Attribute:ospatches_list' => 'OS patches',
'Class:OSVersion/Attribute:ospatches_list+' => 'All the OS patches for this OS version',
]);
//
@@ -1082,6 +1084,8 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:OSFamily' => 'OS Family',
'Class:OSFamily+' => '',
'Class:OSFamily/Attribute:osversions_list' => 'OS versions',
'Class:OSFamily/Attribute:osversions_list+' => 'All the OS versions for this OS family',
]);
//
@@ -1091,8 +1095,12 @@ Dict::Add('EN US', 'English', 'English', [
Dict::Add('EN US', 'English', 'English', [
'Class:Brand' => 'Brand',
'Class:Brand+' => '',
'Class:Brand/Attribute:iosversions_list' => 'IOS versions',
'Class:Brand/Attribute:iosversions_list+' => 'All the IOS versions from this brand',
'Class:Brand/Attribute:logo' => 'Logo',
'Class:Brand/Attribute:logo+' => '',
'Class:Brand/Attribute:models_list' => 'Models',
'Class:Brand/Attribute:models_list+' => 'All models for this brand',
'Class:Brand/Attribute:physicaldevices_list' => 'Physical devices',
'Class:Brand/Attribute:physicaldevices_list+' => 'All the physical devices corresponding to this brand',
'Class:Brand/UniquenessRule:name+' => 'The name must be unique',
@@ -1179,6 +1187,8 @@ Dict::Add('EN US', 'English', 'English', [
'Class:IOSVersion/Attribute:brand_id+' => '',
'Class:IOSVersion/Attribute:brand_name' => 'Brand name',
'Class:IOSVersion/Attribute:brand_name+' => '',
'Class:IOSVersion/Attribute:networkdevices_list' => 'Network devices',
'Class:IOSVersion/Attribute:networkdevices_list+' => 'All the network devices running this IOS version',
]);
//

View File

@@ -1203,6 +1203,8 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:OSVersion/Attribute:osfamily_id+' => '',
'Class:OSVersion/Attribute:osfamily_name' => 'Nom Famille OS',
'Class:OSVersion/Attribute:osfamily_name+' => '',
'Class:OSVersion/Attribute:ospatches_list' => 'Patchs OS',
'Class:OSVersion/Attribute:ospatches_list+' => 'Tous les patchs de cette version OS',
]);
//
@@ -1212,6 +1214,8 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:OSFamily' => 'Famille OS',
'Class:OSFamily+' => '',
'Class:OSFamily/Attribute:osversions_list' => 'Versions OS',
'Class:OSFamily/Attribute:osversions_list+' => 'Toutes les versions OS pour cette famille',
]);
//
@@ -1221,8 +1225,12 @@ Dict::Add('FR FR', 'French', 'Français', [
Dict::Add('FR FR', 'French', 'Français', [
'Class:Brand' => 'Marque',
'Class:Brand+' => '',
'Class:Brand/Attribute:iosversions_list' => 'Versions IOS',
'Class:Brand/Attribute:iosversions_list+' => 'Toutes les versions IOS pour cette marque',
'Class:Brand/Attribute:logo' => 'Logo',
'Class:Brand/Attribute:logo+' => '',
'Class:Brand/Attribute:models_list' => 'Modèles',
'Class:Brand/Attribute:models_list+' => 'Tous les modèles pour cette marque',
'Class:Brand/Attribute:physicaldevices_list' => 'Matériels',
'Class:Brand/Attribute:physicaldevices_list+' => 'Tous les matériels correspondant à cette marque',
'Class:Brand/Attribute:physicaldevices_list/UI:Links:Create:Button+' => 'Créer un %4$s',
@@ -1327,6 +1335,8 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:IOSVersion/Attribute:brand_id+' => '',
'Class:IOSVersion/Attribute:brand_name' => 'Nom Marque',
'Class:IOSVersion/Attribute:brand_name+' => '',
'Class:IOSVersion/Attribute:networkdevices_list' => 'Equipements réseaux',
'Class:IOSVersion/Attribute:networkdevices_list+' => 'Tous les équipements réseaux utilisant cette version IOS',
]);
//

View File

@@ -18,7 +18,7 @@ class HubNewsroomProvider extends NewsroomProviderBase
* {@inheritDoc}
* @see NewsroomProviderBase::IsApplicable()
*/
public function IsApplicable(User $oUser = null)
public function IsApplicable(?User $oUser = null)
{
if ($oUser !== null) {
return UserRights::IsAdministrator($oUser);

View File

@@ -27,7 +27,7 @@ class PortalCollector extends AbstractDataCollector
}
/** @inheritdoc */
public function collect(Request $request, Response $response, Throwable $exception = null): void
public function collect(Request $request, Response $response, ?Throwable $exception = null): void
{
$oRegister = $this->oTemplatesProviderService->GetRegister();
$aTemplatesDefinitions = $oRegister->GetTemplatesDefinitions();

View File

@@ -129,7 +129,7 @@ class ObjectFormHandlerHelper
* @throws \OQLException
* @throws \Exception
*/
public function HandleForm(Request $oRequest, $sMode, $sObjectClass, $sObjectId = null, array $aFormProperties = null)
public function HandleForm(Request $oRequest, $sMode, $sObjectClass, $sObjectId = null, ?array $aFormProperties = null)
{
$aFormData = [];
$sOperation = $this->oRequestManipulator->ReadParam('operation', '');

View File

@@ -40,7 +40,7 @@ class AppVariable implements ArrayAccess
/** @var DecoratedAppVariable */
private $decorated;
public function __construct(DecoratedAppVariable $decorated, ContainerInterface $container = null)
public function __construct(DecoratedAppVariable $decorated, ?ContainerInterface $container = null)
{
$this->decorated = $decorated;
$this->container = $container;

View File

@@ -57,7 +57,7 @@ class TemplatesTwigExtension extends AbstractExtension
* @return string the template path
* @throws \ReflectionException
*/
public function GetTemplate(string $sId, string $sProviderClass = self::DEFAULT_PROVIDER_CLASS, object $oProviderInstance = null): string
public function GetTemplate(string $sId, string $sProviderClass = self::DEFAULT_PROVIDER_CLASS, ?object $oProviderInstance = null): string
{
if ($oProviderInstance === null) {
return $this->oTemplatesService->GetTemplatePath($sProviderClass, $sId);

View File

@@ -981,8 +981,8 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of
'Class:SynchroDataSource/Error:DataTableAlreadyExists' => 'The table %1$s already exists in the database. Please use another name for the synchro data table.',
'Core:SynchroReplica:PublicData' => 'Public Data',
'Core:SynchroReplica:PrivateDetails' => 'Private Details',
'Core:SynchroReplica:BackToDataSource' => 'Go Back to the Synchro Data Source: %1$s',
'Core:SynchroReplica:ListOfReplicas' => 'List of Replica',
'Core:SynchroReplica:BackToDataSource' => 'Back to the Synchro Data Source',
'Core:SynchroReplica:ListOfReplicas' => 'Replicas of the data source: %1$s',
'Core:SynchroAttExtKey:ReconciliationById' => 'id (Primary Key)',
'Core:SynchroAtt:attcode' => 'Attribute',
'Core:SynchroAtt:attcode+' => 'Field of the object',
@@ -1036,65 +1036,99 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Rows separator',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Attributes separator',
'Class:SynchroLog' => 'Synchro Log',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroLog/Attribute:start_date' => 'Start Date',
'Class:SynchroLog/Attribute:end_date' => 'End Date',
'Class:SynchroLog/Attribute:status' => 'Status',
'Class:SynchroLog/Attribute:status/Value:completed' => 'Completed',
'Class:SynchroLog/Attribute:status/Value:error' => 'Error',
'Class:SynchroLog/Attribute:status/Value:running' => 'Still Running',
'Class:SynchroLog/Attribute:stats_nb_replica_seen' => 'Nb replica seen',
'Class:SynchroLog/Attribute:stats_nb_replica_total' => 'Nb replica total',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted' => 'Nb objects deleted',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted_errors' => 'Nb of errors while deleting',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted' => 'Nb objects obsoleted',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted_errors' => 'Nb of errors while obsoleting',
'Class:SynchroLog/Attribute:stats_nb_obj_created' => 'Nb objects created',
'Class:SynchroLog/Attribute:stats_nb_obj_created_errors' => 'Nb or errors while creating',
'Class:SynchroLog/Attribute:stats_nb_obj_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_updated_errors' => 'Nb errors while updating',
'Class:SynchroLog/Attribute:stats_nb_replica_reconciled_errors' => 'Nb of errors during reconciliation',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroLog/Attribute:start_date' => 'Start Date',
'Class:SynchroLog/Attribute:end_date' => 'End Date',
'Class:SynchroLog/Attribute:status' => 'Status',
'Class:SynchroLog/Attribute:status/Value:completed' => 'Completed',
'Class:SynchroLog/Attribute:status/Value:error' => 'Error',
'Class:SynchroLog/Attribute:status/Value:running' => 'Still Running',
'Class:SynchroLog/Attribute:stats_nb_replica_seen' => 'Nb replica seen',
'Class:SynchroLog/Attribute:stats_nb_replica_total' => 'Nb replica total',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted' => 'Nb objects deleted',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted_errors' => 'Nb of errors while deleting',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted' => 'Nb objects obsoleted',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted_errors' => 'Nb of errors while obsoleting',
'Class:SynchroLog/Attribute:stats_nb_obj_created' => 'Nb objects created',
'Class:SynchroLog/Attribute:stats_nb_obj_created_errors' => 'Nb or errors while creating',
'Class:SynchroLog/Attribute:stats_nb_obj_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_updated_errors' => 'Nb errors while updating',
'Class:SynchroLog/Attribute:stats_nb_replica_reconciled_errors' => 'Nb of errors during reconciliation',
'Class:SynchroLog/Attribute:stats_nb_replica_disappeared_no_action' => 'Nb replica disappeared',
'Class:SynchroLog/Attribute:stats_nb_obj_new_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_new_unchanged' => 'Nb objects unchanged',
'Class:SynchroLog/Attribute:last_error' => 'Last error',
'Class:SynchroLog/Attribute:traces' => 'Traces',
'Class:SynchroReplica' => 'Synchro Replica',
'Class:SynchroReplica/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroReplica/Attribute:dest_id' => 'Destination object (ID)',
'Class:SynchroReplica/Attribute:dest_class' => 'Destination type',
'Class:SynchroReplica/Attribute:status_last_seen' => 'Last seen',
'Class:SynchroReplica/Attribute:status' => 'Status',
'Class:SynchroReplica/Attribute:status/Value:modified' => 'Modified',
'Class:SynchroReplica/Attribute:status/Value:new' => 'New',
'Class:SynchroReplica/Attribute:status/Value:obsolete' => 'Obsolete',
'Class:SynchroReplica/Attribute:status/Value:orphan' => 'Orphan',
'Class:SynchroReplica/Attribute:status/Value:synchronized' => 'Synchronized',
'Class:SynchroReplica/Attribute:status_dest_creator' => 'Object Created ?',
'Class:SynchroReplica/Attribute:status_last_error' => 'Last Error',
'Class:SynchroReplica/Attribute:status_last_warning' => 'Warnings',
'Class:SynchroReplica/Attribute:info_creation_date' => 'Creation Date',
'Class:SynchroReplica/Attribute:info_last_modified' => 'Last Modified Date',
'Class:appUserPreferences' => 'User Preferences',
'Class:appUserPreferences/Attribute:userid' => 'User',
'Class:SynchroLog/Attribute:stats_nb_obj_new_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_new_unchanged' => 'Nb objects unchanged',
'Class:SynchroLog/Attribute:last_error' => 'Last error',
'Class:SynchroLog/Attribute:traces' => 'Traces',
'Class:SynchroReplica' => 'Synchro Replica',
'Class:SynchroReplica/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroReplica/Attribute:dest_id' => 'Destination object (ID)',
'Class:SynchroReplica/Attribute:dest_class' => 'Destination type',
'Class:SynchroReplica/Attribute:status_last_seen' => 'Last seen',
'Class:SynchroReplica/Attribute:status' => 'Status',
'Class:SynchroReplica/Attribute:status/Value:modified' => 'Modified',
'Class:SynchroReplica/Attribute:status/Value:new' => 'New',
'Class:SynchroReplica/Attribute:status/Value:obsolete' => 'Obsolete',
'Class:SynchroReplica/Attribute:status/Value:orphan' => 'Orphan',
'Class:SynchroReplica/Attribute:status/Value:synchronized' => 'Synchronized',
'Class:SynchroReplica/Attribute:status_dest_creator' => 'Object Created ?',
'Class:SynchroReplica/Attribute:status_last_error' => 'Last Error',
'Class:SynchroReplica/Attribute:status_last_warning' => 'Warnings',
'Class:SynchroReplica/Attribute:info_creation_date' => 'Creation Date',
'Class:SynchroReplica/Attribute:info_last_modified' => 'Last Modified Date',
'Class:SynchroReplica/Action:delete+' => 'delete replica',
'Class:SynchroReplica/Action:unlink' => 'Unlink',
'Class:SynchroReplica/Action:unlink+' => 'Unlink replica with destination object',
'Class:SynchroReplica/Action:unlinksynchro' => 'Unlink & Synchro',
'Class:SynchroReplica/Action:unlinksynchro+' => 'Unlink replica with destination object and execute synchronization with this replica',
'Class:SynchroReplica/Action:synchro' => 'Synchro',
'Class:SynchroReplica/Action:synchro+' => 'Execute synchronization with this replica',
'Class:SynchroReplica/Action:allowdelete' => 'Allow delete of object linked to this synchro replica',
'Class:SynchroReplica/Action:allowdelete+' => 'Object linked to a deleted replica is deleted',
'Class:SynchroReplica/Action:denydelete' => 'Deny delete of object linked to this synchro replica',
'Class:SynchroReplica/Action:denydelete+' => 'Object linked to a deleted replica is not deleted',
'Class:SynchroReplica/Action:unlink_all' => 'Unlink Synchro Replica objects',
'Class:SynchroReplica/Action:unlink_all+' => 'Unlink replica with destination object',
'Class:SynchroReplica/Action:unlinksynchro_all' => 'Unlink & Synchronize Synchro Replica objects',
'Class:SynchroReplica/Action:unlinksynchro_all+' => 'Unlink replica with destination object and execute synchronization with this replica',
'Class:SynchroReplica/Action:synchro_all' => 'Synchronize Synchro Replica objects',
'Class:SynchroReplica/Action:synchro_all+' => 'Execute synchronization with this replica',
'Class:SynchroReplica/Action:allowdelete_all' => 'Allow delete of objects linked to Synchro Replica',
'Class:SynchroReplica/Action:allowdelete_all+' => 'Object linked to a deleted replica is deleted',
'Class:SynchroReplica/Action:denydelete_all' => 'Deny delete of objects linked to Synchro Replica',
'Class:SynchroReplica/Action:denydelete_all+' => 'Object linked to a deleted replica is not deleted',
'UI:UnlinkAllTabTitle' => 'Unlink Synchro Replica objects',
'UI:UnlinkAllPageTitle' => 'Unlink Synchro Replica objects',
'UI:UnlinkSynchroAllTabTitle' => 'Unlink & Synchronize Synchro Replica objects',
'UI:UnlinkSynchroAllPageTitle' => ' Unlink & Synchronize Synchro Replica objects',
'UI:SynchroAllTabTitle' => 'Synchronize Synchro Replica objects',
'UI:SynchroAllPageTitle' => 'Synchronize Synchro Replica objects',
'UI:AllowDeleteAllTabTitle' => 'Allow delete of objects linked to Synchro Replica',
'UI:AllowDeleteAllPageTitle' => 'Allow delete of objects linked to Synchro Replica',
'UI:DenyDeleteAllTabTitle' => 'Deny delete of objects linked to Synchro Replica',
'UI:DenyDeleteAllPageTitle' => 'Deny delete of objects linked to Synchro Replica',
'Class:appUserPreferences' => 'User Preferences',
'Class:appUserPreferences/Attribute:userid' => 'User',
'Class:appUserPreferences/Attribute:preferences' => 'Prefs',
'Core:ExecProcess:Code1' => 'Wrong command or command finished with errors (e.g. wrong script name)',
'Core:ExecProcess:Code255' => 'PHP Error (parsing, or runtime)',
'Core:ExecProcess:Code1' => 'Wrong command or command finished with errors (e.g. wrong script name)',
'Core:ExecProcess:Code255' => 'PHP Error (parsing, or runtime)',
// Attribute Duration
'Core:Duration_Seconds' => '%1$ds',
'Core:Duration_Minutes_Seconds' => '%1$dmin %2$ds',
'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds',
'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sd %2$dh %3$dmin %4$ds',
'Core:Duration_Seconds' => '%1$ds',
'Core:Duration_Minutes_Seconds' => '%1$dmin %2$ds',
'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds',
'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sd %2$dh %3$dmin %4$ds',
// Explain working time computing
'Core:ExplainWTC:ElapsedTime' => 'Time elapsed (stored as "%1$s")',
'Core:ExplainWTC:StopWatch-TimeSpent' => 'Time spent for "%1$s"',
'Core:ExplainWTC:StopWatch-Deadline' => 'Deadline for "%1$s" at %2$d%%',
'Core:ExplainWTC:ElapsedTime' => 'Time elapsed (stored as "%1$s")',
'Core:ExplainWTC:StopWatch-TimeSpent' => 'Time spent for "%1$s"',
'Core:ExplainWTC:StopWatch-Deadline' => 'Deadline for "%1$s" at %2$d%%',
// Bulk export
'Core:BulkExport:MissingParameter_Param' => 'Missing parameter "%1$s"',
'Core:BulkExport:InvalidParameter_Query' => 'Invalid value for the parameter "query". There is no Query Phrasebook corresponding to the id: "%1$s".',
'Core:BulkExport:MissingParameter_Param' => 'Missing parameter "%1$s"',
'Core:BulkExport:InvalidParameter_Query' => 'Invalid value for the parameter "query". There is no Query Phrasebook corresponding to the id: "%1$s".',
'Core:BulkExport:ExportFormatPrompt' => 'Export format:',
'Core:BulkExportOf_Class' => '%1$s Export',
'Core:BulkExport:ClickHereToDownload_FileName' => 'Click here to download %1$s',

View File

@@ -14,7 +14,10 @@ if (PHP_VERSION_ID < 50600) {
echo $err;
}
}
throw new RuntimeException($err);
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';

View File

@@ -0,0 +1,5 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/patch-type-declarations
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
php "%BIN_TARGET%" %*

5
lib/bin/yaml-lint.bat Executable file
View File

@@ -0,0 +1,5 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/yaml-lint
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
php "%BIN_TARGET%" %*

View File

@@ -347,6 +347,7 @@ return array(
'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => $baseDir . '/sources/Controller/Base/Layout/ObjectController.php',
'Combodo\\iTop\\Controller\\Base\\Layout\\OqlController' => $baseDir . '/sources/Controller/Base/Layout/OqlController.php',
'Combodo\\iTop\\Controller\\Links\\LinkSetController' => $baseDir . '/sources/Controller/Links/LinkSetController.php',
'Combodo\\iTop\\Controller\\Links\\SynchroReplicaController' => $baseDir . '/sources/Controller/Links/SynchroReplicaController.php',
'Combodo\\iTop\\Controller\\Newsroom\\iTopNewsroomController' => $baseDir . '/sources/Controller/Newsroom/iTopNewsroomController.php',
'Combodo\\iTop\\Controller\\Notifications\\ActionController' => $baseDir . '/sources/Controller/Notifications/ActionController.php',
'Combodo\\iTop\\Controller\\Notifications\\NotificationsCenterController' => $baseDir . '/sources/Controller/Notifications/NotificationsCenterController.php',
@@ -854,6 +855,8 @@ return array(
'Firebase\\JWT\\JWTExceptionWithPayloadInterface' => $vendorDir . '/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
'Firebase\\JWT\\Key' => $vendorDir . '/firebase/php-jwt/src/Key.php',
'Firebase\\JWT\\SignatureInvalidException' => $vendorDir . '/firebase/php-jwt/src/SignatureInvalidException.php',
'ForgotPasswordApplicationException' => $baseDir . '/application/exceptions/ForgotPasswordApplicationException.php',
'ForgotPasswordUserInputException' => $baseDir . '/application/exceptions/ForgotPasswordUserInputException.php',
'FunctionExpression' => $baseDir . '/core/oql/expression.class.inc.php',
'FunctionOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
'GraphEdge' => $baseDir . '/core/simplegraph.class.inc.php',
@@ -1767,22 +1770,43 @@ return array(
'Symfony\\Component\\Cache\\Psr16Cache' => $vendorDir . '/symfony/cache/Psr16Cache.php',
'Symfony\\Component\\Cache\\ResettableInterface' => $vendorDir . '/symfony/cache/ResettableInterface.php',
'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => $vendorDir . '/symfony/cache/Traits/AbstractAdapterTrait.php',
'Symfony\\Component\\Cache\\Traits\\CachedValueInterface' => $vendorDir . '/symfony/cache/Traits/CachedValueInterface.php',
'Symfony\\Component\\Cache\\Traits\\ContractsTrait' => $vendorDir . '/symfony/cache/Traits/ContractsTrait.php',
'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemCommonTrait.php',
'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemTrait.php',
'Symfony\\Component\\Cache\\Traits\\ProxyTrait' => $vendorDir . '/symfony/cache/Traits/ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis5Proxy' => $vendorDir . '/symfony/cache/Traits/Redis5Proxy.php',
'Symfony\\Component\\Cache\\Traits\\Redis61ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis61ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis62ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis62ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis63ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis63ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis6Proxy' => $vendorDir . '/symfony/cache/Traits/Redis6Proxy.php',
'Symfony\\Component\\Cache\\Traits\\Redis6ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis6ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster5Proxy' => $vendorDir . '/symfony/cache/Traits/RedisCluster5Proxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster61ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster61ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster62ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster62ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster63ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster63ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster6Proxy' => $vendorDir . '/symfony/cache/Traits/RedisCluster6Proxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster6ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster6ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisClusterNodeProxy' => $vendorDir . '/symfony/cache/Traits/RedisClusterNodeProxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisClusterProxy' => $vendorDir . '/symfony/cache/Traits/RedisClusterProxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisProxy' => $vendorDir . '/symfony/cache/Traits/RedisProxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisTrait' => $vendorDir . '/symfony/cache/Traits/RedisTrait.php',
'Symfony\\Component\\Cache\\Traits\\RelayProxy' => $vendorDir . '/symfony/cache/Traits/RelayProxy.php',
'Symfony\\Component\\Cache\\Traits\\RelayProxyTrait' => $vendorDir . '/symfony/cache/Traits/RelayProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\BgsaveTrait' => $vendorDir . '/symfony/cache/Traits/Relay/BgsaveTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\CopyTrait' => $vendorDir . '/symfony/cache/Traits/Relay/CopyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\FtTrait' => $vendorDir . '/symfony/cache/Traits/Relay/FtTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\GeosearchTrait' => $vendorDir . '/symfony/cache/Traits/Relay/GeosearchTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\GetWithMetaTrait' => $vendorDir . '/symfony/cache/Traits/Relay/GetWithMetaTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\GetrangeTrait' => $vendorDir . '/symfony/cache/Traits/Relay/GetrangeTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\HsetTrait' => $vendorDir . '/symfony/cache/Traits/Relay/HsetTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\IsTrackedTrait' => $vendorDir . '/symfony/cache/Traits/Relay/IsTrackedTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\MoveTrait' => $vendorDir . '/symfony/cache/Traits/Relay/MoveTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\NullableReturnTrait' => $vendorDir . '/symfony/cache/Traits/Relay/NullableReturnTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\PfcountTrait' => $vendorDir . '/symfony/cache/Traits/Relay/PfcountTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay11Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay11Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay121Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay121Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay12Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay12Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay20Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay20Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\SwapdbTrait' => $vendorDir . '/symfony/cache/Traits/Relay/SwapdbTrait.php',
'Symfony\\Component\\Config\\Builder\\ClassBuilder' => $vendorDir . '/symfony/config/Builder/ClassBuilder.php',
'Symfony\\Component\\Config\\Builder\\ConfigBuilderGenerator' => $vendorDir . '/symfony/config/Builder/ConfigBuilderGenerator.php',
'Symfony\\Component\\Config\\Builder\\ConfigBuilderGeneratorInterface' => $vendorDir . '/symfony/config/Builder/ConfigBuilderGeneratorInterface.php',
@@ -1947,6 +1971,7 @@ return array(
'Symfony\\Component\\Console\\Helper\\TableRows' => $vendorDir . '/symfony/console/Helper/TableRows.php',
'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php',
'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php',
'Symfony\\Component\\Console\\Helper\\TerminalInputHelper' => $vendorDir . '/symfony/console/Helper/TerminalInputHelper.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php',
'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php',
'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php',
@@ -2614,17 +2639,6 @@ return array(
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => $vendorDir . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
'Symfony\\Component\\HttpFoundation\\StreamedJsonResponse' => $vendorDir . '/symfony/http-foundation/StreamedJsonResponse.php',
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => $vendorDir . '/symfony/http-foundation/StreamedResponse.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderLocationSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderLocationSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => $vendorDir . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
'Symfony\\Component\\HttpFoundation\\UriSigner' => $vendorDir . '/symfony/http-foundation/UriSigner.php',
'Symfony\\Component\\HttpFoundation\\UrlHelper' => $vendorDir . '/symfony/http-foundation/UrlHelper.php',
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => $vendorDir . '/symfony/http-kernel/Attribute/AsController.php',
@@ -3623,6 +3637,7 @@ return array(
'Twig\\ExpressionParser\\InfixExpressionParserInterface' => $vendorDir . '/twig/twig/src/ExpressionParser/InfixExpressionParserInterface.php',
'Twig\\ExpressionParser\\Infix\\ArgumentsTrait' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/ArgumentsTrait.php',
'Twig\\ExpressionParser\\Infix\\ArrowExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/ArrowExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\AssignmentExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/AssignmentExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\BinaryOperatorExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/BinaryOperatorExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\ConditionalTernaryExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/ConditionalTernaryExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\DotExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/DotExpressionParser.php',
@@ -3708,10 +3723,15 @@ return array(
'Twig\\Node\\Expression\\Binary\\MulBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MulBinary.php',
'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php',
'Twig\\Node\\Expression\\Binary\\NotInBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php',
'Twig\\Node\\Expression\\Binary\\NotSameAsBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotSameAsBinary.php',
'Twig\\Node\\Expression\\Binary\\NullCoalesceBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NullCoalesceBinary.php',
'Twig\\Node\\Expression\\Binary\\ObjectDestructuringSetBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ObjectDestructuringSetBinary.php',
'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
'Twig\\Node\\Expression\\Binary\\SameAsBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SameAsBinary.php',
'Twig\\Node\\Expression\\Binary\\SequenceDestructuringSetBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SequenceDestructuringSetBinary.php',
'Twig\\Node\\Expression\\Binary\\SetBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SetBinary.php',
'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php',
'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
@@ -3720,6 +3740,7 @@ return array(
'Twig\\Node\\Expression\\CallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/CallExpression.php',
'Twig\\Node\\Expression\\ConditionalExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConditionalExpression.php',
'Twig\\Node\\Expression\\ConstantExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConstantExpression.php',
'Twig\\Node\\Expression\\EmptyExpression' => $vendorDir . '/twig/twig/src/Node/Expression/EmptyExpression.php',
'Twig\\Node\\Expression\\FilterExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FilterExpression.php',
'Twig\\Node\\Expression\\Filter\\DefaultFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php',
'Twig\\Node\\Expression\\Filter\\RawFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/RawFilter.php',
@@ -3845,6 +3866,7 @@ return array(
'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php',
'Twig\\Util\\ReflectionCallable' => $vendorDir . '/twig/twig/src/Util/ReflectionCallable.php',
'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php',
'UI' => $baseDir . '/sources/Controller/UI.php',
'UIExtKeyWidget' => $baseDir . '/application/ui.extkeywidget.class.inc.php',
'UIHTMLEditorWidget' => $baseDir . '/application/ui.htmleditorwidget.class.inc.php',
'UILinksWidget' => $baseDir . '/application/ui.linkswidget.class.inc.php',

View File

@@ -28,12 +28,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
);
public static $prefixLengthsPsr4 = array (
'T' =>
'T' =>
array (
'Twig\\' => 5,
'TheNetworg\\OAuth2\\Client\\' => 25,
),
'S' =>
'S' =>
array (
'Symfony\\Polyfill\\Php83\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
@@ -82,7 +82,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'ScssPhp\\ScssPhp\\' => 16,
'Sabberworm\\CSS\\' => 15,
),
'P' =>
'P' =>
array (
'Psr\\Log\\' => 8,
'Psr\\Http\\Message\\' => 17,
@@ -93,298 +93,298 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'PhpParser\\' => 10,
'Pelago\\Emogrifier\\' => 18,
),
'L' =>
'L' =>
array (
'League\\OAuth2\\Client\\' => 21,
),
'G' =>
'G' =>
array (
'GuzzleHttp\\Psr7\\' => 16,
'GuzzleHttp\\Promise\\' => 19,
'GuzzleHttp\\' => 11,
),
'F' =>
'F' =>
array (
'Firebase\\JWT\\' => 13,
),
'E' =>
'E' =>
array (
'Egulias\\EmailValidator\\' => 23,
),
'D' =>
'D' =>
array (
'Doctrine\\Common\\Lexer\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
'Twig\\' =>
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
),
'TheNetworg\\OAuth2\\Client\\' =>
'TheNetworg\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/thenetworg/oauth2-azure/src',
),
'Symfony\\Polyfill\\Php83\\' =>
'Symfony\\Polyfill\\Php83\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
),
'Symfony\\Polyfill\\Mbstring\\' =>
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer',
),
'Symfony\\Polyfill\\Intl\\Idn\\' =>
'Symfony\\Polyfill\\Intl\\Idn\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
),
'Symfony\\Polyfill\\Intl\\Icu\\' =>
'Symfony\\Polyfill\\Intl\\Icu\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-icu',
),
'Symfony\\Polyfill\\Intl\\Grapheme\\' =>
'Symfony\\Polyfill\\Intl\\Grapheme\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme',
),
'Symfony\\Polyfill\\Ctype\\' =>
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Symfony\\Contracts\\Translation\\' =>
'Symfony\\Contracts\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation-contracts',
),
'Symfony\\Contracts\\Service\\' =>
'Symfony\\Contracts\\Service\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/service-contracts',
),
'Symfony\\Contracts\\EventDispatcher\\' =>
'Symfony\\Contracts\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts',
),
'Symfony\\Contracts\\Cache\\' =>
'Symfony\\Contracts\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache-contracts',
),
'Symfony\\Component\\Yaml\\' =>
'Symfony\\Component\\Yaml\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/yaml',
),
'Symfony\\Component\\VarExporter\\' =>
'Symfony\\Component\\VarExporter\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-exporter',
),
'Symfony\\Component\\VarDumper\\' =>
'Symfony\\Component\\VarDumper\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-dumper',
),
'Symfony\\Component\\Validator\\' =>
'Symfony\\Component\\Validator\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/validator',
),
'Symfony\\Component\\String\\' =>
'Symfony\\Component\\String\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/string',
),
'Symfony\\Component\\Stopwatch\\' =>
'Symfony\\Component\\Stopwatch\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/stopwatch',
),
'Symfony\\Component\\Security\\Csrf\\' =>
'Symfony\\Component\\Security\\Csrf\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/security-csrf',
),
'Symfony\\Component\\Security\\Core\\' =>
'Symfony\\Component\\Security\\Core\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/security-core',
),
'Symfony\\Component\\Routing\\' =>
'Symfony\\Component\\Routing\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/routing',
),
'Symfony\\Component\\PropertyInfo\\' =>
'Symfony\\Component\\PropertyInfo\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/property-info',
),
'Symfony\\Component\\PropertyAccess\\' =>
'Symfony\\Component\\PropertyAccess\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/property-access',
),
'Symfony\\Component\\PasswordHasher\\' =>
'Symfony\\Component\\PasswordHasher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/password-hasher',
),
'Symfony\\Component\\OptionsResolver\\' =>
'Symfony\\Component\\OptionsResolver\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/options-resolver',
),
'Symfony\\Component\\Mime\\' =>
'Symfony\\Component\\Mime\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/mime',
),
'Symfony\\Component\\Mailer\\' =>
'Symfony\\Component\\Mailer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/mailer',
),
'Symfony\\Component\\HttpKernel\\' =>
'Symfony\\Component\\HttpKernel\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-kernel',
),
'Symfony\\Component\\HttpFoundation\\' =>
'Symfony\\Component\\HttpFoundation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-foundation',
),
'Symfony\\Component\\Form\\' =>
'Symfony\\Component\\Form\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/form',
),
'Symfony\\Component\\Finder\\' =>
'Symfony\\Component\\Finder\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/finder',
),
'Symfony\\Component\\Filesystem\\' =>
'Symfony\\Component\\Filesystem\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/filesystem',
),
'Symfony\\Component\\EventDispatcher\\' =>
'Symfony\\Component\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Symfony\\Component\\ErrorHandler\\' =>
'Symfony\\Component\\ErrorHandler\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/error-handler',
),
'Symfony\\Component\\Dotenv\\' =>
'Symfony\\Component\\Dotenv\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dotenv',
),
'Symfony\\Component\\DependencyInjection\\' =>
'Symfony\\Component\\DependencyInjection\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dependency-injection',
),
'Symfony\\Component\\CssSelector\\' =>
'Symfony\\Component\\CssSelector\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/css-selector',
),
'Symfony\\Component\\Console\\' =>
'Symfony\\Component\\Console\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/console',
),
'Symfony\\Component\\Config\\' =>
'Symfony\\Component\\Config\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/config',
),
'Symfony\\Component\\Cache\\' =>
'Symfony\\Component\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache',
),
'Symfony\\Bundle\\WebProfilerBundle\\' =>
'Symfony\\Bundle\\WebProfilerBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/web-profiler-bundle',
),
'Symfony\\Bundle\\TwigBundle\\' =>
'Symfony\\Bundle\\TwigBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/twig-bundle',
),
'Symfony\\Bundle\\FrameworkBundle\\' =>
'Symfony\\Bundle\\FrameworkBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/framework-bundle',
),
'Symfony\\Bridge\\Twig\\' =>
'Symfony\\Bridge\\Twig\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/twig-bridge',
),
'Soundasleep\\' =>
'Soundasleep\\' =>
array (
0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
),
'ScssPhp\\ScssPhp\\' =>
'ScssPhp\\ScssPhp\\' =>
array (
0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
),
'Sabberworm\\CSS\\' =>
'Sabberworm\\CSS\\' =>
array (
0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src',
),
'Psr\\Log\\' =>
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/src',
),
'Psr\\Http\\Message\\' =>
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-factory/src',
1 => __DIR__ . '/..' . '/psr/http-message/src',
),
'Psr\\Http\\Client\\' =>
'Psr\\Http\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-client/src',
),
'Psr\\EventDispatcher\\' =>
'Psr\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/psr/event-dispatcher/src',
),
'Psr\\Container\\' =>
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'Psr\\Cache\\' =>
'Psr\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/cache/src',
),
'PhpParser\\' =>
'PhpParser\\' =>
array (
0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
'Pelago\\Emogrifier\\' =>
'Pelago\\Emogrifier\\' =>
array (
0 => __DIR__ . '/..' . '/pelago/emogrifier/src',
),
'League\\OAuth2\\Client\\' =>
'League\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/league/oauth2-google/src',
1 => __DIR__ . '/..' . '/league/oauth2-client/src',
),
'GuzzleHttp\\Psr7\\' =>
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
),
'GuzzleHttp\\Promise\\' =>
'GuzzleHttp\\Promise\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
),
'GuzzleHttp\\' =>
'GuzzleHttp\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Firebase\\JWT\\' =>
'Firebase\\JWT\\' =>
array (
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
),
'Egulias\\EmailValidator\\' =>
'Egulias\\EmailValidator\\' =>
array (
0 => __DIR__ . '/..' . '/egulias/email-validator/src',
),
'Doctrine\\Common\\Lexer\\' =>
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/src',
),
);
public static $prefixesPsr0 = array (
'C' =>
'C' =>
array (
'Console' =>
'Console' =>
array (
0 => __DIR__ . '/..' . '/pear/console_getopt',
),
),
'A' =>
'A' =>
array (
'Archive_Tar' =>
'Archive_Tar' =>
array (
0 => __DIR__ . '/..' . '/pear/archive_tar',
),
@@ -733,6 +733,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ObjectController.php',
'Combodo\\iTop\\Controller\\Base\\Layout\\OqlController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/OqlController.php',
'Combodo\\iTop\\Controller\\Links\\LinkSetController' => __DIR__ . '/../..' . '/sources/Controller/Links/LinkSetController.php',
'Combodo\\iTop\\Controller\\Links\\SynchroReplicaController' => __DIR__ . '/../..' . '/sources/Controller/Links/SynchroReplicaController.php',
'Combodo\\iTop\\Controller\\Newsroom\\iTopNewsroomController' => __DIR__ . '/../..' . '/sources/Controller/Newsroom/iTopNewsroomController.php',
'Combodo\\iTop\\Controller\\Notifications\\ActionController' => __DIR__ . '/../..' . '/sources/Controller/Notifications/ActionController.php',
'Combodo\\iTop\\Controller\\Notifications\\NotificationsCenterController' => __DIR__ . '/../..' . '/sources/Controller/Notifications/NotificationsCenterController.php',
@@ -1240,6 +1241,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Firebase\\JWT\\JWTExceptionWithPayloadInterface' => __DIR__ . '/..' . '/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php',
'Firebase\\JWT\\Key' => __DIR__ . '/..' . '/firebase/php-jwt/src/Key.php',
'Firebase\\JWT\\SignatureInvalidException' => __DIR__ . '/..' . '/firebase/php-jwt/src/SignatureInvalidException.php',
'ForgotPasswordApplicationException' => __DIR__ . '/../..' . '/application/exceptions/ForgotPasswordApplicationException.php',
'ForgotPasswordUserInputException' => __DIR__ . '/../..' . '/application/exceptions/ForgotPasswordUserInputException.php',
'FunctionExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
'FunctionOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
'GraphEdge' => __DIR__ . '/../..' . '/core/simplegraph.class.inc.php',
@@ -2153,22 +2156,43 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Cache\\Psr16Cache' => __DIR__ . '/..' . '/symfony/cache/Psr16Cache.php',
'Symfony\\Component\\Cache\\ResettableInterface' => __DIR__ . '/..' . '/symfony/cache/ResettableInterface.php',
'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractAdapterTrait.php',
'Symfony\\Component\\Cache\\Traits\\CachedValueInterface' => __DIR__ . '/..' . '/symfony/cache/Traits/CachedValueInterface.php',
'Symfony\\Component\\Cache\\Traits\\ContractsTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ContractsTrait.php',
'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemCommonTrait.php',
'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemTrait.php',
'Symfony\\Component\\Cache\\Traits\\ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis5Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis5Proxy.php',
'Symfony\\Component\\Cache\\Traits\\Redis61ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis61ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis62ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis62ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis63ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis63ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Redis6Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis6Proxy.php',
'Symfony\\Component\\Cache\\Traits\\Redis6ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis6ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster5Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster5Proxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster61ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster61ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster62ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster62ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster63ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster63ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster6Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster6Proxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisCluster6ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster6ProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\RedisClusterNodeProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisClusterNodeProxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisClusterProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisClusterProxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisProxy.php',
'Symfony\\Component\\Cache\\Traits\\RedisTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisTrait.php',
'Symfony\\Component\\Cache\\Traits\\RelayProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RelayProxy.php',
'Symfony\\Component\\Cache\\Traits\\RelayProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RelayProxyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\BgsaveTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/BgsaveTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\CopyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/CopyTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\FtTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/FtTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\GeosearchTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/GeosearchTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\GetWithMetaTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/GetWithMetaTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\GetrangeTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/GetrangeTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\HsetTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/HsetTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\IsTrackedTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/IsTrackedTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\MoveTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/MoveTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\NullableReturnTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/NullableReturnTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\PfcountTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/PfcountTrait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay11Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay11Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay121Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay121Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay12Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay12Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\Relay20Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay20Trait.php',
'Symfony\\Component\\Cache\\Traits\\Relay\\SwapdbTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/SwapdbTrait.php',
'Symfony\\Component\\Config\\Builder\\ClassBuilder' => __DIR__ . '/..' . '/symfony/config/Builder/ClassBuilder.php',
'Symfony\\Component\\Config\\Builder\\ConfigBuilderGenerator' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderGenerator.php',
'Symfony\\Component\\Config\\Builder\\ConfigBuilderGeneratorInterface' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderGeneratorInterface.php',
@@ -2333,6 +2357,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Console\\Helper\\TableRows' => __DIR__ . '/..' . '/symfony/console/Helper/TableRows.php',
'Symfony\\Component\\Console\\Helper\\TableSeparator' => __DIR__ . '/..' . '/symfony/console/Helper/TableSeparator.php',
'Symfony\\Component\\Console\\Helper\\TableStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableStyle.php',
'Symfony\\Component\\Console\\Helper\\TerminalInputHelper' => __DIR__ . '/..' . '/symfony/console/Helper/TerminalInputHelper.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => __DIR__ . '/..' . '/symfony/console/Input/ArgvInput.php',
'Symfony\\Component\\Console\\Input\\ArrayInput' => __DIR__ . '/..' . '/symfony/console/Input/ArrayInput.php',
'Symfony\\Component\\Console\\Input\\Input' => __DIR__ . '/..' . '/symfony/console/Input/Input.php',
@@ -3000,17 +3025,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface' => __DIR__ . '/..' . '/symfony/http-foundation/Session/Storage/SessionStorageInterface.php',
'Symfony\\Component\\HttpFoundation\\StreamedJsonResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedJsonResponse.php',
'Symfony\\Component\\HttpFoundation\\StreamedResponse' => __DIR__ . '/..' . '/symfony/http-foundation/StreamedResponse.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\RequestAttributeValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/RequestAttributeValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseCookieValueSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseFormatSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseFormatSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasCookie' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHasHeader' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHasHeader.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderLocationSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderLocationSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseHeaderSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseHeaderSame.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsRedirected' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsRedirected.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsSuccessful' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsSuccessful.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseIsUnprocessable' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseIsUnprocessable.php',
'Symfony\\Component\\HttpFoundation\\Test\\Constraint\\ResponseStatusCodeSame' => __DIR__ . '/..' . '/symfony/http-foundation/Test/Constraint/ResponseStatusCodeSame.php',
'Symfony\\Component\\HttpFoundation\\UriSigner' => __DIR__ . '/..' . '/symfony/http-foundation/UriSigner.php',
'Symfony\\Component\\HttpFoundation\\UrlHelper' => __DIR__ . '/..' . '/symfony/http-foundation/UrlHelper.php',
'Symfony\\Component\\HttpKernel\\Attribute\\AsController' => __DIR__ . '/..' . '/symfony/http-kernel/Attribute/AsController.php',
@@ -4009,6 +4023,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Twig\\ExpressionParser\\InfixExpressionParserInterface' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/InfixExpressionParserInterface.php',
'Twig\\ExpressionParser\\Infix\\ArgumentsTrait' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/ArgumentsTrait.php',
'Twig\\ExpressionParser\\Infix\\ArrowExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/ArrowExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\AssignmentExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/AssignmentExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\BinaryOperatorExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/BinaryOperatorExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\ConditionalTernaryExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/ConditionalTernaryExpressionParser.php',
'Twig\\ExpressionParser\\Infix\\DotExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/DotExpressionParser.php',
@@ -4094,10 +4109,15 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Twig\\Node\\Expression\\Binary\\MulBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MulBinary.php',
'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php',
'Twig\\Node\\Expression\\Binary\\NotInBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php',
'Twig\\Node\\Expression\\Binary\\NotSameAsBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotSameAsBinary.php',
'Twig\\Node\\Expression\\Binary\\NullCoalesceBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NullCoalesceBinary.php',
'Twig\\Node\\Expression\\Binary\\ObjectDestructuringSetBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ObjectDestructuringSetBinary.php',
'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
'Twig\\Node\\Expression\\Binary\\SameAsBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SameAsBinary.php',
'Twig\\Node\\Expression\\Binary\\SequenceDestructuringSetBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SequenceDestructuringSetBinary.php',
'Twig\\Node\\Expression\\Binary\\SetBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SetBinary.php',
'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php',
'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
@@ -4106,6 +4126,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Twig\\Node\\Expression\\CallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/CallExpression.php',
'Twig\\Node\\Expression\\ConditionalExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConditionalExpression.php',
'Twig\\Node\\Expression\\ConstantExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConstantExpression.php',
'Twig\\Node\\Expression\\EmptyExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/EmptyExpression.php',
'Twig\\Node\\Expression\\FilterExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FilterExpression.php',
'Twig\\Node\\Expression\\Filter\\DefaultFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php',
'Twig\\Node\\Expression\\Filter\\RawFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/RawFilter.php',
@@ -4231,6 +4252,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php',
'Twig\\Util\\ReflectionCallable' => __DIR__ . '/..' . '/twig/twig/src/Util/ReflectionCallable.php',
'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php',
'UI' => __DIR__ . '/../..' . '/sources/Controller/UI.php',
'UIExtKeyWidget' => __DIR__ . '/../..' . '/application/ui.extkeywidget.class.inc.php',
'UIHTMLEditorWidget' => __DIR__ . '/../..' . '/application/ui.htmleditorwidget.class.inc.php',
'UILinksWidget' => __DIR__ . '/../..' . '/application/ui.linkswidget.class.inc.php',

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
'name' => 'combodo/itop',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '2b828f8a22d238f2221cc9e157c83d8d2ebd0696',
'reference' => '0f11fd9919aab579586a6f52e1c74f317518040c',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -22,7 +22,7 @@
'combodo/itop' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '2b828f8a22d238f2221cc9e157c83d8d2ebd0696',
'reference' => '0f11fd9919aab579586a6f52e1c74f317518040c',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -310,9 +310,9 @@
'dev_requirement' => false,
),
'symfony/cache' => array(
'pretty_version' => 'v6.4.12',
'version' => '6.4.12.0',
'reference' => 'a463451b7f6ac4a47b98dbfc78ec2d3560c759d8',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => '5b088fa41eb9568748dc255c45e4054c387ba73b',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/cache',
'aliases' => array(),
@@ -334,18 +334,18 @@
),
),
'symfony/config' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '80e2cf005cf17138c97193be0434cdcfd1b2212e',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => 'd445badf0ad2c2a492e38c0378c39997a56ef97b',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/config',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/console' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '273fd29ff30ba0a88ca5fb83f7cf1ab69306adae',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/console',
'aliases' => array(),
@@ -361,9 +361,9 @@
'dev_requirement' => false,
),
'symfony/dependency-injection' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '900da8a42eceeb4a13a0ec34caa7db49328daff3',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => 'b17882e933c4c606620247b6708ab53aa3b88753',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/dependency-injection',
'aliases' => array(),
@@ -379,27 +379,27 @@
'dev_requirement' => false,
),
'symfony/dotenv' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '234b6c602f12b00693f4b0d1054386fb30dfc8ff',
'pretty_version' => 'v6.4.30',
'version' => '6.4.30.0',
'reference' => '924edbc9631b75302def0258ed1697948b17baf6',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/dotenv',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/error-handler' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '30fd0b3cf0e972e82636038ce4db0e4fe777112c',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '8c18400784fcb014dc73c8d5601a9576af7f8ad4',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/error-handler',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/event-dispatcher' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => 'b0cf3162020603587363f0551cd3be43958611ff',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '99d7e101826e6610606b9433248f80c1997cd20b',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(),
@@ -421,90 +421,90 @@
),
),
'symfony/filesystem' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '75ae2edb7cdcc0c53766c30b0a2512b8df574bd8',
'pretty_version' => 'v6.4.30',
'version' => '6.4.30.0',
'reference' => '441c6b69f7222aadae7cbf5df588496d5ee37789',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/filesystem',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/finder' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '73089124388c8510efb8d2d1689285d285937b08',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => '24965ca011dac87431729640feef8bcf7b5523e0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/finder',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/form' => array(
'pretty_version' => 'v6.4.26',
'version' => '6.4.26.0',
'reference' => 'b40cdbe70be9274ea807ef61da7d0f8d1c70dc51',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => 'b758162fb45024f898640ec27f4ac90be0dbfb8f',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/form',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/framework-bundle' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '1d6a764b58e4f780df00f71c20ba3a61095ea447',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => '9ef2d0b63b9e855ba351e770a603d89699115801',
'type' => 'symfony-bundle',
'install_path' => __DIR__ . '/../symfony/framework-bundle',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/http-foundation' => array(
'pretty_version' => 'v6.4.29',
'version' => '6.4.29.0',
'reference' => 'b03d11e015552a315714c127d8d1e0f9e970ec88',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => 'f1a490cc9d595ba7ebe684220e625d1e472ad278',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-foundation',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/http-kernel' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => 'a0ee3cea5cabf4ed960fd2ef57668ceeacdb6e15',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => '73fa5c999d7f741ca544a97d3c791cc97890ae4d',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-kernel',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/mailer' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '628b43b45a3e6b15c8a633fb22df547ed9b492a2',
'pretty_version' => 'v6.4.31',
'version' => '6.4.31.0',
'reference' => '8835f93333474780fda1b987cae37e33c3e026ca',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mailer',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/mime' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '664d5e844a2de5e11c8255d0aef6bc15a9660ac7',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '7409686879ca36c09fc970a5fa8ff6e93504dba4',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mime',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/options-resolver' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => 'd28e7e2db8a73e9511df892d36445f61314bbebe',
'pretty_version' => 'v6.4.30',
'version' => '6.4.30.0',
'reference' => 'eeaa8cabe54c7b3516938c72a4a161c0cc80a34f',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/options-resolver',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/password-hasher' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => 'dcab5ac87450aaed26483ba49c2ce86808da7557',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => 'fbdfa5a2ca218ec8bb9029517426df2d780bdba9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/password-hasher',
'aliases' => array(),
@@ -574,45 +574,45 @@
'dev_requirement' => false,
),
'symfony/property-access' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => 'fedc771326d4978a7d3167fa009a509b06a2e168',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '6dfa655ac9e9860c05cabb287f34da86b18c237e',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/property-access',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/property-info' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '1056ae3621eeddd78d7c5ec074f1c1784324eec6',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => '7d961dbb543fcfaa57fa55e555edd466e90160be',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/property-info',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/routing' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => 'e4f94e625c8e6f910aa004a0042f7b2d398278f5',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '0dc6253e864e71b486e8ba4970a56ab849106ebe',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/routing',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/security-core' => array(
'pretty_version' => 'v6.4.26',
'version' => '6.4.26.0',
'reference' => '8b7c95bf04d82fcd0c06a918b2d849bfb2ab9cc0',
'pretty_version' => 'v6.4.31',
'version' => '6.4.31.0',
'reference' => 'fa269ad61a021cc54329dc96e57bed78ba720bfe',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/security-core',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/security-csrf' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '9a1efc8c10b86bcedc9233affd10c716b54ca1b7',
'pretty_version' => 'v6.4.31',
'version' => '6.4.31.0',
'reference' => '52f62836fcb19cd351ef3a2aa9cf61a489e8990f',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/security-csrf',
'aliases' => array(),
@@ -643,54 +643,54 @@
'dev_requirement' => true,
),
'symfony/string' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1',
'pretty_version' => 'v6.4.30',
'version' => '6.4.30.0',
'reference' => '50590a057841fa6bf69d12eceffce3465b9e32cb',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/string',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/translation-contracts' => array(
'pretty_version' => 'v3.6.0',
'version' => '3.6.0.0',
'reference' => 'df210c7a2573f1913b2d17cc95f90f53a73d8f7d',
'pretty_version' => 'v3.6.1',
'version' => '3.6.1.0',
'reference' => '65a8bc82080447fae78373aa10f8d13b38338977',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/twig-bridge' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '9d13e87591c9de3221c8d6f23cd9a2b5958607bf',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8',
'type' => 'symfony-bridge',
'install_path' => __DIR__ . '/../symfony/twig-bridge',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/twig-bundle' => array(
'pretty_version' => 'v6.4.24',
'version' => '6.4.24.0',
'reference' => '3b48b6e8225495c6d2438828982b4d219ca565ba',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => 'a5c8dcc11a5bf9c96320da20070d2e158a4e0b30',
'type' => 'symfony-bundle',
'install_path' => __DIR__ . '/../symfony/twig-bundle',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/validator' => array(
'pretty_version' => 'v6.4.29',
'version' => '6.4.29.0',
'reference' => '99df8a769e64e399f510166141ea74f450e8dd1d',
'pretty_version' => 'v6.4.33',
'version' => '6.4.33.0',
'reference' => 'da1a40418439c0483ca7e0d4ae4c4f744f6b8536',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/validator',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/var-dumper' => array(
'pretty_version' => 'v6.4.26',
'version' => '6.4.26.0',
'reference' => 'cfae1497a2f1eaad78dbc0590311c599c7178d4a',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '131fc9915e0343052af5ed5040401b481ca192aa',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
@@ -706,18 +706,18 @@
'dev_requirement' => false,
),
'symfony/web-profiler-bundle' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => '4c1754d6b3ffe52e9eaed0d9a392eb43a60fc910',
'pretty_version' => 'v6.4.32',
'version' => '6.4.32.0',
'reference' => '011f59e3f3d20f60d11b4e78b8dc63504f56e145',
'type' => 'symfony-bundle',
'install_path' => __DIR__ . '/../symfony/web-profiler-bundle',
'aliases' => array(),
'dev_requirement' => true,
),
'symfony/yaml' => array(
'pretty_version' => 'v6.4.25',
'version' => '6.4.25.0',
'reference' => 'e54b060bc9c3dc3d4258bf0d165d0064e755f565',
'pretty_version' => 'v6.4.30',
'version' => '6.4.30.0',
'reference' => '8207ae83da19ee3748d6d4f567b4d9a7c656e331',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/yaml',
'aliases' => array(),
@@ -742,9 +742,9 @@
'dev_requirement' => false,
),
'twig/twig' => array(
'pretty_version' => 'v3.21.1',
'version' => '3.21.1.0',
'reference' => '285123877d4dd97dd7c11842ac5fb7e86e60d81d',
'pretty_version' => 'v3.23.0',
'version' => '3.23.0.0',
'reference' => 'a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9',
'type' => 'library',
'install_path' => __DIR__ . '/../twig/twig',
'aliases' => array(),

View File

@@ -36,7 +36,8 @@ if ($issues) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
throw new \RuntimeException(
'Composer detected issues in your platform: ' . implode(' ', $issues)
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@@ -40,7 +40,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR;
$this->defaultLifetime = $defaultLifetime;
if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
throw new InvalidArgumentException(\sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
}
self::$createCacheItem ??= \Closure::bind(
static function ($key, $value, $isHit) {
@@ -155,7 +155,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
$ok = false;
$v = $values[$id];
$type = get_debug_type($v);
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
$message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
}
} else {
@@ -178,7 +178,7 @@ abstract class AbstractAdapter implements AdapterInterface, CacheInterface, Logg
}
$ok = false;
$type = get_debug_type($v);
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
$message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
}
}

View File

@@ -42,7 +42,7 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
$this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':';
$this->defaultLifetime = $defaultLifetime;
if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) {
throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
throw new InvalidArgumentException(\sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace));
}
self::$createCacheItem ??= \Closure::bind(
static function ($key, $value, $isHit) {
@@ -194,7 +194,7 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
$ok = false;
$v = $values[$id];
$type = get_debug_type($v);
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
$message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
}
} else {
@@ -218,7 +218,7 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
}
$ok = false;
$type = get_debug_type($v);
$message = sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
$message = \sprintf('Failed to save key "{key}" of type %s%s', $type, $e instanceof \Exception ? ': '.$e->getMessage() : '.');
CacheItem::log($this->logger, $message, ['key' => substr($id, \strlen($this->namespace)), 'exception' => $e instanceof \Exception ? $e : null, 'cache-adapter' => get_debug_type($this)]);
}
}

View File

@@ -82,7 +82,7 @@ class ApcuAdapter extends AbstractAdapter
protected function doClear(string $namespace): bool
{
return isset($namespace[0]) && class_exists(\APCUIterator::class, false) && ('cli' !== \PHP_SAPI || filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL))
? apcu_delete(new \APCUIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY))
? apcu_delete(new \APCUIterator(\sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY))
: apcu_clear_cache();
}
@@ -101,19 +101,10 @@ class ApcuAdapter extends AbstractAdapter
return $failed;
}
try {
if (false === $failures = apcu_store($values, null, $lifetime)) {
$failures = $values;
}
return array_keys($failures);
} catch (\Throwable $e) {
if (1 === \count($values)) {
// Workaround https://github.com/krakjoe/apcu/issues/170
apcu_delete(array_key_first($values));
}
throw $e;
if (false === $failures = apcu_store($values, null, $lifetime)) {
$failures = $values;
}
return array_keys($failures);
}
}

View File

@@ -46,11 +46,11 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
public function __construct(int $defaultLifetime = 0, bool $storeSerialized = true, float $maxLifetime = 0, int $maxItems = 0)
{
if (0 > $maxLifetime) {
throw new InvalidArgumentException(sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime));
throw new InvalidArgumentException(\sprintf('Argument $maxLifetime must be positive, %F passed.', $maxLifetime));
}
if (0 > $maxItems) {
throw new InvalidArgumentException(sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems));
throw new InvalidArgumentException(\sprintf('Argument $maxItems must be a positive integer, %d passed.', $maxItems));
}
$this->defaultLifetime = $defaultLifetime;
@@ -312,9 +312,11 @@ class ArrayAdapter implements AdapterInterface, CacheInterface, LoggerAwareInter
try {
$serialized = serialize($value);
} catch (\Exception $e) {
unset($this->values[$key], $this->tags[$key]);
if (!isset($this->expiries[$key])) {
unset($this->values[$key]);
}
$type = get_debug_type($value);
$message = sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
$message = \sprintf('Failed to save key "{key}" of type %s: %s', $type, $e->getMessage());
CacheItem::log($this->logger, $message, ['key' => $key, 'exception' => $e, 'cache-adapter' => get_debug_type($this)]);
return null;

View File

@@ -51,7 +51,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
foreach ($adapters as $adapter) {
if (!$adapter instanceof CacheItemPoolInterface) {
throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', get_debug_type($adapter), CacheItemPoolInterface::class));
throw new InvalidArgumentException(\sprintf('The class "%s" does not implement the "%s" interface.', get_debug_type($adapter), CacheItemPoolInterface::class));
}
if ('cli' === \PHP_SAPI && $adapter instanceof ApcuAdapter && !filter_var(\ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOL)) {
continue; // skip putting APCu in the chain when the backend is disabled
@@ -76,7 +76,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
$item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata;
if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) {
$item->expiresAt(\DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY])));
$item->expiresAt(\DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $item->metadata[CacheItem::METADATA_EXPIRY])));
} elseif (0 < $defaultLifetime) {
$item->expiresAfter($defaultLifetime);
}
@@ -106,7 +106,7 @@ class ChainAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
$callback = $wrap;
$beta = \INF === $beta ? \INF : 0;
}
if ($adapter instanceof CacheInterface) {
if ($adapter instanceof CacheInterface && $i !== $this->adapterCount) {
$value = $adapter->get($key, $callback, $beta, $metadata);
} else {
$value = $this->doGet($adapter, $key, $callback, $beta, $metadata);

View File

@@ -62,7 +62,7 @@ class DoctrineDbalAdapter extends AbstractAdapter implements PruneableInterface
public function __construct(Connection|string $connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], ?MarshallerInterface $marshaller = null)
{
if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) {
throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0]));
throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0]));
}
if ($connOrDsn instanceof Connection) {
@@ -151,7 +151,7 @@ class DoctrineDbalAdapter extends AbstractAdapter implements PruneableInterface
if ('' !== $this->namespace) {
$deleteSql .= " AND $this->idCol LIKE ?";
$params[] = sprintf('%s%%', $this->namespace);
$params[] = \sprintf('%s%%', $this->namespace);
$paramTypes[] = ParameterType::STRING;
}

View File

@@ -25,7 +25,7 @@ class MemcachedAdapter extends AbstractAdapter
/**
* We are replacing characters that are illegal in Memcached keys with reserved characters from
* {@see \Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS} that are legal in Memcached.
* Note: dont use {@see \Symfony\Component\Cache\Adapter\AbstractAdapter::NS_SEPARATOR}.
* Note: dont use {@see AbstractAdapter::NS_SEPARATOR}.
*/
private const RESERVED_MEMCACHED = " \n\r\t\v\f\0";
private const RESERVED_PSR6 = '@()\{}/';
@@ -314,7 +314,7 @@ class MemcachedAdapter extends AbstractAdapter
throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".');
}
if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) {
throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix));
throw new CacheException(\sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix));
}
return $this->client = $this->lazyClient;

View File

@@ -29,7 +29,7 @@ final class ParameterNormalizer
try {
return \DateTimeImmutable::createFromFormat('U', 0)->add(new \DateInterval($duration))->getTimestamp();
} catch (\Exception $e) {
throw new \InvalidArgumentException(sprintf('Cannot parse date interval "%s".', $duration), 0, $e);
throw new \InvalidArgumentException(\sprintf('Cannot parse date interval "%s".', $duration), 0, $e);
}
}
}

View File

@@ -57,16 +57,16 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
public function __construct(#[\SensitiveParameter] \PDO|string $connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], ?MarshallerInterface $marshaller = null)
{
if (\is_string($connOrDsn) && str_contains($connOrDsn, '://')) {
throw new InvalidArgumentException(sprintf('Usage of Doctrine DBAL URL with "%s" is not supported. Use a PDO DSN or "%s" instead.', __CLASS__, DoctrineDbalAdapter::class));
throw new InvalidArgumentException(\sprintf('Usage of Doctrine DBAL URL with "%s" is not supported. Use a PDO DSN or "%s" instead.', __CLASS__, DoctrineDbalAdapter::class));
}
if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) {
throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0]));
throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0]));
}
if ($connOrDsn instanceof \PDO) {
if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__));
throw new InvalidArgumentException(\sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__));
}
$this->conn = $connOrDsn;
@@ -108,12 +108,12 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
// - trailing space removal
// - case-insensitivity
// - language processing like é == e
'mysql' => "CREATE TABLE $this->table ($this->idCol VARBINARY(255) NOT NULL PRIMARY KEY, $this->dataCol MEDIUMBLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8mb4_bin, ENGINE = InnoDB",
'mysql' => "CREATE TABLE $this->table ($this->idCol VARBINARY(255) NOT NULL PRIMARY KEY, $this->dataCol MEDIUMBLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED, $this->timeCol INTEGER UNSIGNED NOT NULL), ENGINE = InnoDB",
'sqlite' => "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)",
'pgsql' => "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)",
'oci' => "CREATE TABLE $this->table ($this->idCol VARCHAR2(255) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)",
'sqlsrv' => "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)",
default => throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $driver)),
default => throw new \DomainException(\sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $driver)),
};
$this->getConnection()->exec($sql);
@@ -137,7 +137,7 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
$delete->bindValue(':time', time(), \PDO::PARAM_INT);
if ('' !== $this->namespace) {
$delete->bindValue(':namespace', sprintf('%s%%', $this->namespace), \PDO::PARAM_STR);
$delete->bindValue(':namespace', \sprintf('%s%%', $this->namespace), \PDO::PARAM_STR);
}
try {
return $delete->execute();
@@ -314,7 +314,17 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface
$insertStmt->bindValue(':time', $now, \PDO::PARAM_INT);
}
if ('sqlsrv' === $driver) {
$dataStream = fopen('php://memory', 'r+');
}
foreach ($values as $id => $data) {
if ('sqlsrv' === $driver) {
rewind($dataStream);
fwrite($dataStream, $data);
ftruncate($dataStream, \strlen($data));
rewind($dataStream);
$data = $dataStream;
}
try {
$stmt->execute();
} catch (\PDOException $e) {

View File

@@ -17,6 +17,7 @@ use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\ResettableInterface;
use Symfony\Component\Cache\Traits\CachedValueInterface;
use Symfony\Component\Cache\Traits\ContractsTrait;
use Symfony\Component\Cache\Traits\ProxyTrait;
use Symfony\Component\VarExporter\VarExporter;
@@ -96,22 +97,21 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
if ('N;' === $value) {
return null;
}
if (!$value instanceof CachedValueInterface) {
return $value;
}
try {
if ($value instanceof \Closure) {
return $value();
}
return $value->getValue();
} catch (\Throwable) {
unset($this->keys[$key]);
goto get_from_pool;
}
return $value;
}
public function getItem(mixed $key): CacheItem
{
if (!\is_string($key)) {
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
}
if (!isset($this->values)) {
$this->initialize();
@@ -125,9 +125,9 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
if ('N;' === $value) {
$value = null;
} elseif ($value instanceof \Closure) {
} elseif ($value instanceof CachedValueInterface) {
try {
$value = $value();
$value = $value->getValue();
} catch (\Throwable) {
$value = null;
$isHit = false;
@@ -141,7 +141,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
{
foreach ($keys as $key) {
if (!\is_string($key)) {
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
}
}
if (!isset($this->values)) {
@@ -154,7 +154,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
public function hasItem(mixed $key): bool
{
if (!\is_string($key)) {
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
}
if (!isset($this->values)) {
$this->initialize();
@@ -166,7 +166,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
public function deleteItem(mixed $key): bool
{
if (!\is_string($key)) {
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
}
if (!isset($this->values)) {
$this->initialize();
@@ -182,7 +182,7 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
foreach ($keys as $key) {
if (!\is_string($key)) {
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
}
if (isset($this->keys[$key])) {
@@ -250,21 +250,21 @@ class PhpArrayAdapter implements AdapterInterface, CacheInterface, PruneableInte
{
if (file_exists($this->file)) {
if (!is_file($this->file)) {
throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file));
throw new InvalidArgumentException(\sprintf('Cache path exists and is not a file: "%s".', $this->file));
}
if (!is_writable($this->file)) {
throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file));
throw new InvalidArgumentException(\sprintf('Cache file is not writable: "%s".', $this->file));
}
} else {
$directory = \dirname($this->file);
if (!is_dir($directory) && !@mkdir($directory, 0777, true)) {
throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory));
throw new InvalidArgumentException(\sprintf('Cache directory does not exist and cannot be created: "%s".', $directory));
}
if (!is_writable($directory)) {
throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory));
throw new InvalidArgumentException(\sprintf('Cache directory is not writable: "%s".', $directory));
}
}
@@ -291,7 +291,7 @@ EOF;
try {
$value = VarExporter::export($value, $isStaticValue, $preload);
} catch (\Exception $e) {
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
}
} elseif (\is_string($value)) {
// Wrap "N;" in a closure to not confuse it with an encoded `null`
@@ -300,14 +300,13 @@ EOF;
}
$value = var_export($value, true);
} elseif (!\is_scalar($value)) {
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
} else {
$value = var_export($value, true);
}
if (!$isStaticValue) {
$value = str_replace("\n", "\n ", $value);
$value = "static function () {\n return {$value};\n}";
$value = 'new class() implements \\'.CachedValueInterface::class." { public function getValue(): mixed { return {$value}; } }";
}
$hash = hash('xxh128', $value);
@@ -368,9 +367,9 @@ EOF;
if ('N;' === $value) {
yield $key => $f($key, null, true);
} elseif ($value instanceof \Closure) {
} elseif ($value instanceof CachedValueInterface) {
try {
yield $key => $f($key, $value(), true);
yield $key => $f($key, $value->getValue(), true);
} catch (\Throwable) {
yield $key => $f($key, null, false);
}

View File

@@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Adapter;
use Symfony\Component\Cache\Exception\CacheException;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Traits\CachedValueInterface;
use Symfony\Component\Cache\Traits\FilesystemCommonTrait;
use Symfony\Component\VarExporter\VarExporter;
@@ -114,8 +115,10 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
$values[$id] = null;
} elseif (!\is_object($value)) {
$values[$id] = $value;
} elseif ($value instanceof CachedValueInterface) {
$values[$id] = $value->getValue();
} elseif (!$value instanceof LazyValue) {
$values[$id] = $value();
$values[$id] = $value;
} elseif (false === $values[$id] = include $value->file) {
unset($values[$id], $this->values[$id]);
$missingIds[] = $id;
@@ -152,7 +155,7 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
if ($now >= $expiresAt) {
unset($this->values[$id], $missingIds[$k], self::$valuesCache[$file]);
}
} catch (\ErrorException $e) {
} catch (\ErrorException) {
unset($missingIds[$k]);
}
}
@@ -217,7 +220,7 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
try {
$value = VarExporter::export($value, $isStaticValue);
} catch (\Exception $e) {
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)), 0, $e);
}
} elseif (\is_string($value)) {
// Wrap "N;" in a closure to not confuse it with an encoded `null`
@@ -226,7 +229,7 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
}
$value = var_export($value, true);
} elseif (!\is_scalar($value)) {
throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
throw new InvalidArgumentException(\sprintf('Cache key "%s" has non-serializable "%s" value.', $key, get_debug_type($value)));
} else {
$value = var_export($value, true);
}
@@ -236,7 +239,7 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
if ($isStaticValue) {
$value = "return [{$expiry}, {$value}];";
} elseif ($this->appendOnly) {
$value = "return [{$expiry}, static fn () => {$value}];";
$value = "return [{$expiry}, new class() implements \\".CachedValueInterface::class." { public function getValue(): mixed { return {$value}; } }];";
} else {
// We cannot use a closure here because of https://bugs.php.net/76982
$value = str_replace('\Symfony\Component\VarExporter\Internal\\', '', $value);
@@ -255,7 +258,7 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface
}
if (!$ok && !is_writable($this->directory)) {
throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory));
throw new CacheException(\sprintf('Cache directory is not writable (%s).', $this->directory));
}
return $ok;

View File

@@ -73,7 +73,7 @@ class ProxyAdapter implements AdapterInterface, CacheInterface, PruneableInterfa
self::$setInnerItem ??= \Closure::bind(
static function (CacheItemInterface $innerItem, CacheItem $item, $expiry = null) {
$innerItem->set($item->pack());
$innerItem->expiresAt(($expiry ?? $item->expiry) ? \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', $expiry ?? $item->expiry)) : null);
$innerItem->expiresAt(($expiry ?? $item->expiry) ? \DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $expiry ?? $item->expiry)) : null);
},
null,
CacheItem::class

View File

@@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Adapter;
use Predis\Connection\Aggregate\ClusterInterface;
use Predis\Connection\Aggregate\PredisCluster;
use Predis\Connection\Aggregate\ReplicationInterface;
use Predis\Connection\Replication\ReplicationInterface as Predis2ReplicationInterface;
use Predis\Response\ErrorInterface;
use Predis\Response\Status;
use Relay\Relay;
@@ -63,7 +64,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
public function __construct(\Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis, string $namespace = '', int $defaultLifetime = 0, ?MarshallerInterface $marshaller = null)
{
if ($redis instanceof \Predis\ClientInterface && $redis->getConnection() instanceof ClusterInterface && !$redis->getConnection() instanceof PredisCluster) {
throw new InvalidArgumentException(sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection())));
throw new InvalidArgumentException(\sprintf('Unsupported Predis cluster connection: only "%s" is, "%s" given.', PredisCluster::class, get_debug_type($redis->getConnection())));
}
$isRelay = $redis instanceof Relay;
@@ -72,7 +73,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
foreach (\is_array($compression) ? $compression : [$compression] as $c) {
if ($isRelay ? Relay::COMPRESSION_NONE : \Redis::COMPRESSION_NONE !== $c) {
throw new InvalidArgumentException(sprintf('redis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class));
throw new InvalidArgumentException(\sprintf('redis compression must be disabled when using "%s", use "%s" instead.', static::class, DeflateMarshaller::class));
}
}
}
@@ -85,7 +86,7 @@ class RedisTagAwareAdapter extends AbstractTagAwareAdapter
{
$eviction = $this->getRedisEvictionPolicy();
if ('noeviction' !== $eviction && !str_starts_with($eviction, 'volatile-')) {
throw new LogicException(sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction));
throw new LogicException(\sprintf('Redis maxmemory-policy setting "%s" is *not* supported by RedisTagAwareAdapter, use "noeviction" or "volatile-*" eviction policies.', $eviction));
}
// serialize values
@@ -286,9 +287,16 @@ EOLUA;
$hosts = $this->getHosts();
$host = reset($hosts);
if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) {
if ($host instanceof \Predis\Client) {
$connection = $host->getConnection();
// Predis supports info command only on the master in replication environments
$hosts = [$host->getClientFor('master')];
if ($connection instanceof ReplicationInterface) {
$hosts = [$host->getClientFor('master')];
} elseif ($connection instanceof Predis2ReplicationInterface) {
$connection->switchToMaster();
$hosts = [$host];
}
}
foreach ($hosts as $host) {

View File

@@ -294,15 +294,12 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
$this->tags instanceof ResettableInterface && $this->tags->reset();
}
public function __sleep(): array
public function __serialize(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
/**
* @return void
*/
public function __wakeup()
public function __unserialize(array $data): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
@@ -366,7 +363,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
(self::$saveTags)($this->tags, $newTags);
}
while ($now > ($this->knownTagVersions[$tag = array_key_first($this->knownTagVersions)][0] ?? \INF)) {
while ($now > ($this->knownTagVersions[$tag = array_key_first($this->knownTagVersions) ?? ''][0] ?? \INF)) {
unset($this->knownTagVersions[$tag]);
}

View File

@@ -38,7 +38,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInt
public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed
{
if (!$this->pool instanceof CacheInterface) {
throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class));
throw new \BadMethodCallException(\sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class));
}
$isHit = true;

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache;
use Psr\Cache\CacheItemInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Exception\LogicException;
@@ -30,7 +31,7 @@ final class CacheItem implements ItemInterface
protected float|int|null $expiry = null;
protected array $metadata = [];
protected array $newMetadata = [];
protected ?ItemInterface $innerItem = null;
protected ?CacheItemInterface $innerItem = null;
protected ?string $poolHash = null;
protected bool $isTaggable = false;
@@ -81,7 +82,7 @@ final class CacheItem implements ItemInterface
} elseif (\is_int($time)) {
$this->expiry = $time + microtime(true);
} else {
throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', get_debug_type($time)));
throw new InvalidArgumentException(\sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', get_debug_type($time)));
}
return $this;
@@ -90,14 +91,14 @@ final class CacheItem implements ItemInterface
public function tag(mixed $tags): static
{
if (!$this->isTaggable) {
throw new LogicException(sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
throw new LogicException(\sprintf('Cache item "%s" comes from a non tag-aware pool: you cannot tag it.', $this->key));
}
if (!\is_array($tags) && !$tags instanceof \Traversable) { // don't use is_iterable(), it's slow
$tags = [$tags];
}
foreach ($tags as $tag) {
if (!\is_string($tag) && !$tag instanceof \Stringable) {
throw new InvalidArgumentException(sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', get_debug_type($tag)));
throw new InvalidArgumentException(\sprintf('Cache tag must be string or object that implements __toString(), "%s" given.', get_debug_type($tag)));
}
$tag = (string) $tag;
if (isset($this->newMetadata[self::METADATA_TAGS][$tag])) {
@@ -107,7 +108,7 @@ final class CacheItem implements ItemInterface
throw new InvalidArgumentException('Cache tag length must be greater than zero.');
}
if (false !== strpbrk($tag, self::RESERVED_CHARACTERS)) {
throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS));
throw new InvalidArgumentException(\sprintf('Cache tag "%s" contains reserved characters "%s".', $tag, self::RESERVED_CHARACTERS));
}
$this->newMetadata[self::METADATA_TAGS][$tag] = $tag;
}
@@ -130,13 +131,13 @@ final class CacheItem implements ItemInterface
public static function validateKey($key): string
{
if (!\is_string($key)) {
throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
throw new InvalidArgumentException(\sprintf('Cache key must be string, "%s" given.', get_debug_type($key)));
}
if ('' === $key) {
throw new InvalidArgumentException('Cache key length must be greater than zero.');
}
if (false !== strpbrk($key, self::RESERVED_CHARACTERS)) {
throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
throw new InvalidArgumentException(\sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
}
return $key;
@@ -196,3 +197,5 @@ final class CacheItem implements ItemInterface
return true;
}
}
// @php-cs-fixer-ignore protected_to_private Friend-level scope access relies on protected properties

View File

@@ -38,15 +38,7 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
{
$empty = ['calls' => [], 'adapters' => [], 'config' => [], 'options' => [], 'statistics' => []];
$this->data = ['instances' => $empty, 'total' => $empty];
foreach ($this->instances as $name => $instance) {
$this->data['instances']['calls'][$name] = $instance->getCalls();
$this->data['instances']['adapters'][$name] = get_debug_type($instance->getPool());
}
$this->data['instances']['statistics'] = $this->calculateStatistics();
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
$this->lateCollect();
}
public function reset(): void
@@ -59,6 +51,15 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
public function lateCollect(): void
{
$empty = ['calls' => [], 'adapters' => [], 'config' => [], 'options' => [], 'statistics' => []];
$this->data = ['instances' => $empty, 'total' => $empty];
foreach ($this->instances as $name => $instance) {
$this->data['instances']['calls'][$name] = $instance->getCalls();
$this->data['instances']['adapters'][$name] = get_debug_type($instance->getPool());
}
$this->data['instances']['statistics'] = $this->calculateStatistics();
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
$this->data['instances']['calls'] = $this->cloneVar($this->data['instances']['calls']);
}
@@ -142,6 +143,8 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
}
} elseif ('save' === $call->name) {
++$statistics[$name]['writes'];
} elseif ('saveDeferred' === $call->name) {
++$statistics[$name]['writes'];
} elseif ('deleteItem' === $call->name) {
++$statistics[$name]['deletes'];
}

View File

@@ -16,7 +16,9 @@ use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\ParameterNormalizer;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Messenger\EarlyExpirationDispatcher;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -51,6 +53,7 @@ class CachePoolPass implements CompilerPassInterface
'default_lifetime',
'early_expiration_message_bus',
'reset',
'pruneable',
];
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $tags) {
$adapter = $pool = $container->getDefinition($id);
@@ -58,9 +61,11 @@ class CachePoolPass implements CompilerPassInterface
continue;
}
$class = $adapter->getClass();
$providers = $adapter->getArguments();
while ($adapter instanceof ChildDefinition) {
$adapter = $container->findDefinition($adapter->getParent());
$class = $class ?: $adapter->getClass();
$providers += $adapter->getArguments();
if ($t = $adapter->getTag('cache.pool')) {
$tags[0] += $t[0];
}
@@ -88,11 +93,13 @@ class CachePoolPass implements CompilerPassInterface
$tags[0]['provider'] = new Reference(static::getServiceProvider($container, $tags[0]['provider']));
}
$pruneable = $tags[0]['pruneable'] ?? $container->getReflectionClass($class, false)?->implementsInterface(PruneableInterface::class) ?? false;
if (ChainAdapter::class === $class) {
$adapters = [];
foreach ($adapter->getArgument(0) as $provider => $adapter) {
foreach ($providers['index_0'] ?? $providers[0] as $provider => $adapter) {
if ($adapter instanceof ChildDefinition) {
$chainedPool = $adapter;
$chainedPool = clone $adapter;
} else {
$chainedPool = $adapter = new ChildDefinition($adapter);
}
@@ -109,7 +116,7 @@ class CachePoolPass implements CompilerPassInterface
}
if (ChainAdapter::class === $chainedClass) {
throw new InvalidArgumentException(sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent()));
throw new InvalidArgumentException(\sprintf('Invalid service "%s": chain of adapters cannot reference another chain, found "%s".', $id, $chainedPool->getParent()));
}
$i = 0;
@@ -154,7 +161,9 @@ class CachePoolPass implements CompilerPassInterface
),
]);
$pool->addTag('container.reversible');
} elseif ('namespace' !== $attr || !\in_array($class, [ArrayAdapter::class, NullAdapter::class], true)) {
} elseif ('pruneable' === $attr) {
// no-op
} elseif ('namespace' !== $attr || !\in_array($class, [ArrayAdapter::class, NullAdapter::class, TagAwareAdapter::class], true)) {
$argument = $tags[0][$attr];
if ('default_lifetime' === $attr && !is_numeric($argument)) {
@@ -167,13 +176,17 @@ class CachePoolPass implements CompilerPassInterface
unset($tags[0][$attr]);
}
if (!empty($tags[0])) {
throw new InvalidArgumentException(sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime", "early_expiration_message_bus" and "reset", found "%s".', $id, implode('", "', array_keys($tags[0]))));
throw new InvalidArgumentException(\sprintf('Invalid "cache.pool" tag for service "%s": accepted attributes are "clearer", "provider", "name", "namespace", "default_lifetime", "early_expiration_message_bus", "reset" and "pruneable", found "%s".', $id, implode('", "', array_keys($tags[0]))));
}
if (null !== $clearer) {
$clearers[$clearer][$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
}
$poolTags = $pool->getTags();
$poolTags['cache.pool'][0]['pruneable'] ??= $pruneable;
$pool->setTags($poolTags);
$allPools[$name] = new Reference($id, $container::IGNORE_ON_UNINITIALIZED_REFERENCE);
}
@@ -197,10 +210,6 @@ class CachePoolPass implements CompilerPassInterface
$clearer->setArgument(0, $pools);
}
$clearer->addTag('cache.pool.clearer');
if ('cache.system_clearer' === $id) {
$clearer->addTag('kernel.cache_clearer');
}
}
$allPoolsKeys = array_keys($allPools);

View File

@@ -15,7 +15,6 @@ use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
/**
@@ -35,14 +34,8 @@ class CachePoolPrunerPass implements CompilerPassInterface
$services = [];
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $tags) {
$class = $container->getParameterBag()->resolveValue($container->getDefinition($id)->getClass());
if (!$reflection = $container->getReflectionClass($class)) {
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
}
if ($reflection->implementsInterface(PruneableInterface::class)) {
$services[$id] = new Reference($id);
if ($tags[0]['pruneable'] ?? $container->getReflectionClass($container->getDefinition($id)->getClass(), false)?->implementsInterface(PruneableInterface::class) ?? false) {
$services[$tags[0]['name'] ?? $id] = new Reference($id);
}
}

View File

@@ -83,7 +83,7 @@ final class LockRegistry
return $previousFiles;
}
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, ?\Closure $setMetadata = null, ?LoggerInterface $logger = null): mixed
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, ?\Closure $setMetadata = null, ?LoggerInterface $logger = null, ?float $beta = null): mixed
{
if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedFiles) {
// disable locking on Windows by default
@@ -105,7 +105,7 @@ final class LockRegistry
$locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
if ($locked || !$wouldBlock) {
$logger?->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
$logger?->info(\sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
self::$lockedFiles[$key] = true;
$value = $callback($item, $save);
@@ -124,6 +124,11 @@ final class LockRegistry
// if we failed the race, retry locking in blocking mode to wait for the winner
$logger?->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
flock($lock, \LOCK_SH);
if (\INF === $beta) {
$logger?->info('Force-recomputing item "{key}"', ['key' => $item->getKey()]);
continue;
}
} finally {
flock($lock, \LOCK_UN);
unset(self::$lockedFiles[$key]);

View File

@@ -37,13 +37,13 @@ class EarlyExpirationDispatcher
/**
* @return mixed
*/
public function __invoke(callable $callback, CacheItem $item, bool &$save, AdapterInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger = null)
public function __invoke(callable $callback, CacheItem $item, bool &$save, AdapterInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger = null, ?float $beta = null)
{
if (!$item->isHit() || null === $message = EarlyExpirationMessage::create($this->reverseContainer, $callback, $item, $pool)) {
// The item is stale or the callback cannot be reversed: we must compute the value now
$logger?->info('Computing item "{key}" online: '.($item->isHit() ? 'callback cannot be reversed' : 'item is stale'), ['key' => $item->getKey()]);
return null !== $this->callbackWrapper ? ($this->callbackWrapper)($callback, $item, $save, $pool, $setMetadata, $logger) : $callback($item, $save);
return null !== $this->callbackWrapper ? ($this->callbackWrapper)($callback, $item, $save, $pool, $setMetadata, $logger, $beta) : $callback($item, $save);
}
$envelope = $this->bus->dispatch($message);

View File

@@ -35,6 +35,11 @@ final class EarlyExpirationMessage
$pool = $reverseContainer->getId($pool);
if ($callback instanceof \Closure && !str_contains(($r = new \ReflectionFunction($callback))->name, '{closure')) {
$callback = [$r->getClosureThis() ?? (\PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass())?->name, $r->name];
$callback[0] ?: $callback = $r->name;
}
if (\is_object($callback)) {
if (null === $id = $reverseContainer->getId($callback)) {
return null;

View File

@@ -135,7 +135,7 @@ class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterf
if ($keys instanceof \Traversable) {
$keys = iterator_to_array($keys, false);
} elseif (!\is_array($keys)) {
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
throw new InvalidArgumentException(\sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
}
try {
@@ -166,7 +166,7 @@ class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterf
{
$valuesIsArray = \is_array($values);
if (!$valuesIsArray && !$values instanceof \Traversable) {
throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', get_debug_type($values)));
throw new InvalidArgumentException(\sprintf('Cache values must be array or Traversable, "%s" given.', get_debug_type($values)));
}
$items = [];
@@ -215,7 +215,7 @@ class Psr16Cache implements CacheInterface, PruneableInterface, ResettableInterf
if ($keys instanceof \Traversable) {
$keys = iterator_to_array($keys, false);
} elseif (!\is_array($keys)) {
throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
throw new InvalidArgumentException(\sprintf('Cache keys must be array or Traversable, "%s" given.', get_debug_type($keys)));
}
try {

View File

@@ -276,15 +276,12 @@ trait AbstractAdapterTrait
$this->ids = [];
}
public function __sleep(): array
public function __serialize(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
/**
* @return void
*/
public function __wakeup()
public function __unserialize(array $data): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}
@@ -303,7 +300,7 @@ trait AbstractAdapterTrait
try {
foreach ($items as $id => $value) {
if (!isset($keys[$id])) {
throw new InvalidArgumentException(sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys)));
throw new InvalidArgumentException(\sprintf('Could not match value id "%s" to keys "%s".', $id, implode('", "', $keys)));
}
$key = $keys[$id];
unset($keys[$id]);

View File

@@ -0,0 +1,20 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Traits;
/**
* @internal
*/
interface CachedValueInterface
{
public function getValue(): mixed;
}

View File

@@ -54,7 +54,7 @@ trait ContractsTrait
}
$previousWrapper = $this->callbackWrapper;
$this->callbackWrapper = $callbackWrapper ?? static fn (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) => $callback($item, $save);
$this->callbackWrapper = $callbackWrapper ?? static fn (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger, ?float $beta = null) => $callback($item, $save);
return $previousWrapper;
}
@@ -62,7 +62,7 @@ trait ContractsTrait
private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, ?array &$metadata = null): mixed
{
if (0 > $beta ??= 1.0) {
throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta));
throw new InvalidArgumentException(\sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta));
}
static $setMetadata;
@@ -82,7 +82,7 @@ trait ContractsTrait
$this->callbackWrapper ??= LockRegistry::compute(...);
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) {
return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key, $beta) {
// don't wrap nor save recursive calls
if (isset($this->computing[$key])) {
$value = $callback($item, $save);
@@ -101,7 +101,7 @@ trait ContractsTrait
try {
$value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) {
$setMetadata($item, $startTime, $metadata);
}, $this->logger ?? null);
}, $this->logger ?? null, $beta);
$setMetadata($item, $startTime, $metadata);
return $value;

View File

@@ -32,7 +32,7 @@ trait FilesystemCommonTrait
}
if (isset($namespace[0])) {
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
}
$directory .= \DIRECTORY_SEPARATOR.$namespace;
} else {
@@ -44,7 +44,7 @@ trait FilesystemCommonTrait
$directory .= \DIRECTORY_SEPARATOR;
// On Windows the whole path is limited to 258 chars
if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) {
throw new InvalidArgumentException(sprintf('Cache directory too long (%s).', $directory));
throw new InvalidArgumentException(\sprintf('Cache directory too long (%s).', $directory));
}
$this->directory = $directory;
@@ -172,15 +172,12 @@ trait FilesystemCommonTrait
}
}
public function __sleep(): array
public function __serialize(): array
{
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
}
/**
* @return void
*/
public function __wakeup()
public function __unserialize(array $data): void
{
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
}

View File

@@ -92,7 +92,7 @@ trait FilesystemTrait
}
if ($failed && !is_writable($this->directory)) {
throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory));
throw new CacheException(\sprintf('Cache directory is not writable (%s).', $this->directory));
}
return $failed;

View File

@@ -15,7 +15,7 @@ if (version_compare(phpversion('redis'), '6.1.0-dev', '>=')) {
/**
* @internal
*/
trait Redis6ProxyTrait
trait Redis61ProxyTrait
{
public function dump($key): \Redis|string|false
{
@@ -51,7 +51,7 @@ if (version_compare(phpversion('redis'), '6.1.0-dev', '>=')) {
/**
* @internal
*/
trait Redis6ProxyTrait
trait Redis61ProxyTrait
{
public function dump($key): \Redis|string
{

View File

@@ -0,0 +1,52 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Traits;
if (version_compare(phpversion('redis'), '6.2.0', '>=')) {
/**
* @internal
*/
trait Redis62ProxyTrait
{
public function expiremember($key, $field, $ttl, $unit = null): \Redis|false|int
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expiremember(...\func_get_args());
}
public function expirememberat($key, $field, $timestamp): \Redis|false|int
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expirememberat(...\func_get_args());
}
public function getWithMeta($key): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getWithMeta(...\func_get_args());
}
public function serverName(): false|string
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->serverName(...\func_get_args());
}
public function serverVersion(): false|string
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->serverVersion(...\func_get_args());
}
}
} else {
/**
* @internal
*/
trait Redis62ProxyTrait
{
}
}

View File

@@ -0,0 +1,162 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Traits;
if (version_compare(phpversion('redis'), '6.3.0', '>=')) {
/**
* @internal
*/
trait Redis63ProxyTrait
{
public function delifeq($key, $value): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->delifeq(...\func_get_args());
}
public function hexpire($key, $ttl, $fields, $mode = null): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexpire(...\func_get_args());
}
public function hexpireat($key, $time, $fields, $mode = null): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexpireat(...\func_get_args());
}
public function hexpiretime($key, $fields): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexpiretime(...\func_get_args());
}
public function hgetdel($key, $fields): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetdel(...\func_get_args());
}
public function hgetex($key, $fields, $expiry = null): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetex(...\func_get_args());
}
public function hGetWithMeta($key, $member): mixed
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hGetWithMeta(...\func_get_args());
}
public function hpersist($key, $fields): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpersist(...\func_get_args());
}
public function hpexpire($key, $ttl, $fields, $mode = null): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpexpire(...\func_get_args());
}
public function hpexpireat($key, $mstime, $fields, $mode = null): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpexpireat(...\func_get_args());
}
public function hpexpiretime($key, $fields): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpexpiretime(...\func_get_args());
}
public function hpttl($key, $fields): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpttl(...\func_get_args());
}
public function hsetex($key, $fields, $expiry = null): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hsetex(...\func_get_args());
}
public function httl($key, $fields): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->httl(...\func_get_args());
}
public function vadd($key, $values, $element, $options = null): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vadd(...\func_get_args());
}
public function vcard($key): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vcard(...\func_get_args());
}
public function vdim($key): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vdim(...\func_get_args());
}
public function vemb($key, $member, $raw = false): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vemb(...\func_get_args());
}
public function vgetattr($key, $member, $decode = true): \Redis|array|string|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vgetattr(...\func_get_args());
}
public function vinfo($key): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vinfo(...\func_get_args());
}
public function vismember($key, $member): \Redis|bool
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vismember(...\func_get_args());
}
public function vlinks($key, $member, $withscores = false): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vlinks(...\func_get_args());
}
public function vrandmember($key, $count = 0): \Redis|array|string|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vrandmember(...\func_get_args());
}
public function vrange($key, $min, $max, $count = -1): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vrange(...\func_get_args());
}
public function vrem($key, $member): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vrem(...\func_get_args());
}
public function vsetattr($key, $member, $attributes): \Redis|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vsetattr(...\func_get_args());
}
public function vsim($key, $member, $options = null): \Redis|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vsim(...\func_get_args());
}
}
} else {
/**
* @internal
*/
trait Redis63ProxyTrait
{
}
}

View File

@@ -25,7 +25,9 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);
*/
class Redis6Proxy extends \Redis implements ResetInterface, LazyObjectInterface
{
use Redis6ProxyTrait;
use Redis61ProxyTrait;
use Redis62ProxyTrait;
use Redis63ProxyTrait;
use LazyProxyTrait {
resetLazyObject as reset;
}

View File

@@ -15,7 +15,7 @@ if (version_compare(phpversion('redis'), '6.1.0-dev', '>')) {
/**
* @internal
*/
trait RedisCluster6ProxyTrait
trait RedisCluster61ProxyTrait
{
public function getex($key, $options = []): \RedisCluster|string|false
{
@@ -36,7 +36,7 @@ if (version_compare(phpversion('redis'), '6.1.0-dev', '>')) {
/**
* @internal
*/
trait RedisCluster6ProxyTrait
trait RedisCluster61ProxyTrait
{
public function publish($channel, $message): \RedisCluster|bool
{

View File

@@ -0,0 +1,47 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Traits;
if (version_compare(phpversion('redis'), '6.2.0', '>=')) {
/**
* @internal
*/
trait RedisCluster62ProxyTrait
{
public function expiremember($key, $field, $ttl, $unit = null): \Redis|false|int
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expiremember(...\func_get_args());
}
public function expirememberat($key, $field, $timestamp): \Redis|false|int
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->expirememberat(...\func_get_args());
}
public function getdel($key): mixed
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getdel(...\func_get_args());
}
public function getWithMeta($key): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->getWithMeta(...\func_get_args());
}
}
} else {
/**
* @internal
*/
trait RedisCluster62ProxyTrait
{
}
}

View File

@@ -0,0 +1,162 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Traits;
if (version_compare(phpversion('redis'), '6.3.0', '>=')) {
/**
* @internal
*/
trait RedisCluster63ProxyTrait
{
public function delifeq($key, $value): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->delifeq(...\func_get_args());
}
public function hexpire($key, $ttl, $fields, $mode = null): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexpire(...\func_get_args());
}
public function hexpireat($key, $time, $fields, $mode = null): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexpireat(...\func_get_args());
}
public function hexpiretime($key, $fields): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hexpiretime(...\func_get_args());
}
public function hgetdel($key, $fields): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetdel(...\func_get_args());
}
public function hgetex($key, $fields, $expiry = null): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetex(...\func_get_args());
}
public function hgetWithMeta($key, $member): mixed
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hgetWithMeta(...\func_get_args());
}
public function hpersist($key, $fields): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpersist(...\func_get_args());
}
public function hpexpire($key, $ttl, $fields, $mode = null): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpexpire(...\func_get_args());
}
public function hpexpireat($key, $mstime, $fields, $mode = null): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpexpireat(...\func_get_args());
}
public function hpexpiretime($key, $fields): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpexpiretime(...\func_get_args());
}
public function hpttl($key, $fields): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hpttl(...\func_get_args());
}
public function hsetex($key, $fields, $expiry = null): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->hsetex(...\func_get_args());
}
public function httl($key, $fields): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->httl(...\func_get_args());
}
public function vadd($key, $values, $element, $options = null): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vadd(...\func_get_args());
}
public function vcard($key): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vcard(...\func_get_args());
}
public function vdim($key): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vdim(...\func_get_args());
}
public function vemb($key, $member, $raw = false): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vemb(...\func_get_args());
}
public function vgetattr($key, $member, $decode = true): \RedisCluster|array|string|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vgetattr(...\func_get_args());
}
public function vinfo($key): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vinfo(...\func_get_args());
}
public function vismember($key, $member): \RedisCluster|bool
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vismember(...\func_get_args());
}
public function vlinks($key, $member, $withscores = false): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vlinks(...\func_get_args());
}
public function vrandmember($key, $count = 0): \RedisCluster|array|string|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vrandmember(...\func_get_args());
}
public function vrange($key, $min, $max, $count = -1): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vrange(...\func_get_args());
}
public function vrem($key, $member): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vrem(...\func_get_args());
}
public function vsetattr($key, $member, $attributes): \RedisCluster|int|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vsetattr(...\func_get_args());
}
public function vsim($key, $member, $options = null): \RedisCluster|array|false
{
return ($this->lazyObjectState->realInstance ??= ($this->lazyObjectState->initializer)())->vsim(...\func_get_args());
}
}
} else {
/**
* @internal
*/
trait RedisCluster63ProxyTrait
{
}
}

View File

@@ -25,7 +25,9 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);
*/
class RedisCluster6Proxy extends \RedisCluster implements ResetInterface, LazyObjectInterface
{
use RedisCluster6ProxyTrait;
use RedisCluster61ProxyTrait;
use RedisCluster62ProxyTrait;
use RedisCluster63ProxyTrait;
use LazyProxyTrait {
resetLazyObject as reset;
}

View File

@@ -17,6 +17,7 @@ use Predis\Connection\Aggregate\RedisCluster;
use Predis\Connection\Aggregate\ReplicationInterface;
use Predis\Connection\Cluster\ClusterInterface as Predis2ClusterInterface;
use Predis\Connection\Cluster\RedisCluster as Predis2RedisCluster;
use Predis\Connection\Replication\ReplicationInterface as Predis2ReplicationInterface;
use Predis\Response\ErrorInterface;
use Predis\Response\Status;
use Relay\Relay;
@@ -36,6 +37,7 @@ trait RedisTrait
{
private static array $defaultConnectionOptions = [
'class' => null,
'auth' => null,
'persistent' => 0,
'persistent_id' => null,
'timeout' => 30,
@@ -57,7 +59,7 @@ trait RedisTrait
parent::__construct($namespace, $defaultLifetime);
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
throw new InvalidArgumentException(\sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
}
if ($redis instanceof \Predis\ClientInterface && $redis->getOptions()->exceptions) {
@@ -94,10 +96,11 @@ trait RedisTrait
throw new InvalidArgumentException('Invalid Redis DSN: it does not start with "redis[s]:".');
}
if (!\extension_loaded('redis') && !class_exists(\Predis\Client::class)) {
throw new CacheException('Cannot find the "redis" extension nor the "predis/predis" package.');
if (!\extension_loaded('redis') && !\extension_loaded('relay') && !class_exists(\Predis\Client::class)) {
throw new CacheException('Cannot find the "redis" extension nor the "relay" extension nor the "predis/predis" package.');
}
$auth = null;
$params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:(?<user>[^:@]*+):)?(?<password>[^@]*+)@)?#', function ($m) use (&$auth) {
if (isset($m['password'])) {
if (\in_array($m['user'], ['', 'default'], true)) {
@@ -172,6 +175,7 @@ trait RedisTrait
}
$params += $query + $options + self::$defaultConnectionOptions;
$params['auth'] ??= $auth;
if (isset($params['redis_sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) {
throw new CacheException('Redis Sentinel support requires one of: "predis/predis", "ext-redis >= 5.2", "ext-relay".');
@@ -200,7 +204,7 @@ trait RedisTrait
};
if (isset($params['redis_sentinel']) && !is_a($class, \Predis\Client::class, true) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) {
throw new CacheException(sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 5.2 nor ext-relay have been found.', $class));
throw new CacheException(\sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 5.2 nor ext-relay have been found.', $class));
}
$isRedisExt = is_a($class, \Redis::class, true);
@@ -216,7 +220,7 @@ trait RedisTrait
do {
$host = $hosts[$hostIndex]['host'] ?? $hosts[$hostIndex]['path'];
$port = $hosts[$hostIndex]['port'] ?? 0;
$passAuth = isset($params['auth']) && (!$isRedisExt || \defined('Redis::OPT_NULL_MULTIBULK_AS_NULL'));
$passAuth = null !== $params['auth'] && (!$isRedisExt || \defined('Redis::OPT_NULL_MULTIBULK_AS_NULL'));
$address = false;
if (isset($hosts[$hostIndex]['host']) && $tls) {
@@ -228,7 +232,7 @@ trait RedisTrait
}
try {
if (version_compare(phpversion('redis'), '6.0.0', '>=') && $isRedisExt) {
if ($isRedisExt && version_compare(phpversion('redis'), '6.0.0', '>=')) {
$options = [
'host' => $host,
'port' => $port,
@@ -246,10 +250,10 @@ trait RedisTrait
} else {
$extra = $passAuth ? [$params['auth']] : [];
$sentinel = new $sentinelClass($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...$extra);
$sentinel = @new $sentinelClass($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...$extra);
}
if ($address = $sentinel->getMasterAddrByName($params['redis_sentinel'])) {
if ($address = @$sentinel->getMasterAddrByName($params['redis_sentinel'])) {
[$host, $port] = $address;
}
} catch (\RedisException|\Relay\Exception $redisException) {
@@ -257,7 +261,7 @@ trait RedisTrait
} while (++$hostIndex < \count($hosts) && !$address);
if (isset($params['redis_sentinel']) && !$address) {
throw new InvalidArgumentException(sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel']), previous: $redisException ?? null);
throw new InvalidArgumentException(\sprintf('Failed to retrieve master information from sentinel "%s".', $params['redis_sentinel']), previous: $redisException ?? null);
}
try {
@@ -280,7 +284,7 @@ trait RedisTrait
}
}
if (isset($params['auth'])) {
if (null !== $params['auth']) {
$extra['auth'] = $params['auth'];
}
@$redis->{$connect}($host, $port, (float) $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...\defined('Redis::SCAN_PREFIX') || !$isRedisExt ? [$extra] : []);
@@ -292,23 +296,19 @@ trait RedisTrait
restore_error_handler();
}
if (!$isConnected) {
$error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? sprintf(' (%s)', $error[1]) : '';
$error = preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? \sprintf(' (%s)', $error[1]) : '';
throw new InvalidArgumentException('Redis connection failed: '.$error.'.');
}
if ((null !== $auth && !$redis->auth($auth))
// Due to a bug in phpredis we must always select the dbindex if persistent pooling is enabled
// @see https://github.com/phpredis/phpredis/issues/1920
// @see https://github.com/symfony/symfony/issues/51578
|| (($params['dbindex'] || ('pconnect' === $connect && '0' !== \ini_get('redis.pconnect.pooling_enabled'))) && !$redis->select($params['dbindex']))
) {
$e = preg_replace('/^ERR /', '', $redis->getLastError());
throw new InvalidArgumentException('Redis connection failed: '.$e.'.');
}
if (0 < $params['tcp_keepalive'] && (!$isRedisExt || \defined('Redis::OPT_TCP_KEEPALIVE'))) {
$redis->setOption($isRedisExt ? \Redis::OPT_TCP_KEEPALIVE : Relay::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);
}
if ((!\defined('Redis::SCAN_PREFIX') && null !== $auth && $isRedisExt && !$redis->auth($auth)) || !$redis->select($params['dbindex'])) {
$e = preg_replace('/^ERR /', '', $redis->getLastError());
throw new InvalidArgumentException('Redis connection failed: '.$e.'.');
}
} catch (\RedisException|\Relay\Exception $e) {
throw new InvalidArgumentException('Redis connection failed: '.$e->getMessage());
}
@@ -388,14 +388,12 @@ trait RedisTrait
if ($params['dbindex']) {
$params['parameters']['database'] = $params['dbindex'];
}
if (null !== $auth) {
if (\is_array($auth)) {
// ACL
$params['parameters']['username'] = $auth[0];
$params['parameters']['password'] = $auth[1];
} else {
$params['parameters']['password'] = $auth;
}
if (\is_array($params['auth'])) {
// ACL
$params['parameters']['username'] = $params['auth'][0];
$params['parameters']['password'] = $params['auth'][1];
} elseif (null !== $params['auth']) {
$params['parameters']['password'] = $params['auth'];
}
if (isset($params['ssl'])) {
@@ -417,9 +415,9 @@ trait RedisTrait
$redis->getConnection()->setSentinelTimeout($params['timeout']);
}
} elseif (class_exists($class, false)) {
throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster", "Relay\Relay" nor "Predis\ClientInterface".', $class));
throw new InvalidArgumentException(\sprintf('"%s" is not a subclass of "Redis", "RedisArray", "RedisCluster", "Relay\Relay" nor "Predis\ClientInterface".', $class));
} else {
throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
throw new InvalidArgumentException(\sprintf('Class "%s" does not exist.', $class));
}
return $redis;
@@ -433,7 +431,7 @@ trait RedisTrait
$result = [];
if ($this->redis instanceof \Predis\ClientInterface && ($this->redis->getConnection() instanceof ClusterInterface || $this->redis->getConnection() instanceof Predis2ClusterInterface)) {
if (($this->redis instanceof \Predis\ClientInterface && ($this->redis->getConnection() instanceof ClusterInterface || $this->redis->getConnection() instanceof Predis2ClusterInterface)) || $this->redis instanceof RelayCluster) {
$values = $this->pipeline(function () use ($ids) {
foreach ($ids as $id) {
yield 'get' => [$id];
@@ -473,9 +471,16 @@ trait RedisTrait
$cleared = true;
$hosts = $this->getHosts();
$host = reset($hosts);
if ($host instanceof \Predis\Client && $host->getConnection() instanceof ReplicationInterface) {
// Predis supports info command only on the master in replication environments
$hosts = [$host->getClientFor('master')];
if ($host instanceof \Predis\Client) {
$connection = $host->getConnection();
if ($connection instanceof ReplicationInterface) {
$hosts = [$host->getClientFor('master')];
} elseif ($connection instanceof Predis2ReplicationInterface) {
$connection->switchToMaster();
$hosts = [$host];
}
}
foreach ($hosts as $host) {
@@ -508,7 +513,7 @@ trait RedisTrait
$cursor = null;
do {
$keys = $host instanceof \Predis\ClientInterface ? $host->scan($cursor, 'MATCH', $pattern, 'COUNT', 1000) : $host->scan($cursor, $pattern, 1000);
$keys = $host instanceof \Predis\ClientInterface ? $host->scan($cursor ?? 0, 'MATCH', $pattern, 'COUNT', 1000) : $host->scan($cursor, $pattern, 1000);
if (isset($keys[1]) && \is_array($keys[1])) {
$cursor = $keys[0];
$keys = $keys[1];

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