mirror of
https://github.com/Combodo/iTop.git
synced 2026-08-27 00:18:19 +02:00
Compare commits
22 Commits
feature/97
...
faf/data_t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7517298c5 | ||
|
|
7663be6e6e | ||
|
|
574b7579c8 | ||
|
|
6a5f83e767 | ||
|
|
556f612f7e | ||
|
|
edc69bebba | ||
|
|
dce1994b85 | ||
|
|
fde6527057 | ||
|
|
0de0592c18 | ||
|
|
c9d512cc31 | ||
|
|
a3ef049063 | ||
|
|
87ec702c5e | ||
|
|
127be1933d | ||
|
|
2c14030fc5 | ||
|
|
7825c08069 | ||
|
|
4ddf17233f | ||
|
|
9493bb03d5 | ||
|
|
8f87c759b5 | ||
|
|
348c90145d | ||
|
|
c37143176a | ||
|
|
0c8229a68e | ||
|
|
fda5fe5ded |
@@ -5368,6 +5368,7 @@ JS
|
||||
/**
|
||||
* @param array $aChanges
|
||||
* @param bool $bIsNew
|
||||
* @param string|null $sStimulusBeingApplied
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
@@ -5381,6 +5382,20 @@ JS
|
||||
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied, 'cmdb_change' => self::GetCurrentChange()]);
|
||||
}
|
||||
|
||||
//////////////
|
||||
/// READ
|
||||
///
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @throws \CoreException
|
||||
* @since 3.3.0
|
||||
*/
|
||||
final public function FireEventReadDetails(string $sExportType): void
|
||||
{
|
||||
$this->FireEvent(EVENT_DATA_EXPORT, ['export_type' => $sExportType]);
|
||||
}
|
||||
|
||||
//////////////
|
||||
/// DELETE
|
||||
///
|
||||
|
||||
@@ -519,6 +519,31 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DATA_EXPORT" _delta="define">
|
||||
<name>Object details read from outside iTop</name>
|
||||
<description><![CDATA[An object details has been read during an export]]></description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<event_data>
|
||||
<event_datum id="object">
|
||||
<description>The object unarchived</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="attributes">
|
||||
<description>Attribute codes exposed (empty means potentially all attributes)</description>
|
||||
<type>array</type>
|
||||
</event_datum>
|
||||
<event_datum id="export_type">
|
||||
<description>Type of export</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DOWNLOAD_DOCUMENT" _delta="define">
|
||||
<name>Document downloaded</name>
|
||||
<description><![CDATA[A document has been downloaded from the GUI]]></description>
|
||||
|
||||
@@ -113,17 +113,43 @@ abstract class Query extends cmdbAbstractObject
|
||||
]
|
||||
));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeExternalKey(
|
||||
"owner_id",
|
||||
[
|
||||
"targetclass" => 'Contact',
|
||||
"allowed_values" => null,
|
||||
"sql" => 'owner_id',
|
||||
"is_null_allowed" => true,
|
||||
"depends_on" => [],
|
||||
"display_style" => 'select',
|
||||
"always_load_in_tables" => false,
|
||||
"on_target_delete" => DEL_AUTO,
|
||||
]
|
||||
));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeEnumSet(
|
||||
"usages",
|
||||
[
|
||||
"allowed_values" => null,
|
||||
"possible_values" => new ValueSetEnumPadded("export,reference,notif,draft,dashlet"),
|
||||
"sql" => "usages",
|
||||
"depends_on" => [],
|
||||
"is_null_allowed" => true,
|
||||
"max_items" => 12,
|
||||
]
|
||||
));
|
||||
|
||||
// Display lists
|
||||
MetaModel::Init_SetZListItems(
|
||||
'details',
|
||||
['name', 'is_template', 'description']
|
||||
['name', 'is_template', 'owner_id', 'usages', 'description']
|
||||
); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', ['description', 'usages']); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems('standard_search', ['name', 'description', 'is_template']); // Criteria of the std search form
|
||||
MetaModel::Init_SetZListItems(
|
||||
'default_search',
|
||||
['name', 'description', 'is_template']
|
||||
['name', 'description', 'is_template', 'owner_id', 'usages']
|
||||
); // Criteria of the default search form
|
||||
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
|
||||
}
|
||||
@@ -143,6 +169,15 @@ abstract class Query extends cmdbAbstractObject
|
||||
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
|
||||
}
|
||||
|
||||
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = [])
|
||||
{
|
||||
// read only attribute
|
||||
if (in_array($sAttCode, ['export_count', 'export_last_date', 'export_last_user_id'])) {
|
||||
return OPT_ATT_READONLY;
|
||||
}
|
||||
return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return export url.
|
||||
*
|
||||
@@ -214,15 +249,15 @@ class QueryOQL extends Query
|
||||
MetaModel::Init_SetZListItems(
|
||||
'details',
|
||||
[
|
||||
'col:col1' => ['fieldset:Query:baseinfo' => ['name', 'is_template', 'description', 'oql', 'fields']],
|
||||
'col:col1' => ['fieldset:Query:baseinfo' => ['name', 'is_template', 'owner_id', 'usages', 'description', 'oql', 'fields']],
|
||||
'col:col2' => ['fieldset:Query:exportInfo' => ['export_count', 'export_last_date', 'export_last_user_id', 'export_last_user_contact']],
|
||||
]
|
||||
); // Attributes to be displayed for the complete details
|
||||
MetaModel::Init_SetZListItems('list', ['description']); // Attributes to be displayed for a list
|
||||
MetaModel::Init_SetZListItems('list', ['description', 'usages']); // Attributes to be displayed for a list
|
||||
// Search criteria
|
||||
MetaModel::Init_SetZListItems(
|
||||
'standard_search',
|
||||
['name', 'description', 'is_template', 'fields', 'oql']
|
||||
['name', 'description', 'is_template', 'owner_id', 'usages', 'oql']
|
||||
); // Criteria of the std search form
|
||||
}
|
||||
|
||||
|
||||
14
composer.lock
generated
14
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "1cca58a0e26794fb9c546a001f7f7de8",
|
||||
"content-hash": "24e7507794b971955358df5f2b143ac4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "apereo/phpcas",
|
||||
@@ -5570,16 +5570,16 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.24.0",
|
||||
"version": "v3.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0"
|
||||
"reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6769aefb305efef849dc25c9fd1653358c148f0",
|
||||
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b",
|
||||
"reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5634,7 +5634,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.24.0"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5646,7 +5646,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-03-17T21:31:11+00:00"
|
||||
"time": "2026-07-03T20:44:34+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
@@ -334,12 +334,14 @@ EOF
|
||||
while ($aRow = $oSet->FetchAssoc()) {
|
||||
set_time_limit(intval($iLoopTimeLimit));
|
||||
$aData = [];
|
||||
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
|
||||
$aExportedObjects = [];
|
||||
foreach ($this->aStatusInfo['fields'] as $aFieldSpec) {
|
||||
$sAlias = $aFieldSpec['sAlias'];
|
||||
$sAttCode = $aFieldSpec['sAttCode'];
|
||||
|
||||
$sField = '';
|
||||
$oObj = $aRow[$sAlias];
|
||||
$aExportedObjects[] = $oObj;
|
||||
if ($oObj != null) {
|
||||
switch ($sAttCode) {
|
||||
case 'id':
|
||||
@@ -366,7 +368,13 @@ EOF
|
||||
}
|
||||
$sData .= implode($this->aStatusInfo['separator'], $aData)."\n";
|
||||
$iCount++;
|
||||
|
||||
$aExportedObjects = array_unique($aExportedObjects);
|
||||
foreach ($aExportedObjects as $oExportedObject) {
|
||||
$oExportedObject->FireEventReadDetails(get_class($this));
|
||||
}
|
||||
}
|
||||
|
||||
// Restore original date & time formats
|
||||
AttributeDateTime::SetFormat($oPrevDateTimeFormat);
|
||||
AttributeDate::SetFormat($oPrevDateFormat);
|
||||
|
||||
@@ -6247,7 +6247,9 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aChanges
|
||||
* @param bool $bIsNew
|
||||
* @param string|null $sStimulusBeingApplied
|
||||
*
|
||||
* @return void
|
||||
* @since 3.1.0
|
||||
@@ -6256,6 +6258,18 @@ abstract class DBObject implements iDisplay
|
||||
{
|
||||
}
|
||||
|
||||
//////////////
|
||||
/// READ
|
||||
///
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @since 3.3.0
|
||||
*/
|
||||
public function FireEventReadDetails(string $sExportType): void
|
||||
{
|
||||
}
|
||||
|
||||
//////////////
|
||||
/// DELETE
|
||||
///
|
||||
|
||||
@@ -288,11 +288,13 @@ EOF
|
||||
while ($aRow = $oSet->FetchAssoc()) {
|
||||
set_time_limit(intval($iLoopTimeLimit));
|
||||
$aData = [];
|
||||
$aExportedObjects = [];
|
||||
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
|
||||
$sAlias = $aFieldSpec['sAlias'];
|
||||
$sAttCode = $aFieldSpec['sAttCode'];
|
||||
|
||||
$oObj = $aRow[$sAlias];
|
||||
$aExportedObjects[] = $oObj;
|
||||
$sField = '';
|
||||
if ($oObj) {
|
||||
$sField = $this->GetValue($oObj, $sAttCode);
|
||||
@@ -301,6 +303,11 @@ EOF
|
||||
}
|
||||
fwrite($hFile, json_encode($aData)."\n");
|
||||
$iCount++;
|
||||
|
||||
$aExportedObjects = array_unique($aExportedObjects);
|
||||
foreach ($aExportedObjects as $oExportedObject) {
|
||||
$oExportedObject->FireEventReadDetails(get_class($this));
|
||||
}
|
||||
}
|
||||
set_time_limit(intval($iPreviousTimeLimit));
|
||||
$this->aStatusInfo['position'] += $this->iChunkSize;
|
||||
|
||||
@@ -139,6 +139,7 @@ class HTMLBulkExport extends TabularBulkExport
|
||||
} else {
|
||||
$sData .= "<tr>";
|
||||
}
|
||||
$aExportedObjects = [];
|
||||
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
|
||||
$sAlias = $aFieldSpec['sAlias'];
|
||||
$sAttCode = $aFieldSpec['sAttCode'];
|
||||
@@ -147,12 +148,18 @@ class HTMLBulkExport extends TabularBulkExport
|
||||
$sField = '';
|
||||
if ($oObj) {
|
||||
$sField = $this->GetValue($oObj, $sAttCode);
|
||||
$aExportedObjects[] = $oObj;
|
||||
}
|
||||
$sValue = ($sField === '') ? ' ' : $sField;
|
||||
$sData .= "<td>$sValue</td>";
|
||||
}
|
||||
$sData .= "</tr>";
|
||||
$iCount++;
|
||||
|
||||
$aExportedObjects = array_unique($aExportedObjects);
|
||||
foreach ($aExportedObjects as $oExportedObject) {
|
||||
$oExportedObject->FireEventReadDetails(get_class($this));
|
||||
}
|
||||
}
|
||||
set_time_limit(intval($iPreviousTimeLimit));
|
||||
$this->aStatusInfo['position'] += $this->iChunkSize;
|
||||
|
||||
@@ -434,7 +434,7 @@ JS
|
||||
* Resize an image so that it fits the maximum width/height defined in the config file
|
||||
* @param ormDocument $oImage The original image stored as an array (content / mimetype / filename)
|
||||
* @return ormDocument The resampled image (or the original one if it already fit)
|
||||
* @deprecated since 3.3.0 Replaced by ormDocument::ResizeImageToFit
|
||||
* @deprecated 3.3.0 Use ormDocument::ResizeImageToFit instead
|
||||
*/
|
||||
public static function ResizeImageToFit(ormDocument $oImage, &$aDimensions = null)
|
||||
{
|
||||
|
||||
@@ -408,7 +408,7 @@ class ormDocument
|
||||
* @param int $iMaxImageHeight Maximum height for the resized image
|
||||
* @param array|null $aFinalDimensions Image dimensions after resizing or null if unable to read the image
|
||||
* @return ormDocument The resampled image
|
||||
*
|
||||
* @since 3.3.0 N°3124
|
||||
*/
|
||||
public function ResizeImageToFit(int $iMaxWidth, int $iMaxHeight, array|null &$aFinalDimensions = null): static
|
||||
{
|
||||
|
||||
@@ -625,6 +625,7 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
|
||||
}
|
||||
|
||||
while ($oObject = $oObjectSet->Fetch()) {
|
||||
$oObject->FireEventReadDetails(get_class($this));
|
||||
$oResult->AddObject(0, '', $oObject, $aShowFields, RestUtils::HasRequestedExtendedOutput($sShowFields));
|
||||
}
|
||||
$oResult->message = "Found: ".$oObjectSet->Count();
|
||||
@@ -699,6 +700,7 @@ class CoreServices implements iRestServiceProvider, iRestInputSanitizer
|
||||
if ($oElement instanceof RelationObjectNode) {
|
||||
$oObject = $oElement->GetProperty('object');
|
||||
if ($oObject) {
|
||||
$oObject->FireEventReadDetails(get_class($this));
|
||||
if ($bEnableRedundancy && $sDirection == 'down') {
|
||||
// Add only the "reached" objects
|
||||
if ($oElement->GetProperty('is_reached')) {
|
||||
|
||||
@@ -233,7 +233,6 @@ EOF
|
||||
public function GetNextChunk(&$aStatus)
|
||||
{
|
||||
$sRetCode = 'run';
|
||||
$iPercentage = 0;
|
||||
|
||||
$oSet = new DBObjectSet($this->oSearch);
|
||||
$oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']);
|
||||
@@ -254,7 +253,8 @@ EOF
|
||||
set_time_limit(intval($iLoopTimeLimit));
|
||||
|
||||
$sData .= "<tr>";
|
||||
foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
|
||||
$aExportedObjects = [];
|
||||
foreach ($this->aStatusInfo['fields'] as $aFieldSpec) {
|
||||
$sAlias = $aFieldSpec['sAlias'];
|
||||
$sAttCode = $aFieldSpec['sAttCode'];
|
||||
|
||||
@@ -265,7 +265,7 @@ EOF
|
||||
$sData .= "<td x:str></td>";
|
||||
continue;
|
||||
}
|
||||
|
||||
$aExportedObjects[] = $oObj;
|
||||
switch ($sAttCode) {
|
||||
case 'id':
|
||||
$sField = $oObj->GetKey();
|
||||
@@ -322,6 +322,11 @@ EOF
|
||||
}
|
||||
$sData .= "</tr>";
|
||||
$iCount++;
|
||||
|
||||
$aExportedObjects = array_unique($aExportedObjects);
|
||||
foreach ($aExportedObjects as $oExportedObject) {
|
||||
$oExportedObject->FireEventReadDetails(get_class($this));
|
||||
}
|
||||
}
|
||||
set_time_limit(intval($iPreviousTimeLimit));
|
||||
$this->aStatusInfo['position'] += $this->iChunkSize;
|
||||
|
||||
@@ -135,6 +135,11 @@ abstract class Trigger extends cmdbAbstractObject
|
||||
if ($oAction->IsActive()) {
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aContextArgs['action->object()'] = $oAction;
|
||||
if (array_key_exists('this->object()', $aContextArgs)) {
|
||||
/** @var \DBObject $oObject */
|
||||
$oObject = $aContextArgs['this->object()'];
|
||||
$oObject->FireEventReadDetails(get_class($oAction));
|
||||
}
|
||||
$oAction->DoExecute($this, $aContextArgs);
|
||||
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ class XMLBulkExport extends BulkExport
|
||||
if (count($aAuthorizedClasses) > 1) {
|
||||
$sData .= "<Row>\n";
|
||||
}
|
||||
$aExportedObjects = [];
|
||||
foreach ($aAuthorizedClasses as $sAlias => $sClassName) {
|
||||
$oObj = $aObjects[$sAlias];
|
||||
if (is_null($oObj)) {
|
||||
@@ -151,6 +152,7 @@ class XMLBulkExport extends BulkExport
|
||||
} else {
|
||||
$sClassName = get_class($oObj);
|
||||
$sData .= "<$sClassName alias=\"$sAlias\" id=\"".$oObj->GetKey()."\">\n";
|
||||
$aExportedObjects[] = $oObj;
|
||||
}
|
||||
foreach ($aClass2Attributes[$sAlias] as $sAttCode => $oAttDef) {
|
||||
if (is_null($oObj)) {
|
||||
@@ -166,6 +168,11 @@ class XMLBulkExport extends BulkExport
|
||||
$sData .= "</Row>\n";
|
||||
}
|
||||
$iCount++;
|
||||
|
||||
$aExportedObjects = array_unique($aExportedObjects);
|
||||
foreach ($aExportedObjects as $oExportedObject) {
|
||||
$oExportedObject->FireEventReadDetails(get_class($this));
|
||||
}
|
||||
}
|
||||
|
||||
set_time_limit(intval($iPreviousTimeLimit));
|
||||
|
||||
@@ -19,6 +19,8 @@ $ibo-badge-colors: (
|
||||
'orange' : ($ibo-color-orange-100, $ibo-color-orange-900),
|
||||
'red': ($ibo-color-red-100, $ibo-color-red-900),
|
||||
'pink': ($ibo-color-pink-100, $ibo-color-pink-900),
|
||||
'purple': ($ibo-color-purple-100, $ibo-color-purple-900),
|
||||
'yellow': ($ibo-color-yellow-200, $ibo-color-yellow-900),
|
||||
) !default;
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
$ibo-input-select-icon--menu--icon--max-height: 100% !default;
|
||||
$ibo-input-select-icon--menu--icon--max-width: 100% !default;
|
||||
$ibo-input-select-icon--icon--padding-right: $ibo-spacing-200 !default;
|
||||
$ibo-input-select-icon--max-height: 100% !default;
|
||||
$ibo-input-select-icon--max-width: 100% !default;
|
||||
$ibo-input-select-icon--padding-right: $ibo-spacing-200 !default;
|
||||
|
||||
$ibo-input-select-icon--menu--z-index: 21 !default;
|
||||
$ibo-input-select-icon--menu--max-height: 300px !default;
|
||||
@@ -18,9 +18,9 @@ $ibo-input-select-icon--menu--icon--margin-right: 10px !default;
|
||||
display: inline-flex;
|
||||
text-align: left;
|
||||
>img{
|
||||
max-height: $ibo-input-select-icon--menu--icon--max-height;
|
||||
max-width: $ibo-input-select-icon--menu--icon--max-width;
|
||||
padding-right: $ibo-input-select-icon--icon--padding-right;
|
||||
max-height: $ibo-input-select-icon--max-height;
|
||||
max-width: $ibo-input-select-icon--max-width;
|
||||
padding-right: $ibo-input-select-icon--padding-right;
|
||||
}
|
||||
>span{
|
||||
overflow: hidden;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -611,32 +611,6 @@ body {
|
||||
.setup-extension--missing .setup-extension--icon{
|
||||
color:#a00000;
|
||||
}
|
||||
.setup-extension-tag {
|
||||
display: inline-flex;
|
||||
background-color: grey;
|
||||
border-radius: 8px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
margin-right: 3px;
|
||||
&.installed{
|
||||
background-color:#9eff9e
|
||||
}
|
||||
&.notinstalled{
|
||||
background-color:#ed9eff
|
||||
}
|
||||
&.tobeinstalled{
|
||||
background-color:#9ef0ff
|
||||
}
|
||||
&.tobeuninstalled{
|
||||
background-color:#ff9e9e
|
||||
}
|
||||
&.notuninstallable{
|
||||
background-color:#ffc98c
|
||||
}
|
||||
&.removed{
|
||||
background-color: #969594
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-extension-details {
|
||||
align-items: flex-start;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
namespace Combodo\iTop\DataFeatureRemoval\Controller;
|
||||
|
||||
require_once APPROOT.'setup/feature_removal/SetupAudit.php';
|
||||
require_once APPROOT.'setup/feature_removal/DryRemovalRuntimeEnvironment.php';
|
||||
|
||||
use Combodo\iTop\Application\Helper\Session;
|
||||
use Combodo\iTop\Application\TwigBase\Controller\Controller;
|
||||
@@ -20,7 +19,6 @@ use Combodo\iTop\DataFeatureRemoval\Service\DataCleanupService;
|
||||
use Combodo\iTop\DataFeatureRemoval\Service\DataFeatureRemoverExtensionService;
|
||||
use Combodo\iTop\DataFeatureRemoval\Service\StaticDeletionPlan;
|
||||
use Combodo\iTop\Service\Session\SessionParameters;
|
||||
use Combodo\iTop\Setup\FeatureRemoval\DryRemovalRuntimeEnvironment;
|
||||
use Combodo\iTop\Setup\FeatureRemoval\SetupAudit;
|
||||
use ContextTag;
|
||||
use CoreException;
|
||||
@@ -39,10 +37,10 @@ class DataFeatureRemovalController extends Controller
|
||||
private array $aCountClassesToCleanup = [];
|
||||
private array $aAnalysisDataTable = [];
|
||||
private array $aDeletionExecutionSummary = [];
|
||||
private ?RuntimeEnvironment $oRuntimeEnvironment = null;
|
||||
|
||||
private int $iCount = 0;
|
||||
private int $iColumnCount = 2;
|
||||
private RunTimeEnvironment $oRuntimeEnvironment;
|
||||
|
||||
public function OperationMain($sErrorMessage = null): void
|
||||
{
|
||||
@@ -131,8 +129,6 @@ class DataFeatureRemovalController extends Controller
|
||||
$aHiddenInputs['removed_extensions'] = $this->ConvertIntoSetupFormat($aRemovedExtensions);
|
||||
}
|
||||
|
||||
$aRemoveExtensionCodes = array_keys($aRemovedExtensions);
|
||||
|
||||
$aParams['aAddedExtensions'] = $aAddedExtensions;
|
||||
$aParams['aRemovedExtensions'] = $aRemovedExtensions;
|
||||
|
||||
@@ -144,9 +140,24 @@ class DataFeatureRemovalController extends Controller
|
||||
$aParams['iColumnCount'] = $this->iColumnCount;
|
||||
$aParams['aAvailableExtensions'] = $this->SplitArrayIntoColumns($this->GetExtensionsDiff($aAddedExtensions, $aRemovedExtensions), $this->iColumnCount);
|
||||
|
||||
$bForceCompilation = Session::Get('bForceCompilation', false);
|
||||
//to make setup redirection work, we need to pass complex data structures to setup wizards (ie extension/module lists)
|
||||
$sSourceEnv = MetaModel::GetEnvironment();
|
||||
$this->oRuntimeEnvironment = new RunTimeEnvironment($sSourceEnv, false);
|
||||
|
||||
if ('[]' === $aHiddenInputs['selected_modules']) {
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$aSelectedExtensions = DataFeatureRemoverExtensionService::GetInstance()->GetExtensionMap()->GetSelectedExtensions($oConfig, array_keys($aAddedExtensions), array_keys($aRemovedExtensions));
|
||||
$aHiddenInputs['selected_extensions'] = $this->ConvertIntoSetupFormat($aSelectedExtensions);
|
||||
|
||||
$aSelectedModules = []; // keep it to compile method
|
||||
} else {
|
||||
$aSelectedExtensions = json_decode($aHiddenInputs['selected_extensions'], true);
|
||||
$aSelectedModules = json_decode($aHiddenInputs['selected_modules'], true);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->Compile($aAddedExtensions, $aRemoveExtensionCodes, $bForceCompilation);
|
||||
$this->Compile($aSelectedExtensions, array_keys($aRemovedExtensions), $aSelectedModules);
|
||||
$aHiddenInputs['selected_modules'] = $this->ConvertIntoSetupFormat($aSelectedModules);
|
||||
} catch (CoreException $e) {
|
||||
$aParams['DataFeatureRemovalErrorMessage'] = $e->getHtmlDesc();
|
||||
$this->DisplayPage($aParams, 'AnalysisResult');
|
||||
@@ -157,19 +168,6 @@ class DataFeatureRemovalController extends Controller
|
||||
return;
|
||||
}
|
||||
|
||||
if ("[]" === $aHiddenInputs['selected_modules']) {
|
||||
//to make setup redirection work, we need to pass complex data structures to setup wizards (ie extension/module lists)
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$aSelectedExtensions = DataFeatureRemoverExtensionService::GetInstance()->GetExtensionMap()->GetSelectedExtensions($oConfig, array_keys($aAddedExtensions), array_keys($aRemovedExtensions));
|
||||
$aHiddenInputs['selected_extensions'] = $this->ConvertIntoSetupFormat($aSelectedExtensions);
|
||||
|
||||
$oRunTimeEnvironment = $this->GetRuntimeEnvironment($aAddedExtensions, $aRemovedExtensions);
|
||||
$aSearchDirs = [$oRunTimeEnvironment->GetBuildDir()];
|
||||
$aSelectedModules = $oRunTimeEnvironment->GetModulesToLoadFromChoices($oConfig, $aSelectedExtensions, $aSearchDirs);
|
||||
$aHiddenInputs['selected_modules'] = $this->ConvertIntoSetupFormat($aSelectedModules);
|
||||
}
|
||||
|
||||
$sSourceEnv = MetaModel::GetEnvironment();
|
||||
$oSetupAudit = new SetupAudit($sSourceEnv);
|
||||
$aGetRemovedClasses = array_keys($oSetupAudit->RunDataAudit());
|
||||
DataFeatureRemovalLog::Debug(__METHOD__, null, ['aGetRemovedClasses' => $aGetRemovedClasses]);
|
||||
@@ -211,15 +209,15 @@ class DataFeatureRemovalController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aAddedExtensions
|
||||
* @param array $aSelectedExtensions
|
||||
* @param array $aRemovedExtensions
|
||||
* @param bool $bForceCompilation
|
||||
* @param array $aSelectedModules
|
||||
*
|
||||
* @return void
|
||||
* @throws \ConfigException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
private function Compile(array $aAddedExtensions, array $aRemovedExtensions, bool $bForceCompilation = true): void
|
||||
private function Compile(array $aSelectedExtensions, array $aRemovedExtensions, array &$aSelectedModules): void
|
||||
{
|
||||
$sSourceEnv = MetaModel::GetEnvironment();
|
||||
$sBuildDir = APPROOT."/env-$sSourceEnv-build";
|
||||
@@ -227,28 +225,28 @@ class DataFeatureRemovalController extends Controller
|
||||
SetupUtils::builddir($sBuildDir);
|
||||
}
|
||||
$bIsDirEmpty = count(scandir($sBuildDir)) === 2;
|
||||
$bForceCompilation = Session::Get('bForceCompilation', false);
|
||||
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
if ($bIsDirEmpty || $bForceCompilation) {
|
||||
Session::Unset('bForceCompilation');
|
||||
$this->oRuntimeEnvironment->CopySetupFiles();
|
||||
if (count($aSelectedModules) === 0) {
|
||||
$aSelectedModules = $this->oRuntimeEnvironment->GetModulesToLoadFromChoices($oConfig, $aSelectedExtensions);
|
||||
}
|
||||
DataFeatureRemovalLog::Debug(
|
||||
__METHOD__,
|
||||
null,
|
||||
['sSourceEnv' => $sSourceEnv, 'sBuildDir' => $sBuildDir, 'bIsDirEmpty' => $bIsDirEmpty, glob("$sBuildDir/*")]
|
||||
);
|
||||
$this->GetRuntimeEnvironment($aAddedExtensions, $aRemovedExtensions)->CompileFrom($sSourceEnv);
|
||||
$this->oRuntimeEnvironment->DoCompile($aSelectedExtensions, $aRemovedExtensions, $aSelectedModules, MFCompiler::CanUseSymbolicLinks());
|
||||
} else {
|
||||
if (count($aSelectedModules) === 0) {
|
||||
$aSelectedModules = $this->oRuntimeEnvironment->GetModulesToLoadFromChoices($oConfig, $aSelectedExtensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function GetRuntimeEnvironment(array $aAddedExtensions, array $aRemovedExtensions): RunTimeEnvironment
|
||||
{
|
||||
if (is_null($this->oRuntimeEnvironment)) {
|
||||
$sSourceEnv = MetaModel::GetEnvironment();
|
||||
$this->oRuntimeEnvironment = new DryRemovalRuntimeEnvironment($sSourceEnv, $aAddedExtensions, $aRemovedExtensions);
|
||||
}
|
||||
|
||||
return $this->oRuntimeEnvironment;
|
||||
}
|
||||
|
||||
private function GetExecutionSummaryTable(): array
|
||||
{
|
||||
$sName = 'ExcutionSummary';
|
||||
@@ -346,6 +344,7 @@ class DataFeatureRemovalController extends Controller
|
||||
'uninstallable' => $oExtension->CanBeUninstalled(),
|
||||
'remote' => $oExtension->IsRemote(),
|
||||
'missing' => $oExtension->bRemovedFromDisk,
|
||||
'cannot-be-installed' => (!$oExtension->bInstalled && count($oExtension->aMissingDependencies) > 0),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
@@ -133,8 +133,7 @@ class HubController
|
||||
throw new Exception('Sorry the installation of extensions is not allowed in demo mode');
|
||||
}
|
||||
|
||||
$aSelectModules = $oRuntimeEnv->CompileFrom('production'); // WARNING symlinks does not seem to be compatible with manual Commit
|
||||
|
||||
$oRuntimeEnv->CompileFrom('production'); // WARNING symlinks does not seem to be compatible with manual Commit
|
||||
$oRuntimeEnv->UpdateIncludes($oConfig);
|
||||
|
||||
$oRuntimeEnv->InitDataModel($oConfig, true /* model only */);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="4">
|
||||
<name>Bearbeiter des Tickets, außer der Bearbeiter selbst löst eine Benachrichtigung aus.</name>
|
||||
@@ -16,7 +16,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="3">
|
||||
<name>Melder und Kontaktliste des Tickets</name>
|
||||
@@ -27,7 +27,7 @@
|
||||
SELECT Person WHERE id=:this->caller_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="1">
|
||||
<name>Melder des Tickets</name>
|
||||
@@ -35,7 +35,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="2">
|
||||
<name>Kontaktliste des Tickets</name>
|
||||
@@ -43,7 +43,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="7">
|
||||
<name>Manager des Ticketmelders</name>
|
||||
@@ -51,7 +51,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="9">
|
||||
<name>Auslösende Person einer Benachrichtigung</name>
|
||||
@@ -61,7 +61,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="6">
|
||||
<name>Teammitglieder des Tickets</name>
|
||||
@@ -71,7 +71,7 @@
|
||||
WHERE L.team_id = :this->team_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="5">
|
||||
<name>Teammitglieder des Tickets, die nicht Bearbeiter sind</name>
|
||||
@@ -83,7 +83,7 @@
|
||||
WHERE L.team_id = :this->team_id AND P.id != :this->agent_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="10">
|
||||
<name>Team des Tickets</name>
|
||||
@@ -91,7 +91,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Team WHERE id = :this->team_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="11">
|
||||
<name>Kontaktliste eines Funktionales CI</name>
|
||||
@@ -101,7 +101,7 @@
|
||||
WHERE L.functionalci_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="12">
|
||||
<name>Kontaktliste eines Dienstes</name>
|
||||
@@ -111,7 +111,7 @@
|
||||
WHERE L.service_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="13">
|
||||
<name>Kontaktliste eines Vertrages</name>
|
||||
@@ -121,6 +121,6 @@
|
||||
WHERE L.contract_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
</Set>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="4">
|
||||
<name>Agent of the Ticket unless the agent himself triggered the notification</name>
|
||||
@@ -16,7 +16,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="3">
|
||||
<name>Caller and Contacts linked to the Ticket</name>
|
||||
@@ -27,7 +27,7 @@
|
||||
SELECT Person WHERE id=:this->caller_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="1">
|
||||
<name>Caller of the Ticket</name>
|
||||
@@ -35,7 +35,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="2">
|
||||
<name>Contacts linked to the Ticket</name>
|
||||
@@ -43,7 +43,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="7">
|
||||
<name>Manager of the Ticket caller</name>
|
||||
@@ -51,7 +51,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="9">
|
||||
<name>Person who triggered the notification</name>
|
||||
@@ -61,7 +61,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="6">
|
||||
<name>Team members of the Ticket</name>
|
||||
@@ -71,7 +71,7 @@
|
||||
WHERE L.team_id = :this->team_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="5">
|
||||
<name>Team members of the Ticket other than the agent</name>
|
||||
@@ -83,7 +83,7 @@
|
||||
WHERE L.team_id = :this->team_id AND P.id != :this->agent_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="10">
|
||||
<name>Team of the Ticket</name>
|
||||
@@ -91,7 +91,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Team WHERE id = :this->team_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="11">
|
||||
<name>Contacts of a Functional CI</name>
|
||||
@@ -101,7 +101,7 @@
|
||||
WHERE L.functionalci_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="12">
|
||||
<name>Contacts of a Service</name>
|
||||
@@ -111,7 +111,7 @@
|
||||
WHERE L.service_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="13">
|
||||
<name>Contacts of a Contract</name>
|
||||
@@ -121,6 +121,6 @@
|
||||
WHERE L.contract_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
</Set>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="4">
|
||||
<name>L'agent du Ticket s'il n'a pas déclenché la notification</name>
|
||||
@@ -14,7 +14,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->agent_id AND id != :current_contact_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="3">
|
||||
<name>Le demandeur et les contacts liés au Ticket</name>
|
||||
@@ -24,7 +24,7 @@
|
||||
UNION SELECT Person WHERE id=:this->caller_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="1">
|
||||
<name>Le demandeur du Ticket</name>
|
||||
@@ -32,7 +32,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id=:this->caller_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="2">
|
||||
<name>Les contacts liés au Ticket</name>
|
||||
@@ -40,7 +40,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Contact AS C JOIN lnkContactToTicket AS L ON L.contact_id=C.id WHERE L.ticket_id=:this->id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="7">
|
||||
<name>Le manager du demandeur</name>
|
||||
@@ -48,7 +48,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person AS manager JOIN Person AS employee ON employee.manager_id = manager.id WHERE employee.id=:this->caller_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="9">
|
||||
<name>La personne qui a déclenché la notification</name>
|
||||
@@ -58,7 +58,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Person WHERE id = :current_contact_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="6">
|
||||
<name>Les membres de l'équipe en charge du Ticket</name>
|
||||
@@ -68,7 +68,7 @@
|
||||
WHERE L.team_id = :this->team_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="5">
|
||||
<name>Les membres de l'équipe hors l'agent</name>
|
||||
@@ -80,7 +80,7 @@
|
||||
WHERE L.team_id = :this->team_id AND P.id != :this->agent_id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="10">
|
||||
<name>L'équipe du Ticket</name>
|
||||
@@ -88,7 +88,7 @@
|
||||
<is_template>yes</is_template>
|
||||
<oql><![CDATA[SELECT Team WHERE id = :this->team_id]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="11">
|
||||
<name>Les contacts d'un CI fonctionnel</name>
|
||||
@@ -98,7 +98,7 @@
|
||||
WHERE L.functionalci_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="12">
|
||||
<name>Les contacts d'un Service</name>
|
||||
@@ -108,7 +108,7 @@
|
||||
WHERE L.service_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
<QueryOQL alias="QueryOQL" id="13">
|
||||
<name>Les contacts d'un Contrat</name>
|
||||
@@ -118,6 +118,6 @@
|
||||
WHERE L.contract_id = :this->id
|
||||
]]></oql>
|
||||
<fields>id,email</fields>
|
||||
<finalclass>QueryOQL</finalclass>
|
||||
<usages>notif</usages>
|
||||
</QueryOQL>
|
||||
</Set>
|
||||
|
||||
@@ -295,12 +295,13 @@
|
||||
}
|
||||
]]></code>
|
||||
</method>
|
||||
<method id="AddCurrentUserToContacts" _revision_id="294">
|
||||
<method id="AddCurrentUserToContacts">
|
||||
<comment>/**
|
||||
*
|
||||
* Add the current contact associated Person to the contacts_list of this Ticket
|
||||
* No error if there is no associated Person or if the Person is already in the list
|
||||
* @return bool Return true on success
|
||||
* Must be called while the Ticket is not under modification by the current user
|
||||
* Can fail if the person was linked to the Ticket by another user since the Ticket was last loaded by the current user (concurrent access)
|
||||
* @return void
|
||||
*/
|
||||
</comment>
|
||||
<static>false</static>
|
||||
@@ -314,21 +315,19 @@
|
||||
$oLnk = MetaModel::NewObject('lnkContactToTicket');
|
||||
$oLnk->Set('contact_id', $iPersonId);
|
||||
$oLnk->Set('ticket_id', $this->GetKey());
|
||||
$oContactsSet->AddItem($oLnk);
|
||||
$this->Set('contacts_list', $oContactsSet);
|
||||
$this->DBUpdate();
|
||||
$oLnk->DBInsert();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}]]></code>
|
||||
<arguments/>
|
||||
</method>
|
||||
<method id="RemoveCurrentUserFromContacts" _revision_id="296">
|
||||
<method id="RemoveCurrentUserFromContacts">
|
||||
<comment>/**
|
||||
*
|
||||
* Remove the current user associated Person from the contacts_list of this Ticket
|
||||
* No error if there is no associated Person or if the Person is not in the list
|
||||
* @return bool Return true
|
||||
* Must be called while the Ticket is not under modification by the current user
|
||||
* Can fail if the person was removed from the Ticket by another user since the Ticket was last loaded by the current user (concurrent access)
|
||||
* @return void
|
||||
*/
|
||||
</comment>
|
||||
<static>false</static>
|
||||
@@ -340,14 +339,11 @@
|
||||
$oContactsSet = $this->Get('contacts_list');
|
||||
foreach ($oContactsSet as $oLnk) {
|
||||
if ($oLnk->Get('contact_id') == $iPersonId) {
|
||||
$oContactsSet->RemoveItem($oLnk->GetKey());
|
||||
$this->Set('contacts_list', $oContactsSet);
|
||||
$this->DBUpdate();
|
||||
return true;
|
||||
}
|
||||
$oLnk->DBDelete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}]]></code>
|
||||
<arguments/>
|
||||
</method>
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'Uživatel, který naposledy spustil export',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Kontakt',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'kontakt, který naposledy spustil export',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'Hlavní informace',
|
||||
'Query:exportInfo' => 'Informace o Exportu',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Atributy',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Felter',
|
||||
|
||||
@@ -115,6 +115,18 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'Der Benutzer, der den letzten Export durchgeführt hat',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Kontakt',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'Der Kontakt, der den letzten Export durchgeführt hat',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'Allgemeine Informationen',
|
||||
'Query:exportInfo' => 'Export-Informationen',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Felder',
|
||||
|
||||
@@ -129,6 +129,18 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export',
|
||||
'Class:Query/Attribute:usages' => 'Usages',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query',
|
||||
'Query:baseinfo' => 'General information',
|
||||
'Query:exportInfo' => 'Export information',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Fields',
|
||||
|
||||
@@ -129,6 +129,18 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information',
|
||||
'Query:exportInfo' => 'Export information',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Fields',
|
||||
|
||||
@@ -114,6 +114,18 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'El usuario que ejecutó la última exportación.',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contacto',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'El contacto que ejecutó la última exportación.',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'Información general',
|
||||
'Query:exportInfo' => 'Exportar información',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Campos',
|
||||
|
||||
@@ -121,6 +121,18 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'Dernier utilisateur ayant exécuté cette requête',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'Dernier contact ayant exécuté cette requête',
|
||||
'Class:Query/Attribute:usages' => 'Usages',
|
||||
'Class:Query/Attribute:usages+' => 'Spécifie les usages possibles de cette requête.
|
||||
- L\'étiquette "Référence pour IA" suppose que la description est très explicite et conforme à l\'OQL. Elle pourra servir d\'exemple pour la construction de requêtes OQL par des IA.
|
||||
- L\'étiquette "Notification" implique que la classe d\'objets retournés possède un et un seul champ de type email.
|
||||
- L\'étiquette "Dashlet" suppose que l\'OQL ne retourne qu\'une seule classe d\'objets.',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Référence pour IA',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Brouillon',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet',
|
||||
'Class:Query/Attribute:owner_id' => 'Responsable',
|
||||
'Class:Query/Attribute:owner_id+' => 'Personne ou équipe utilisatrice de cette requête, responsable de sa définition',
|
||||
'Query:baseinfo' => 'Informations générales',
|
||||
'Query:exportInfo' => 'Informations sur les exports',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Champs',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Mezők',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'L\'utente che ha eseguito l\'ultima esportazione',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contatto',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'Il contatto che ha eseguito l\'ultima esportazione',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'Informazioni generali',
|
||||
'Query:exportInfo' => 'Informazioni sull\'esportazione',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Campi',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'フィールド',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'Algemene informatie',
|
||||
'Query:exportInfo' => 'Export informatie',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Velden',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'Użytkownik, który wykonał ostatni eksport',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Kontakt',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'Osoba kontaktowa, która wykonała ostatni eksport',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'Informacje ogólne',
|
||||
'Query:exportInfo' => 'Informacje o eksporcie',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Pola',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Campos',
|
||||
|
||||
@@ -117,6 +117,18 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Экспорт. поля',
|
||||
|
||||
@@ -120,6 +120,18 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Polia',
|
||||
|
||||
@@ -116,6 +116,18 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => 'The user who executed the last export~~',
|
||||
'Class:Query/Attribute:export_last_user_contact' => 'Contact~~',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => 'The contact who executed the last export~~',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => 'General information~~',
|
||||
'Query:exportInfo' => 'Export information~~',
|
||||
'Class:QueryOQL/Attribute:fields' => 'Alanlar',
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
|
||||
// Message
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Vítejte v '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Gratulujeme, přistáli jste do '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>Jsme rádi, že vám můžeme představit tuto novou verzi. </div>
|
||||
<div>Kromě nových funkcionalit, jako je např. Newsroom, '.ITOP_APPLICATION_SHORT.' obsahuje verze 3.2 bezpečnostní opravy, lepší přístupnost a další významná vylepšení zaměřená na zajištění stability a bezpečnosti.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Objevte všechny '.ITOP_APPLICATION_SHORT.' vzrušující nové funkce a zůstaňte informováni o důležitých oznámeních a aktualizacích prostřednictvím nového vyskakovacího okna na uvítanou!</div>
|
||||
<div>Doufáme, že se vám tato verze bude líbit stejně, jako se nám líbila její tvorba.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Přizpůsobte si svoje předvolby '.ITOP_APPLICATION_SHORT.' a získejte tak individuální zážitek.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Centrum notifikací',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
|
||||
// Message
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -14,43 +14,29 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
|
||||
// Message
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Willkommen bei '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Herzlichen Glückwunsch, Sie sind auf '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' gelandet!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>Wir freuen uns, diese neue Version anzukündigen.</div>
|
||||
<div>Neben der Einführung neuer Funktionen wie dem Newsroom enthält '.ITOP_APPLICATION_SHORT.' 3.2 wichtige Sicherheitsupdates, verbesserte Barrierefreiheit und andere bedeutende Verbesserungen, die auf Stabilität und Sicherheit abzielen.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Entdecken Sie alle neuen Funktionen von '.ITOP_APPLICATION_SHORT.' und bleiben Sie mit unserem neuen Willkommens-Popup über wichtige Benachrichtigungen auf dem Laufenden!</div>
|
||||
<div>Wir hoffen, dass Sie diese Version genauso genießen werden wie wir es genossen haben, sie uns auszudenken und zu erstellen.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Passen Sie Ihre '.ITOP_APPLICATION_SHORT.' Präferenzen an, um ein personalisiertes Erlebnis zu erhalten.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Sagen Sie "Hallo" zum Newsroom',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Sagen Sie Auf Wiedersehen zu überfüllten Posteingängen und Hallo zu personalisierten Benachrichtigungen mit dem <b>Newsroom von '.ITOP_APPLICATION_SHORT.'</b>!</div>
|
||||
<div><a href="%1$s" target="_blank">Der Newsroom</a> ermöglicht es Ihnen, Benachrichtigungen innerhalb der Plattform einfach zu verwalten, sodass Sie über wichtige Updates informiert bleiben, ohne ständig Ihre E-Mails überprüfen zu müssen. Mit der Fähigkeit, Nachrichten als gelesen oder ungelesen zu markieren und alte Benachrichtigungen automatisch zu löschen, haben Sie die volle Kontrolle über Ihre Benachrichtigungen.</div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Probieren Sie es noch heute aus und optimieren Sie die Benachrichtigungserfahrung von '.ITOP_APPLICATION_SHORT.'!</div>',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Benachrichtigungszentrum',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>Da wir wissen, dass Ihre Informationsaufnahme bereits am Limit ist, können Sie nun leicht wählen, wie Sie Ihre Benachrichtigungen erhalten - per E-Mail, Chat oder sogar über die Newsroom-Funktion.</div>
|
||||
<div>Sie möchten eine bestimmte Art von Benachrichtigungen nicht erhalten? Nichts leichter als das mit diesen erweiterten Anpassungsmöglichkeiten, die Ihnen die Flexibilität geben, Ihr Erlebnis an Ihre Bedürfnisse anzupassen.</div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Zugriff auf Ihr <a href="%1$s" target="_blank">Benachrichtigungszentrum</a> über den Newsroom oder über Ihre Präferenzen und vermeiden Sie Informationsüberflutung auf allen Ihren Kommunikationskanälen!</div>',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Barrierefreiheit für die Benutzeroberfläche von '.ITOP_APPLICATION_SHORT.'',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>Um die Barrierefreiheit von '.ITOP_APPLICATION_SHORT.' zu gewährleisten, hat unser Team an <a href="%1$s" target="_blank">neuen Back-Office-Themen</a> gearbeitet. WCAG-konform konzentrieren sich diese Benutzeroberflächen darauf, es Benutzern mit Sehbehinderungen zu erleichtern, die Lösung zu verwenden:
|
||||
<ul>
|
||||
<li><b>Farbenblindes Thema:</b> Entwickelt, um Benutzern mit Farbenblindheit zu helfen, teilt sich dieses Thema tatsächlich in zwei Unterthemen auf, um sich an spezifische Fälle anzupassen:</li>
|
||||
<ul>
|
||||
<li>Eins, das an Protanopie und Deuteranopie angepasst ist</li>
|
||||
<li>Und ein weiteres für Tritanopie</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>Kontrastreiches Thema:</b> Erhöhter Kontrast, um es Benutzern zu ermöglichen, verschiedene Elemente auf dem Bildschirm leichter zu unterscheiden, und zu vermeiden, dass zur Vermittlung von Informationen auf Farbschemas zurückgegriffen wird. Es kann Benutzern mit verschiedenen Pathologien von Farbenblindheit bis zu Sehschwächen hilfreich sein.</li>
|
||||
</ul>
|
||||
</div>',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Leistungsstarke Benachrichtigungen',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>Der Newsroom von '.ITOP_APPLICATION_SHORT.' bietet Ihnen eine neue Möglichkeit, Ihre Benachrichtigungen basierend auf wiederkehrenden Ereignissen zu <b>automatisieren</b>, sodass Sie leicht Regeln einrichten können, die für Sie funktionieren.</div>
|
||||
<div>Unsere <b>prioritätsbasierte Sortierung von Benachrichtigungen</b> stellt sicher, dass wichtige Nachrichten zuerst angezeigt werden, während unsere URL-Anpassungsoptionen es Ihnen ermöglichen, Empfänger an die richtige Stelle zu leiten.</div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>Mit Unterstützung für <b>mehrere Sprachen</b> haben Sie jetzt die vollständige Kontrolle über die Anzeige Ihrer Benachrichtigungen.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Konfigurieren Sie es noch heute und sehen Sie, wie viel effizienter Ihr Benachrichtigungsprozess sein kann!</div>',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -14,43 +14,29 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
|
||||
// Message
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>',
|
||||
]);
|
||||
|
||||
@@ -14,43 +14,29 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
|
||||
// Message
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications centre',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -16,43 +16,29 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
|
||||
// Message
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -18,46 +18,29 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
|
||||
// Message
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Bienvenue sur '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Félicitations, vous avez atterri sur '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.' !</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Bienvenue dans '.ITOP_APPLICATION_SHORT.' 3.3',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>Nous sommes ravis de vous présenter cette nouvelle version, qui vous apporte une série de mises à jour et d’améliorations !</div>
|
||||
<br>
|
||||
<div>Nous sommes ravis de vous présenter cette nouvelle version.</div>
|
||||
<div>En plus de nouvelles fonctionnalités comme l’authentification multifacteur, cette version inclut des mises à jour de sécurité essentielles, les premiers briques d’IA et diverses améliorations conçues pour offrir une expérience plus fluide et plus fiable.</div>
|
||||
<br>
|
||||
<div>En plus d\'introduire de nouvelles fonctionnalités telles que la Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 inclut des correctifs de sécurité critiques, une meilleure accessibilité et d\'autres améliorations significatives visant à vous apporter stabilité et sécurité.</div>
|
||||
<div>Nous espérons que vous prendrez autant de plaisir à utiliser cette version que nous en avons eu à la concevoir.</div>
|
||||
<div>N’oubliez pas d’ajuster vos préférences iTop afin d’adapter l’expérience à vos besoins.</div>',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Poser les bases de l’IA',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>Cette version introduit les premiers éléments de base de nos futures fonctionnalités propulsées par l’IA.</div>
|
||||
<br>
|
||||
<div>Découvrez toutes les nouvelles fonctionnalités d\'iTop et restez informé des notifications importantes grâce à notre nouvelle pop-up de bienvenue !
|
||||
Nous espérons que vous apprécierez cette version autant que nous avons pris plaisir à l\'imaginer et à la créer.</div>
|
||||
<div>Nous avons implémenté les API coeur qui prendront en charge les prochaines améliorations, ouvrant la voie à de nouvelles capacités intelligentes et à des expériences enrichies dans les mises à jour à venir.</div>
|
||||
<br>
|
||||
<div>Paramétrez vos préférences iTop pour une expérience personnalisée.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Decouvrez la newsroom',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Dites adieu aux boîtes de réception encombrées et bonjour aux alertes personnalisées grâce à la <a href="%1$s" target="_blank">Newsroom d\''.ITOP_APPLICATION_SHORT.'</a> !</div>
|
||||
<div>Restez à l’écoute — ce n’est que le début de ce qui vous attend.</div>',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'CMDB enrichie',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>Cette version apporte plusieurs améliorations à notre modèle de données afin de mieux répondre aux besoins qui évoluent.</div>
|
||||
<br>
|
||||
<div>La Newsroom vous permet de gérer facilement les notifications au sein de la plateforme, afin que vous puissiez rester au courant des mises à jour importantes sans avoir à vérifier constamment vos méls. Avec la possibilité de marquer les messages comme lus ou non lus, et de supprimer automatiquement les anciennes notifications, vous avez un contrôle total sur vos notifications</div>
|
||||
<div>Nous avons introduit la gestion de la conteneurisation, amélioré la gestion des flux, enrichi les descriptions de classes et la gestion du cycle de vie (fin de vie / fin de support). Le menu de gestion des services a également été repensé pour offrir plus de clarté et de facilité d\'utilisation, avec en complément l\'ajout d\'images et de logos sur certains éléments de configuration.</div>
|
||||
<br>
|
||||
<div>Essayez-le dès aujourd\'hui et optimisez la communication de votre '.ITOP_APPLICATION_SHORT.' !</div>',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Centre de notifications',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>Comme nous savons que vous êtes déjà saturé d\'informations, vous pouvez désormais choisir facilement la manière dont vous recevez vos notifications - par mél, par chat ou même par la fonction Newsroom.</div>
|
||||
<div>Vous ne voulez pas recevoir un certain type d\'alerte ? Rien de plus facile avec ces fonctionnalités de personnalisation avancées qui permettent d\'adapter votre expérience utilisateur à vos besoins.</div>
|
||||
<div>Ces mises à jour visent à proposer une expérience plus structurée et plus intuitive.</div>',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Renforcer la sécurité avec la MFA',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>L’authentification multifacteur (MFA) est désormais entièrement intégrée à iTop.</div>
|
||||
<br>
|
||||
<div>Accédez à votre <a href="%1$s" target="_blank">centre de notifications</a> via la newsroom ou vos préférences et évitez la surcharge d\'information sur vos canaux de communication !</div>',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibilité de l\'interface utilisateur d\''.ITOP_APPLICATION_SHORT,
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>Afin d\'assurer l\'accessibilité d\''.ITOP_APPLICATION_SHORT.', notre équipe a travaillé sur de <a href="%1$s" target="_blank">nouveaux thèmes pour la console</a>. Conformes aux normes WCAG, ces interfaces utilisateur visent à faciliter l\'utilisation de la solution par les utilisateurs souffrant de déficiences visuelles :
|
||||
<ul>
|
||||
<li><b>Thème daltonien :</b> Conçu pour aider les utilisateurs daltoniens, ce thème se décompose en deux sous-thèmes pour s\'adapter à des cas spécifiques : </li>
|
||||
<ul>
|
||||
<li>L\'un adapté à la protanopie et à la deutéranopie</li>
|
||||
<li>Et l\'autre pour la tritanopie</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>Thème à contraste élevé :</b> Augmentation du contraste pour permettre aux utilisateurs de distinguer plus facilement les différents éléments à l\'écran et éviter de s\'appuyer sur des schémas de couleurs pour transmettre l\'information. Il peut être utile aux utilisateurs souffrant de différentes pathologies, du daltonisme aux problèmes de basse vision.
|
||||
</li>
|
||||
</ul>
|
||||
</div>',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Des notifications évoluées',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>La Newsroom d\''.ITOP_APPLICATION_SHORT.' vous offre une nouvelle façon <a href="%1$s" target="_blank">d\'<b>automatiser</b> vos alertes en fonction d\'événements récurrents</a>, ce qui vous permet de définir facilement des règles qui vous conviennent.</div>
|
||||
<div>Notre <b>tri des notifications basé sur la priorité</b> garantit que les messages importants sont affichés en premier, tandis que nos options de personnalisation des URL vous permettent de diriger les destinataires au bon endroit.</div>
|
||||
<div>La MFA, désormais intégrée directement à l’expérience coeur, renforce la sécurité globale tout en garantissant une expérience utilisateur plus fluide et cohérente.</div>
|
||||
<br>
|
||||
<div>Grâce à la prise en charge de <b>plusieurs langues</b>, vous avez désormais un contrôle total sur l\'affichage de vos notifications.</div>
|
||||
<br>
|
||||
<div>Configurez-le dès aujourd\'hui et voyez à quel point votre processus d\'alerte peut être plus efficace !</div>',
|
||||
<div>Nous vous encourageons à vérifier vos paramètres et à activer la MFA afin de bénéficier d’une meilleure protection de compte.</div>',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
|
||||
// Message
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
|
||||
// Message
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
|
||||
// Message
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
|
||||
// Message
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
|
||||
// Message
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Witaj w '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Gratulacje, trafiłeś do '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>Z radością ogłaszamy tę nową wersję. </div>
|
||||
<div>Oprócz wprowadzenia nowych funkcji, takich jak Newsroom, '.ITOP_APPLICATION_SHORT.' wersja 3.2 zawiera krytyczne poprawki bezpieczeństwa, zwiększoną dostępność i inne znaczące ulepszenia mające na celu zapewnienie stabilności i bezpieczeństwa.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Odkryj wszystkie ekscytujące nowe funkcje '.ITOP_APPLICATION_SHORT.' i bądź na bieżąco z ważnymi powiadomieniami dzięki naszemu nowemu wyskakującemu okienku powitalnemu!</div>
|
||||
<div>Mamy nadzieję, że spodoba ci się ta wersja tak samo, jak nam podobało się jej wyobrażanie i tworzenie.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Dostosuj swoją aplikację '.ITOP_APPLICATION_SHORT.' w preferencjach dotyczących spersonalizowanych doświadczeń.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Przywitaj się z newsroomem',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Pożegnaj zaśmiecone skrzynki odbiorcze i przywitaj się ze spersonalizowanymi alertami <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom umożliwia łatwe zarządzanie powiadomieniami w ramach platformy, dzięki czemu możesz być na bieżąco z ważnymi aktualizacjami bez ciągłego sprawdzania poczty. Dzięki możliwości oznaczania wiadomości jako przeczytanych lub nieprzeczytanych oraz automatycznego usuwania starych powiadomień, masz pełną kontrolę nad swoimi powiadomieniami. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Wypróbuj już dziś i usprawnij swoje doświadczenie komunikacji w '.ITOP_APPLICATION_SHORT.'!</div>',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Centrum powiadomień',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>Ponieważ wiemy, że Twoje zapotrzebowanie na informacje jest już maksymalne, możesz teraz łatwo wybrać sposób otrzymywania powiadomień – e-mailem, czatem, a nawet funkcją Newsroom</div>
|
||||
<div>Nie chcesz otrzymywać określonego rodzaju alertów? Nie ma nic łatwiejszego dzięki zaawansowanym możliwościom dostosowywania, które zapewniają elastyczność dostosowywania wrażeń do Twoich potrzeb. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Uzyskaj dostęp do swojego centrum powiadomień poprzez newsroom lub poprzez swoje preferencje i unikaj przeciążenia informacjami we wszystkich kanałach komunikacji!</div>',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Dostępność '.ITOP_APPLICATION_SHORT,
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>Aby zapewnić dostępność'.ITOP_APPLICATION_SHORT.', nasz zespół pracował nad nowymi motywami zaplecza. Zgodny z WCAG, interfejs użytkownika skupia się na ułatwieniu użytkownikom z wadami wzroku korzystania z rozwiązania:
|
||||
<ul>
|
||||
<li><b>Temat dla daltonistów:</b> Zaprojektowany, aby pomóc użytkownikom z daltonizmem, motyw ten dzieli się na dwa podtematy, aby dostosować się do konkretnych przypadków: </li>
|
||||
<ul>
|
||||
<li>Jeden przystosowany do protanopii i deuteranopii</li>
|
||||
<li>I jeszcze jeden na tritanopię</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>Motyw o wysokim kontraście:</b> Zwiększony kontrast, aby umożliwić użytkownikom łatwiejsze rozróżnienie pomiędzy różnymi elementami na ekranie i uniknąć polegania na schemacie kolorów w przekazywaniu informacji. Może być pomocny dla użytkowników z różnymi patologiami, od ślepoty barw po problemy ze wzrokiem.</li>
|
||||
</ul>
|
||||
</div>',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Potężne powiadomienia',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.' Newsroom oferuje nowy sposób <b>automatyzacji</b> alertów na podstawie powtarzających się zdarzeń, dzięki czemu możesz łatwo skonfigurować odpowiednie dla siebie reguły. </div>
|
||||
<div>Nasze <b>sortowanie powiadomień oparte na priorytetach</b> gwarantuje, że ważne wiadomości będą wyświetlane jako pierwsze, a nasze opcje dostosowywania adresów URL pozwalają kierować odbiorców we właściwe miejsce. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>Dzięki obsłudze <b>wielu języków</b> masz teraz pełną kontrolę nad wyświetlaniem powiadomień.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Skonfiguruj już dziś i przekonaj się, o ile efektywniejszy może być Twój proces alertów!</div>',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
|
||||
// Message
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
|
||||
// Message
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
|
||||
// Message
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -13,43 +13,29 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
|
||||
// Message
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.2~~',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>Congratulations, you landed on '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>We\'re excited to announce this new release. </div>
|
||||
<div>In addition to introducing new features such as Newsroom, '.ITOP_APPLICATION_SHORT.' 3.2 includes critical security patches, enhanced accessibility and other significant improvements focused on providing you with stability and security.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>Discover all of '.ITOP_APPLICATION_SHORT.'\'s exciting new features and stay up-to-date with important notifications with our new welcome pop-up!</div>
|
||||
<div>We hope you\'ll enjoy this version as much as we enjoyed imagining and creating it.</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>Customize your '.ITOP_APPLICATION_SHORT.' preferences for a personalized experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => 'Say "Hello" to the newsroom~~',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>Say goodbye to cluttered inboxes and hello to personalized alerts with <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.'\'s Newsroom</a>!</div>
|
||||
<div>Newsroom allows you to easily manage notifications within the platform, so you can stay on top of important updates without constantly checking your email. With the ability to mark messages as read or unread, and automatically delete old notifications, you have complete control over your notifications. </div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>Try it out today and streamline your '.ITOP_APPLICATION_SHORT.'\'s communication experience!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => 'Notifications center~~',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>As we know your information intake is already at its max, you can now easily choose how you receive your notifications - via email, chat, or even the Newsroom feature</div>
|
||||
<div>You don\'t want to receive a certain type of alerts? Nothing easier with these advanced customization capabilities giving you the flexibility to tailor your experience to your needs. </div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>Access your <a href="%1$s" target="_blank">notifications center</a> through the newsroom or through your preferences and avoid information overload on all your communication channels!</div>~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => 'Accessibility for '.ITOP_APPLICATION_SHORT.'\'s UI~~',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>To ensure '.ITOP_APPLICATION_SHORT.'\'s accessibility, our team has been working on <a href="%1$s" target="_blank">new back-office themes</a>. WCAG compliants, those UI focus on making it easier for users with visual impairments to use the solution:
|
||||
<ul>
|
||||
<li><b>Color-blind theme:</b> Designed to help users with colorblindness, this theme actually breaks down in two sub-themes to adapt to specific cases: </li>
|
||||
<ul>
|
||||
<li>One adapted to protanopia and deuteranopia</li>
|
||||
<li>And another one for tritanopia</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>High-contrast theme:</b> Increased contrast to allow users an easier distinction between different elements on screen and avoid to rely on color schema to convey information. It can be helpful for users with different pathology from colorblindness to low vision issues.</li>
|
||||
</ul>
|
||||
</div>~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => 'Powerful notifications~~',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.'\'s Newsroom gives you a new way to <a href="%1$s" target="_blank"><b>automate</b> your alerts based on events</a> with recurrence, so you can easily set up rules that work for you. </div>
|
||||
<div>Our <b>priority-based notifications sorting</b> ensures that important messages are displayed first, while our URL customization options allow you to direct recipients to the right place. </div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>With support for <b>multiple languages</b>, you have now complete control over your notifications display.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>Configure it today and see how much more efficient your alerts process can be!</div>~~',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
* @copyright Copyright (C) 2010-2024 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
// UI elements
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'UI:WelcomePopup:Button:RemindLater' => '以后再提醒我',
|
||||
@@ -14,43 +13,29 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
|
||||
// Message
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Title' => '欢迎使用 '.ITOP_APPLICATION_SHORT.' 3.2',
|
||||
'UI:WelcomePopup:Message:320_01_Welcome:Description' => '<div>恭喜, 您已登录 '.ITOP_APPLICATION.' '.ITOP_VERSION_NAME.'!</div>
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Title' => 'Welcome to '.ITOP_APPLICATION_SHORT.' 3.3~~',
|
||||
'UI:WelcomePopup:Message:330_01_Welcome:Description' => '<div>We’re pleased to introduce this latest release, bringing you a range of updates and improvements !</div>
|
||||
<br>
|
||||
<div>很高兴向你宣布这个新版本. </div>
|
||||
<div>新增了新闻室等新功能, '.ITOP_APPLICATION_SHORT.' 3.2 还包含了关键的安全补丁, 增强的可访问性以及其它重要的改进,旨在为您提供更好的稳定性和安全性.</div>
|
||||
<div>Alongside new features like Multi-Factor Authentication, this version includes essential security updates, the first AI bricks, and various enhancements designed to deliver a smoother and more reliable experience.</div>
|
||||
<br>
|
||||
<div>发现 '.ITOP_APPLICATION_SHORT.' 所有令人兴奋的新功能,并通过我们的新欢迎弹窗保持与重要通知的同步!</div>
|
||||
<div>我们希望你能像我们一样,从构思到创造,全程享受这个版本!</div>
|
||||
<div>We hope you enjoy using this version as much as we enjoyed building it.</div>
|
||||
<div>Don’t forget to adjust your iTop preferences to tailor the experience to your needs.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Title' => 'Laying the foundations for AI~~',
|
||||
'UI:WelcomePopup:Message:330_02_AIFoundations:Description' => '<div>This release introduces the first building blocks for our upcoming AI-powered features.</div>
|
||||
<br>
|
||||
<div>定制您的 '.ITOP_APPLICATION_SHORT.' 偏好设置,可以获得个性化的使用体验.</div>',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Title' => '向新闻室说 "Hello" ',
|
||||
'UI:WelcomePopup:Message:320_02_Newsroom:Description' => '<div>告别杂乱的收件箱,用 <a href="%1$s" target="_blank">'.ITOP_APPLICATION_SHORT.' 新闻室</a>迎接个性化的告警!</div>
|
||||
<div>新闻室允许您轻松管理平台内的通知,因此您可以掌握重要更新而无需频繁查收电子邮件.通过将消息标记为已读或未读,并自动删除旧通知,您可以完全控制您的通知.</div>
|
||||
<div>We’ve implemented the core APIs that will support future enhancements, paving the way for new intelligent capabilities and richer experiences in the next updates.</div>
|
||||
<br>
|
||||
<div>今天就试试,简化您的 '.ITOP_APPLICATION_SHORT.' 沟通体验!</div>',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Title' => '通知中心',
|
||||
'UI:WelcomePopup:Message:320_03_NotificationsCenter:Description' => '<div>由于我们知道您的信息摄入量已经达到最大限度,现在您可以轻松选择如何接收通知 - 通过电子邮件、聊天,甚至新闻室功能</div>
|
||||
<div>您不想接收某种类型的警报?使用这些高级自定义功能,您可以根据需要轻松定制体验.</div>
|
||||
<div>Stay tuned—this is just the beginning of what’s ahead.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Title' => 'Enhanced CMDB~~',
|
||||
'UI:WelcomePopup:Message:330_03_CMDB:Description' => '<div>This version brings several improvements to our datamodel to better support evolving needs.</div>
|
||||
<br>
|
||||
<div>通过新闻室或您的偏好设置访问您的<a href="%1$s" target="_blank">通知中心</a>,避免所有通信渠道的信息过载!</div>',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Title' => ITOP_APPLICATION_SHORT.' UI 的可访问性',
|
||||
'UI:WelcomePopup:Message:320_05_A11yThemes:Description' => '<div>为了确保 '.ITOP_APPLICATION_SHORT.' 的可访问性,我们的团队一直在开发<a href="%1$s" target="_blank">新的后台主题</a>.符合 WCAG 标准,这些 UI 主题可以帮助视力障碍用户更容易的使用:
|
||||
<ul>
|
||||
<li><b>色盲主题:</b> 设计用于帮助色盲用户,此主题实际上分为两个子主题以适应特定情况:</li>
|
||||
<ul>
|
||||
<li>一个适用于红绿色盲和绿色色盲</li>
|
||||
<li>另一个适用于黄蓝色盲</li>
|
||||
</ul>
|
||||
<br>
|
||||
<li><b>高对比度主题:</b> 增加对比度以允许用户更容易区分屏幕上的不同元素,并避免依赖颜色方案传递信息.它可以帮助从色盲到弱视等不同病理的用户.</li>
|
||||
</ul>
|
||||
</div>',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Title' => '强大的通知',
|
||||
'UI:WelcomePopup:Message:320_04_PowerfulNotifications_AdminOnly:Description' => '<div>'.ITOP_APPLICATION_SHORT.' 的新闻室为您提供了一种新的方法,可以 <a href="%1$s" target="_blank"><b>自动化</b> 基于事件的告警</a> 并支持重复设置, 因此您可以轻松设置适合您的规则. </div>
|
||||
<div>我们的<b>基于优先级的通知排序</b>确保重要消息优先展示,同时,我们的 URL 自定义选项允许您将收件人引导到正确的位置.</div>
|
||||
<div>We’ve introduced containerization management, improved flow management, enriched class descriptions, and lifecycle management (End of Life / End of Support). The service management menu has also been redesigned for greater clarity and usability, along with the addition of images and logos on selected configuration items.</div>
|
||||
<br>
|
||||
<div>支持<b>多语言</b>,您现在可以完全控制通知显示.</div>
|
||||
<div>These updates aim to provide a more structured and intuitive experience.</div>~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Title' => 'Strengthening security with MFA~~',
|
||||
'UI:WelcomePopup:Message:330_04_MFA:Description' => '<div>Multi-Factor Authentication (MFA) is now fully integrated into iTop.</div>
|
||||
<br>
|
||||
<div>现在就配置它,看看您的警报流程可以变得多么高效!</div>',
|
||||
<div>MFA, now built directly into the core experience, strengthens overall security while ensuring a more seamless and consistent user experience.</div>
|
||||
<br>
|
||||
<div>We encourage you to review your settings and enable MFA to benefit from enhanced account protection.</div>~~',
|
||||
]);
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -13,6 +13,8 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'Cette extension fait partie de l\'installation actuelle.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'va être installé',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'Cette extension sera installée lors de l\'installation.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'ne peut pas être installée',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'Cette extension ne peut pas être installée car une ou plusieurs dépendances ne sont pas satisfaites.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'pas installé',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'Cette extension ne fait pas partie de l\'installation actuelle.',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'va être désinstallé',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -15,6 +15,8 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'UI:Layout:ExtensionsDetails:BadgeInstalled+' => 'This extension is part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled' => 'to be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeInstalled+' => 'This extension will be installed during the setup.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled' => 'cannot be installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeCannotBeInstalled+' => 'This extension cannot be installed because one or more dependencies are not satisfied.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled' => 'not installed~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeNotInstalled+' => 'This extension is not part of the current installation.~~',
|
||||
'UI:Layout:ExtensionsDetails:BadgeToBeUninstalled' => 'to be uninstalled~~',
|
||||
|
||||
@@ -129,6 +129,18 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:Query/Attribute:export_last_user_id+' => '执行最近一次导出的用户',
|
||||
'Class:Query/Attribute:export_last_user_contact' => '联系人',
|
||||
'Class:Query/Attribute:export_last_user_contact+' => '执行最近一次导出的联系人',
|
||||
'Class:Query/Attribute:usages' => 'Usages~~',
|
||||
'Class:Query/Attribute:usages+' => 'Specify the possible usages for this query.
|
||||
- The "Reference for AI" tag assumes the description is very explicit and compliant with OQL. It may be used as an example for building OQL queries by AI.
|
||||
- The "Notification" tag implies the class of returned objects has one and only one field of type email.
|
||||
- The "Dashlet" tag assumes the OQL returns a single class of objects.~~',
|
||||
'Class:Query/Attribute:usages/Value:export' => 'Export~~',
|
||||
'Class:Query/Attribute:usages/Value:reference' => 'Reference for AI~~',
|
||||
'Class:Query/Attribute:usages/Value:notif' => 'Notification~~',
|
||||
'Class:Query/Attribute:usages/Value:draft' => 'Draft~~',
|
||||
'Class:Query/Attribute:usages/Value:dashlet' => 'Dashlet~~',
|
||||
'Class:Query/Attribute:owner_id' => 'Owner~~',
|
||||
'Class:Query/Attribute:owner_id+' => 'Team or person responsible for this query~~',
|
||||
'Query:baseinfo' => '基本信息',
|
||||
'Query:exportInfo' => '导出信息',
|
||||
'Class:QueryOQL/Attribute:fields' => '字段',
|
||||
|
||||
1
images/illustrations/undraw_maintenance.svg
Normal file
1
images/illustrations/undraw_maintenance.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.7 KiB |
1
images/illustrations/undraw_searching_everywhere.svg
Normal file
1
images/illustrations/undraw_searching_everywhere.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.8 KiB |
52
images/illustrations/undraw_to_the_moon.svg
Normal file
52
images/illustrations/undraw_to_the_moon.svg
Normal file
@@ -0,0 +1,52 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="926" height="584.958" viewBox="0 0 926 584.958" xmlns:xlink="http://www.w3.org/1999/xlink" role="img" artist="Katerina Limpitsouni" source="https://undraw.co/">
|
||||
<g id="Group_236" data-name="Group 236" transform="translate(-497 -248)">
|
||||
<circle id="Ellipse_613" data-name="Ellipse 613" cx="83.979" cy="83.979" r="83.979" transform="translate(650.926 248)" fill="#ff6584"/>
|
||||
<path id="Path_3715-106" data-name="Path 3715" d="M1063,276.46V497.34c0,180.055-145.962,326.01-326.009,326H137V602.46c0-118.03,62.73-221.42,156.68-278.63a323.578,323.578,0,0,1,50.88-25.18,320.085,320.085,0,0,1,31.76-10.53c.21-.07.43-.13.64-.18q4.77-1.3,9.6-2.46c.18-.05.35-.09.53-.13a326.114,326.114,0,0,1,60.47-8.53c2.41-.11,4.82-.2,7.25-.25.87-.03,1.75-.05,2.64-.05q2.76-.06,5.55-.06Z" transform="translate(360 8.458)" fill="#090814"/>
|
||||
<path id="Path_3768-107" data-name="Path 3768" d="M1063,276.46V497.34c0,180.055-145.962,326.01-326.009,326H137V602.46c0-118.03,62.73-221.42,156.68-278.63a323.578,323.578,0,0,1,50.88-25.18,320.085,320.085,0,0,1,31.76-10.53c.21-.07.43-.13.64-.18q4.77-1.3,9.6-2.46c.18-.05.35-.09.53-.13a326.114,326.114,0,0,1,60.47-8.53c2.41-.11,4.82-.2,7.25-.25.87-.03,1.75-.05,2.64-.05q2.76-.06,5.55-.06Z" transform="translate(360 8.458)" fill="#6c63ff" opacity="0.199"/>
|
||||
<path id="Path_3716-108" data-name="Path 3716" d="M559.01,681c-232.58,0-421.209,53.34-422,119.223h844C980.219,734.34,791.59,681,559.01,681Z" transform="translate(360 32.735)" fill="#d6d6e3"/>
|
||||
<g id="Group_232" data-name="Group 232" transform="translate(497 101.347)" opacity="0.1">
|
||||
<ellipse id="Ellipse_614" data-name="Ellipse 614" cx="80" cy="22.222" rx="80" ry="22.222" transform="translate(272 669.778)"/>
|
||||
</g>
|
||||
<g id="Group_233" data-name="Group 233" transform="translate(497 101.347)" opacity="0.1">
|
||||
<ellipse id="Ellipse_615" data-name="Ellipse 615" cx="80" cy="22.222" rx="80" ry="22.222" transform="translate(445 629.778)"/>
|
||||
</g>
|
||||
<g id="Group_234" data-name="Group 234" transform="translate(497 101.347)" opacity="0.1">
|
||||
<ellipse id="Ellipse_616" data-name="Ellipse 616" cx="72" cy="20" rx="72" ry="20" transform="translate(280 672)"/>
|
||||
</g>
|
||||
<g id="Group_235" data-name="Group 235" transform="translate(497 101.347)" opacity="0.1">
|
||||
<ellipse id="Ellipse_617" data-name="Ellipse 617" cx="72" cy="20" rx="72" ry="20" transform="translate(453 632)"/>
|
||||
</g>
|
||||
<circle id="Ellipse_618" data-name="Ellipse 618" cx="7" cy="7" r="7" transform="translate(628 366.958)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_619" data-name="Ellipse 619" cx="7" cy="7" r="7" transform="translate(1230 640.958)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_620" data-name="Ellipse 620" cx="7" cy="7" r="7" transform="translate(900 415.958)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_621" data-name="Ellipse 621" cx="4" cy="4" r="4" transform="translate(1250 376.958)" fill="#6c63ff"/>
|
||||
<circle id="Ellipse_622" data-name="Ellipse 622" cx="4" cy="4" r="4" transform="translate(647 576.958)" fill="#6c63ff"/>
|
||||
<path id="Path_3717-109" data-name="Path 3717" d="M94,581.322H92.178V579.5h-.356v1.822H90v.356h1.822V583.5h.356v-1.822H94Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3718-110" data-name="Path 3718" d="M679,433.322h-1.822V431.5h-.356v1.822H675v.356h1.822V435.5h.356v-1.822H679Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3719-111" data-name="Path 3719" d="M830,403.322h-1.822V401.5h-.356v1.822H826v.356h1.822V405.5h.356v-1.822H830Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3720-112" data-name="Path 3720" d="M505,483.322h-1.822V481.5h-.356v1.822H501v.356h1.822V485.5h.356v-1.822H505Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3721-113" data-name="Path 3721" d="M786,493.322h-1.822V491.5h-.356v1.822H782v.356h1.822V495.5h.356v-1.822H786Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3722-114" data-name="Path 3722" d="M447,536.322h-1.822V534.5h-.356v1.822H443v.356h1.822V538.5h.356v-1.822H447Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3723-115" data-name="Path 3723" d="M575,538.322h-1.822V536.5h-.356v1.822H571v.356h1.822V540.5h.356v-1.822H575Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3724-116" data-name="Path 3724" d="M96,368.322H94.178V366.5h-.356v1.822H92v.356h1.822V370.5h.356v-1.822H96Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3725-117" data-name="Path 3725" d="M611.748,385.046,585.3,445.984l5.174,8.623-1.725,2.874,12.073,6.324v-3.449l4.6-1.15,19.546-35.643Z" transform="translate(497 83.958)" fill="#d6d6e3"/>
|
||||
<path id="Path_3726-118" data-name="Path 3726" d="M728.052,532.407s-19.546,30.469,2.3,35.068,4.024-32.194,4.024-32.194Z" transform="translate(360 8.458)" fill="#d6d6e3"/>
|
||||
<path id="Path_3727-119" data-name="Path 3727" d="M756.221,518.609l-6.9,22.421-2.874,28.744-5.174,10.348,5.749,46.566,9.2,9.2,4.024,45.991v20.7l10.923,18.971L757.1,741.508a6.361,6.361,0,0,0,4.99,10.031c3.105.082,7.2-.8,12.525-3.55,16.672-8.623,16.1-16.672,16.1-16.672s10.348,0,10.923-8.048-6.324-65.537-6.324-65.537l-6.324-24.72V565.75h2.3l1.15,57.489,5.174,21.271.575,9.2,7.474,91.982s33.343,9.2,35.068,1.725-12.647-12.073-12.647-12.073l8.623-16.672V686.476l-2.874-6.9,3.449-38.02V623.813l4.6-5.749V572.074l-5.749-17.821-1.725-14.947-9.2-23S783.241,502.513,756.221,518.609Z" transform="translate(360 8.458)" fill="#f2f2f2"/>
|
||||
<path id="Path_3728-120" data-name="Path 3728" d="M830.956,388.685a43.691,43.691,0,1,1-78.759-26.06l.012-.012a43.687,43.687,0,0,1,78.748,26.071Z" transform="translate(360 8.458)" fill="#6c63ff"/>
|
||||
<path id="Path_3730-121" data-name="Path 3730" d="M838.192,374.063l-15.859,14.622c-26.784-69.527-69.389-26.818-70.125-26.071a43.691,43.691,0,0,1,38.4-17.492c14.955,1.148,40.571,15.68,47.579,28.941Z" transform="translate(360 8.458)" fill="#f2f2f2"/>
|
||||
<path id="Path_3731-122" data-name="Path 3731" d="M819.908,359.653l5.989,20.79s-12.433,37.263-70.086,38.562l-1.89,5.323-6.324,1.725-2.874,12.073,8.048,76.46s-3.449,7.474,2.3,6.9c0,0,37.942-12.647,70.711-1.15,0,0,6.9,2.874,5.174-3.449,0,0,23-14.372,21.271-29.319s1.725-84.508,1.725-84.508,3.449-20.121-6.9-24.72C847.053,378.337,831.855,357.065,819.908,359.653Z" transform="translate(360 8.458)" fill="#f2f2f2"/>
|
||||
<path id="Path_3732-123" data-name="Path 3732" d="M807.3,504.918s-36.018,3.617-26.048,23.591,27.725-16.851,27.725-16.851Z" transform="translate(360 8.458)" fill="#d6d6e3"/>
|
||||
<path id="Path_3733-124" data-name="Path 3733" d="M825.782,415.7s-6.324,7.474-4.024,19.546,10.923,39.092,10.923,39.092l-30.469,28.169,9.2,12.647L852.8,493.889l9.2-5.749h0a238.506,238.506,0,0,0-16.892-67.64l-1.5-3.645S832.681,412.256,825.782,415.7Z" transform="translate(360 8.458)" fill="#d6d6e3"/>
|
||||
<path id="Path_3734-125" data-name="Path 3734" d="M481,352.322h-1.822V350.5h-.356v1.822H477v.356h1.822V354.5h.356v-1.822H481Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3735-126" data-name="Path 3735" d="M645,296.322h-1.822V294.5h-.356v1.822H641v.356h1.822V298.5h.356v-1.822H645Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3736-127" data-name="Path 3736" d="M627,313.322h-1.822V311.5h-.356v1.822H623v.356h1.822V315.5h.356v-1.822H627Z" transform="translate(497 83.958)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_625" data-name="Ellipse 625" cx="4" cy="4" r="4" transform="translate(1049 346.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3740-128" data-name="Path 3740" d="M983.01,276.46h-2A82.085,82.085,0,0,0,1063,358v-2a80.079,80.079,0,0,1-79.99-79.54Z" transform="translate(360 8.458)" fill="#6c63ff"/>
|
||||
<path id="Path_3741-129" data-name="Path 3741" d="M946.01,276.46h-2A119.115,119.115,0,0,0,1063,395v-2A117.123,117.123,0,0,1,946.01,276.46Z" transform="translate(360 8.458)" fill="#6c63ff"/>
|
||||
<path id="Path_3742-130" data-name="Path 3742" d="M908,276.46h-2C906.25,362.82,976.58,433,1063,433v-2C977.68,431,908.25,361.72,908,276.46Z" transform="translate(360 8.458)" fill="#6c63ff"/>
|
||||
<circle id="Ellipse_658" data-name="Ellipse 658" cx="7" cy="7" r="7" transform="translate(729 587.958)" fill="#f2f2f2"/>
|
||||
<path id="Path_3765-131" data-name="Path 3765" d="M505,483.678h-1.822V485.5h-.356v-1.822H501v-.356h1.822V481.5h.356v1.822H505Z" transform="translate(326 -33.042)" fill="#f2f2f2"/>
|
||||
<path id="Path_3766-132" data-name="Path 3766" d="M447,536.678h-1.822V538.5h-.356v-1.822H443v-.356h1.822V534.5h.356v1.822H447Z" transform="translate(326 -139.042)" fill="#f2f2f2"/>
|
||||
<path id="Path_3767-133" data-name="Path 3767" d="M481,352.678h-1.822V354.5h-.356v-1.822H477v-.356h1.822V350.5h.356v1.822H481Z" transform="translate(326 228.958)" fill="#f2f2f2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
48
images/illustrations/undraw_two_factor_authentication.svg
Normal file
48
images/illustrations/undraw_two_factor_authentication.svg
Normal file
@@ -0,0 +1,48 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="490.473" viewBox="0 0 800 490.473" xmlns:xlink="http://www.w3.org/1999/xlink" role="img" artist="Katerina Limpitsouni" source="https://undraw.co/">
|
||||
<g id="Group_2117" data-name="Group 2117" transform="translate(-381 -194.147)">
|
||||
<path id="Path_22785-314" data-name="Path 22785" d="M1104.195,366.288h-1.351V329.275a21.422,21.422,0,0,0-21.422-21.422h-78.416a21.422,21.422,0,0,0-21.422,21.422V532.329a21.422,21.422,0,0,0,21.422,21.422h78.416a21.422,21.422,0,0,0,21.422-21.422v-139.7h1.351Z" transform="translate(76.805 34.376)" fill="#090814"/>
|
||||
<path id="Path_22786-315" data-name="Path 22786" d="M1100.507,333.046V535.8a16,16,0,0,1-16,16h-78.794a15.994,15.994,0,0,1-15.993-16V333.046a15.993,15.993,0,0,1,15.992-15.993h9.56a7.6,7.6,0,0,0,7.037,10.468h44.925a7.59,7.59,0,0,0,7.037-10.468h10.235a16,16,0,0,1,16,15.994Z" transform="translate(74.583 31.864)" fill="#f2f2f2"/>
|
||||
<rect id="Rectangle_3655" data-name="Rectangle 3655" width="91.595" height="24.716" transform="translate(1068.579 452.725)" fill="#6c63ff"/>
|
||||
<path id="Path_22787-316" data-name="Path 22787" d="M1092.469,478.023h-88.687a2.183,2.183,0,0,1-2.181-2.181V454.034a2.183,2.183,0,0,1,2.181-2.181h88.687a2.183,2.183,0,0,1,2.181,2.181v21.808A2.183,2.183,0,0,1,1092.469,478.023Zm-88.687-24.716a.728.728,0,0,0-.727.727v21.808a.727.727,0,0,0,.727.727h88.687a.727.727,0,0,0,.727-.727V454.034a.728.728,0,0,0-.727-.727Z" transform="translate(71.339 -4.944)" fill="#090814"/>
|
||||
<rect id="Rectangle_3656" data-name="Rectangle 3656" width="11.631" height="1.454" transform="translate(1078.756 466.537)" fill="#090814"/>
|
||||
<rect id="Rectangle_3657" data-name="Rectangle 3657" width="11.631" height="1.454" transform="translate(1094.749 466.537)" fill="#090814"/>
|
||||
<rect id="Rectangle_3658" data-name="Rectangle 3658" width="11.631" height="1.454" transform="translate(1110.742 466.537)" fill="#090814"/>
|
||||
<rect id="Rectangle_3659" data-name="Rectangle 3659" width="11.631" height="1.454" transform="translate(1126.735 466.537)" fill="#090814"/>
|
||||
<rect id="Rectangle_3660" data-name="Rectangle 3660" width="11.631" height="1.454" transform="translate(1142.727 466.537)" fill="#090814"/>
|
||||
<rect id="Rectangle_3661" data-name="Rectangle 3661" width="343.844" height="168.651" transform="translate(468.852 514.515)" fill="#f2f2f2"/>
|
||||
<rect id="Rectangle_3662" data-name="Rectangle 3662" width="532.848" height="1.454" transform="translate(612.787 550.862)" fill="#090814"/>
|
||||
<path id="Path_22790-317" data-name="Path 22790" d="M455.894,107.285H303.607v-3.139H234.554v3.139H81.64a10.3,10.3,0,0,0-10.3,10.3V326.114a10.3,10.3,0,0,0,10.3,10.3H455.894a10.3,10.3,0,0,0,10.3-10.3V117.586A10.3,10.3,0,0,0,455.894,107.285Z" transform="translate(325.355 90)" fill="#090814"/>
|
||||
<rect id="Rectangle_3663" data-name="Rectangle 3663" width="367.229" height="207.164" transform="translate(410.508 215.487)" fill="#f2f2f2"/>
|
||||
<circle id="Ellipse_3596" data-name="Ellipse 3596" cx="3.767" cy="3.767" r="3.767" transform="translate(590.041 202.307)" fill="#6c63ff"/>
|
||||
<path id="Path_22791-318" data-name="Path 22791" d="M236.505,234.938h-8.723a2.183,2.183,0,0,1-2.181-2.181v-8.723a2.183,2.183,0,0,1,2.181-2.181h8.723a2.183,2.183,0,0,1,2.181,2.181v8.723a2.183,2.183,0,0,1-2.181,2.181Zm-8.723-11.631a.728.728,0,0,0-.727.727v8.723a.728.728,0,0,0,.727.727h8.723a.728.728,0,0,0,.727-.727v-8.723a.728.728,0,0,0-.727-.727Z" transform="translate(283.232 57.859)" fill="#090814"/>
|
||||
<rect id="Rectangle_3664" data-name="Rectangle 3664" width="165.743" height="1.454" transform="translate(509.561 291.344)" fill="#090814"/>
|
||||
<rect id="Rectangle_3665" data-name="Rectangle 3665" width="38.528" height="11.631" transform="translate(632.414 331.326)" fill="#6c63ff"/>
|
||||
<path id="Path_22792-319" data-name="Path 22792" d="M438.4,299.938h-35.62a2.183,2.183,0,0,1-2.181-2.181v-8.723a2.183,2.183,0,0,1,2.181-2.181H438.4a2.183,2.183,0,0,1,2.181,2.181v8.723a2.183,2.183,0,0,1-2.181,2.181Zm-35.62-11.631a.728.728,0,0,0-.727.727v8.723a.728.728,0,0,0,.727.727H438.4a.728.728,0,0,0,.727-.727v-8.723a.728.728,0,0,0-.727-.727Z" transform="translate(235.447 40.11)" fill="#090814"/>
|
||||
<rect id="Rectangle_3666" data-name="Rectangle 3666" width="72.694" height="50.886" transform="translate(892.659 344.411)" fill="#6c63ff"/>
|
||||
<path id="Path_22793-320" data-name="Path 22793" d="M836.3,355.147H766.509a2.911,2.911,0,0,1-2.908-2.908V304.261a2.911,2.911,0,0,1,2.908-2.908H836.3a2.911,2.911,0,0,1,2.908,2.908v47.978a2.911,2.911,0,0,1-2.908,2.908Zm-69.786-50.886v47.978H836.3l0-47.978Z" transform="translate(136.327 36.151)" fill="#090814"/>
|
||||
<path id="Path_22794-321" data-name="Path 22794" d="M832.395,292.75h-2.908a23.989,23.989,0,1,0-47.978,0H778.6a26.9,26.9,0,0,1,53.794,0Z" transform="translate(132.231 45.845)" fill="#090814"/>
|
||||
<path id="Path_22795-322" data-name="Path 22795" d="M820.139,327.619a7.27,7.27,0,1,0-11.118,6.159v7.8a3.849,3.849,0,0,0,3.849,3.849h0a3.849,3.849,0,0,0,3.849-3.849v-7.8A7.257,7.257,0,0,0,820.139,327.619Z" transform="translate(124.859 30.966)" fill="#3f3d56"/>
|
||||
<rect id="Rectangle_3667" data-name="Rectangle 3667" width="11.631" height="1.454" transform="translate(587.707 603.202)" fill="#090814"/>
|
||||
<rect id="Rectangle_3668" data-name="Rectangle 3668" width="11.631" height="1.454" transform="translate(603.7 603.202)" fill="#090814"/>
|
||||
<rect id="Rectangle_3669" data-name="Rectangle 3669" width="11.631" height="1.454" transform="translate(619.693 603.202)" fill="#090814"/>
|
||||
<rect id="Rectangle_3670" data-name="Rectangle 3670" width="11.631" height="1.454" transform="translate(635.685 603.202)" fill="#090814"/>
|
||||
<rect id="Rectangle_3671" data-name="Rectangle 3671" width="11.631" height="1.454" transform="translate(651.678 603.202)" fill="#090814"/>
|
||||
<path id="Path_22796-323" data-name="Path 22796" d="M514.444,714.412H173.509A2.911,2.911,0,0,1,170.6,711.5V545.761a2.911,2.911,0,0,1,2.908-2.908H514.444a2.911,2.911,0,0,1,2.908,2.908V711.5A2.911,2.911,0,0,1,514.444,714.412ZM173.509,545.761V711.5H514.446l0-165.743Z" transform="translate(298.251 -29.792)" fill="#3f3d56"/>
|
||||
<circle id="Ellipse_3597" data-name="Ellipse 3597" cx="4.362" cy="4.362" r="4.362" transform="translate(482.664 531.962)" fill="#090814"/>
|
||||
<circle id="Ellipse_3598" data-name="Ellipse 3598" cx="4.362" cy="4.362" r="4.362" transform="translate(497.93 531.962)" fill="#090814"/>
|
||||
<circle id="Ellipse_3599" data-name="Ellipse 3599" cx="4.362" cy="4.362" r="4.362" transform="translate(513.195 531.962)" fill="#090814"/>
|
||||
<path id="Path_22797-324" data-name="Path 22797" d="M415.919,669.931H317.782a2.183,2.183,0,0,1-2.181-2.181V643.034a2.183,2.183,0,0,1,2.181-2.181h98.137a2.183,2.183,0,0,1,2.181,2.181V667.75a2.183,2.183,0,0,1-2.181,2.181Zm-98.137-27.624a.728.728,0,0,0-.727.727V667.75a.728.728,0,0,0,.727.727h98.137a.728.728,0,0,0,.727-.727V643.034a.728.728,0,0,0-.727-.727Z" transform="translate(258.657 -56.552)" fill="#090814"/>
|
||||
<circle id="Ellipse_3600" data-name="Ellipse 3600" cx="13.085" cy="13.085" r="13.085" transform="translate(686.208 587.936)" fill="#6c63ff"/>
|
||||
<path id="Path_22798-325" data-name="Path 22798" d="M488.413,669.477a13.812,13.812,0,1,1,13.812-13.812A13.812,13.812,0,0,1,488.413,669.477Zm0-26.17a12.358,12.358,0,1,0,12.358,12.358A12.358,12.358,0,0,0,488.413,643.307Z" transform="translate(215.241 -56.825)" fill="#090814"/>
|
||||
<path id="Path_22799-326" data-name="Path 22799" d="M441.475,555.271l-7.037-7.038,2.056-2.056,4.594,4.593L453.9,532.555l2.378,1.674Z" transform="translate(262.373 48.728)" fill="#090814"/>
|
||||
<path id="Path_22801-327" data-name="Path 22801" d="M470.611,410.782h-35.84V409.33c0-.159-.229-.288-.512-.288H421.971c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H400.98c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H379.988c-.283,0-.512.129-.512.288v1.452H371.8V409.33c0-.159-.229-.288-.512-.288H359c-.283,0-.512.129-.512.288v1.452H350.8V409.33c0-.159-.229-.288-.512-.288H338c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H317.012c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H212.053c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H191.061c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H170.069c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H149.077c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H128.085c-.283,0-.512.129-.512.288v1.452h-7.68V409.33c0-.159-.229-.288-.512-.288H107.093c-.283,0-.512.129-.512.288v1.452H98.9V409.33c0-.159-.229-.288-.512-.288H86.1c-.283,0-.512.129-.512.288v1.452H62.038c-6.786,0-12.288,3.093-12.288,6.909v3.124c0,3.816,5.5,6.909,12.288,6.909H470.611c6.787,0,12.288-3.093,12.288-6.909v-3.124C482.9,413.875,477.4,410.782,470.611,410.782Z" transform="translate(331.25 6.746)" fill="#090814"/>
|
||||
<path id="Path_22802-328" data-name="Path 22802" d="M401.695,290.179H209.782A2.183,2.183,0,0,1,207.6,288V208.034a2.183,2.183,0,0,1,2.181-2.181H401.695a2.183,2.183,0,0,1,2.181,2.181V288a2.183,2.183,0,0,1-2.181,2.181ZM209.782,207.307a.728.728,0,0,0-.727.727V288a.728.728,0,0,0,.727.727H401.695a.728.728,0,0,0,.727-.727V208.034a.728.728,0,0,0-.727-.727Z" transform="translate(288.147 62.228)" fill="#3f3d56"/>
|
||||
<path id="Path_22803-329" data-name="Path 22803" d="M236.505,264.938h-8.723a2.183,2.183,0,0,1-2.181-2.181v-8.723a2.183,2.183,0,0,1,2.181-2.181h8.723a2.183,2.183,0,0,1,2.181,2.181v8.723a2.183,2.183,0,0,1-2.181,2.181Zm-8.723-11.631a.728.728,0,0,0-.727.727v8.723a.728.728,0,0,0,.727.727h8.723a.728.728,0,0,0,.727-.727v-8.723a.728.728,0,0,0-.727-.727Z" transform="translate(283.232 49.667)" fill="#090814"/>
|
||||
<rect id="Rectangle_3672" data-name="Rectangle 3672" width="165.743" height="1.454" transform="translate(509.561 313.152)" fill="#090814"/>
|
||||
<rect id="Rectangle_3673" data-name="Rectangle 3673" width="532.848" height="1.454" transform="translate(573.532 390.208)" fill="#090814"/>
|
||||
<circle id="Ellipse_3601" data-name="Ellipse 3601" cx="10.177" cy="10.177" r="10.177" transform="translate(563.354 380.031)" fill="#6c63ff"/>
|
||||
<circle id="Ellipse_3602" data-name="Ellipse 3602" cx="7.996" cy="7.996" r="7.996" transform="translate(1098.384 383.665)" fill="#6c63ff"/>
|
||||
<circle id="Ellipse_3603" data-name="Ellipse 3603" cx="7.996" cy="7.996" r="7.996" transform="translate(1137.639 544.32)" fill="#6c63ff"/>
|
||||
<circle id="Ellipse_3604" data-name="Ellipse 3604" cx="7.996" cy="7.996" r="7.996" transform="translate(606.971 544.32)" fill="#6c63ff"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
@@ -3720,6 +3720,7 @@ return array(
|
||||
'Twig\\Markup' => $vendorDir . '/twig/twig/src/Markup.php',
|
||||
'Twig\\NodeTraverser' => $vendorDir . '/twig/twig/src/NodeTraverser.php',
|
||||
'Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
|
||||
'Twig\\NodeVisitor\\CorrectnessNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/CorrectnessNodeVisitor.php',
|
||||
'Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
|
||||
'Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
|
||||
'Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
|
||||
@@ -3734,6 +3735,8 @@ return array(
|
||||
'Twig\\Node\\CheckSecurityCallNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityCallNode.php',
|
||||
'Twig\\Node\\CheckSecurityNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityNode.php',
|
||||
'Twig\\Node\\CheckToStringNode' => $vendorDir . '/twig/twig/src/Node/CheckToStringNode.php',
|
||||
'Twig\\Node\\CoercesChildrenToStringInterface' => $vendorDir . '/twig/twig/src/Node/CoercesChildrenToStringInterface.php',
|
||||
'Twig\\Node\\ConfigNode' => $vendorDir . '/twig/twig/src/Node/ConfigNode.php',
|
||||
'Twig\\Node\\DeprecatedNode' => $vendorDir . '/twig/twig/src/Node/DeprecatedNode.php',
|
||||
'Twig\\Node\\DoNode' => $vendorDir . '/twig/twig/src/Node/DoNode.php',
|
||||
'Twig\\Node\\EmbedNode' => $vendorDir . '/twig/twig/src/Node/EmbedNode.php',
|
||||
@@ -3872,6 +3875,7 @@ return array(
|
||||
'Twig\\Sandbox\\SecurityNotAllowedMethodError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
|
||||
'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
|
||||
'Twig\\Sandbox\\SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php',
|
||||
'Twig\\Sandbox\\SecurityNotAllowedTestError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedTestError.php',
|
||||
'Twig\\Sandbox\\SecurityPolicy' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicy.php',
|
||||
'Twig\\Sandbox\\SecurityPolicyInterface' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php',
|
||||
'Twig\\Sandbox\\SourcePolicyInterface' => $vendorDir . '/twig/twig/src/Sandbox/SourcePolicyInterface.php',
|
||||
@@ -3907,6 +3911,7 @@ return array(
|
||||
'Twig\\TwigFunction' => $vendorDir . '/twig/twig/src/TwigFunction.php',
|
||||
'Twig\\TwigTest' => $vendorDir . '/twig/twig/src/TwigTest.php',
|
||||
'Twig\\Util\\CallableArgumentsExtractor' => $vendorDir . '/twig/twig/src/Util/CallableArgumentsExtractor.php',
|
||||
'Twig\\Util\\CallableParameters' => $vendorDir . '/twig/twig/src/Util/CallableParameters.php',
|
||||
'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',
|
||||
|
||||
@@ -28,12 +28,12 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'T' =>
|
||||
'T' =>
|
||||
array (
|
||||
'Twig\\' => 5,
|
||||
'TheNetworg\\OAuth2\\Client\\' => 25,
|
||||
),
|
||||
'S' =>
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Runtime\\Symfony\\Component\\' => 34,
|
||||
'Symfony\\Polyfill\\Php83\\' => 23,
|
||||
@@ -85,7 +85,7 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'ScssPhp\\ScssPhp\\' => 16,
|
||||
'Sabberworm\\CSS\\' => 15,
|
||||
),
|
||||
'P' =>
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\Log\\' => 8,
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
@@ -96,310 +96,310 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'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\\Runtime\\Symfony\\Component\\' =>
|
||||
'Symfony\\Runtime\\Symfony\\Component\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/runtime/Internal',
|
||||
),
|
||||
'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\\Runtime\\' =>
|
||||
'Symfony\\Component\\Runtime\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/runtime',
|
||||
),
|
||||
'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\\Bundle\\DebugBundle\\' =>
|
||||
'Symfony\\Bundle\\DebugBundle\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/debug-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',
|
||||
),
|
||||
@@ -4121,6 +4121,7 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Twig\\Markup' => __DIR__ . '/..' . '/twig/twig/src/Markup.php',
|
||||
'Twig\\NodeTraverser' => __DIR__ . '/..' . '/twig/twig/src/NodeTraverser.php',
|
||||
'Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
|
||||
'Twig\\NodeVisitor\\CorrectnessNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/CorrectnessNodeVisitor.php',
|
||||
'Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
|
||||
'Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
|
||||
'Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
|
||||
@@ -4135,6 +4136,8 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Twig\\Node\\CheckSecurityCallNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityCallNode.php',
|
||||
'Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityNode.php',
|
||||
'Twig\\Node\\CheckToStringNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckToStringNode.php',
|
||||
'Twig\\Node\\CoercesChildrenToStringInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/CoercesChildrenToStringInterface.php',
|
||||
'Twig\\Node\\ConfigNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ConfigNode.php',
|
||||
'Twig\\Node\\DeprecatedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DeprecatedNode.php',
|
||||
'Twig\\Node\\DoNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DoNode.php',
|
||||
'Twig\\Node\\EmbedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/EmbedNode.php',
|
||||
@@ -4273,6 +4276,7 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Twig\\Sandbox\\SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
|
||||
'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
|
||||
'Twig\\Sandbox\\SecurityNotAllowedTagError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php',
|
||||
'Twig\\Sandbox\\SecurityNotAllowedTestError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedTestError.php',
|
||||
'Twig\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicy.php',
|
||||
'Twig\\Sandbox\\SecurityPolicyInterface' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php',
|
||||
'Twig\\Sandbox\\SourcePolicyInterface' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SourcePolicyInterface.php',
|
||||
@@ -4308,6 +4312,7 @@ class ComposerStaticInitfc0e9e9dea11dcbb6272414776c30685
|
||||
'Twig\\TwigFunction' => __DIR__ . '/..' . '/twig/twig/src/TwigFunction.php',
|
||||
'Twig\\TwigTest' => __DIR__ . '/..' . '/twig/twig/src/TwigTest.php',
|
||||
'Twig\\Util\\CallableArgumentsExtractor' => __DIR__ . '/..' . '/twig/twig/src/Util/CallableArgumentsExtractor.php',
|
||||
'Twig\\Util\\CallableParameters' => __DIR__ . '/..' . '/twig/twig/src/Util/CallableParameters.php',
|
||||
'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',
|
||||
|
||||
@@ -6016,17 +6016,17 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.24.0",
|
||||
"version_normalized": "3.24.0.0",
|
||||
"version": "v3.28.0",
|
||||
"version_normalized": "3.28.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0"
|
||||
"reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6769aefb305efef849dc25c9fd1653358c148f0",
|
||||
"reference": "a6769aefb305efef849dc25c9fd1653358c148f0",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b",
|
||||
"reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6041,7 +6041,7 @@
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
|
||||
},
|
||||
"time": "2026-03-17T21:31:11+00:00",
|
||||
"time": "2026-07-03T20:44:34+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@@ -6083,7 +6083,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.24.0"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '99cfe95c32885c98c66555bfec290df7d0e522a6',
|
||||
'reference' => '9493bb03d54320431907bd20e28f930d7e2807a7',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -24,7 +24,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '99cfe95c32885c98c66555bfec290df7d0e522a6',
|
||||
'reference' => '9493bb03d54320431907bd20e28f930d7e2807a7',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -49,9 +49,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'firebase/php-jwt' => array(
|
||||
'pretty_version' => 'v7.0.3',
|
||||
'version' => '7.0.3.0',
|
||||
'reference' => '28aa0694bcfdfa5e2959c394d5a1ee7a5083629e',
|
||||
'pretty_version' => 'v7.0.5',
|
||||
'version' => '7.0.5.0',
|
||||
'reference' => '47ad26bab5e7c70ae8a6f08ed25ff83631121380',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||
'aliases' => array(),
|
||||
@@ -76,9 +76,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/psr7' => array(
|
||||
'pretty_version' => '2.8.0',
|
||||
'version' => '2.8.0.0',
|
||||
'reference' => '21dc724a0583619cd1652f673303492272778051',
|
||||
'pretty_version' => '2.9.0',
|
||||
'version' => '2.9.0.0',
|
||||
'reference' => '7d0ed42f28e42d61352a7a79de682e5e67fec884',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||
'aliases' => array(),
|
||||
@@ -94,9 +94,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'league/oauth2-google' => array(
|
||||
'pretty_version' => '4.1.0',
|
||||
'version' => '4.1.0.0',
|
||||
'reference' => '8b9bb43740ac6d994aca881a35f7bacbe98c0ffb',
|
||||
'pretty_version' => '4.2.0',
|
||||
'version' => '4.2.0.0',
|
||||
'reference' => '72be69505f890ea8b6d4e716f619b3c10a1f5010',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../league/oauth2-google',
|
||||
'aliases' => array(),
|
||||
@@ -105,7 +105,7 @@
|
||||
'nikic/php-parser' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => 'b2cd0735eb27788d5d41fa3c2cfaa01a593fd7fb',
|
||||
'reference' => 'b27e577f70d2114b8ba96105e403017919a8611b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nikic/php-parser',
|
||||
'aliases' => array(
|
||||
@@ -312,9 +312,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/cache' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => 'a0a1690543329685c044362c873b78c6de9d4faa',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '5b94fba945d1f9e7929cffd50e7a17f1ac36f10b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/cache',
|
||||
'aliases' => array(),
|
||||
@@ -345,9 +345,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/console' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '7b1f1c37eff5910ddda2831345467e593a5120ad',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '9f481cfb580db8bcecc9b2d4c63f3e13df022ad5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/console',
|
||||
'aliases' => array(),
|
||||
@@ -362,10 +362,19 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/debug-bundle' => array(
|
||||
'pretty_version' => 'v6.4.35',
|
||||
'version' => '6.4.35.0',
|
||||
'reference' => 'eb79084c2c9778559b21f61cb1507cbd580cc6e1',
|
||||
'type' => 'symfony-bundle',
|
||||
'install_path' => __DIR__ . '/../symfony/debug-bundle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => true,
|
||||
),
|
||||
'symfony/dependency-injection' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '91e49958b8a6092e48e4711894a1aeb1b151c62a',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => 'cd7881a6dc84b780411199cd0584e1a53a3b9ba7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/dependency-injection',
|
||||
'aliases' => array(),
|
||||
@@ -381,27 +390,27 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/dotenv' => array(
|
||||
'pretty_version' => 'v6.4.30',
|
||||
'version' => '6.4.30.0',
|
||||
'reference' => '924edbc9631b75302def0258ed1697948b17baf6',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => 'cae019cc92a46fe9e498ea011107f26bdf5d897f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/dotenv',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/error-handler' => array(
|
||||
'pretty_version' => 'v6.4.32',
|
||||
'version' => '6.4.32.0',
|
||||
'reference' => '8c18400784fcb014dc73c8d5601a9576af7f8ad4',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '2ea68f0e1835ad6a126f93bbc14cd236c10ab361',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/error-handler',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/event-dispatcher' => array(
|
||||
'pretty_version' => 'v6.4.32',
|
||||
'version' => '6.4.32.0',
|
||||
'reference' => '99d7e101826e6610606b9433248f80c1997cd20b',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => 'fc828863e26ceec86e2513b5e46aa0b149d76b69',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
|
||||
'aliases' => array(),
|
||||
@@ -441,36 +450,36 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/form' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => 'ed9275a133809bb48d949ba6dfdc808a819ebea2',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '3a38a81150400f0a486f8963e21a195311b30b27',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/form',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/framework-bundle' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '5b5d19473f22d699811a41b01cef2462bc42b238',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '147b02cfa45dcc74a290462551f5ee5c7fa8ab17',
|
||||
'type' => 'symfony-bundle',
|
||||
'install_path' => __DIR__ . '/../symfony/framework-bundle',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-foundation' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '5bb346d1b4b2a616e5c3d99b3ee4d5810735c535',
|
||||
'pretty_version' => 'v6.4.35',
|
||||
'version' => '6.4.35.0',
|
||||
'reference' => 'cffffd0a2c037117b742b4f8b379a22a2a33f6d2',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-kernel' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '006a49fc4f41ee21a6ca61e69caed1c30b29f07c',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '4087ec02119de450e9ebb60806d69c6bb8c6e468',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-kernel',
|
||||
'aliases' => array(),
|
||||
@@ -486,9 +495,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/mime' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '2b32fbbe10b36a8379efab6e702ad8b917151839',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '9c31726137c70798f815fb98293ffb8a2a47694c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/mime',
|
||||
'aliases' => array(),
|
||||
@@ -513,35 +522,35 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => '141046a8f9477948ff284fa65be2095baafb94f2',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-grapheme' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '380872130d3a5dd3ace2f4010d95125fde5d5c70',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => 'ad1b7b9092976d6c948b8a187cec9faaea9ec1df',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-icu' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => 'bfc8fa13dbaf21d69114b0efcd72ab700fb04d0c',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => '3510b63d07376b04e57e27e82607d468bb134f78',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-icu',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-idn' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => '9614ac4d8061dc257ecc64cba1b140873dce8ad3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
|
||||
@@ -549,8 +558,8 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-normalizer' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => '3833d7255cc303546435cb650316bff708a1c75c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
|
||||
@@ -558,18 +567,18 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => '6a21eb99c6973357967f6ce3708cd55a6bec6315',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php83' => array(
|
||||
'pretty_version' => 'v1.33.0',
|
||||
'version' => '1.33.0.0',
|
||||
'reference' => '17f6f9a6b1735c0f163024d959f700cfbc5155e5',
|
||||
'pretty_version' => 'v1.36.0',
|
||||
'version' => '1.36.0.0',
|
||||
'reference' => '3600c2cb22399e25bb226e4a135ce91eeb2a6149',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php83',
|
||||
'aliases' => array(),
|
||||
@@ -602,10 +611,19 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/runtime' => array(
|
||||
'pretty_version' => 'v6.4.30',
|
||||
'version' => '6.4.30.0',
|
||||
'reference' => 'fb3149ee85d3b639dd3e49ea9dda05656f0537e3',
|
||||
'type' => 'composer-plugin',
|
||||
'install_path' => __DIR__ . '/../symfony/runtime',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/security-core' => array(
|
||||
'pretty_version' => 'v6.4.31',
|
||||
'version' => '6.4.31.0',
|
||||
'reference' => 'fa269ad61a021cc54329dc96e57bed78ba720bfe',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '1b7db28bcc3655543abfe58764025aef563705cd',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/security-core',
|
||||
'aliases' => array(),
|
||||
@@ -663,9 +681,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/twig-bridge' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '5169074f4a88dfb02eeccddaba78edfdf212a9b2',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '3ae963a108fd6fc14d09a7fe5e41fe64d8ac11ba',
|
||||
'type' => 'symfony-bridge',
|
||||
'install_path' => __DIR__ . '/../symfony/twig-bridge',
|
||||
'aliases' => array(),
|
||||
@@ -681,36 +699,36 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/validator' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '7c3897b7f739d4ab913481e680405ca82d08084d',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '14921e87b2bd69dfbd9757cdb1c6974a1316aac5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/validator',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-dumper' => array(
|
||||
'pretty_version' => 'v6.4.32',
|
||||
'version' => '6.4.32.0',
|
||||
'reference' => '131fc9915e0343052af5ed5040401b481ca192aa',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '7c8ad9ce4faf6c8a99948e70ce02b601a0439782',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-dumper',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/var-exporter' => array(
|
||||
'pretty_version' => 'v6.4.26',
|
||||
'version' => '6.4.26.0',
|
||||
'reference' => '466fcac5fa2e871f83d31173f80e9c2684743bfc',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => 'f9c4a9695a9e2bbc65c920e147d8d7ae28f8d79a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/var-exporter',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/web-profiler-bundle' => array(
|
||||
'pretty_version' => 'v6.4.34',
|
||||
'version' => '6.4.34.0',
|
||||
'reference' => '848bc5d5745500f855bb201d57ae066fd7e67448',
|
||||
'pretty_version' => 'v6.4.36',
|
||||
'version' => '6.4.36.0',
|
||||
'reference' => '6f75b4c748886c8e04a3674225d00eaa51f3842d',
|
||||
'type' => 'symfony-bundle',
|
||||
'install_path' => __DIR__ . '/../symfony/web-profiler-bundle',
|
||||
'aliases' => array(),
|
||||
@@ -726,9 +744,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'tecnickcom/tcpdf' => array(
|
||||
'pretty_version' => '6.11.0',
|
||||
'version' => '6.11.0.0',
|
||||
'reference' => '81172e58edb1cfae4019ef150ccbdc0e9a8c85c9',
|
||||
'pretty_version' => '6.11.2',
|
||||
'version' => '6.11.2.0',
|
||||
'reference' => 'e1e2ade18e574e963473f53271591edd8c0033ec',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../tecnickcom/tcpdf',
|
||||
'aliases' => array(),
|
||||
@@ -744,9 +762,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'twig/twig' => array(
|
||||
'pretty_version' => 'v3.23.0',
|
||||
'version' => '3.23.0.0',
|
||||
'reference' => 'a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9',
|
||||
'pretty_version' => 'v3.28.0',
|
||||
'version' => '3.28.0.0',
|
||||
'reference' => '597c12ed286fb9d1701a36684ce6e0cbe28ebc8b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../twig/twig',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -1,3 +1,75 @@
|
||||
# 3.28.0 (2026-07-03)
|
||||
|
||||
* Render backed enums using their backing value in the `html_attr` function
|
||||
* Fix empty Markup values being treated as truthy in and, or, xor, not, ternary, and elvis expressions
|
||||
* Fix a PHP 8.5 `chr()` deprecation when decoding an octal string escape sequence larger than `\377` (such as `"\777"`)
|
||||
* Mark `Twig\Markup` as `@final`; it will be final in Twig 4.0
|
||||
* Reduce memory usage and speed up the context restoration compiled at the end of `for` loops
|
||||
* Allow calling a macro with a dynamic name via the dot operator (`macros.(name)(args)`)
|
||||
* Report the column number in syntax errors and expose it via `Error::getTemplateColumn()`
|
||||
* Track the source offset of each token and expose it via `Token::getOffset()`
|
||||
* Fix nested `block()` calls to resolve against the overriding template when a block rendered through `block(name, template)` calls `parent()`
|
||||
* Deprecate the possibility to use a `block` tag within a capture node (like `set`)
|
||||
* Deprecate the possibility to use a `block` tag within a capture node (like `set`) in child templates
|
||||
* Deprecate using a `macro`, `extends`, or `use` tag outside the root of a template
|
||||
* Stop reporting a skipped test in `IntegrationTestCase` when there is no legacy test to run
|
||||
* Fix `markdown_to_html` to strip the indentation shared by all lines instead of mangling content that starts with a blank line
|
||||
* Make the `IntegrationTestCase` and `NodeTestCase` test helpers compatible with PHPUnit 11
|
||||
* Cast printed expressions to string so values that cannot be converted to a string (arrays, non-`Stringable` objects, ...) report a usable stack trace at the print location
|
||||
* Make the `include()` function return a `Markup` object so an assigned result is not re-escaped when printed
|
||||
* Skip the sandbox `__toString` check on arguments whose PHP parameter type cannot implicitly coerce to string
|
||||
* Document the criteria for marking a callable or tag as always allowed in a sandbox, and the list of built-in tags, filters, and functions that will be always allowed in Twig 4.0
|
||||
* Add an `always_allowed_in_sandbox` option for filters, functions, and tests, and an `isAlwaysAllowedInSandbox()` method for token parsers, to let authors mark callables and tags that are always allowed in sandbox mode without explicit allow-listing
|
||||
* Add an allow-list for tests to `Twig\Sandbox\SecurityPolicy`, with the safe built-in tests flagged as always allowed so they keep working without allow-listing
|
||||
|
||||
# 3.27.1 (2026-05-30)
|
||||
|
||||
* Fix array access with a `Stringable` key to coerce the key to string consistently instead of throwing in the optimized path
|
||||
* Fix sandbox replacing `IteratorAggregate` arguments (e.g. Symfony's `FormView`) by a plain array
|
||||
|
||||
# 3.27.0 (2026-05-27)
|
||||
|
||||
* Add a strict mode to `Twig\Sandbox\SecurityPolicy` to opt-in to the 4.0 behavior for the `extends`/`use` tags and the `parent`/`block`/`attribute` functions, which are otherwise still implicitly allowed in a sandbox
|
||||
* Deprecate the fact that the `parent`, `block`, and `attribute` functions are always allowed in a sandboxed template
|
||||
* Fix sandbox filter/tag/function allow-list bypass when the sandbox state changed between renders of a cached `Template` instance
|
||||
* Fix PHP 8.1+ implicit float-to-int deprecation triggered by sandboxed `ArrayAccess` attribute access with a float key
|
||||
* Restrict allowed classes in `Twig\Profiler\Profile::unserialize()` to prevent arbitrary class instantiation
|
||||
* Escape root profile name in `HtmlDumper`
|
||||
* Fix sandbox bypass in deprecated internal wrappers `twig_array_some()`, `twig_array_every()`, and `twig_check_arrow_in_sandbox()` (`src/Resources/core.php`)
|
||||
* Deprecate the `Twig\Sandbox\SourcePolicyInterface` interface with no replacement
|
||||
* Fix sandbox bypass in the "column" filter when sandboxing is enabled via `SourcePolicyInterface`
|
||||
* Fix sandbox `__toString` bypass via `Traversable` arguments to the `join` and `replace` filters (also covers containers that implement both `Stringable` and `Traversable`)
|
||||
* Fix sandbox `__toString` bypass via the `in` and `not in` operators
|
||||
* Prevent a stack overflow in `SandboxExtension::ensureToStringAllowed()` when a self-referencing iterable is passed to a sandboxed template
|
||||
* Add support for any expression as a dynamic mapping key (attribute access, filters, ...)
|
||||
* Fix sandbox `__toString` policy bypass via dynamic mapping keys
|
||||
|
||||
# 3.26.0 (2026-05-20)
|
||||
|
||||
* Document that the sandbox doesn't protect against resource exhaustion
|
||||
* Document `template_from_string` caveats when used in a sandboxed environment
|
||||
* Add docs on `Markup` about the goal of this class in the context of a sandbox
|
||||
* Pre-escape HTML input on the `spaceless` filter
|
||||
* Pre-escape HTML input on `inline_css` and `inky_to_html` filters
|
||||
* Fix XSS by adjusting `is_safe` annotation on HTML-emitting filters
|
||||
* [Profiler] Escape template and profile names in `HtmlDumper`
|
||||
* Fix unbounded memoisation of `IntlDateFormatter` / `NumberFormatter`
|
||||
* Fix sandbox bypass in the "column" filter
|
||||
* Fix sandbox bypass in the `{% sandbox %}` tag when including a preloaded template
|
||||
* Fix sandbox bypass: PHP code injection via `{% use %}` template name
|
||||
* Fix sandbox bypass: PHP code injection via `_self` / import macro reference
|
||||
* Fix sandbox bypass in object destructuring assignment
|
||||
* Fix sandbox bypass: propagate `Source` to `checkArrow` for source-policy sandboxing
|
||||
* Encode single quotes as `\x27` in `Compiler::string()` as a defense-in-depth measure
|
||||
* Fix sandbox `__toString` bypasses
|
||||
* Add `Twig\Node\CoercesChildrenToStringInterface` to let nodes declare which of their child nodes will be string-coerced at runtime so the sandbox wraps them with a `__toString` check
|
||||
|
||||
# 3.25.0 (2026-05-17)
|
||||
|
||||
* Add a `needs_is_sandboxed` option for filters, functions, and tests
|
||||
* Use deterministic suffixes for generated embed classes
|
||||
* Lazy-load `EscaperRuntime` in `EscaperExtension`
|
||||
|
||||
# 3.24.0 (2026-03-17)
|
||||
|
||||
* Deprecate not implementing the `getOperatorTokens()` method in `ExpressionParserInterface` implementations
|
||||
|
||||
@@ -32,7 +32,9 @@ abstract class AbstractTwigCallable implements TwigCallableInterface
|
||||
'needs_environment' => false,
|
||||
'needs_context' => false,
|
||||
'needs_charset' => false,
|
||||
'needs_is_sandboxed' => false,
|
||||
'is_variadic' => false,
|
||||
'always_allowed_in_sandbox' => false,
|
||||
'deprecation_info' => null,
|
||||
'deprecated' => false,
|
||||
'deprecating_package' => '',
|
||||
@@ -107,6 +109,16 @@ abstract class AbstractTwigCallable implements TwigCallableInterface
|
||||
return $this->options['needs_context'];
|
||||
}
|
||||
|
||||
public function needsIsSandboxed(): bool
|
||||
{
|
||||
return $this->options['needs_is_sandboxed'];
|
||||
}
|
||||
|
||||
public function isAlwaysAllowedInSandbox(): bool
|
||||
{
|
||||
return $this->options['always_allowed_in_sandbox'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
@@ -182,6 +194,6 @@ abstract class AbstractTwigCallable implements TwigCallableInterface
|
||||
|
||||
public function getMinimalNumberOfRequiredArguments(): int
|
||||
{
|
||||
return ($this->options['needs_charset'] ? 1 : 0) + ($this->options['needs_environment'] ? 1 : 0) + ($this->options['needs_context'] ? 1 : 0) + \count($this->arguments);
|
||||
return ($this->options['needs_charset'] ? 1 : 0) + ($this->options['needs_environment'] ? 1 : 0) + ($this->options['needs_context'] ? 1 : 0) + ($this->options['needs_is_sandboxed'] ? 1 : 0) + \count($this->arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,26 +31,30 @@ use Twig\TwigFilter;
|
||||
final class AsTwigFilter
|
||||
{
|
||||
/**
|
||||
* @param non-empty-string $name The name of the filter in Twig
|
||||
* @param bool|null $needsCharset Whether the filter needs the charset passed as the first argument
|
||||
* @param bool|null $needsEnvironment Whether the filter needs the environment passed as the first argument, or after the charset
|
||||
* @param bool|null $needsContext Whether the filter needs the context array passed as the first argument, or after the charset and the environment
|
||||
* @param string[]|null $isSafe List of formats in which you want the raw output to be printed unescaped
|
||||
* @param string|array|null $isSafeCallback Function called at compilation time to determine if the filter is safe
|
||||
* @param string|null $preEscape Some filters may need to work on input that is already escaped or safe
|
||||
* @param string[]|null $preservesSafety Preserves the safety of the value that the filter is applied to
|
||||
* @param DeprecatedCallableInfo|null $deprecationInfo Information about the deprecation
|
||||
* @param non-empty-string $name The name of the filter in Twig
|
||||
* @param bool|null $needsCharset Whether the filter needs the charset passed as the first argument
|
||||
* @param bool|null $needsEnvironment Whether the filter needs the environment passed as the first argument, or after the charset
|
||||
* @param bool|null $needsContext Whether the filter needs the context array passed as the first argument, or after the charset and the environment
|
||||
* @param bool|null $needsIsSandboxed Whether the filter needs the current sandbox state (a boolean) passed as the first argument, or after the charset, the environment, and the context
|
||||
* @param string[]|null $isSafe List of formats in which you want the raw output to be printed unescaped
|
||||
* @param string|array|null $isSafeCallback Function called at compilation time to determine if the filter is safe
|
||||
* @param string|null $preEscape Some filters may need to work on input that is already escaped or safe
|
||||
* @param string[]|null $preservesSafety Preserves the safety of the value that the filter is applied to
|
||||
* @param DeprecatedCallableInfo|null $deprecationInfo Information about the deprecation
|
||||
* @param bool|null $alwaysAllowedInSandbox Whether the filter is always allowed in sandbox mode, even when not explicitly allow-listed
|
||||
*/
|
||||
public function __construct(
|
||||
public string $name,
|
||||
public ?bool $needsCharset = null,
|
||||
public ?bool $needsEnvironment = null,
|
||||
public ?bool $needsContext = null,
|
||||
public ?bool $needsIsSandboxed = null,
|
||||
public ?array $isSafe = null,
|
||||
public string|array|null $isSafeCallback = null,
|
||||
public ?string $preEscape = null,
|
||||
public ?array $preservesSafety = null,
|
||||
public ?DeprecatedCallableInfo $deprecationInfo = null,
|
||||
public ?bool $alwaysAllowedInSandbox = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,22 +31,26 @@ use Twig\TwigFunction;
|
||||
final class AsTwigFunction
|
||||
{
|
||||
/**
|
||||
* @param non-empty-string $name The name of the function in Twig
|
||||
* @param bool|null $needsCharset Whether the function needs the charset passed as the first argument
|
||||
* @param bool|null $needsEnvironment Whether the function needs the environment passed as the first argument, or after the charset
|
||||
* @param bool|null $needsContext Whether the function needs the context array passed as the first argument, or after the charset and the environment
|
||||
* @param string[]|null $isSafe List of formats in which you want the raw output to be printed unescaped
|
||||
* @param string|array|null $isSafeCallback Function called at compilation time to determine if the function is safe
|
||||
* @param DeprecatedCallableInfo|null $deprecationInfo Information about the deprecation
|
||||
* @param non-empty-string $name The name of the function in Twig
|
||||
* @param bool|null $needsCharset Whether the function needs the charset passed as the first argument
|
||||
* @param bool|null $needsEnvironment Whether the function needs the environment passed as the first argument, or after the charset
|
||||
* @param bool|null $needsContext Whether the function needs the context array passed as the first argument, or after the charset and the environment
|
||||
* @param bool|null $needsIsSandboxed Whether the function needs the current sandbox state (a boolean) passed as the first argument, or after the charset, the environment, and the context
|
||||
* @param string[]|null $isSafe List of formats in which you want the raw output to be printed unescaped
|
||||
* @param string|array|null $isSafeCallback Function called at compilation time to determine if the function is safe
|
||||
* @param DeprecatedCallableInfo|null $deprecationInfo Information about the deprecation
|
||||
* @param bool|null $alwaysAllowedInSandbox Whether the function is always allowed in sandbox mode, even when not explicitly allow-listed
|
||||
*/
|
||||
public function __construct(
|
||||
public string $name,
|
||||
public ?bool $needsCharset = null,
|
||||
public ?bool $needsEnvironment = null,
|
||||
public ?bool $needsContext = null,
|
||||
public ?bool $needsIsSandboxed = null,
|
||||
public ?array $isSafe = null,
|
||||
public string|array|null $isSafeCallback = null,
|
||||
public ?DeprecatedCallableInfo $deprecationInfo = null,
|
||||
public ?bool $alwaysAllowedInSandbox = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,18 +31,22 @@ use Twig\TwigTest;
|
||||
final class AsTwigTest
|
||||
{
|
||||
/**
|
||||
* @param non-empty-string $name The name of the test in Twig
|
||||
* @param bool|null $needsCharset Whether the test needs the charset passed as the first argument
|
||||
* @param bool|null $needsEnvironment Whether the test needs the environment passed as the first argument, or after the charset
|
||||
* @param bool|null $needsContext Whether the test needs the context array passed as the first argument, or after the charset and the environment
|
||||
* @param DeprecatedCallableInfo|null $deprecationInfo Information about the deprecation
|
||||
* @param non-empty-string $name The name of the test in Twig
|
||||
* @param bool|null $needsCharset Whether the test needs the charset passed as the first argument
|
||||
* @param bool|null $needsEnvironment Whether the test needs the environment passed as the first argument, or after the charset
|
||||
* @param bool|null $needsContext Whether the test needs the context array passed as the first argument, or after the charset and the environment
|
||||
* @param bool|null $needsIsSandboxed Whether the test needs the current sandbox state (a boolean) passed as the first argument, or after the charset, the environment, and the context
|
||||
* @param DeprecatedCallableInfo|null $deprecationInfo Information about the deprecation
|
||||
* @param bool|null $alwaysAllowedInSandbox Whether the test is always allowed in sandbox mode, even when not explicitly allow-listed
|
||||
*/
|
||||
public function __construct(
|
||||
public string $name,
|
||||
public ?bool $needsCharset = null,
|
||||
public ?bool $needsEnvironment = null,
|
||||
public ?bool $needsContext = null,
|
||||
public ?bool $needsIsSandboxed = null,
|
||||
public ?DeprecatedCallableInfo $deprecationInfo = null,
|
||||
public ?bool $alwaysAllowedInSandbox = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,13 @@ class Compiler
|
||||
*/
|
||||
public function string(string $value)
|
||||
{
|
||||
$this->source .= \sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
|
||||
// Single quotes are encoded as \x27 (not \') as a defense-in-depth measure:
|
||||
// it guarantees that the compiled output never contains a literal "'" derived
|
||||
// from user input, which prevents breaking out of a surrounding single-quoted
|
||||
// PHP context if a caller mistakenly concatenates the result into one.
|
||||
// \' is not a recognized escape sequence in PHP double-quoted strings (the
|
||||
// backslash would be kept literally), so \x27 is used instead.
|
||||
$this->source .= \sprintf('"%s"', str_replace("'", '\\x27', addcslashes($value, "\0\t\"\$\\")));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -43,10 +43,10 @@ use Twig\TokenParser\TokenParserInterface;
|
||||
*/
|
||||
class Environment
|
||||
{
|
||||
public const VERSION = '3.24.0';
|
||||
public const VERSION_ID = 32400;
|
||||
public const VERSION = '3.28.0';
|
||||
public const VERSION_ID = 32800;
|
||||
public const MAJOR_VERSION = 3;
|
||||
public const MINOR_VERSION = 24;
|
||||
public const MINOR_VERSION = 28;
|
||||
public const RELEASE_VERSION = 0;
|
||||
public const EXTRA_VERSION = '';
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ use Twig\Template;
|
||||
class Error extends \Exception
|
||||
{
|
||||
private $lineno;
|
||||
/** @var positive-int|null */
|
||||
private ?int $columnno;
|
||||
private $rawMessage;
|
||||
private ?Source $source;
|
||||
private string $phpFile;
|
||||
@@ -46,17 +48,19 @@ class Error extends \Exception
|
||||
*
|
||||
* By default, automatic guessing is enabled.
|
||||
*
|
||||
* @param string $message The error message
|
||||
* @param int $lineno The template line where the error occurred
|
||||
* @param Source|null $source The source context where the error occurred
|
||||
* @param string $message The error message
|
||||
* @param int $lineno The template line where the error occurred
|
||||
* @param Source|null $source The source context where the error occurred
|
||||
* @param positive-int|null $columnno The template column where the error occurred
|
||||
*/
|
||||
public function __construct(string $message, int $lineno = -1, ?Source $source = null, ?\Throwable $previous = null)
|
||||
public function __construct(string $message, int $lineno = -1, ?Source $source = null, ?\Throwable $previous = null, ?int $columnno = null)
|
||||
{
|
||||
parent::__construct('', 0, $previous);
|
||||
|
||||
$this->phpFile = $this->getFile();
|
||||
$this->phpLine = $this->getLine();
|
||||
$this->lineno = $lineno;
|
||||
$this->columnno = $columnno;
|
||||
$this->source = $source;
|
||||
$this->rawMessage = $message;
|
||||
$this->updateRepr();
|
||||
@@ -78,6 +82,25 @@ class Error extends \Exception
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 1-based column where the error occurred, or null if unknown.
|
||||
*
|
||||
* @return positive-int|null
|
||||
*/
|
||||
public function getTemplateColumn(): ?int
|
||||
{
|
||||
return $this->columnno;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param positive-int|null $columnno
|
||||
*/
|
||||
public function setTemplateColumn(?int $columnno): void
|
||||
{
|
||||
$this->columnno = $columnno;
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
public function getSourceContext(): ?Source
|
||||
{
|
||||
return $this->source;
|
||||
@@ -127,6 +150,9 @@ class Error extends \Exception
|
||||
}
|
||||
if ($this->lineno > 0) {
|
||||
$this->message .= \sprintf(' at line %d', $this->lineno);
|
||||
if (null !== $this->columnno) {
|
||||
$this->message .= \sprintf(' column %d', $this->columnno);
|
||||
}
|
||||
}
|
||||
if ($punctuation) {
|
||||
$this->message .= $punctuation;
|
||||
|
||||
@@ -65,14 +65,23 @@ final class DotExpressionParser extends AbstractExpressionParser implements Infi
|
||||
$arguments = $this->parseCallableArguments($parser, $token->getLine());
|
||||
}
|
||||
|
||||
if (
|
||||
$expr instanceof NameExpression
|
||||
$isMacroTarget = $expr instanceof NameExpression
|
||||
&& (
|
||||
null !== $parser->getImportedSymbol('template', $expr->getAttribute('name'))
|
||||
|| '_self' === $expr->getAttribute('name') && $attribute instanceof ConstantExpression
|
||||
)
|
||||
|| '_self' === $expr->getAttribute('name')
|
||||
);
|
||||
|
||||
if (
|
||||
$isMacroTarget
|
||||
&& $attribute instanceof ConstantExpression
|
||||
&& \is_string($name = $attribute->getAttribute('value'))
|
||||
&& preg_match('#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#D', $name)
|
||||
) {
|
||||
return new MacroReferenceExpression(new TemplateVariable($expr->getAttribute('name'), $expr->getTemplateLine()), 'macro_'.$attribute->getAttribute('value'), $arguments, $expr->getTemplateLine());
|
||||
return new MacroReferenceExpression(new TemplateVariable($expr->getAttribute('name'), $expr->getTemplateLine()), 'macro_'.$name, $arguments, $expr->getTemplateLine());
|
||||
}
|
||||
|
||||
if ($isMacroTarget && !$attribute instanceof ConstantExpression) {
|
||||
return new MacroReferenceExpression(new TemplateVariable($expr->getAttribute('name'), $expr->getTemplateLine()), $attribute, $arguments, $expr->getTemplateLine());
|
||||
}
|
||||
|
||||
return new GetAttrExpression($expr, $attribute, $arguments, $type, $lineno, $nullSafe);
|
||||
|
||||
@@ -54,7 +54,14 @@ final class FunctionExpressionParser extends AbstractExpressionParser implements
|
||||
$fakeNode = new EmptyNode($line);
|
||||
$fakeNode->setSourceContext($parser->getStream()->getSourceContext());
|
||||
|
||||
return ($function->getParserCallable())($parser, $fakeNode, $args, $line);
|
||||
$node = ($function->getParserCallable())($parser, $fakeNode, $args, $line);
|
||||
// remember the original function name so the sandbox can enforce
|
||||
// the `allowedFunctions` allow-list even though the parser callable
|
||||
// returned a specialized node (e.g. `parent`, `block`, `attribute`).
|
||||
$node->setAttribute('sandboxed_function_name', $name);
|
||||
$node->setAttribute('sandboxed_function', $function);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
if (!isset($this->readyNodes[$class = $function->getNodeClass()])) {
|
||||
|
||||
@@ -95,11 +95,13 @@ final class AttributeExtension extends AbstractExtension
|
||||
'needs_context' => $attribute->needsContext ?? false,
|
||||
'needs_environment' => $attribute->needsEnvironment ?? $this->needsEnvironment($method),
|
||||
'needs_charset' => $attribute->needsCharset ?? false,
|
||||
'needs_is_sandboxed' => $attribute->needsIsSandboxed ?? false,
|
||||
'is_variadic' => $method->isVariadic(),
|
||||
'is_safe' => $attribute->isSafe,
|
||||
'is_safe_callback' => $attribute->isSafeCallback,
|
||||
'pre_escape' => $attribute->preEscape,
|
||||
'preserves_safety' => $attribute->preservesSafety,
|
||||
'always_allowed_in_sandbox' => $attribute->alwaysAllowedInSandbox ?? false,
|
||||
'deprecation_info' => $attribute->deprecationInfo,
|
||||
]);
|
||||
|
||||
@@ -118,9 +120,11 @@ final class AttributeExtension extends AbstractExtension
|
||||
'needs_context' => $attribute->needsContext ?? false,
|
||||
'needs_environment' => $attribute->needsEnvironment ?? $this->needsEnvironment($method),
|
||||
'needs_charset' => $attribute->needsCharset ?? false,
|
||||
'needs_is_sandboxed' => $attribute->needsIsSandboxed ?? false,
|
||||
'is_variadic' => $method->isVariadic(),
|
||||
'is_safe' => $attribute->isSafe,
|
||||
'is_safe_callback' => $attribute->isSafeCallback,
|
||||
'always_allowed_in_sandbox' => $attribute->alwaysAllowedInSandbox ?? false,
|
||||
'deprecation_info' => $attribute->deprecationInfo,
|
||||
]);
|
||||
|
||||
@@ -139,7 +143,9 @@ final class AttributeExtension extends AbstractExtension
|
||||
'needs_context' => $attribute->needsContext ?? false,
|
||||
'needs_environment' => $attribute->needsEnvironment ?? $this->needsEnvironment($method),
|
||||
'needs_charset' => $attribute->needsCharset ?? false,
|
||||
'needs_is_sandboxed' => $attribute->needsIsSandboxed ?? false,
|
||||
'is_variadic' => $method->isVariadic(),
|
||||
'always_allowed_in_sandbox' => $attribute->alwaysAllowedInSandbox ?? false,
|
||||
'deprecation_info' => $attribute->deprecationInfo,
|
||||
]);
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ use Twig\Node\Expression\Unary\NotUnary;
|
||||
use Twig\Node\Expression\Unary\PosUnary;
|
||||
use Twig\Node\Expression\Unary\SpreadUnary;
|
||||
use Twig\Node\Node;
|
||||
use Twig\NodeVisitor\CorrectnessNodeVisitor;
|
||||
use Twig\Parser;
|
||||
use Twig\Sandbox\SecurityNotAllowedMethodError;
|
||||
use Twig\Sandbox\SecurityNotAllowedPropertyError;
|
||||
@@ -258,19 +259,19 @@ final class CoreExtension extends AbstractExtension
|
||||
new TwigFilter('striptags', [self::class, 'striptags']),
|
||||
new TwigFilter('trim', [self::class, 'trim']),
|
||||
new TwigFilter('nl2br', [self::class, 'nl2br'], ['pre_escape' => 'html', 'is_safe' => ['html']]),
|
||||
new TwigFilter('spaceless', [self::class, 'spaceless'], ['is_safe' => ['html'], 'deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.12')]),
|
||||
new TwigFilter('spaceless', [self::class, 'spaceless'], ['pre_escape' => 'html', 'is_safe' => ['html'], 'deprecation_info' => new DeprecatedCallableInfo('twig/twig', '3.12')]),
|
||||
|
||||
// array helpers
|
||||
new TwigFilter('join', [self::class, 'join']),
|
||||
new TwigFilter('split', [self::class, 'split'], ['needs_charset' => true]),
|
||||
new TwigFilter('sort', [self::class, 'sort'], ['needs_environment' => true]),
|
||||
new TwigFilter('sort', [self::class, 'sort'], ['needs_environment' => true, 'needs_is_sandboxed' => true]),
|
||||
new TwigFilter('merge', [self::class, 'merge']),
|
||||
new TwigFilter('batch', [self::class, 'batch']),
|
||||
new TwigFilter('column', [self::class, 'column']),
|
||||
new TwigFilter('filter', [self::class, 'filter'], ['needs_environment' => true]),
|
||||
new TwigFilter('map', [self::class, 'map'], ['needs_environment' => true]),
|
||||
new TwigFilter('reduce', [self::class, 'reduce'], ['needs_environment' => true]),
|
||||
new TwigFilter('find', [self::class, 'find'], ['needs_environment' => true]),
|
||||
new TwigFilter('column', [self::class, 'column'], ['needs_environment' => true, 'needs_is_sandboxed' => true]),
|
||||
new TwigFilter('filter', [self::class, 'filter'], ['needs_environment' => true, 'needs_is_sandboxed' => true]),
|
||||
new TwigFilter('map', [self::class, 'map'], ['needs_environment' => true, 'needs_is_sandboxed' => true]),
|
||||
new TwigFilter('reduce', [self::class, 'reduce'], ['needs_environment' => true, 'needs_is_sandboxed' => true]),
|
||||
new TwigFilter('find', [self::class, 'find'], ['needs_environment' => true, 'needs_is_sandboxed' => true]),
|
||||
|
||||
// string/array filters
|
||||
new TwigFilter('reverse', [self::class, 'reverse'], ['needs_charset' => true]),
|
||||
@@ -310,25 +311,27 @@ final class CoreExtension extends AbstractExtension
|
||||
public function getTests(): array
|
||||
{
|
||||
return [
|
||||
new TwigTest('even', null, ['node_class' => EvenTest::class]),
|
||||
new TwigTest('odd', null, ['node_class' => OddTest::class]),
|
||||
new TwigTest('defined', null, ['node_class' => DefinedTest::class]),
|
||||
new TwigTest('same as', null, ['node_class' => SameasTest::class, 'one_mandatory_argument' => true]),
|
||||
new TwigTest('none', null, ['node_class' => NullTest::class]),
|
||||
new TwigTest('null', null, ['node_class' => NullTest::class]),
|
||||
new TwigTest('divisible by', null, ['node_class' => DivisiblebyTest::class, 'one_mandatory_argument' => true]),
|
||||
new TwigTest('even', null, ['node_class' => EvenTest::class, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('odd', null, ['node_class' => OddTest::class, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('defined', null, ['node_class' => DefinedTest::class, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('same as', null, ['node_class' => SameasTest::class, 'one_mandatory_argument' => true, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('none', null, ['node_class' => NullTest::class, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('null', null, ['node_class' => NullTest::class, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('divisible by', null, ['node_class' => DivisiblebyTest::class, 'one_mandatory_argument' => true, 'always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('constant', null, ['node_class' => ConstantTest::class]),
|
||||
new TwigTest('empty', [self::class, 'testEmpty']),
|
||||
new TwigTest('iterable', 'is_iterable'),
|
||||
new TwigTest('sequence', [self::class, 'testSequence']),
|
||||
new TwigTest('mapping', [self::class, 'testMapping']),
|
||||
new TwigTest('true', null, ['node_class' => TrueTest::class]),
|
||||
new TwigTest('empty', [self::class, 'testEmpty'], ['always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('iterable', 'is_iterable', ['always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('sequence', [self::class, 'testSequence'], ['always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('mapping', [self::class, 'testMapping'], ['always_allowed_in_sandbox' => true]),
|
||||
new TwigTest('true', null, ['node_class' => TrueTest::class, 'always_allowed_in_sandbox' => true]),
|
||||
];
|
||||
}
|
||||
|
||||
public function getNodeVisitors(): array
|
||||
{
|
||||
return [];
|
||||
return [
|
||||
new CorrectnessNodeVisitor(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getExpressionParsers(): array
|
||||
@@ -1044,7 +1047,7 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function sort(Environment $env, $array, $arrow = null): array
|
||||
public static function sort(Environment $env, bool $isSandboxed, $array, $arrow = null): array
|
||||
{
|
||||
if ($array instanceof \Traversable) {
|
||||
$array = iterator_to_array($array);
|
||||
@@ -1053,7 +1056,7 @@ final class CoreExtension extends AbstractExtension
|
||||
}
|
||||
|
||||
if (null !== $arrow) {
|
||||
self::checkArrow($env, $arrow, 'sort', 'filter');
|
||||
self::checkArrow($isSandboxed, $arrow, 'sort', 'filter');
|
||||
|
||||
uasort($array, $arrow);
|
||||
} else {
|
||||
@@ -1490,9 +1493,11 @@ final class CoreExtension extends AbstractExtension
|
||||
* @param bool $ignoreMissing Whether to ignore missing templates or not
|
||||
* @param bool $sandboxed Whether to sandbox the template or not
|
||||
*
|
||||
* @return string|Markup
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function include(Environment $env, $context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false): string
|
||||
public static function include(Environment $env, $context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false)
|
||||
{
|
||||
$alreadySandboxed = false;
|
||||
$sandbox = null;
|
||||
@@ -1519,11 +1524,9 @@ final class CoreExtension extends AbstractExtension
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($isSandboxed) {
|
||||
$loaded->unwrap()->checkSecurity();
|
||||
}
|
||||
$rendered = $loaded->render($variables);
|
||||
|
||||
return $loaded->render($variables);
|
||||
return '' === $rendered ? '' : new Markup($rendered, $env->getCharset());
|
||||
} finally {
|
||||
if ($isSandboxed && !$alreadySandboxed) {
|
||||
$sandbox->disableSandbox();
|
||||
@@ -1686,6 +1689,9 @@ final class CoreExtension extends AbstractExtension
|
||||
public static function getAttribute(Environment $env, Source $source, $object, $item, array $arguments = [], $type = Template::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false, $sandboxed = false, int $lineno = -1)
|
||||
{
|
||||
$propertyNotAllowedError = null;
|
||||
if ($sandboxed && $item instanceof \Stringable) {
|
||||
$env->getExtension(SandboxExtension::class)->ensureToStringAllowed($item, $lineno, $source);
|
||||
}
|
||||
|
||||
// array
|
||||
if (Template::METHOD_CALL !== $type) {
|
||||
@@ -1695,6 +1701,10 @@ final class CoreExtension extends AbstractExtension
|
||||
try {
|
||||
$env->getExtension(SandboxExtension::class)->checkPropertyAllowed($object, $arrayItem, $lineno, $source);
|
||||
} catch (SecurityNotAllowedPropertyError $propertyNotAllowedError) {
|
||||
// The methodCheck path expects $item to be a string; stringify it here
|
||||
// to avoid PHP 8.1+ implicit float-to-int deprecations on downstream
|
||||
// array key lookups (e.g. isset($cache[$class][$item])).
|
||||
$item = (string) $item;
|
||||
goto methodCheck;
|
||||
}
|
||||
}
|
||||
@@ -1788,10 +1798,6 @@ final class CoreExtension extends AbstractExtension
|
||||
|
||||
static $propertyCheckers = [];
|
||||
|
||||
if ($object instanceof \Closure && '__invoke' === $item) {
|
||||
return $isDefinedTest ? true : $object();
|
||||
}
|
||||
|
||||
if (isset($object->$item)
|
||||
|| ($propertyCheckers[$object::class][$item] ??= self::getPropertyChecker($object::class, $item))($object, $item)
|
||||
) {
|
||||
@@ -1840,14 +1846,14 @@ final class CoreExtension extends AbstractExtension
|
||||
$classCache[$lcName = $lcMethods[$i]] = $method;
|
||||
|
||||
if ('g' === $lcName[0] && str_starts_with($lcName, 'get')) {
|
||||
$name = substr($method, 3);
|
||||
$lcName = substr($lcName, 3);
|
||||
$prefixLength = 3;
|
||||
$lcName = substr($lcName, $prefixLength);
|
||||
} elseif ('i' === $lcName[0] && str_starts_with($lcName, 'is')) {
|
||||
$name = substr($method, 2);
|
||||
$lcName = substr($lcName, 2);
|
||||
$prefixLength = 2;
|
||||
$lcName = substr($lcName, $prefixLength);
|
||||
} elseif ('h' === $lcName[0] && str_starts_with($lcName, 'has')) {
|
||||
$name = substr($method, 3);
|
||||
$lcName = substr($lcName, 3);
|
||||
$prefixLength = 3;
|
||||
$lcName = substr($lcName, $prefixLength);
|
||||
if (\in_array('is'.$lcName, $lcMethods, true)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1855,8 +1861,11 @@ final class CoreExtension extends AbstractExtension
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip get() and is() methods (in which case, $name is empty)
|
||||
if ($name) {
|
||||
// skip get(), is() and has() methods (in which case, $lcName is empty)
|
||||
if ($lcName) {
|
||||
// camelCase name (e.g. getFooBar() -> fooBar)
|
||||
$name = $lcName[0].substr($method, $prefixLength + 1);
|
||||
|
||||
if (!isset($classCache[$name])) {
|
||||
$classCache[$name] = $method;
|
||||
}
|
||||
@@ -1946,7 +1955,7 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function column($array, $name, $index = null): array
|
||||
public static function column(Environment $env, bool $isSandboxed, $array, $name, $index = null): array
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "column" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
|
||||
@@ -1956,6 +1965,21 @@ final class CoreExtension extends AbstractExtension
|
||||
$array = iterator_to_array($array);
|
||||
}
|
||||
|
||||
if ($isSandboxed) {
|
||||
// The sandbox might be enabled via a SourcePolicyInterface, in which case the SandboxExtension
|
||||
// would not consider the sandbox active without the current Source: $isSandboxed is already
|
||||
// computed against the call-site source, so check the policy directly to honor that decision.
|
||||
$policy = $env->getExtension(SandboxExtension::class)->getSecurityPolicy();
|
||||
foreach ($array as $item) {
|
||||
if (\is_object($item)) {
|
||||
$policy->checkPropertyAllowed($item, (string) $name);
|
||||
if (null !== $index) {
|
||||
$policy->checkPropertyAllowed($item, (string) $index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_column($array, $name, $index);
|
||||
}
|
||||
|
||||
@@ -1964,13 +1988,13 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function filter(Environment $env, $array, $arrow)
|
||||
public static function filter(Environment $env, bool $isSandboxed, $array, $arrow)
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "filter" filter expects a sequence/mapping or "Traversable", got "%s".', get_debug_type($array)));
|
||||
}
|
||||
|
||||
self::checkArrow($env, $arrow, 'filter', 'filter');
|
||||
self::checkArrow($isSandboxed, $arrow, 'filter', 'filter');
|
||||
|
||||
if (\is_array($array)) {
|
||||
return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH);
|
||||
@@ -1985,13 +2009,13 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function find(Environment $env, $array, $arrow)
|
||||
public static function find(Environment $env, bool $isSandboxed, $array, $arrow)
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "find" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
|
||||
}
|
||||
|
||||
self::checkArrow($env, $arrow, 'find', 'filter');
|
||||
self::checkArrow($isSandboxed, $arrow, 'find', 'filter');
|
||||
|
||||
foreach ($array as $k => $v) {
|
||||
if ($arrow($v, $k)) {
|
||||
@@ -2007,13 +2031,13 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function map(Environment $env, $array, $arrow)
|
||||
public static function map(Environment $env, bool $isSandboxed, $array, $arrow)
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "map" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
|
||||
}
|
||||
|
||||
self::checkArrow($env, $arrow, 'map', 'filter');
|
||||
self::checkArrow($isSandboxed, $arrow, 'map', 'filter');
|
||||
|
||||
$r = [];
|
||||
foreach ($array as $k => $v) {
|
||||
@@ -2028,13 +2052,13 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function reduce(Environment $env, $array, $arrow, $initial = null)
|
||||
public static function reduce(Environment $env, bool $isSandboxed, $array, $arrow, $initial = null)
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "reduce" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
|
||||
}
|
||||
|
||||
self::checkArrow($env, $arrow, 'reduce', 'filter');
|
||||
self::checkArrow($isSandboxed, $arrow, 'reduce', 'filter');
|
||||
|
||||
$accumulator = $initial;
|
||||
foreach ($array as $key => $value) {
|
||||
@@ -2049,13 +2073,13 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function arraySome(Environment $env, $array, $arrow)
|
||||
public static function arraySome(Environment $env, $array, $arrow, bool $isSandboxed = false)
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "has some" test expects a sequence or a mapping, got "%s".', get_debug_type($array)));
|
||||
}
|
||||
|
||||
self::checkArrow($env, $arrow, 'has some', 'operator');
|
||||
self::checkArrow($isSandboxed, $arrow, 'has some', 'operator');
|
||||
|
||||
foreach ($array as $k => $v) {
|
||||
if ($arrow($v, $k)) {
|
||||
@@ -2071,13 +2095,13 @@ final class CoreExtension extends AbstractExtension
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function arrayEvery(Environment $env, $array, $arrow)
|
||||
public static function arrayEvery(Environment $env, $array, $arrow, bool $isSandboxed = false)
|
||||
{
|
||||
if (!is_iterable($array)) {
|
||||
throw new RuntimeError(\sprintf('The "has every" test expects a sequence or a mapping, got "%s".', get_debug_type($array)));
|
||||
}
|
||||
|
||||
self::checkArrow($env, $arrow, 'has every', 'operator');
|
||||
self::checkArrow($isSandboxed, $arrow, 'has every', 'operator');
|
||||
|
||||
foreach ($array as $k => $v) {
|
||||
if (!$arrow($v, $k)) {
|
||||
@@ -2091,13 +2115,13 @@ final class CoreExtension extends AbstractExtension
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public static function checkArrow(Environment $env, $arrow, $thing, $type)
|
||||
public static function checkArrow(bool $isSandboxed, $arrow, $thing, $type)
|
||||
{
|
||||
if ($arrow instanceof \Closure) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($env->hasExtension(SandboxExtension::class) && $env->getExtension(SandboxExtension::class)->isSandboxed()) {
|
||||
if ($isSandboxed) {
|
||||
throw new RuntimeError(\sprintf('The callable passed to the "%s" %s must be a Closure in sandbox mode.', $thing, $type));
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ final class EscaperExtension extends AbstractExtension
|
||||
}
|
||||
|
||||
$this->environment = $environment;
|
||||
$this->escaper = $environment->getRuntime(EscaperRuntime::class);
|
||||
$this->escaper = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,16 +140,14 @@ final class EscaperExtension extends AbstractExtension
|
||||
{
|
||||
trigger_deprecation('twig/twig', '3.10', 'The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::setEscaper()" method instead (be warned that Environment is not passed anymore to the callable).', __METHOD__);
|
||||
|
||||
if (!isset($this->environment)) {
|
||||
throw new \LogicException(\sprintf('You must call "setEnvironment()" before calling "%s()".', __METHOD__));
|
||||
}
|
||||
$escaper = $this->getEscaper(__METHOD__);
|
||||
|
||||
$this->escapers[$strategy] = $callable;
|
||||
$callable = function ($string, $charset) use ($callable) {
|
||||
return $callable($this->environment, $string, $charset);
|
||||
};
|
||||
|
||||
$this->escaper->setEscaper($strategy, $callable);
|
||||
$escaper->setEscaper($strategy, $callable);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,11 +173,7 @@ final class EscaperExtension extends AbstractExtension
|
||||
{
|
||||
trigger_deprecation('twig/twig', '3.10', 'The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::setSafeClasses()" method instead.', __METHOD__);
|
||||
|
||||
if (!isset($this->escaper)) {
|
||||
throw new \LogicException(\sprintf('You must call "setEnvironment()" before calling "%s()".', __METHOD__));
|
||||
}
|
||||
|
||||
$this->escaper->setSafeClasses($safeClasses);
|
||||
$this->getEscaper(__METHOD__)->setSafeClasses($safeClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,11 +185,20 @@ final class EscaperExtension extends AbstractExtension
|
||||
{
|
||||
trigger_deprecation('twig/twig', '3.10', 'The "%s()" method is deprecated, use the "Twig\Runtime\EscaperRuntime::addSafeClass()" method instead.', __METHOD__);
|
||||
|
||||
if (!isset($this->escaper)) {
|
||||
throw new \LogicException(\sprintf('You must call "setEnvironment()" before calling "%s()".', __METHOD__));
|
||||
$this->getEscaper(__METHOD__)->addSafeClass($class, $strategies);
|
||||
}
|
||||
|
||||
private function getEscaper(string $fromMethod): EscaperRuntime
|
||||
{
|
||||
if (isset($this->escaper)) {
|
||||
return $this->escaper;
|
||||
}
|
||||
|
||||
$this->escaper->addSafeClass($class, $strategies);
|
||||
if (isset($this->environment)) {
|
||||
return $this->escaper = $this->environment->getRuntime(EscaperRuntime::class);
|
||||
}
|
||||
|
||||
throw new \LogicException(\sprintf('You must call "setEnvironment()" before calling "%s()".', $fromMethod));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,10 @@ final class SandboxExtension extends AbstractExtension
|
||||
|
||||
public function __construct(SecurityPolicyInterface $policy, $sandboxed = false, ?SourcePolicyInterface $sourcePolicy = null)
|
||||
{
|
||||
if (null !== $sourcePolicy) {
|
||||
trigger_deprecation('twig/twig', '3.27.0', 'The "%s" interface is deprecated with no replacement, do not pass an instance to "%s".', SourcePolicyInterface::class, self::class);
|
||||
}
|
||||
|
||||
$this->policy = $policy;
|
||||
$this->sandboxedGlobally = $sandboxed;
|
||||
$this->sourcePolicy = $sourcePolicy;
|
||||
@@ -82,11 +86,29 @@ final class SandboxExtension extends AbstractExtension
|
||||
return $this->policy;
|
||||
}
|
||||
|
||||
public function checkSecurity($tags, $filters, $functions, ?Source $source = null): void
|
||||
public function checkSecurity($tags, $filters, $functions, $tests = [], $source = null): void
|
||||
{
|
||||
if ($this->isSandboxed($source)) {
|
||||
$this->policy->checkSecurity($tags, $filters, $functions);
|
||||
// BC: previous signature was checkSecurity($tags, $filters, $functions, ?Source $source = null);
|
||||
// detect a legacy call where the 4th positional argument was the Source.
|
||||
if ($tests instanceof Source || (null === $tests && \func_num_args() < 5)) {
|
||||
trigger_deprecation('twig/twig', '3.28', 'Passing a "Twig\Source" as the 4th argument of "%s()" is deprecated; pass an array of tests instead.', __METHOD__);
|
||||
$source = $tests;
|
||||
$tests = [];
|
||||
}
|
||||
|
||||
if (!$this->isSandboxed($source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((new \ReflectionMethod($this->policy, 'checkSecurity'))->getNumberOfParameters() >= 4) {
|
||||
$this->policy->checkSecurity($tags, $filters, $functions, $tests);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
trigger_deprecation('twig/twig', '3.28', 'The "%s::checkSecurity()" method will take a 4th "array $tests" argument in 4.0; not declaring it is deprecated.', $this->policy::class);
|
||||
|
||||
$this->policy->checkSecurity($tags, $filters, $functions);
|
||||
}
|
||||
|
||||
public function checkMethodAllowed($obj, $method, int $lineno = -1, ?Source $source = null): void
|
||||
@@ -121,14 +143,43 @@ final class SandboxExtension extends AbstractExtension
|
||||
* @throws SecurityNotAllowedMethodError
|
||||
*/
|
||||
public function ensureToStringAllowed($obj, int $lineno = -1, ?Source $source = null)
|
||||
{
|
||||
return $this->doEnsureToStringAllowed($obj, $lineno, $source, new \SplObjectStorage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Materialises a spread operand and runs the policy on every element.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @throws SecurityNotAllowedMethodError
|
||||
*/
|
||||
public function ensureSpreadAllowed(iterable $obj, int $lineno = -1, ?Source $source = null): array
|
||||
{
|
||||
$seen = new \SplObjectStorage();
|
||||
if ($obj instanceof \Traversable) {
|
||||
$seen[$obj] = true;
|
||||
$obj = iterator_to_array($obj);
|
||||
}
|
||||
|
||||
$this->ensureToStringAllowedForArray($obj, $lineno, $source, $seen);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
private function doEnsureToStringAllowed($obj, int $lineno, ?Source $source, \SplObjectStorage $seen)
|
||||
{
|
||||
if (\is_array($obj)) {
|
||||
$this->ensureToStringAllowedForArray($obj, $lineno, $source);
|
||||
$this->ensureToStringAllowedForArray($obj, $lineno, $source, $seen);
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
if ($obj instanceof \Stringable && $this->isSandboxed($source)) {
|
||||
if (!$this->isSandboxed($source)) {
|
||||
return $obj;
|
||||
}
|
||||
|
||||
if ($obj instanceof \Stringable) {
|
||||
try {
|
||||
$this->policy->checkMethodAllowed($obj, '__toString');
|
||||
} catch (SecurityNotAllowedMethodError $e) {
|
||||
@@ -139,10 +190,38 @@ final class SandboxExtension extends AbstractExtension
|
||||
}
|
||||
}
|
||||
|
||||
// Elements yielded by a Traversable may be string-coerced downstream
|
||||
// (e.g. by `join`/`replace`), bypassing the policy. Check them now.
|
||||
if ($obj instanceof \Traversable) {
|
||||
if (isset($seen[$obj])) {
|
||||
return $obj;
|
||||
}
|
||||
$seen[$obj] = true;
|
||||
|
||||
// IteratorAggregate::getIterator() is idempotent, so we can walk
|
||||
// the elements and return the original object: host code typed
|
||||
// against a specific class (e.g. FormView) keeps working.
|
||||
if ($obj instanceof \IteratorAggregate) {
|
||||
foreach ($obj as $v) {
|
||||
$this->doEnsureToStringAllowed($v, $lineno, $source, $seen);
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
// Single-pass Iterator/Generator: materialise to validate.
|
||||
$array = iterator_to_array($obj);
|
||||
$this->ensureToStringAllowedForArray($array, $lineno, $source, $seen);
|
||||
|
||||
if (!$obj instanceof \Stringable) {
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
private function ensureToStringAllowedForArray(array $obj, int $lineno, ?Source $source, array &$stack = []): void
|
||||
private function ensureToStringAllowedForArray(array $obj, int $lineno, ?Source $source, \SplObjectStorage $seen, array &$stack = []): void
|
||||
{
|
||||
foreach ($obj as $k => $v) {
|
||||
if (!$v) {
|
||||
@@ -150,7 +229,7 @@ final class SandboxExtension extends AbstractExtension
|
||||
}
|
||||
|
||||
if (!\is_array($v)) {
|
||||
$this->ensureToStringAllowed($v, $lineno, $source);
|
||||
$this->doEnsureToStringAllowed($v, $lineno, $source, $seen);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -162,7 +241,7 @@ final class SandboxExtension extends AbstractExtension
|
||||
$stack[$r->getId()] = true;
|
||||
}
|
||||
|
||||
$this->ensureToStringAllowedForArray($v, $lineno, $source, $stack);
|
||||
$this->ensureToStringAllowedForArray($v, $lineno, $source, $seen, $stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ final class StringLoaderExtension extends AbstractExtension
|
||||
*
|
||||
* {{ include(template_from_string("Hello {{ name }}")) }}
|
||||
*
|
||||
* Never expose `template_from_string` to untrusted template
|
||||
* authors (like in a sandboxed environment). See the docs for more details.
|
||||
*
|
||||
* @param string|null $name An optional name of the template to be used in error messages
|
||||
*
|
||||
* @internal
|
||||
|
||||
@@ -62,6 +62,8 @@ class Lexer
|
||||
public const REGEX_INLINE_COMMENT = '/#[^\n]*/A';
|
||||
public const PUNCTUATION = '()[]{}?:.,|';
|
||||
|
||||
private const REGEX_RAW_INLINE_COMMENT = '/#[^\r\n]*/A';
|
||||
|
||||
private const SPECIAL_CHARS = [
|
||||
'f' => "\f",
|
||||
'n' => "\n",
|
||||
@@ -113,7 +115,7 @@ class Lexer
|
||||
'|'.
|
||||
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]*
|
||||
'|'.
|
||||
preg_quote($this->options['tag_block'][1], '#').'\n?'. // %}\n?
|
||||
preg_quote($this->options['tag_block'][1], '#').'(?:\r\n?|\n)?'. // %}(?:\r\n?|\n)?
|
||||
')
|
||||
}Ax',
|
||||
|
||||
@@ -143,7 +145,7 @@ class Lexer
|
||||
'|'.
|
||||
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_comment'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~#}[ \t\0\x0B]*
|
||||
'|'.
|
||||
preg_quote($this->options['tag_comment'][1], '#').'\n?'. // #}\n?
|
||||
preg_quote($this->options['tag_comment'][1], '#').'(?:\r\n?|\n)?'. // #}(?:\r\n?|\n)?
|
||||
')
|
||||
}sx',
|
||||
|
||||
@@ -187,7 +189,7 @@ class Lexer
|
||||
$this->initialize();
|
||||
|
||||
$this->source = $source;
|
||||
$this->code = str_replace(["\r\n", "\r"], "\n", $source->getCode());
|
||||
$this->code = $source->getCode();
|
||||
$this->cursor = 0;
|
||||
$this->lineno = 1;
|
||||
$this->end = \strlen($this->code);
|
||||
@@ -241,8 +243,9 @@ class Lexer
|
||||
{
|
||||
// if no matches are left we return the rest of the template as simple text token
|
||||
if ($this->position == \count($this->positions[0]) - 1) {
|
||||
$this->pushToken(Token::TEXT_TYPE, substr($this->code, $this->cursor));
|
||||
$this->cursor = $this->end;
|
||||
$text = substr($this->code, $this->cursor);
|
||||
$this->pushToken(Token::TEXT_TYPE, $this->normalizeNewlines($text));
|
||||
$this->moveCursor($text);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -270,15 +273,20 @@ class Lexer
|
||||
$text = rtrim($text, " \t\0\x0B");
|
||||
}
|
||||
}
|
||||
$this->pushToken(Token::TEXT_TYPE, $text);
|
||||
$this->moveCursor($textContent.$position[0]);
|
||||
$this->pushToken(Token::TEXT_TYPE, $this->normalizeNewlines($text));
|
||||
$this->moveCursor($textContent);
|
||||
|
||||
switch ($this->positions[1][$this->position][0]) {
|
||||
case $this->options['tag_comment'][0]:
|
||||
$this->moveCursor($position[0]);
|
||||
$this->lexComment();
|
||||
break;
|
||||
|
||||
case $this->options['tag_block'][0]:
|
||||
$lineno = $this->lineno;
|
||||
$cursor = $this->cursor;
|
||||
$this->moveCursor($position[0]);
|
||||
|
||||
// raw data?
|
||||
if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, 0, $this->cursor)) {
|
||||
$this->moveCursor($match[0]);
|
||||
@@ -288,14 +296,17 @@ class Lexer
|
||||
$this->moveCursor($match[0]);
|
||||
$this->lineno = (int) $match[1];
|
||||
} else {
|
||||
$this->pushToken(Token::BLOCK_START_TYPE);
|
||||
$this->pushToken(Token::BLOCK_START_TYPE, '', $cursor, $lineno);
|
||||
$this->pushState(self::STATE_BLOCK);
|
||||
$this->currentVarBlockLine = $this->lineno;
|
||||
}
|
||||
break;
|
||||
|
||||
case $this->options['tag_variable'][0]:
|
||||
$this->pushToken(Token::VAR_START_TYPE);
|
||||
$lineno = $this->lineno;
|
||||
$cursor = $this->cursor;
|
||||
$this->moveCursor($position[0]);
|
||||
$this->pushToken(Token::VAR_START_TYPE, '', $cursor, $lineno);
|
||||
$this->pushState(self::STATE_VAR);
|
||||
$this->currentVarBlockLine = $this->lineno;
|
||||
break;
|
||||
@@ -305,8 +316,7 @@ class Lexer
|
||||
private function lexBlock(): void
|
||||
{
|
||||
if (!$this->brackets && preg_match($this->regexes['lex_block'], $this->code, $match, 0, $this->cursor)) {
|
||||
$this->pushToken(Token::BLOCK_END_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->pushClosingToken(Token::BLOCK_END_TYPE, $match[0]);
|
||||
$this->popState();
|
||||
} else {
|
||||
$this->lexExpression();
|
||||
@@ -316,8 +326,7 @@ class Lexer
|
||||
private function lexVar(): void
|
||||
{
|
||||
if (!$this->brackets && preg_match($this->regexes['lex_var'], $this->code, $match, 0, $this->cursor)) {
|
||||
$this->pushToken(Token::VAR_END_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->pushClosingToken(Token::VAR_END_TYPE, $match[0]);
|
||||
$this->popState();
|
||||
} else {
|
||||
$this->lexExpression();
|
||||
@@ -358,11 +367,11 @@ class Lexer
|
||||
elseif (str_contains(self::PUNCTUATION, $this->code[$this->cursor])) {
|
||||
$this->checkBrackets($this->code[$this->cursor]);
|
||||
$this->pushToken(Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
|
||||
++$this->cursor;
|
||||
$this->moveCursor($this->code[$this->cursor]);
|
||||
}
|
||||
// strings
|
||||
elseif (preg_match(self::REGEX_STRING, $this->code, $match, 0, $this->cursor)) {
|
||||
$this->pushToken(Token::STRING_TYPE, $this->stripcslashes(substr($match[0], 1, -1), substr($match[0], 0, 1)));
|
||||
$this->pushToken(Token::STRING_TYPE, $this->stripcslashes($this->normalizeNewlines(substr($match[0], 1, -1)), substr($match[0], 0, 1)));
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// opening double quoted string
|
||||
@@ -372,12 +381,12 @@ class Lexer
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// inline comment
|
||||
elseif (preg_match(self::REGEX_INLINE_COMMENT, $this->code, $match, 0, $this->cursor)) {
|
||||
elseif (preg_match(self::REGEX_RAW_INLINE_COMMENT, $this->code, $match, 0, $this->cursor)) {
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// unlexable
|
||||
else {
|
||||
throw new SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
|
||||
throw new SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source, columnno: $this->source->getColumn($this->cursor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +435,7 @@ class Lexer
|
||||
while ($i + 1 < $length && ctype_digit($str[$i + 1]) && $str[$i + 1] < '8' && \strlen($octal) < 3) {
|
||||
$octal .= $str[++$i];
|
||||
}
|
||||
$result .= \chr(octdec($octal));
|
||||
$result .= \chr(octdec($octal) % 256);
|
||||
} else {
|
||||
trigger_deprecation('twig/twig', '3.12', 'Character "%s" should not be escaped; the "\" character is ignored in Twig 3 but will not be in Twig 4. Please remove the extra "\" character at position %d in "%s" at line %d.', $nextChar, $i + 1, $this->source->getName(), $this->lineno);
|
||||
$result .= $nextChar;
|
||||
@@ -444,6 +453,7 @@ class Lexer
|
||||
throw new SyntaxError('Unexpected end of file: Unclosed "verbatim" block.', $this->lineno, $this->source);
|
||||
}
|
||||
|
||||
$offset = $this->cursor;
|
||||
$text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
|
||||
$this->moveCursor($text.$match[0][0]);
|
||||
|
||||
@@ -459,7 +469,7 @@ class Lexer
|
||||
}
|
||||
}
|
||||
|
||||
$this->pushToken(Token::TEXT_TYPE, $text);
|
||||
$this->pushToken(Token::TEXT_TYPE, $this->normalizeNewlines($text), $offset);
|
||||
}
|
||||
|
||||
private function lexComment(): void
|
||||
@@ -479,7 +489,7 @@ class Lexer
|
||||
$this->moveCursor($match[0]);
|
||||
$this->pushState(self::STATE_INTERPOLATION);
|
||||
} elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, 0, $this->cursor) && '' !== $match[0]) {
|
||||
$this->pushToken(Token::STRING_TYPE, $this->stripcslashes($match[0], '"'));
|
||||
$this->pushToken(Token::STRING_TYPE, $this->stripcslashes($this->normalizeNewlines($match[0]), '"'));
|
||||
$this->moveCursor($match[0]);
|
||||
} elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
|
||||
[$expect, $lineno] = array_pop($this->brackets);
|
||||
@@ -488,10 +498,10 @@ class Lexer
|
||||
}
|
||||
|
||||
$this->popState();
|
||||
++$this->cursor;
|
||||
$this->moveCursor($match[0]);
|
||||
} else {
|
||||
// unlexable
|
||||
throw new SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
|
||||
throw new SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source, columnno: $this->source->getColumn($this->cursor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,28 +510,47 @@ class Lexer
|
||||
$bracket = end($this->brackets);
|
||||
if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, 0, $this->cursor)) {
|
||||
array_pop($this->brackets);
|
||||
$this->pushToken(Token::INTERPOLATION_END_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->pushClosingToken(Token::INTERPOLATION_END_TYPE, $match[0]);
|
||||
$this->popState();
|
||||
} else {
|
||||
$this->lexExpression();
|
||||
}
|
||||
}
|
||||
|
||||
private function pushToken($type, $value = ''): void
|
||||
private function pushToken($type, $value = '', ?int $offset = null, ?int $lineno = null): void
|
||||
{
|
||||
// do not push empty text tokens
|
||||
if (Token::TEXT_TYPE === $type && '' === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->tokens[] = new Token($type, $value, $this->lineno);
|
||||
// by default the token starts at the current cursor; callers that
|
||||
// emit a token after consuming it must pass an explicit offset
|
||||
$this->tokens[] = new Token($type, $value, $lineno ?? $this->lineno, $offset ?? $this->cursor);
|
||||
}
|
||||
|
||||
private function moveCursor($text): void
|
||||
{
|
||||
$this->cursor += \strlen($text);
|
||||
$this->lineno += substr_count($text, "\n");
|
||||
// count "\r\n" and "\r" as a single newline without allocating a
|
||||
// normalized copy when the chunk has no carriage return (common case)
|
||||
$this->lineno += str_contains($text, "\r") ? substr_count($this->normalizeNewlines($text), "\n") : substr_count($text, "\n");
|
||||
}
|
||||
|
||||
private function normalizeNewlines(string $text): string
|
||||
{
|
||||
return str_replace(["\r\n", "\r"], "\n", $text);
|
||||
}
|
||||
|
||||
private function pushClosingToken(int $type, string $match): void
|
||||
{
|
||||
$leadingWhitespaceLength = \strlen($match) - \strlen(ltrim($match));
|
||||
if ($leadingWhitespaceLength) {
|
||||
$this->moveCursor(substr($match, 0, $leadingWhitespaceLength));
|
||||
}
|
||||
|
||||
$this->pushToken($type);
|
||||
$this->moveCursor(substr($match, $leadingWhitespaceLength));
|
||||
}
|
||||
|
||||
private function getOperatorRegex(): string
|
||||
@@ -580,7 +609,7 @@ class Lexer
|
||||
} elseif (\in_array($code, $this->closingBrackets, true)) {
|
||||
// closing bracket
|
||||
if (!$this->brackets) {
|
||||
throw new SyntaxError(\sprintf('Unexpected "%s".', $code), $this->lineno, $this->source);
|
||||
throw new SyntaxError(\sprintf('Unexpected "%s".', $code), $this->lineno, $this->source, columnno: $this->source->getColumn($this->cursor));
|
||||
}
|
||||
|
||||
[$expect, $lineno] = array_pop($this->brackets);
|
||||
|
||||
@@ -14,6 +14,16 @@ namespace Twig;
|
||||
/**
|
||||
* Marks a content as safe.
|
||||
*
|
||||
* Instances of this class (and existing subclasses) are trusted by the Twig
|
||||
* sandbox: method calls and property accesses on a Markup instance bypass the
|
||||
* SecurityPolicy method/property allowlists. This is by design: Markup
|
||||
* represents content that has already been deemed safe to output.
|
||||
*
|
||||
* This class is considered final as of Twig 3.28 and will be final in Twig
|
||||
* 4.0.
|
||||
*
|
||||
* @final since Twig 3.28
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Markup implements \Countable, \JsonSerializable, \Stringable
|
||||
|
||||
@@ -27,7 +27,6 @@ class CheckSecurityCallNode extends Node
|
||||
{
|
||||
$compiler
|
||||
->write("\$this->sandbox = \$this->extensions[SandboxExtension::class];\n")
|
||||
->write("\$this->checkSecurity();\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user